@zihanw/pi-forge 0.4.0 → 0.4.1

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.
Files changed (109) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.zh-CN.md +3 -3
  3. package/dist/agent-profile.d.ts +24 -1
  4. package/dist/agent-profile.d.ts.map +1 -1
  5. package/dist/agent-profile.js +146 -36
  6. package/dist/agent-profile.js.map +1 -1
  7. package/dist/catalog.d.ts +27 -0
  8. package/dist/catalog.d.ts.map +1 -0
  9. package/dist/catalog.js +59 -0
  10. package/dist/catalog.js.map +1 -0
  11. package/dist/forge-config.d.ts +35 -9
  12. package/dist/forge-config.d.ts.map +1 -1
  13. package/dist/forge-config.js +62 -25
  14. package/dist/forge-config.js.map +1 -1
  15. package/dist/index.d.ts +4 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +27 -5
  18. package/dist/index.js.map +1 -1
  19. package/dist/lifecycle.d.ts +2 -1
  20. package/dist/lifecycle.d.ts.map +1 -1
  21. package/dist/lifecycle.js +6 -3
  22. package/dist/lifecycle.js.map +1 -1
  23. package/dist/loader.d.ts +17 -1
  24. package/dist/loader.d.ts.map +1 -1
  25. package/dist/loader.js +84 -25
  26. package/dist/loader.js.map +1 -1
  27. package/dist/preset-command.d.ts +1 -1
  28. package/dist/preset-command.d.ts.map +1 -1
  29. package/dist/preset-command.js +38 -10
  30. package/dist/preset-command.js.map +1 -1
  31. package/dist/profile-command.d.ts.map +1 -1
  32. package/dist/profile-command.js +46 -21
  33. package/dist/profile-command.js.map +1 -1
  34. package/dist/profile-service.d.ts +5 -2
  35. package/dist/profile-service.d.ts.map +1 -1
  36. package/dist/profile-service.js +50 -13
  37. package/dist/profile-service.js.map +1 -1
  38. package/dist/resource-identity.d.ts +33 -0
  39. package/dist/resource-identity.d.ts.map +1 -0
  40. package/dist/resource-identity.js +56 -0
  41. package/dist/resource-identity.js.map +1 -0
  42. package/dist/runtime/profile-runtime.d.ts.map +1 -1
  43. package/dist/runtime/profile-runtime.js +7 -2
  44. package/dist/runtime/profile-runtime.js.map +1 -1
  45. package/dist/runtime/prompt-stack-runtime.d.ts +1 -1
  46. package/dist/runtime/prompt-stack-runtime.d.ts.map +1 -1
  47. package/dist/runtime/prompt-stack-runtime.js +22 -12
  48. package/dist/runtime/prompt-stack-runtime.js.map +1 -1
  49. package/dist/runtime/subagent-runtime.d.ts.map +1 -1
  50. package/dist/runtime/subagent-runtime.js +15 -7
  51. package/dist/runtime/subagent-runtime.js.map +1 -1
  52. package/dist/storage.d.ts +10 -0
  53. package/dist/storage.d.ts.map +1 -1
  54. package/dist/storage.js +45 -10
  55. package/dist/storage.js.map +1 -1
  56. package/dist/subagent/plan.js +1 -1
  57. package/dist/subagent/plan.js.map +1 -1
  58. package/dist/subagent/request.d.ts.map +1 -1
  59. package/dist/subagent/request.js +36 -4
  60. package/dist/subagent/request.js.map +1 -1
  61. package/dist/subagent/types.d.ts +4 -0
  62. package/dist/subagent/types.d.ts.map +1 -1
  63. package/dist/subagent-command.d.ts +2 -1
  64. package/dist/subagent-command.d.ts.map +1 -1
  65. package/dist/subagent-command.js +9 -6
  66. package/dist/subagent-command.js.map +1 -1
  67. package/dist/subagent-host.d.ts.map +1 -1
  68. package/dist/subagent-host.js +42 -16
  69. package/dist/subagent-host.js.map +1 -1
  70. package/dist/subagent-profile-tool.d.ts.map +1 -1
  71. package/dist/subagent-profile-tool.js +3 -2
  72. package/dist/subagent-profile-tool.js.map +1 -1
  73. package/dist/subagent-tool.d.ts +25 -1
  74. package/dist/subagent-tool.d.ts.map +1 -1
  75. package/dist/subagent-tool.js +256 -153
  76. package/dist/subagent-tool.js.map +1 -1
  77. package/dist/types.d.ts +3 -0
  78. package/dist/types.d.ts.map +1 -1
  79. package/dist/types.js.map +1 -1
  80. package/dist/web-editor/client-script.generated.d.ts.map +1 -1
  81. package/dist/web-editor/client-script.generated.js +1 -1
  82. package/dist/web-editor/client-script.generated.js.map +1 -1
  83. package/dist/web-editor/client-styles.generated.d.ts.map +1 -1
  84. package/dist/web-editor/client-styles.generated.js +1 -1
  85. package/dist/web-editor/client-styles.generated.js.map +1 -1
  86. package/dist/web-editor/server.d.ts.map +1 -1
  87. package/dist/web-editor/server.js +31 -4
  88. package/dist/web-editor/server.js.map +1 -1
  89. package/dist/web-editor/types.d.ts +11 -3
  90. package/dist/web-editor/types.d.ts.map +1 -1
  91. package/dist/web-host.d.ts.map +1 -1
  92. package/dist/web-host.js +109 -66
  93. package/dist/web-host.js.map +1 -1
  94. package/docs/concepts/agent-profiles.md +1 -1
  95. package/docs/concepts/prompt-stacks.md +7 -2
  96. package/docs/development/roadmap.md +3 -9
  97. package/docs/development/scoped-global-profiles-stacks.md +325 -0
  98. package/docs/getting-started.md +6 -4
  99. package/docs/guides/delegation.md +9 -1
  100. package/docs/guides/web-editor.md +4 -4
  101. package/docs/reference/configuration.md +3 -1
  102. package/docs/reference/features.md +1 -0
  103. package/docs/zh-CN/concepts/agent-profiles.md +4 -2
  104. package/docs/zh-CN/concepts/prompt-stacks.md +5 -3
  105. package/docs/zh-CN/getting-started.md +9 -7
  106. package/docs/zh-CN/guides/delegation.md +3 -3
  107. package/docs/zh-CN/guides/web-editor.md +5 -5
  108. package/docs/zh-CN/reference/commands.md +4 -2
  109. package/package.json +2 -2
@@ -0,0 +1,325 @@
1
+ # Scoped global profiles and prompt stacks
2
+
3
+ [Documentation](../README.md) · [Roadmap](roadmap.md)
4
+
5
+ Status: accepted design; implementation complete for 0.4.1 (identity, catalogs, scoped stacks/profiles, persistence, auto-activation, delegation, zh-CN docs, and web-editor global create/fork/import with explicit scope).
6
+
7
+ ## Confirmed design decisions
8
+
9
+ Recorded before implementation started; these resolve the options left open by the analysis above.
10
+
11
+ - **D1** Unified resource ID grammar: `/^[A-Za-z0-9][A-Za-z0-9._-]*$/` for both profiles and stacks. `:` is reserved for scope qualification and rejected in JSON IDs (with a diagnostic, not a load failure).
12
+ - **D2** When capturing/saving a profile, `promptStack` is serialized relative to the target profile scope: same scope writes a bare ID, a different scope writes a qualified selector (`global:<id>`), and a global profile is never allowed to reference a project stack (the save is rejected).
13
+ - **D3** Global profiles/stacks are loaded and can be browsed/previewed in untrusted projects, but applying a profile or stack still requires project trust.
14
+ - **D4** Subagent delegation remains entirely disabled in untrusted projects, including for global profiles.
15
+ - **D5** `default.json` has no special auto-activation role anymore. Only `autoActivate: true` participates in standalone stack activation. A `default.json` without an explicit `autoActivate` field receives a one-time migration warning; `autoActivate: false` remains an explicit opt-out. Multiple `autoActivate: true` stacks in the same scope fail closed.
16
+ - **D6** Legacy provenance records without a scope field are interpreted as project-scoped.
17
+ - **D7** `forge_subagent` accepts a bare `profileId` through effective lookup (project first) and `global:<id>` for exact global access; tool descriptions and `forge_subagent_profiles` explain the canonical selectors.
18
+ - **D8** New session entries and provenance persist the string selector form (`project:<id>` / `global:<id>`); `none` stays a scope-independent bare opt-out.
19
+ - **D9** Runtime state keeps flat `Loaded*[]` arrays whose entries carry `scope`/`key`; a shared catalog module owns `all`/`effective`/exact resolution.
20
+ - **D10** Web editor API routes encode scope as a single path segment (`scope:id`, e.g. `/api/stacks/global:reviewer`).
21
+ - **D11** A new `PI_FORGE_GLOBAL_DIR` environment override replaces the real `~/.pi/forge` for tests and embedders; loaders accept an explicit global Forge directory, and `globalForgeDir()` is only the default.
22
+ - **D12** Slice 5 is split into 5a (forge-config data model, scoped authorization, and unit tests) and 5b (discovery, tool descriptions, approval display, commands, docs, and browser verification).
23
+ - **D13** The web editor may edit/delete global resources when the route uses an explicit scope; unqualified routes remain project-only.
24
+
25
+
26
+ This note defines the resource identity, lookup, activation, persistence, and delegation model for adding user-global agent profiles and prompt stacks without weakening project shadowing or authorization boundaries.
27
+
28
+ ## Goals
29
+
30
+ - Reuse profiles and prompt stacks across projects.
31
+ - Keep common commands concise through project-over-global shadowing.
32
+ - Preserve an explicit way to address either scope when IDs collide.
33
+ - Make stored profile dependencies deterministic rather than dependent on later shadowing.
34
+ - Keep global and project delegation authorization separate.
35
+ - Preserve existing project-only files and unqualified commands where no collision exists.
36
+
37
+ ## Non-goals
38
+
39
+ - Do not add inheritance or merging between two profile or stack definitions.
40
+ - Do not make profiles continuously own runtime state.
41
+ - Do not move tool or skill policy from prompt stacks into profiles.
42
+ - Do not let a global profile depend on project-controlled prompt content.
43
+ - Do not add writable subagents, compaction settings, or a concurrency cap as part of this feature.
44
+
45
+ ## Storage and identity
46
+
47
+ Global resources use the existing user-owned Forge root:
48
+
49
+ ```text
50
+ ~/.pi/forge/prompt-stacks/*.json
51
+ ~/.pi/forge/agent-profiles/*.json
52
+ ```
53
+
54
+ Project resources keep their current locations:
55
+
56
+ ```text
57
+ <project>/.pi/forge/prompt-stacks/*.json
58
+ <project>/.pi/forge/agent-profiles/*.json
59
+ ```
60
+
61
+ The JSON `id` remains an unqualified value such as `reviewer`. Scope comes from the storage location and must not be duplicated as an editable field in the file.
62
+
63
+ Every loaded resource must carry a first-class scoped identity:
64
+
65
+ ```ts
66
+ type ResourceScope = "global" | "project";
67
+
68
+ interface ResourceKey {
69
+ scope: ResourceScope;
70
+ id: string;
71
+ }
72
+ ```
73
+
74
+ Do not repeatedly infer scope from `filePath`. Loaded profiles and stacks should expose their scope/key directly, and runtime state should compare keys rather than bare IDs.
75
+
76
+ Duplicate IDs are errors only within one scope. A project and global resource with the same ID form a valid shadow pair.
77
+
78
+ ## Selector syntax
79
+
80
+ Commands, completion candidates, profile stack references, persisted diagnostics, and delegation discovery use one selector grammar:
81
+
82
+ ```text
83
+ reviewer
84
+ project:reviewer
85
+ global:reviewer
86
+ ```
87
+
88
+ Existing resource IDs cannot contain `:`, so qualification is unambiguous. Reject unknown scope prefixes, empty IDs, and malformed selectors with a specific diagnostic.
89
+
90
+ The canonical formatter should return:
91
+
92
+ - `reviewer` only when presenting the effective unqualified resource;
93
+ - `project:reviewer` or `global:reviewer` when exact identity matters;
94
+ - qualified selectors for both resources when a collision must be shown.
95
+
96
+ Internally, parse selectors into `{ scope?: ResourceScope; id: string }` and resolve them to a required `ResourceKey` before mutation, application, persistence, or delegation.
97
+
98
+ ## Two lookup modes
99
+
100
+ Unqualified interactive selection and unqualified profile dependencies deliberately use different lookup rules.
101
+
102
+ ### Effective lookup
103
+
104
+ Commands such as `/preset use` and `/profile use` use effective lookup:
105
+
106
+ 1. A qualified selector resolves only the named scope.
107
+ 2. An unqualified selector resolves the project resource when present.
108
+ 3. Otherwise it resolves the global resource.
109
+ 4. A project definition shadows the same-ID global definition even when the project definition is invalid. The invalid shadow fails closed; it must not silently fall back to the global resource.
110
+
111
+ Examples:
112
+
113
+ ```text
114
+ /profile use reviewer # project first, otherwise global
115
+ /profile use global:reviewer # exact global profile
116
+ /preset use project:reviewer # exact project stack
117
+ ```
118
+
119
+ Both colliding resources remain inspectable and explicitly selectable. Shadowing is an ergonomic default, not deletion of the global definition.
120
+
121
+ ### Profile dependency lookup
122
+
123
+ A profile's `promptStack` is a stored dependency and must remain stable when unrelated files are later added. Its unqualified reference therefore resolves relative to the profile's own scope rather than through effective lookup.
124
+
125
+ | Profile scope | `"reviewer"` | `"project:reviewer"` | `"global:reviewer"` |
126
+ |---|---|---|---|
127
+ | Project | project stack | project stack | global stack |
128
+ | Global | global stack | rejected | global stack |
129
+
130
+ Consequences:
131
+
132
+ - A project profile may use either a project stack or an explicitly qualified global stack.
133
+ - A project profile with `"promptStack": "reviewer"` does not fall back to a global stack when the project stack is missing. The diagnostic should suggest `global:reviewer` when that global stack exists.
134
+ - A global profile may use only global stacks. `project:*` is rejected even if the project is trusted.
135
+ - Adding a project stack later cannot silently change the dependency of a project profile that explicitly uses `global:reviewer`.
136
+ - A project cannot replace the prompt or tool policy of a user-authorized global profile.
137
+
138
+ The string form remains sufficient for profile schema v1 because qualification expands the accepted reference syntax without adding a new field or object shape. Existing project profiles keep resolving their unqualified stack IDs to project stacks.
139
+
140
+ ## Loading and catalogs
141
+
142
+ Global definitions are user-owned and may load independently of project trust. Project definitions load only when the project is trusted.
143
+
144
+ Pure loaders and tests must not accidentally read the developer's real home directory. Prefer an explicit catalog/repository input for the global Forge directory over relying on a process-wide environment variable. Existing project-only public loader functions may remain as compatibility wrappers while the extension runtime adopts scoped catalog loaders.
145
+
146
+ Maintain both views:
147
+
148
+ - `all`: every loaded scoped definition, including shadowed resources;
149
+ - `effective`: one resource per unqualified ID after project-over-global shadowing.
150
+
151
+ Centralize resolution helpers instead of continuing to use bare `array.find(candidate.id === id)` calls. Application, preview, mutation, auto-activation, subagent preparation, and the editor must resolve through the same catalog semantics.
152
+
153
+ ## Selection and persistence
154
+
155
+ New session entries must persist the exact scoped key, not just the bare ID. This prevents a restored global selection from changing to a newly created project shadow after reload or tree navigation.
156
+
157
+ For compatibility:
158
+
159
+ - Read legacy branch entries containing only `activeStackId` using effective lookup.
160
+ - Write new entries with a scoped active-stack reference.
161
+ - Preserve the explicit `none`/`off` selection as a scope-independent opt-out.
162
+ - Profile provenance should add the profile scope/key while continuing to accept older provenance that has only `profileId` and `sourcePath`.
163
+ - Drift snapshots should store the resolved scoped stack reference so status can distinguish definition changes from a scope change.
164
+
165
+ Profile application remains transactional and one-shot. Later manual model/thinking changes remain respected; the selected stack continues enforcing its existing policy exactly as it does now.
166
+
167
+ ## Auto-activation
168
+
169
+ Restored branch state and explicit opt-out continue to take precedence over all fresh-session defaults.
170
+
171
+ For agent profiles:
172
+
173
+ 1. Inspect project `autoActivate: true` candidates first.
174
+ 2. If any project candidate exists, do not fall back to a global candidate.
175
+ 3. Exactly one usable project candidate applies; an invalid or ambiguous project selection fails closed.
176
+ 4. If no project candidate exists, apply the same rules to global candidates.
177
+ 5. A project and global auto-activation candidate are not a conflict because project scope has explicit precedence.
178
+
179
+ For standalone prompt-stack activation, apply the same scope precedence after profile auto-activation has declined to select a profile:
180
+
181
+ 1. Only stacks with `autoActivate: true` participate; `default.json` has no filename-based activation role (D5).
182
+ 2. Resolve project candidates before global candidates.
183
+ 3. A same-ID project stack shadows the global stack, including an invalid shadow or `autoActivate: false` opt-out.
184
+ 4. Exactly one usable candidate applies; multiple `autoActivate: true` stacks in the same scope fail closed.
185
+ 5. Do not silently activate the global same-ID stack through an invalid or opted-out project shadow.
186
+ 6. Preserve the existing rule that agent-profile auto-activation takes precedence over standalone stack activation, including profiles whose `promptStack` is `null`.
187
+
188
+ ## Commands and editor behavior
189
+
190
+ Unqualified commands use effective lookup. Qualified commands address exact scope.
191
+
192
+ Recommended command behavior:
193
+
194
+ ```text
195
+ /preset use reviewer
196
+ /preset use global:reviewer
197
+ /profile use project:reviewer
198
+ /profile preview global:reviewer
199
+ /profile save reviewer # project by default
200
+ /profile save global:reviewer # explicit global mutation
201
+ ```
202
+
203
+ Mutations must resolve the target scope before computing a path. Existing overwrite, changed-file, containment, and symbolic-link protections apply independently to each storage root. Global mutation must always be explicit; an unqualified save/fork/import continues to target project storage.
204
+
205
+ The web editor should:
206
+
207
+ - show global/project badges on profiles and stacks;
208
+ - show `shadows global:<id>` and `shadowed by project:<id>` states;
209
+ - retain both resources in navigation when IDs collide;
210
+ - require explicit scope for create, fork, import, save-as, and delete targets;
211
+ - prevent editing a shadowed global resource through an unqualified project route;
212
+ - keep the current token, trust, idle-state, overwrite, and browser-test protections for mutations.
213
+
214
+ Completions may prefer concise unqualified effective selectors, but must also offer qualified selectors when a collision exists or when the user has begun typing a scope prefix.
215
+
216
+ ## Delegation boundary
217
+
218
+ Delegation authorization follows the profile's scope, not the effective unqualified ID:
219
+
220
+ - `~/.pi/forge/config.json` `subagents.profiles.<id>` authorizes only `global:<id>`.
221
+ - `<project>/.pi/forge/config.json` `subagents.profiles.<id>` authorizes only `project:<id>`.
222
+ - Same-ID global and project profiles never inherit enablement, backend, or timeout policy from one another.
223
+ - General backend, timeout, and summary defaults retain their current global-then-project layering.
224
+ - Deleting a profile clears delegation policy only from the matching scope's config.
225
+ - A global profile remains bound to global prompt content even when a project profile or stack shadows the same ID.
226
+
227
+ `forge_subagent_profiles` should return canonical callable selectors. When both scopes expose the same ID, the project profile may use the concise effective selector and the global profile must remain callable as `global:<id>`. The `forge_subagent` parameter, `/forge-agent` commands, embedded description summary, preparation lookup, approval display, fingerprints, and reports must retain exact scope.
228
+
229
+ Global profiles are user-owned, but ordinary delegation safety does not change: profiles remain disabled unless authorized in the matching config, unattended invocation remains a separate trusted-project decision, and read-only still does not imply an OS sandbox.
230
+
231
+ ## Compatibility and migration
232
+
233
+ - No files move automatically.
234
+ - Existing `.pi/forge` and legacy `.pi/prompt-stacks` resources remain project-scoped.
235
+ - Existing project profile `promptStack` strings remain project-relative.
236
+ - Existing unqualified commands behave the same when no global collision exists.
237
+ - Legacy bare-ID session entries restore through effective lookup; all new entries record scope.
238
+ - Same-ID cross-scope definitions are valid and must not receive duplicate-ID errors.
239
+ - Duplicate IDs within one scope keep the current fail-closed diagnostics.
240
+ - Global `subagents.profiles` entries, which currently warn and are ignored, become scoped authorization for global profiles only. Document this behavior change prominently.
241
+ - Public loaded-resource types may add scope/key metadata without removing existing fields; compatibility helpers should continue accepting legacy bare IDs where persisted data requires them.
242
+
243
+ ## Implementation slices
244
+
245
+ Each slice should land with focused tests and leave the full verification surface green.
246
+
247
+ ### Slice 1: scoped identity and storage
248
+
249
+ - Add `ResourceScope`, `ResourceKey`, selector parsing/formatting, and exact/effective resolution primitives.
250
+ - Add global profile/stack directory and safe mutation-path helpers.
251
+ - Add scope/key metadata to loaded resources.
252
+ - Keep JSON IDs unqualified and validate selector syntax separately from ID syntax.
253
+ - Add table-driven parser, formatter, storage-containment, and same-ID-key tests.
254
+
255
+ Exit criterion: scoped resources can be represented and addressed without changing runtime loading behavior.
256
+
257
+ ### Slice 2: scoped stack catalog and persistence
258
+
259
+ - Load global stacks plus trusted project/legacy stacks into `all` and `effective` views.
260
+ - Implement project shadowing, exact qualified selection, and invalid-shadow fail-closed behavior.
261
+ - Replace bare-ID runtime lookups with catalog resolution.
262
+ - Persist scoped active-stack references and restore legacy bare-ID entries.
263
+ - Apply scoped standalone stack auto-activation and explicit opt-out rules.
264
+
265
+ Exit criterion: `/preset` runtime behavior, branch restoration, tool policy, preview, and stack diagnostics operate correctly across both scopes before profiles are migrated.
266
+
267
+ ### Slice 3: scoped profiles and dependency resolution
268
+
269
+ - Load global and trusted-project profiles with duplicate and auto-activation diagnostics scoped correctly.
270
+ - Implement the profile-to-stack resolution matrix.
271
+ - Extend preview, application, rollback, provenance, drift, save, delete, and reload with exact scoped keys.
272
+ - Preserve profile auto-activation precedence over standalone stacks.
273
+ - Extend host/subagent profile snapshots and fingerprints with resolved scope where required without changing legacy provenance fingerprint interpretation.
274
+
275
+ Exit criterion: global and project profiles apply deterministically, including explicit project-to-global stack reuse and rejection of global-to-project references.
276
+
277
+ ### Slice 4: commands and web editor
278
+
279
+ - Add qualified parsing and completions to `/preset`, `/profile`, and editor APIs.
280
+ - Make unqualified mutations project-scoped and global mutations explicit.
281
+ - Show scope, collisions, shadow relationships, exact dependencies, and scoped drift in human surfaces.
282
+ - Add real-browser coverage for browsing, applying, editing, forking, deleting, collision handling, and failed scoped preflight.
283
+
284
+ Exit criterion: users can understand and manage both scopes without an unqualified action mutating a global resource.
285
+
286
+ ### Slice 5: scoped delegation, documentation, and release verification
287
+
288
+ - Accept global profile authorization from global config and project profile authorization from project config.
289
+ - Update discovery, embedded summaries, callable selectors, `/forge-agent`, preparation, approval, reports, and policy cleanup.
290
+ - Test same-ID profiles with independent enablement/backend/timeout settings and no authority inheritance.
291
+ - Update English and Chinese concepts, guides, commands, configuration, schema/reference, feature inventory, changelog, and roadmap.
292
+ - Regenerate tracked browser assets and `dist`, then run `npm run verify` and a packed-install smoke test.
293
+
294
+ Exit criterion: scoped ordinary use and scoped delegation are documented, fail closed, package-clean, and verified end to end.
295
+
296
+ ## Required scenario coverage
297
+
298
+ At minimum, automated tests should cover:
299
+
300
+ - Global-only, project-only, and same-ID collision lookup.
301
+ - Exact global access while shadowed.
302
+ - Invalid project shadow without global fallback.
303
+ - Global profile to global stack.
304
+ - Project profile to unqualified project stack.
305
+ - Project profile to explicitly qualified global stack.
306
+ - Missing project stack with a same-ID global suggestion but no fallback.
307
+ - Rejected global profile to project stack.
308
+ - Project auto-activation precedence, global fallback, ambiguity, invalid candidate, restored branch, and explicit opt-out.
309
+ - `default.json` no longer auto-activates by filename; missing `autoActivate` yields a migration warning (D5).
310
+ - Scoped session restoration after a new shadow appears.
311
+ - Scoped provenance and drift after source edits or scope changes.
312
+ - Independent global/project delegation authorization for the same ID.
313
+ - Deletion clearing only matching-scope delegation policy.
314
+ - Untrusted projects loading global resources but not project resources.
315
+ - Web-editor collision navigation and explicit-scope mutation safeguards.
316
+
317
+ ## Architectural guardrails
318
+
319
+ - Keep resolution in shared catalog/services; do not duplicate shadow rules across commands, the editor, and subagent code.
320
+ - Never use project-over-global effective lookup for a stored global profile dependency.
321
+ - Never infer delegation authority from a bare ID after profile resolution.
322
+ - Never persist a new active selection or provenance record without exact scope.
323
+ - Never silently fall back across scopes after an explicit selector or an invalid shadow.
324
+ - Keep profile application transactional and tool/skill policy owned by the resolved prompt stack.
325
+ - Require the complete unit, browser, type, generated-output, documentation, and package verification surface for the final slice.
@@ -62,7 +62,7 @@ Select the model, thinking level, and prompt stack you want in Pi, then save the
62
62
  /profile use reviewer
63
63
  ```
64
64
 
65
- Profiles live in `.pi/forge/agent-profiles/*.json`. Applying one is a preflighted, one-shot operation: later manual model/thinking changes remain until you apply the profile again. Read [agent-profile concepts](concepts/agent-profiles.md) for validation, auto-activation, and drift semantics.
65
+ Profiles live in `.pi/forge/agent-profiles/*.json` by default; `/profile save global:<id>` writes to `~/.pi/forge/agent-profiles`. Applying one is a preflighted, one-shot operation: later manual model/thinking changes remain until you apply the profile again. Read [agent-profile concepts](concepts/agent-profiles.md) for validation, auto-activation, and drift semantics.
66
66
 
67
67
  ## Storage and migration
68
68
 
@@ -70,12 +70,14 @@ Profiles live in `.pi/forge/agent-profiles/*.json`. Applying one is a preflighte
70
70
  |---|---|
71
71
  | `.pi/forge/prompt-stacks/` | Project prompt stacks |
72
72
  | `.pi/forge/agent-profiles/` | Project agent profiles |
73
- | `.pi/forge/config.json` | Trusted project configuration and delegation authorization |
73
+ | `.pi/forge/config.json` | Trusted project configuration and `project:<id>` delegation authorization |
74
74
  | `.pi/forge/extensions/` | Trusted project macro/slot registration code |
75
- | `~/.pi/forge/config.json` | User defaults |
75
+ | `~/.pi/forge/prompt-stacks/` | User-global prompt stacks |
76
+ | `~/.pi/forge/agent-profiles/` | User-global agent profiles |
77
+ | `~/.pi/forge/config.json` | User defaults and `global:<id>` delegation authorization |
76
78
  | `~/.pi/forge/extensions/` | Trusted user macro/slot registration code |
77
79
 
78
- Legacy `.pi/prompt-stacks/*.json` files remain readable. New stacks go to `.pi/forge/prompt-stacks`, and same-named new-location files shadow legacy ones. Migrate safely with:
80
+ Legacy `.pi/prompt-stacks/*.json` files remain readable. Command-created stacks go to `.pi/forge/prompt-stacks`; use the web editor's `global` scope selector to create stacks in `~/.pi/forge/prompt-stacks`. Same-named new-location files shadow legacy ones. Migrate safely with:
79
81
 
80
82
  ```text
81
83
  /preset migrate-stacks --dry-run
@@ -30,7 +30,7 @@ Profiles are not delegatable by default. Enable each eligible ID in the trusted
30
30
  }
31
31
  ```
32
32
 
33
- Enablement and per-profile overrides are project-only because profiles are project-local. A global `~/.pi/forge/config.json` may define general `backend` and `timeoutMs` defaults; global `profiles` entries warn and are ignored. Disabled or unlisted IDs are hidden from discovery and rejected even if guessed.
33
+ Enablement follows the profile's scope. A global `~/.pi/forge/config.json` may define general `backend` and `timeoutMs` defaults and may authorize `global:<id>` profiles through its own `profiles` map. The trusted project's `.pi/forge/config.json` authorizes `project:<id>` profiles. Same-ID global and project profiles never inherit enablement, backend, or timeout policy from one another. Disabled or unlisted profiles are hidden from discovery and rejected even if guessed.
34
34
 
35
35
  ## Discover, plan, and run
36
36
 
@@ -45,8 +45,16 @@ Humans use:
45
45
 
46
46
  `plan` resolves the profile and stack, compiles and validates the exact immutable provider-bound plan, displays it, and discards it without provider transport.
47
47
 
48
+ Profile selectors accept the same grammar everywhere: `reviewer` (project first), `project:reviewer`, or `global:reviewer`. When both scopes expose the same ID, the project profile keeps the concise selector and the global profile remains callable as `global:<id>`.
49
+
48
50
  The parent model uses `forge_subagent_profiles` to discover enabled profiles and `forge_subagent` to invoke one. A restrictive parent stack must allow both tool names. Discovery is local/no-egress and reports metadata, resolution readiness, effective backend/timeout, approval mode, and whether parent tool policy permits invocation.
49
51
 
52
+ Projects with only a few frequently used profiles can set `subagents.summaryInToolDescription: true` (global or trusted-project config). The `forge_subagent` tool description then carries a compact summary of enabled profiles—id, model, thinking level, stack, backend, and timeout—so the parent model does not need a discovery call to pick a profile. Ready profiles appear first; unavailable enabled profiles remain visible with their first resolution error so the model knows not to invoke them. The summary rides in every request, is capped at 8 profiles and 1,000 characters, and refreshes with profiles, stacks, and configuration; `forge_subagent_profiles` remains the authoritative full-detail surface.
53
+
54
+ ## Parallel invocation
55
+
56
+ `forge_subagent` is a parallel-execution tool: the parent model may issue several calls in one turn, and they prepare and run concurrently. Interactive approval dialogs are serialized one at a time because Pi's selector/editor UI is a single slot—a second concurrent dialog would clear the first and leave it unresolved—so each call waits its turn for the dialog and then executes immediately, letting approved runs overlap. Unattended invocation needs no dialog and is fully concurrent. Each run is an independent `pi` subprocess and provider request; a burst of parallel calls multiplies provider cost and process load, so keep the parent tool policy conservative until a configurable concurrency cap lands.
57
+
50
58
  ## Backends and precedence
51
59
 
52
60
  Two fresh-process backends are registered:
@@ -43,21 +43,21 @@ The stack workspace provides:
43
43
  - payload arming and redacted captured-payload inspection;
44
44
  - light and dark themes.
45
45
 
46
- Existing IDs are immutable during edit. Use **Fork** to create a different ID without breaking profile references or the active selection. New stacks, imports, and forks write to `.pi/forge/prompt-stacks`; legacy stacks remain editable in place.
46
+ Existing IDs are immutable during edit. Use **Fork** to create a different ID without breaking profile references or the active selection. The toolbar scope selector (default `project`) chooses where new stacks, imports, and forks are written: `global` targets the user-global `~/.pi/forge/prompt-stacks`, `project` targets `.pi/forge/prompt-stacks`. Stack rows show a `global` badge, and save/delete routes use `global:<id>` for exact global mutations. Legacy stacks remain editable in place.
47
47
 
48
48
  Saves, imports, forks, and deletes reload stack state into the current Pi session. When another surface changes a referenced stack, returning to profiles refreshes profile resolution without discarding unsaved delegation fields.
49
49
 
50
50
  ## Agent-profile workspace
51
51
 
52
- The profile list shows each profile's ID, display metadata, model, thinking level, stack, resolution state, auto-activation, last-applied provenance, and delegation status.
52
+ The profile list shows each profile's ID, display metadata, model, thinking level, stack, resolution state, auto-activation, last-applied provenance, delegation status, and a `project`/`global` scope badge. Same-ID shadow pairs are marked `shadows global:<id>` or `shadowed by project:<id>`.
53
53
 
54
- Trusted projects can create, edit, validate, save, apply once, and delete profiles. Model choices come from Pi's model registry, thinking choices reflect model support, and stack choices come from the shared repository. The editor rejects a second auto-activation profile.
54
+ Trusted projects can create profiles in either scope: the scope selector beside **New profile** (default `project`) chooses whether to write the user-global `~/.pi/forge/agent-profiles` or the project `.pi/forge/agent-profiles`. Global profiles can be edited, validated, saved, applied once, and deleted through explicit `global:<id>` routes; unqualified routes stay project-only. When editing a global profile, the prompt-stack dropdown offers only global stacks. Model choices come from Pi's model registry, thinking choices reflect model support, and stack choices come from the shared repository. The editor rejects a second auto-activation profile within the same scope.
55
55
 
56
56
  The runtime/provenance card separates current runtime state, last-applied snapshot, source-definition changes, and field-level runtime drift.
57
57
 
58
58
  ## Delegation card
59
59
 
60
- The profile delegation card edits only project-level `subagents.profiles.<id>` values: enablement, backend override, and timeout override. General defaults and `allowAgentInvocationWithoutApproval` remain config-file-only because they affect broader authorization.
60
+ The profile delegation card edits the `subagents.profiles.<id>` values for the selected profile's scope: project profiles write to `.pi/forge/config.json`, global profiles write to `~/.pi/forge/config.json`. General defaults and `allowAgentInvocationWithoutApproval` remain config-file-only because they affect broader authorization.
61
61
 
62
62
  Unsaved delegation changes are guarded when selecting another profile, starting another profile operation, refreshing, deleting, or leaving/reloading the page. The card shows effective values and the source of each inherited or overridden setting.
63
63
 
@@ -50,7 +50,9 @@ Trusted project configuration may override defaults, authorize individual projec
50
50
 
51
51
  Valid timeouts are 1,000–3,600,000 ms. Invalid fields warn and fall back to the preceding applicable default. General backend precedence is project then user then built-in; an interactive run and a project profile entry can further override it as described in [delegation](../guides/delegation.md#backends-and-precedence).
52
52
 
53
- `profiles` in global configuration warns and is ignored. `allowAgentInvocationWithoutApproval` is project-only, requires trust, and fails closed when malformed. Deleting a profile also clears its effective delegation policy.
53
+ `subagents.summaryInToolDescription` (default `false`) embeds a compact, bounded summary of enabled subagent profiles directly in the `forge_subagent` tool description so the parent model can pick a profile without a discovery call. Ready profiles appear first, and unavailable enabled profiles include their first resolution error. It may be set in user or trusted-project configuration and applies wherever it is enabled.
54
+
55
+ `profiles` in global configuration authorizes `global:<id>` profiles; the trusted project's `profiles` authorizes `project:<id>` profiles. Same-ID profiles never inherit enablement, backend, or timeout policy from each other. `allowAgentInvocationWithoutApproval` is project-only, requires trust, and fails closed when malformed. Deleting a profile clears delegation policy only from the matching scope's config.
54
56
 
55
57
  Treat project configuration as an authorization boundary. In particular, do not commit unattended delegation unless every permitted parent agent may transmit compiled prompt and readable project content without another human approval.
56
58
 
@@ -45,6 +45,7 @@ This file tracks the currently implemented feature surface for agent profiles, t
45
45
  - Experimental `pi-subprocess-readonly` backend reuses the host Pi runtime for authenticated preparation, then runs a clean foreground Pi subprocess with the exact profile model, thinking level, and compiled prompt. Its candidate model tools are limited to `read`, `grep`, `find`, and `ls`, further filtered by prompt-stack policy; it loads no write/shell tools, skills, prompt templates, context files, or third-party extensions. Host-coupled capability mismatches fail closed during preflight.
46
46
  - Delegation is an explicit per-profile opt-in under the trusted project's `subagents.profiles`; ordinary profile loading/application remains independent. Global profile entries warn and are ignored so project-local profile IDs cannot silently authorize unrelated projects. Disabled and unlisted profiles are omitted from `forge_subagent_profiles` and rejected before preparation by the command, model-callable tool, and concrete runtime.
47
47
  - The no-egress `forge_subagent_profiles` tool gives the main agent a live catalog of enabled profile IDs, names, descriptions, model/thinking/stack metadata, effective backend/timeout and sources, and ready/unavailable resolution status. It also reports whether the parent tool policy currently permits `forge_subagent`.
48
+ - `subagents.summaryInToolDescription` (default `false`) embeds a compact, bounded summary of enabled profiles directly in the `forge_subagent` tool description, so the main agent can pick a frequently used profile without a discovery call. Ready profiles sort first, unavailable enabled profiles include their first resolution error, and the summary is capped at 8 profiles and 1,000 characters. It refreshes whenever profiles, stacks, or configuration change and keeps `forge_subagent_profiles` as the authoritative full-detail surface.
48
49
  - The model-callable `forge_subagent` tool and `/forge-agent run` prepare an immutable plan before provider transport. `/forge-agent run` and the default tool path require explicit human approval; a trusted-project `subagents.allowAgentInvocationWithoutApproval` option may authorize only the model-callable tool without a per-run prompt. The default review shows the task, profile/stack, provider/model/thinking level, effective tools, working directory, shared-user boundary, payload size, and fingerprint; the complete provider-bound prompt can be opened on demand.
49
50
  - Backend selection is layered configuration rather than profile schema: `subagents.backend` supplies global/project defaults, the trusted project's `subagents.profiles.<id>.backend` supplies a per-profile override, and `/forge-agent plan|run --backend <id>` or the interactive `forge_subagent` `backend` parameter overrides one run. Both the `pi-subprocess-readonly` and `pi-rpc-readonly` backends are registered; there is no fallback when the selected backend is unavailable, and unattended tool invocation is pinned to the effective configured profile backend.
50
51
  - Foreground timeout is layered host configuration rather than profile schema: `subagents.timeoutMs` supplies a 60,000-millisecond default and `subagents.profiles.<id>.timeoutMs` can override it per profile; values must be from 1,000 through 3,600,000 milliseconds. Invalid values warn and preserve the preceding valid/default value; discovery, planning, and approval surfaces show the effective best-effort timeout and source.
@@ -2,7 +2,7 @@
2
2
 
3
3
  [中文文档](../README.md) · [English](../../concepts/agent-profiles.md)
4
4
 
5
- Agent profile 是项目级、带 schema version 的预设,只引用一个精确模型、思考等级和 prompt stack。
5
+ Agent profile 是项目级或用户全局、带 schema version 的预设,只引用一个精确模型、思考等级和 prompt stack。项目 profile 位于 `.pi/forge/agent-profiles/`,全局 profile 位于 `~/.pi/forge/agent-profiles/`。命令接受 `reviewer`、`project:reviewer` 和 `global:reviewer`;未限定 ID 优先解析项目 profile,项目 profile 会遮蔽同 ID 全局 profile。
6
6
 
7
7
  ```json
8
8
  {
@@ -23,6 +23,8 @@ Agent profile 是项目级、带 schema version 的预设,只引用一个精
23
23
 
24
24
  `promptStack` 可以是 `null`。Profile v1 不保存生成参数、工具、skills、backend 或 runner policy;不支持字段会直接报错。工具/skill 策略只属于引用的 stack。
25
25
 
26
+ `promptStack` 引用相对 profile 自身 scope 解析:项目 profile 用裸 ID 引用项目 stack,也可用 `global:<id>` 显式引用全局 stack;全局 profile 只能引用全局 stack,`project:<id>` 会被拒绝。
27
+
26
28
  ## 应用
27
29
 
28
30
  ```text
@@ -41,4 +43,4 @@ Agent profile 是项目级、带 schema version 的预设,只引用一个精
41
43
 
42
44
  `/profile status` 会把 profile 源定义变化和当前模型/思考等级/stack drift 分开显示。Provenance 只用于 branch 状态报告;reload、resume、tree navigation 和 compaction 不会重新应用 profile。
43
45
 
44
- 普通 profile 默认不能委派。Delegation 使用独立的可信项目授权;删除 profile 也会清除其授权,防止以后同 ID profile 继承权限。启用前见[前台 delegation](../guides/delegation.md)。
46
+ 普通 profile 默认不能委派。Delegation 授权跟随 profile scope:可信项目 `.pi/forge/config.json` 的 `subagents.profiles.<id>` 只授权 `project:<id>`,用户全局 `~/.pi/forge/config.json` 的 `subagents.profiles.<id>` 只授权 `global:<id>`;同 ID 的全局和项目 profile 永不互相继承授权。删除 profile 会清除同 scope 的授权,防止以后同 ID profile 继承权限。启用前见[前台 delegation](../guides/delegation.md)。
@@ -2,7 +2,7 @@
2
2
 
3
3
  [中文文档](../README.md) · [English](../../concepts/prompt-stacks.md)
4
4
 
5
- Prompt stack 是一份有序、声明式的 prompt 与策略描述,由固定 **block** 和动态 **slot** 组成。
5
+ Prompt stack 是一份有序、声明式的 prompt 与策略描述,由固定 **block** 和动态 **slot** 组成。Stack 可以放在项目 `.pi/forge/prompt-stacks/`,也可以放在用户全局 `~/.pi/forge/prompt-stacks/`。命令接受 `reviewer`、`project:reviewer` 和 `global:reviewer`;未限定 ID 优先解析项目 stack,项目 stack 会遮蔽同 ID 全局 stack。重复 ID 只在同一 scope 内算错误。
6
6
 
7
7
  ## 编译模型
8
8
 
@@ -29,9 +29,11 @@ Prompt stack 是一份有序、声明式的 prompt 与策略描述,由固定 *
29
29
 
30
30
  工具 `allow`/`deny` 会修改 Pi active tools,并在 tool call 时再次检查。Skill policy 只过滤 pi-forge 渲染给模型的列表;它不能阻止明确调用,也不是安全边界。若必须控制模型可见 skill 列表,请使用 `replace`,因为 Pi 的基础 prompt 可能已经在 `append`/`prepend` 内容之前列出 skills。
31
31
 
32
- ## Session 行为
32
+ ## Scope 与自动启用
33
33
 
34
- - `default.json` 默认自动启用。
34
+ - 只有显式设置 `"autoActivate": true` 的 stack 参与自动启用;文件名(包括 `default.json`)没有特殊作用。
35
+ - 项目 stack 优先于全局 stack;项目 scope 存在候选时,即使项目候选无效或冲突也会 fail closed,不会回退到全局 stack。
36
+ - 同 ID 项目 stack 会遮蔽全局 stack,包括无效 shadow 或显式 opt-out。
35
37
  - `/preset use none` 会记录 session branch 的 opt-out。
36
38
  - Active stack 和 session variables 会跟随 Pi session tree branch。
37
39
  - 恢复的 branch 状态优先于新 session 自动启用。
@@ -10,7 +10,7 @@ pi-forge 需要 Node.js 22.19 或更高版本,并作为 Pi extension 运行:
10
10
  pi install npm:@zihanw/pi-forge
11
11
  ```
12
12
 
13
- 安装或更新后请重启 Pi。Pi host 会提供运行时 SDK;精确 package 版本只用于可复现的开发测试。项目被 Pi 信任后,pi-forge 才会加载项目 stack、profile 和 config。
13
+ 安装或更新后请重启 Pi。Pi host 会提供运行时 SDK;精确 package 版本只用于可复现的开发测试。用户全局 stack/profile 始终可以浏览;项目 stack、profile 和 config 只在 Pi 信任项目后加载和写入。
14
14
 
15
15
  ## 第一个 stack
16
16
 
@@ -28,7 +28,7 @@ cp examples/default-prompt-stack.json .pi/forge/prompt-stacks/default.json
28
28
  /preset use default
29
29
  ```
30
30
 
31
- 如果没有恢复的 session 选择或明确 opt-out,`default.json` 会自动启用。设置 `"autoActivate": false` 可以关闭此行为。
31
+ 示例中的 `default.json` 带 `"autoActivate": true`,因此没有恢复的 session 选择或明确 opt-out 时会自动启用。设置 `"autoActivate": false` 可以关闭此行为;文件名本身没有特殊作用。
32
32
 
33
33
  ## 编辑和检查
34
34
 
@@ -36,7 +36,7 @@ cp examples/default-prompt-stack.json .pi/forge/prompt-stacks/default.json
36
36
  /preset ui
37
37
  ```
38
38
 
39
- 编辑器运行在带 token 的本地 `127.0.0.1` URL,支持结构化/原始 JSON 编辑、排序、校验、完整预览、策略、regex、导入导出、fork 和 profile 管理。
39
+ 编辑器运行在带 token 的本地 `127.0.0.1` URL,支持结构化/原始 JSON 编辑、排序、校验、完整预览、策略、regex、导入导出、fork 和 profile 管理。工具栏的 scope 下拉(默认 `project`)决定新建、fork 和导入 stack 写入项目 `.pi/forge/prompt-stacks` 还是用户全局 `~/.pi/forge/prompt-stacks`。
40
40
 
41
41
  命令行也可以检查:
42
42
 
@@ -56,7 +56,7 @@ cp examples/default-prompt-stack.json .pi/forge/prompt-stacks/default.json
56
56
  /profile use reviewer
57
57
  ```
58
58
 
59
- Profile 保存在 `.pi/forge/agent-profiles/*.json`。应用是经过 preflight 的一次性操作;之后的手动设置不会被自动覆盖。
59
+ Profile 默认保存在 `.pi/forge/agent-profiles/*.json`。`/profile save global:reviewer` 会写入用户全局 `~/.pi/forge/agent-profiles`。应用是经过 preflight 的一次性操作;之后的手动设置不会被自动覆盖。
60
60
 
61
61
  ## 存储与迁移
62
62
 
@@ -64,12 +64,14 @@ Profile 保存在 `.pi/forge/agent-profiles/*.json`。应用是经过 preflight
64
64
  |---|---|
65
65
  | `.pi/forge/prompt-stacks/` | 项目 prompt stacks |
66
66
  | `.pi/forge/agent-profiles/` | 项目 agent profiles |
67
- | `.pi/forge/config.json` | 项目配置和 delegation 授权 |
67
+ | `.pi/forge/config.json` | 项目配置和 `project:<id>` delegation 授权 |
68
68
  | `.pi/forge/extensions/` | 可信项目 macro/slot 代码 |
69
- | `~/.pi/forge/config.json` | 用户默认配置 |
69
+ | `~/.pi/forge/prompt-stacks/` | 用户全局 prompt stacks |
70
+ | `~/.pi/forge/agent-profiles/` | 用户全局 agent profiles |
71
+ | `~/.pi/forge/config.json` | 用户默认配置和 `global:<id>` delegation 授权 |
70
72
  | `~/.pi/forge/extensions/` | 可信用户 macro/slot 代码 |
71
73
 
72
- 旧的 `.pi/prompt-stacks/*.json` 仍可读取;新 stack 会写到 `.pi/forge/prompt-stacks`。安全迁移方式:
74
+ 旧的 `.pi/prompt-stacks/*.json` 仍可读取;命令创建的 stack 会写到 `.pi/forge/prompt-stacks`,使用 Web 编辑器的 `global` scope 下拉可创建到用户全局 `~/.pi/forge/prompt-stacks`。安全迁移方式:
73
75
 
74
76
  ```text
75
77
  /preset migrate-stacks --dry-run
@@ -8,7 +8,7 @@ pi-forge 可以把明确授权的 agent profile 作为独立、干净、一次
8
8
 
9
9
  ## 启用 profile
10
10
 
11
- Profile 默认不能委派。请在可信项目的 `.pi/forge/config.json` 中逐个启用,或使用 `/preset ui` 的 delegation 卡片:
11
+ Profile 默认不能委派。请在可信项目的 `.pi/forge/config.json` 中逐个启用项目 profile,在用户全局 `~/.pi/forge/config.json` 中逐个启用全局 profile;也可以使用 `/preset ui` 的 delegation 卡片:
12
12
 
13
13
  ```json
14
14
  {
@@ -25,7 +25,7 @@ Profile 默认不能委派。请在可信项目的 `.pi/forge/config.json` 中
25
25
  }
26
26
  ```
27
27
 
28
- Profile 授权只允许出现在项目配置,因为 profile 本身也是项目资源。全局 `~/.pi/forge/config.json` 可以设置通用 backend/timeout;全局 `profiles` 会警告并被忽略。未启用或未列出的 ID 不会被 discovery 返回,即使猜中 ID 也会被拒绝。
28
+ 授权跟随 profile scope:项目 config 的 `subagents.profiles.<id>` 只授权 `project:<id>`,全局 config 的 `subagents.profiles.<id>` 只授权 `global:<id>`。同 ID 的全局和项目 profile 不会互相继承 enable/backend/timeout。未启用或未列出的 ID 不会被 discovery 返回,即使猜中 ID 也会被拒绝。
29
29
 
30
30
  ## Plan 与运行
31
31
 
@@ -35,7 +35,7 @@ Profile 授权只允许出现在项目配置,因为 profile 本身也是项目
35
35
  /forge-agent run reviewer 检查这个 API 设计。
36
36
  ```
37
37
 
38
- `plan` 会解析 profile/stack、编译并校验不可变的实际 provider-bound 计划,然后在不联系 provider 的情况下丢弃。
38
+ `plan` 会解析 profile/stack、编译并校验不可变的实际 provider-bound 计划,然后在不联系 provider 的情况下丢弃。Profile selector 在所有入口使用同一语法:`reviewer`(项目优先)、`project:reviewer` 或 `global:reviewer`。同 ID 冲突时,项目 profile 保持简写 selector,全局 profile 仍通过 `global:<id>` 调用。
39
39
 
40
40
  父模型使用无数据外发的 `forge_subagent_profiles` 做 discovery,再用 `forge_subagent` 执行。限制严格的父 stack 必须允许这两个工具名。
41
41
 
@@ -10,7 +10,7 @@
10
10
 
11
11
  `/preset ui restart` 会替换 server,`/preset ui stop` 会关闭它。
12
12
 
13
- 编辑器绑定在带 session token 的可用 `127.0.0.1` 端口;多个项目可以同时运行。可以在 `.pi/forge/config.json` 中设置偏好端口:
13
+ 编辑器绑定在带 session token 的可用 `127.0.0.1` 端口;多个项目可以同时运行。读取、预览和 payload 检查在合适范围内可用;写入要求 Pi 信任项目,并且文件被限制在 pi-forge 的 stack/profile 存储内。可以在 `.pi/forge/config.json` 中设置偏好端口:
14
14
 
15
15
  ```json
16
16
  {
@@ -32,14 +32,14 @@
32
32
  - 原生 pi-forge 与 SillyTavern JSON 导入;
33
33
  - 导出、fork、删除和 payload 捕获。
34
34
 
35
- 已有 ID 在编辑时不可修改;需要新 ID 时使用 **Fork**,避免破坏 profile 引用和当前选择。保存、导入、fork 和删除后会重新加载当前 Pi session。
35
+ 已有 ID 在编辑时不可修改;需要新 ID 时使用 **Fork**,避免破坏 profile 引用和当前选择。工具栏的 scope 下拉(默认 `project`)决定新建、导入和 fork 的写入位置:选择 `global` 写入用户全局 `~/.pi/forge/prompt-stacks`,选择 `project` 写入项目 `.pi/forge/prompt-stacks`。列表会为全局 stack 显示 `global` badge;保存和删除通过 `global:<id>` 路由精确作用于全局文件。保存、导入、fork 和删除后会重新加载当前 Pi session。
36
36
 
37
37
  ## Agent profile 工作区
38
38
 
39
- 列表显示 profile ID、名称、模型、思考等级、stack、校验状态、auto-activation、last-applied provenance 和 delegation 状态。
39
+ 列表显示 profile ID、名称、模型、思考等级、stack、校验状态、auto-activation、last-applied provenance 和 delegation 状态。每个 profile 都带 `project` / `global` scope badge;同 ID 的 shadow 对会显示 `shadows global:<id>` 或 `shadowed by project:<id>`。
40
40
 
41
- 可信项目可以新建、编辑、校验、保存、一次性应用和删除 profile。Model 选项来自 Pi registry,thinking 选项反映模型支持,stack 选项来自同一个 repository。编辑器会拒绝第二个 auto-activation profile。
41
+ 可信项目通过 **New profile** 旁的 scope 下拉(默认 `project`)选择目标 scope:选择 `global` 写入用户全局 `~/.pi/forge/agent-profiles`,选择 `project` 写入项目 `.pi/forge/agent-profiles`。全局 profile 可通过显式 `global:<id>` 路由编辑、校验、保存、一次性应用和删除;未限定路由始终只作用于项目资源。编辑全局 profile 时,stack 下拉只显示全局 stack。Model 选项来自 Pi registry,thinking 选项反映模型支持,stack 选项来自同一个 repository。编辑器会拒绝同 scope 内第二个 auto-activation profile。
42
42
 
43
- Delegation 卡片只修改项目级 profile 的 enable/backend/timeout。切换 profile、刷新、删除或离开页面时,未保存的 delegation 字段会得到保护。通用默认值和 `allowAgentInvocationWithoutApproval` 只能在 config 文件中设置。
43
+ Delegation 卡片按 profile 的 scope 修改 `subagents.profiles.<id>` 的 enable/backend/timeout:项目 profile 写入项目 config,全局 profile 写入用户全局 config。切换 profile、刷新、删除或离开页面时,未保存的 delegation 字段会得到保护。通用默认值和 `allowAgentInvocationWithoutApproval` 只能在 config 文件中设置。
44
44
 
45
45
  启用前请阅读[前台 delegation](delegation.md)。