@zihanw/pi-forge 0.4.0 → 0.5.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.
Files changed (341) hide show
  1. package/CHANGELOG.md +49 -1
  2. package/README.md +11 -11
  3. package/README.zh-CN.md +4 -6
  4. package/SUBAGENT_ADAPTER_CONTRACT.md +3 -1
  5. package/dist/agent-profile.d.ts +21 -42
  6. package/dist/agent-profile.d.ts.map +1 -1
  7. package/dist/agent-profile.js +82 -194
  8. package/dist/agent-profile.js.map +1 -1
  9. package/dist/catalog.d.ts +27 -0
  10. package/dist/catalog.d.ts.map +1 -0
  11. package/dist/catalog.js +59 -0
  12. package/dist/catalog.js.map +1 -0
  13. package/dist/codecs/agent-profile.d.ts +53 -0
  14. package/dist/codecs/agent-profile.d.ts.map +1 -0
  15. package/dist/codecs/agent-profile.js +176 -0
  16. package/dist/codecs/agent-profile.js.map +1 -0
  17. package/dist/codecs/index.d.ts +5 -0
  18. package/dist/codecs/index.d.ts.map +1 -0
  19. package/dist/codecs/index.js +3 -0
  20. package/dist/codecs/index.js.map +1 -0
  21. package/dist/codecs/prompt-stack.d.ts +18 -0
  22. package/dist/codecs/prompt-stack.d.ts.map +1 -0
  23. package/dist/codecs/prompt-stack.js +479 -0
  24. package/dist/codecs/prompt-stack.js.map +1 -0
  25. package/dist/compile-cycle.d.ts +18 -0
  26. package/dist/compile-cycle.d.ts.map +1 -0
  27. package/dist/compile-cycle.js +13 -0
  28. package/dist/compile-cycle.js.map +1 -0
  29. package/dist/compiler.d.ts +10 -4
  30. package/dist/compiler.d.ts.map +1 -1
  31. package/dist/compiler.js +53 -19
  32. package/dist/compiler.js.map +1 -1
  33. package/dist/extension-registry.d.ts.map +1 -1
  34. package/dist/extension-registry.js +5 -2
  35. package/dist/extension-registry.js.map +1 -1
  36. package/dist/forge-config.d.ts +2 -81
  37. package/dist/forge-config.d.ts.map +1 -1
  38. package/dist/forge-config.js +5 -280
  39. package/dist/forge-config.js.map +1 -1
  40. package/dist/forge-v1/analyzer.d.ts +3 -0
  41. package/dist/forge-v1/analyzer.d.ts.map +1 -0
  42. package/dist/forge-v1/analyzer.js +50 -0
  43. package/dist/forge-v1/analyzer.js.map +1 -0
  44. package/dist/forge-v1/index.d.ts +6 -0
  45. package/dist/forge-v1/index.d.ts.map +1 -0
  46. package/dist/forge-v1/index.js +13 -0
  47. package/dist/forge-v1/index.js.map +1 -0
  48. package/dist/forge-v1/parser.d.ts +3 -0
  49. package/dist/forge-v1/parser.d.ts.map +1 -0
  50. package/dist/forge-v1/parser.js +186 -0
  51. package/dist/forge-v1/parser.js.map +1 -0
  52. package/dist/forge-v1/renderer.d.ts +9 -0
  53. package/dist/forge-v1/renderer.d.ts.map +1 -0
  54. package/dist/forge-v1/renderer.js +181 -0
  55. package/dist/forge-v1/renderer.js.map +1 -0
  56. package/dist/forge-v1/types.d.ts +87 -0
  57. package/dist/forge-v1/types.d.ts.map +1 -0
  58. package/dist/forge-v1/types.js +4 -0
  59. package/dist/forge-v1/types.js.map +1 -0
  60. package/dist/index.d.ts +12 -9
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +49 -59
  63. package/dist/index.js.map +1 -1
  64. package/dist/lifecycle.d.ts +7 -5
  65. package/dist/lifecycle.d.ts.map +1 -1
  66. package/dist/lifecycle.js +44 -110
  67. package/dist/lifecycle.js.map +1 -1
  68. package/dist/loader.d.ts +16 -3
  69. package/dist/loader.d.ts.map +1 -1
  70. package/dist/loader.js +42 -440
  71. package/dist/loader.js.map +1 -1
  72. package/dist/macro-engine.d.ts +9 -14
  73. package/dist/macro-engine.d.ts.map +1 -1
  74. package/dist/macro-engine.js +5 -238
  75. package/dist/macro-engine.js.map +1 -1
  76. package/dist/payload-command.d.ts +6 -6
  77. package/dist/payload-command.d.ts.map +1 -1
  78. package/dist/payload-command.js.map +1 -1
  79. package/dist/payload-state.d.ts +16 -0
  80. package/dist/payload-state.d.ts.map +1 -0
  81. package/dist/payload-state.js +14 -0
  82. package/dist/payload-state.js.map +1 -0
  83. package/dist/preset-command.d.ts +4 -4
  84. package/dist/preset-command.d.ts.map +1 -1
  85. package/dist/preset-command.js +55 -98
  86. package/dist/preset-command.js.map +1 -1
  87. package/dist/preview.d.ts +4 -4
  88. package/dist/preview.d.ts.map +1 -1
  89. package/dist/preview.js +17 -8
  90. package/dist/preview.js.map +1 -1
  91. package/dist/profile-command.d.ts +2 -2
  92. package/dist/profile-command.d.ts.map +1 -1
  93. package/dist/profile-command.js +52 -26
  94. package/dist/profile-command.js.map +1 -1
  95. package/dist/profile-service.d.ts +5 -2
  96. package/dist/profile-service.d.ts.map +1 -1
  97. package/dist/profile-service.js +63 -42
  98. package/dist/profile-service.js.map +1 -1
  99. package/dist/prompt-analysis.d.ts +24 -0
  100. package/dist/prompt-analysis.d.ts.map +1 -0
  101. package/dist/prompt-analysis.js +84 -0
  102. package/dist/prompt-analysis.js.map +1 -0
  103. package/dist/prompt-runtime.d.ts +19 -0
  104. package/dist/prompt-runtime.d.ts.map +1 -0
  105. package/dist/prompt-runtime.js +30 -0
  106. package/dist/prompt-runtime.js.map +1 -0
  107. package/dist/regex.js +6 -12
  108. package/dist/regex.js.map +1 -1
  109. package/dist/render-helpers.d.ts +2 -10
  110. package/dist/render-helpers.d.ts.map +1 -1
  111. package/dist/render-helpers.js +3 -53
  112. package/dist/render-helpers.js.map +1 -1
  113. package/dist/repositories/agent-profile.d.ts +36 -0
  114. package/dist/repositories/agent-profile.d.ts.map +1 -0
  115. package/dist/repositories/agent-profile.js +153 -0
  116. package/dist/repositories/agent-profile.js.map +1 -0
  117. package/dist/repositories/index.d.ts +3 -0
  118. package/dist/repositories/index.d.ts.map +1 -0
  119. package/dist/repositories/index.js +3 -0
  120. package/dist/repositories/index.js.map +1 -0
  121. package/dist/repositories/prompt-stack.d.ts +57 -0
  122. package/dist/repositories/prompt-stack.d.ts.map +1 -0
  123. package/dist/repositories/prompt-stack.js +175 -0
  124. package/dist/repositories/prompt-stack.js.map +1 -0
  125. package/dist/resource-identity.d.ts +33 -0
  126. package/dist/resource-identity.d.ts.map +1 -0
  127. package/dist/resource-identity.js +56 -0
  128. package/dist/resource-identity.js.map +1 -0
  129. package/dist/runtime/profile-runtime.d.ts +2 -2
  130. package/dist/runtime/profile-runtime.d.ts.map +1 -1
  131. package/dist/runtime/profile-runtime.js +18 -10
  132. package/dist/runtime/profile-runtime.js.map +1 -1
  133. package/dist/runtime/prompt-stack-runtime.d.ts +5 -4
  134. package/dist/runtime/prompt-stack-runtime.d.ts.map +1 -1
  135. package/dist/runtime/prompt-stack-runtime.js +47 -52
  136. package/dist/runtime/prompt-stack-runtime.js.map +1 -1
  137. package/dist/runtime/tool-policy-runtime.d.ts +2 -2
  138. package/dist/runtime/tool-policy-runtime.d.ts.map +1 -1
  139. package/dist/runtime/tool-policy-runtime.js +3 -3
  140. package/dist/runtime/tool-policy-runtime.js.map +1 -1
  141. package/dist/session-adapter.d.ts +17 -0
  142. package/dist/session-adapter.d.ts.map +1 -0
  143. package/dist/session-adapter.js +57 -0
  144. package/dist/session-adapter.js.map +1 -0
  145. package/dist/slot-renderers.d.ts +16 -3
  146. package/dist/slot-renderers.d.ts.map +1 -1
  147. package/dist/slot-renderers.js +15 -63
  148. package/dist/slot-renderers.js.map +1 -1
  149. package/dist/stack-migration.d.ts +6 -0
  150. package/dist/stack-migration.d.ts.map +1 -1
  151. package/dist/stack-migration.js +49 -52
  152. package/dist/stack-migration.js.map +1 -1
  153. package/dist/storage.d.ts +10 -0
  154. package/dist/storage.d.ts.map +1 -1
  155. package/dist/storage.js +45 -10
  156. package/dist/storage.js.map +1 -1
  157. package/dist/subagent/fingerprints.d.ts +24 -0
  158. package/dist/subagent/fingerprints.d.ts.map +1 -0
  159. package/dist/subagent/fingerprints.js +81 -0
  160. package/dist/subagent/fingerprints.js.map +1 -0
  161. package/dist/subagent/host-port.d.ts +296 -0
  162. package/dist/subagent/host-port.d.ts.map +1 -0
  163. package/dist/subagent/host-port.js +560 -0
  164. package/dist/subagent/host-port.js.map +1 -0
  165. package/dist/subagent/index.d.ts +10 -10
  166. package/dist/subagent/index.d.ts.map +1 -1
  167. package/dist/subagent/index.js +9 -10
  168. package/dist/subagent/index.js.map +1 -1
  169. package/dist/subagent-host.d.ts +99 -18
  170. package/dist/subagent-host.d.ts.map +1 -1
  171. package/dist/subagent-host.js +185 -162
  172. package/dist/subagent-host.js.map +1 -1
  173. package/dist/template-render.d.ts +18 -0
  174. package/dist/template-render.d.ts.map +1 -0
  175. package/dist/template-render.js +232 -0
  176. package/dist/template-render.js.map +1 -0
  177. package/dist/types.d.ts +43 -27
  178. package/dist/types.d.ts.map +1 -1
  179. package/dist/types.js.map +1 -1
  180. package/dist/web-editor/client-script.generated.d.ts.map +1 -1
  181. package/dist/web-editor/client-script.generated.js +1 -1
  182. package/dist/web-editor/client-script.generated.js.map +1 -1
  183. package/dist/web-editor/client-styles.generated.d.ts.map +1 -1
  184. package/dist/web-editor/client-styles.generated.js +1 -1
  185. package/dist/web-editor/client-styles.generated.js.map +1 -1
  186. package/dist/web-editor/server.d.ts.map +1 -1
  187. package/dist/web-editor/server.js +32 -72
  188. package/dist/web-editor/server.js.map +1 -1
  189. package/dist/web-editor/styles.d.ts.map +1 -1
  190. package/dist/web-editor/styles.js +13 -0
  191. package/dist/web-editor/styles.js.map +1 -1
  192. package/dist/web-editor/types.d.ts +10 -37
  193. package/dist/web-editor/types.d.ts.map +1 -1
  194. package/dist/web-host.d.ts +4 -2
  195. package/dist/web-host.d.ts.map +1 -1
  196. package/dist/web-host.js +110 -138
  197. package/dist/web-host.js.map +1 -1
  198. package/dist/workspace.d.ts +74 -0
  199. package/dist/workspace.d.ts.map +1 -0
  200. package/dist/workspace.js +351 -0
  201. package/dist/workspace.js.map +1 -0
  202. package/docs/README.md +6 -4
  203. package/docs/concepts/agent-profiles.md +2 -2
  204. package/docs/concepts/prompt-stacks.md +12 -7
  205. package/docs/design/README.md +21 -3
  206. package/docs/design/architecture-0.5.md +211 -0
  207. package/docs/design/archive/0.5-full-proposal/0.5-consumer-audit.md +62 -0
  208. package/docs/design/archive/0.5-full-proposal/0.5-inventory.md +208 -0
  209. package/docs/design/archive/0.5-full-proposal/0.5-phase0-decision-drafts.md +237 -0
  210. package/docs/design/archive/0.5-full-proposal/README.md +12 -0
  211. package/docs/design/archive/0.5-full-proposal/architecture-0.5.md +423 -0
  212. package/docs/design/archive/0.5-full-proposal/host-discovery-spike.md +103 -0
  213. package/docs/design/archive/0.5-full-proposal/template-language-spike.md +156 -0
  214. package/docs/design/context-diff-plan.md +72 -0
  215. package/docs/design/decision-template.md +33 -0
  216. package/docs/design/roadmap-0.4-archive.md +1 -1
  217. package/docs/design/subagents/interface-design.md +1 -1
  218. package/docs/development/architecture-rules.md +148 -0
  219. package/docs/development/roadmap.md +39 -13
  220. package/docs/development/scoped-global-profiles-stacks.md +325 -0
  221. package/docs/development/setup.md +6 -4
  222. package/docs/getting-started.md +9 -6
  223. package/docs/guides/custom-macros-and-slots.md +8 -7
  224. package/docs/guides/debugging.md +1 -1
  225. package/docs/guides/delegation.md +25 -21
  226. package/docs/guides/migrating-to-0.5.md +107 -0
  227. package/docs/guides/use-cases.md +7 -11
  228. package/docs/guides/web-editor.md +7 -11
  229. package/docs/reference/commands.md +4 -3
  230. package/docs/reference/configuration.md +18 -17
  231. package/docs/reference/features.md +34 -79
  232. package/docs/reference/macros-and-slots.md +70 -49
  233. package/docs/reference/public-api.md +64 -17
  234. package/docs/reference/stack-schema.md +14 -9
  235. package/docs/reference/subagent-host-port.md +49 -0
  236. package/docs/zh-CN/README.md +3 -3
  237. package/docs/zh-CN/concepts/agent-profiles.md +4 -2
  238. package/docs/zh-CN/concepts/prompt-stacks.md +9 -7
  239. package/docs/zh-CN/getting-started.md +10 -7
  240. package/docs/zh-CN/guides/delegation.md +11 -13
  241. package/docs/zh-CN/guides/migrating-to-0.5.md +92 -0
  242. package/docs/zh-CN/guides/web-editor.md +7 -7
  243. package/docs/zh-CN/reference/commands.md +6 -3
  244. package/examples/custom-system-status-extension/README.md +3 -3
  245. package/examples/custom-system-status-extension/index.ts +2 -1
  246. package/examples/custom-system-status-extension/prompt-stack.json +4 -3
  247. package/examples/default-prompt-stack.json +9 -4
  248. package/examples/image-reader-prompt-stack.json +16 -26
  249. package/examples/reviewer-prompt-stack.json +13 -24
  250. package/package.json +101 -120
  251. package/dist/runtime/subagent-runtime.d.ts +0 -45
  252. package/dist/runtime/subagent-runtime.d.ts.map +0 -1
  253. package/dist/runtime/subagent-runtime.js +0 -335
  254. package/dist/runtime/subagent-runtime.js.map +0 -1
  255. package/dist/runtime-state.d.ts +0 -30
  256. package/dist/runtime-state.d.ts.map +0 -1
  257. package/dist/runtime-state.js +0 -17
  258. package/dist/runtime-state.js.map +0 -1
  259. package/dist/sillytavern-importer/items.d.ts +0 -3
  260. package/dist/sillytavern-importer/items.d.ts.map +0 -1
  261. package/dist/sillytavern-importer/items.js +0 -88
  262. package/dist/sillytavern-importer/items.js.map +0 -1
  263. package/dist/sillytavern-importer/macros.d.ts +0 -15
  264. package/dist/sillytavern-importer/macros.d.ts.map +0 -1
  265. package/dist/sillytavern-importer/macros.js +0 -141
  266. package/dist/sillytavern-importer/macros.js.map +0 -1
  267. package/dist/sillytavern-importer/prompt-order.d.ts +0 -6
  268. package/dist/sillytavern-importer/prompt-order.d.ts.map +0 -1
  269. package/dist/sillytavern-importer/prompt-order.js +0 -38
  270. package/dist/sillytavern-importer/prompt-order.js.map +0 -1
  271. package/dist/sillytavern-importer/regex.d.ts +0 -3
  272. package/dist/sillytavern-importer/regex.d.ts.map +0 -1
  273. package/dist/sillytavern-importer/regex.js +0 -275
  274. package/dist/sillytavern-importer/regex.js.map +0 -1
  275. package/dist/sillytavern-importer/report.d.ts +0 -21
  276. package/dist/sillytavern-importer/report.d.ts.map +0 -1
  277. package/dist/sillytavern-importer/report.js +0 -166
  278. package/dist/sillytavern-importer/report.js.map +0 -1
  279. package/dist/sillytavern-importer/types.d.ts +0 -106
  280. package/dist/sillytavern-importer/types.d.ts.map +0 -1
  281. package/dist/sillytavern-importer/types.js +0 -2
  282. package/dist/sillytavern-importer/types.js.map +0 -1
  283. package/dist/sillytavern-importer.d.ts +0 -5
  284. package/dist/sillytavern-importer.d.ts.map +0 -1
  285. package/dist/sillytavern-importer.js +0 -117
  286. package/dist/sillytavern-importer.js.map +0 -1
  287. package/dist/subagent/canonical.d.ts +0 -22
  288. package/dist/subagent/canonical.d.ts.map +0 -1
  289. package/dist/subagent/canonical.js +0 -24
  290. package/dist/subagent/canonical.js.map +0 -1
  291. package/dist/subagent/context.d.ts +0 -8
  292. package/dist/subagent/context.d.ts.map +0 -1
  293. package/dist/subagent/context.js +0 -125
  294. package/dist/subagent/context.js.map +0 -1
  295. package/dist/subagent/contract.d.ts +0 -10
  296. package/dist/subagent/contract.d.ts.map +0 -1
  297. package/dist/subagent/contract.js +0 -10
  298. package/dist/subagent/contract.js.map +0 -1
  299. package/dist/subagent/plan.d.ts +0 -18
  300. package/dist/subagent/plan.d.ts.map +0 -1
  301. package/dist/subagent/plan.js +0 -157
  302. package/dist/subagent/plan.js.map +0 -1
  303. package/dist/subagent/preflight.d.ts +0 -4
  304. package/dist/subagent/preflight.d.ts.map +0 -1
  305. package/dist/subagent/preflight.js +0 -108
  306. package/dist/subagent/preflight.js.map +0 -1
  307. package/dist/subagent/request.d.ts +0 -4
  308. package/dist/subagent/request.d.ts.map +0 -1
  309. package/dist/subagent/request.js +0 -122
  310. package/dist/subagent/request.js.map +0 -1
  311. package/dist/subagent/response.d.ts +0 -8
  312. package/dist/subagent/response.d.ts.map +0 -1
  313. package/dist/subagent/response.js +0 -155
  314. package/dist/subagent/response.js.map +0 -1
  315. package/dist/subagent/tools.d.ts +0 -4
  316. package/dist/subagent/tools.d.ts.map +0 -1
  317. package/dist/subagent/tools.js +0 -42
  318. package/dist/subagent/tools.js.map +0 -1
  319. package/dist/subagent/types.d.ts +0 -268
  320. package/dist/subagent/types.d.ts.map +0 -1
  321. package/dist/subagent/types.js +0 -3
  322. package/dist/subagent/types.js.map +0 -1
  323. package/dist/subagent/validation.d.ts +0 -35
  324. package/dist/subagent/validation.d.ts.map +0 -1
  325. package/dist/subagent/validation.js +0 -314
  326. package/dist/subagent/validation.js.map +0 -1
  327. package/dist/subagent-command.d.ts +0 -4
  328. package/dist/subagent-command.d.ts.map +0 -1
  329. package/dist/subagent-command.js +0 -246
  330. package/dist/subagent-command.js.map +0 -1
  331. package/dist/subagent-profile-tool.d.ts +0 -49
  332. package/dist/subagent-profile-tool.d.ts.map +0 -1
  333. package/dist/subagent-profile-tool.js +0 -124
  334. package/dist/subagent-profile-tool.js.map +0 -1
  335. package/dist/subagent-tool.d.ts +0 -53
  336. package/dist/subagent-tool.d.ts.map +0 -1
  337. package/dist/subagent-tool.js +0 -456
  338. package/dist/subagent-tool.js.map +0 -1
  339. package/docs/guides/sillytavern-import.md +0 -47
  340. package/docs/reference/subagent-adapter.md +0 -204
  341. package/examples/sillytavern-dm-writer-prompt-stack.json +0 -190
@@ -9,21 +9,21 @@ Use these as starting patterns rather than rigid templates. The [default Pi mirr
9
9
  Put long-lived character rules in a system block, runtime context in appropriate slots, and the current user action in an explicit final user block:
10
10
 
11
11
  1. System character/personality block.
12
- 2. Tools, project context, variables, and other runtime slots.
12
+ 2. Tools, project context, and other runtime slots.
13
13
  3. `chat-history` with `includeLastUserMessage: false`.
14
- 4. Final user block containing `{{lastUserMessage}}`.
14
+ 4. Final user block containing `{{ runtime.lastUserMessage }}`.
15
15
 
16
- This keeps the latest request clear and avoids duplication. Static `{{char}}` / `{{user}}` variables work well for character constants; turn/session macros can track temporary scene state. Durable project memory belongs in project files, not prompt variables.
16
+ This keeps the latest request clear and avoids duplication. Static `{{ parameters.char }}` / `{{ parameters.user }}` values work well for character constants. Durable project memory belongs in project files, not parameters.
17
17
 
18
18
  ## Focused code review
19
19
 
20
20
  Start from [the reviewer example](../../examples/reviewer-prompt-stack.json). It denies writing tools, wraps prior history as background, omits the latest user message from history, then reinserts it as the explicit review target.
21
21
 
22
- Use a rule such as “prioritize correctness, regressions, security, and missing tests.” Keep tools, project context, variables, and history when the reviewer must inspect the repository. Use `append` to retain Pi's normal coding prompt, or `replace` when the stack must fully control prompt and skill visibility.
22
+ Use a rule such as “prioritize correctness, regressions, security, and missing tests.” Keep tools, project context, and history when the reviewer must inspect the repository. Use `append` to retain Pi's normal coding prompt, or `replace` when the stack must fully control prompt and skill visibility.
23
23
 
24
24
  ## Translation mode
25
25
 
26
- Create a small stack with a system block for target language, register/tone, and terminology rules. Retain history and a final `{{lastUserMessage}}`. Separate literal translation, localization review, and bilingual editing into different stacks when their rules conflict.
26
+ Create a small stack with a system block for target language, register/tone, and terminology rules. Retain history and a final `{{ runtime.lastUserMessage }}`. Separate literal translation, localization review, and bilingual editing into different stacks when their rules conflict.
27
27
 
28
28
  ## Multi-mode switching
29
29
 
@@ -48,13 +48,9 @@ Tool policy constrains model tool calls but is not an operating-system sandbox.
48
48
 
49
49
  Keep the Pi mirror, require the tools needed for the workflow, strip prior assistant thinking from inserted history, and move project context near the current user turn. This reduces distracting prompt material without removing relevant repository instructions.
50
50
 
51
- ## SillyTavern DM writer
52
-
53
- [The DM-writer example](../../examples/sillytavern-dm-writer-prompt-stack.json) defines a Dungeon Master through `{{char}}` / `{{user}}`, wraps prior adventure history, reinserts the current action, and uses deterministic regex cleanup for OOC notes, secret-roll markers, dice notation, and `Player:` prefixes.
54
-
55
51
  ## Payload lab
56
52
 
57
- Include `active-model`, `date-cwd`, and `variables`, then add compiled regex rules for deterministic redaction or formatting. Pair the stack with `/payload next` or the web editor's capture view to audit exactly what changed.
53
+ Include `active-model` and `date-cwd`, then add compiled regex rules for deterministic redaction or formatting. Pair the stack with `/payload next` or the web editor's capture view to audit exactly what changed.
58
54
 
59
55
  ## Pi-docs expert
60
56
 
@@ -62,4 +58,4 @@ Allow read/search tools, include the `pi-docs` and project-context slots, and ke
62
58
 
63
59
  ## Trusted runtime status
64
60
 
65
- The [custom system-status example](../../examples/custom-system-status-extension/README.md) registers `{{cpuLoad}}` and a `machine-status` slot from trusted project code. Use this pattern for deterministic host data that cannot be represented as static stack JSON.
61
+ The [custom system-status example](../../examples/custom-system-status-extension/README.md) registers `{{ extensions.cpuLoad }}` and a `machine-status` slot from trusted project code. Use this pattern for deterministic host data that cannot be represented as static stack JSON.
@@ -38,30 +38,26 @@ The stack workspace provides:
38
38
  - validation and a full compiled preview;
39
39
  - registered-tool and loaded-skill search with exact-name chips and wildcard patterns;
40
40
  - raw JSON recovery for advanced or unknown fields;
41
- - native pi-forge and SillyTavern JSON import;
41
+ - native pi-forge JSON import;
42
42
  - export, fork, and deletion;
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
- 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.
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.
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, 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
- ## Delegation card
58
+ ## Delegation
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.
61
-
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
-
64
- Read [foreground delegation](delegation.md) before enabling a profile.
60
+ Delegation configuration is not part of the main editor. The optional `@zihanw/pi-forge-subagents` package owns the dedicated `.pi/forge/subagents.json` and `~/.pi/forge/subagents.json` files. Read [foreground delegation](delegation.md) before enabling a profile.
65
61
 
66
62
  ## Migration
67
63
 
@@ -23,9 +23,8 @@ Arguments in brackets are optional. Commands that write project files require a
23
23
  | Command | Behavior |
24
24
  |---|---|
25
25
  | `/preset migrate-stacks [--dry-run] [--overwrite] [--delete-legacy]` | Copy legacy `.pi/prompt-stacks` files into `.pi/forge/prompt-stacks`. |
26
- | `/preset import-silly <path> [character_id] [--dry-run] [--overwrite]` | Convert a SillyTavern preset and write a migration report. |
27
26
 
28
- Use migration/import dry runs before overwriting or deleting anything. See [SillyTavern import](../guides/sillytavern-import.md).
27
+ Use migration dry runs before overwriting or deleting anything.
29
28
 
30
29
  ## Agent profiles
31
30
 
@@ -42,13 +41,15 @@ Use migration/import dry runs before overwriting or deleting anything. See [Sill
42
41
 
43
42
  ## Experimental foreground delegation
44
43
 
44
+ The commands below are provided by the optional `@zihanw/pi-forge-subagents` package.
45
+
45
46
  | Command | Behavior |
46
47
  |---|---|
47
48
  | `/forge-agent backends` | List registered experimental backends, capabilities, and effective defaults. |
48
49
  | `/forge-agent plan <profile> [--backend <id>] <task>` | Prepare, validate, display, and discard an exact plan without provider transport. |
49
50
  | `/forge-agent run <profile> [--backend <id>] <task>` | Review and approve an exact foreground read-only run. |
50
51
 
51
- Only project-authorized delegation profiles are accepted. The model-callable equivalents are `forge_subagent_profiles` (local discovery) and `forge_subagent` (execution). See the [delegation safety guide](../guides/delegation.md).
52
+ Only profiles explicitly authorized in the matching scope are accepted: the project `subagents.json` authorizes `project:<id>` profiles and the global `subagents.json` authorizes `global:<id>` profiles; `.pi/forge/config.json.subagents` remains a read-only legacy fallback. The model-callable equivalents are `forge_subagent_profiles` (local discovery) and `forge_subagent` (execution). See the [delegation safety guide](../guides/delegation.md).
52
53
 
53
54
  ## Payload inspection
54
55
 
@@ -18,31 +18,30 @@ The port is preferred, not guaranteed. The editor binds only to `127.0.0.1` and
18
18
 
19
19
  ## Experimental subagents
20
20
 
21
- User configuration may set general defaults:
21
+ Subagent configuration is owned by the optional `@zihanw/pi-forge-subagents` package. Dedicated files are `.pi/forge/subagents.json` for a trusted project and `~/.pi/forge/subagents.json` for user defaults. Legacy `.pi/forge/config.json` / `~/.pi/forge/config.json` `subagents` sections are read-only fallback material and emit a warning.
22
+
23
+ User defaults may set general settings:
22
24
 
23
25
  ```json
24
26
  {
25
- "subagents": {
26
- "backend": "pi-subprocess-readonly",
27
- "timeoutMs": 60000
28
- }
27
+ "backend": "pi-subprocess-readonly",
28
+ "timeoutMs": 60000
29
29
  }
30
30
  ```
31
31
 
32
- Trusted project configuration may override defaults, authorize individual project profile IDs, and authorize unattended model invocation:
32
+ Trusted project `subagents.json` may override defaults, authorize individual project profile IDs, and authorize unattended model invocation:
33
33
 
34
34
  ```json
35
35
  {
36
- "subagents": {
37
- "backend": "pi-subprocess-readonly",
38
- "timeoutMs": 60000,
39
- "allowAgentInvocationWithoutApproval": false,
40
- "profiles": {
41
- "reviewer": {
42
- "enabled": true,
43
- "backend": "pi-rpc-readonly",
44
- "timeoutMs": 180000
45
- }
36
+ "backend": "pi-subprocess-readonly",
37
+ "timeoutMs": 60000,
38
+ "allowAgentInvocationWithoutApproval": false,
39
+ "summaryInToolDescription": false,
40
+ "profiles": {
41
+ "reviewer": {
42
+ "enabled": true,
43
+ "backend": "pi-rpc-readonly",
44
+ "timeoutMs": 180000
46
45
  }
47
46
  }
48
47
  }
@@ -50,7 +49,9 @@ Trusted project configuration may override defaults, authorize individual projec
50
49
 
51
50
  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
51
 
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.
52
+ `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 `subagents.json` and applies wherever it is enabled.
53
+
54
+ `profiles` in global `subagents.json` 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 does not modify `subagents.json`; remove any enabled entry for the deleted profile manually.
54
55
 
55
56
  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
57
 
@@ -1,6 +1,6 @@
1
1
  # Implemented feature inventory
2
2
 
3
- This file tracks the currently implemented feature surface for agent profiles, the prompt-stack runtime, template variables, web editor, SillyTavern importer, storage migration, payload inspector, and regex MVP.
3
+ This file tracks the currently implemented feature surface for agent profiles, the prompt-stack runtime, static stack variables, web editor, storage migration, payload inspector, and regex MVP.
4
4
 
5
5
  ## Package and Runtime
6
6
 
@@ -33,30 +33,16 @@ This file tracks the currently implemented feature surface for agent profiles, t
33
33
  - Project trust gates profile loading, application, and writes.
34
34
  - Shared typed profile services own capture, protected write/update/delete, application/rollback, immutable preview data, provenance changes, and runtime-drift calculation so command, web-editor, and adapter consumers do not duplicate behavior.
35
35
 
36
- ## Subagent Adapter Contract
36
+ ## Subagent Host Port
37
37
 
38
- - Dedicated experimental `@zihanw/pi-forge/subagent` entry point, with the existing package-root exports retained for 0.4 compatibility.
39
- - Subagent types, canonicalization, request/preflight validation, tool negotiation, context preparation, plan construction, response validation, and diagnostics live in focused modules behind a compatibility contract barrel.
40
- - Exported pure v1 `AgentRequest`, profile snapshot, backend preflight, execution-plan, enforcement-receipt, and discriminated response types without registering or shipping a runner.
38
+ - Experimental versioned `@zihanw/pi-forge/subagent` entry point: the minimal Forge DTO host contract (wire messages, recursive exact-field validators, transport-neutral `ForgeHostTransport`, `ForgeHost`/`ForgeHostClient` lifecycle) plus Forge-owned canonical `sha256:v1` fingerprint helpers byte-compatible with the runtime's canonical JSON.
39
+ - Mandatory lifecycle semantics: bounded discovery timeouts, explicit duplicate-host failure, `hostId`+`generation`-bound request/reply with stale/foreign rejection, disposal with `unavailable` and full listener cleanup. The host starts only after the first workspace snapshot exists, so an advertised host implies a loaded workspace; reload honors project trust (untrusted workspaces expose global resources only).
40
+ - Three minimal operations: `listProfiles` (loaded profile summaries with diagnostics), `resolveProfile` (immutable host-owned profile snapshot artifact with content fingerprints), and `prepare` (host-owned prompt compilation).
41
+ - Host-owned preparation: the client sends only a profile selector, the task text, prompt-compilation access facts (`level`/`network`/`allowProcess`), and backend facts (model, thinking level, tool catalog). The workspace resolves the profile and stack from its snapshot, filters the tool catalog through stack policy and access facts, and compiles through the same compilation context as runtime and preview. Responses return the system prompt, messages ending with the protected delegated task, effective tool IDs/names, diagnostics, the profile snapshot, and `preparedAt`.
42
+ - The port never exposes live contexts, internal registries, or execution/runtime material (access workspace model, limits, `resultProjection`, `parent`, `remoteEgressConsent`, base system prompt). The delegated-task base system prompt is host-owned and intentionally empty; the prompt stack composes the system prompt.
41
43
  - Backend-independent host profile resolution produces path-free declarative snapshots and does not consult the parent model registry or authentication state.
42
44
  - Host dependency scanning detects custom macro and slot references, records registration source identities, and fails resolution when required registrations are missing.
43
- - Backend tool negotiation intersects prompt-stack name policy with declared filesystem/process/network effects and per-request access.
44
- - Optional empty-by-default backend registry validates registration and preflight identity, requires the backend to supply a complete fingerprinted prompt runtime, binds the exact host preparation to execution, routes dry-plan discard, rejects unbound or refingerprinted substitute plans, arbitrates cancellation and host timeouts, normalizes failures, and protects opaque trace routing behind authorization-scoped handles.
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
- - 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
- - 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
- - 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
- - 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
- - 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.
51
- - Foreground progress and the bounded final report enter the normal tool-call result. A dedicated child report channel retains the normalized response, complete text transcript, tool calls/results, diagnostics, usage, approval receipt, and execution report without persisting the full prompt or inline image data; omitted images retain MIME and encoded-size metadata.
52
- - The subprocess backend is explicitly shared-user rather than OS-sandboxed: read-only is a tool policy, host timeout/cancellation are best effort, and `/tree` reverts conversation state rather than provider egress, billing, or external side effects.
53
- - `/forge-agent backends` and `/forge-agent plan <profile> <task>` expose backend discovery and provider-free exact dry planning to a human.
54
- - Deterministic fake-backend conformance coverage exercises accepted/rejected preflight, tool effects, access/limit refusal, exact preparation, success/failure, cancellation races, timeout, media, artifacts, and traces. An offline faux-provider test additionally executes the concrete SDK backend through a real Pi `AgentSession` without network traffic.
55
- - Selected parent context uses explicit provenance and deterministic exact UTF-8 budgeting; required items survive, optional items are selected newest-first, and the complete delegated text/media task remains the protected final user message.
56
- - Granular validators cover request access/depth/media/limits, backend capabilities and enforcement, prompt-runtime fidelity, plan correlation, all response terminal statuses, usage units, artifact namespaces/paths, and authorized trace handles.
57
- - Portable profile, prompt-stack, and complete execution fingerprints use canonical `sha256:v1` serialization without changing legacy branch-provenance fingerprints.
58
- - The opt-in internal Pi SDK spike remains available for broader live diagnostics, including media and trusted custom registrations beyond the shipped text-only walking skeleton.
59
- - Adapter responsibilities and unsupported runner behavior are documented in the [subagent adapter contract](subagent-adapter.md).
45
+ - Execution ownership (delegation authorization in `subagents.json`, the 0.4 execution contract, backend preflight/plan sealing via `@zihanw/pi-subagent-runtime`, approval UX, `forge_subagent`/`forge_subagent_profiles`, and `/forge-agent`) lives in the optional `@zihanw/pi-forge-subagents` package, which consumes this port and never imports main-package internals. See the [subagent host port contract](subagent-host-port.md).
60
46
 
61
47
  ## Prompt Stack Loading and Storage
62
48
 
@@ -69,7 +55,6 @@ This file tracks the currently implemented feature surface for agent profiles, t
69
55
  - `/preset migrate-stacks [--dry-run] [--overwrite] [--delete-legacy]` copies legacy stacks into the forge storage location.
70
56
  - `default.json` auto-activation unless `autoActivate` is `false`.
71
57
  - Branch-aware persisted active stack restore from session entries.
72
- - Branch-aware macro session variable restore when navigating the session tree.
73
58
  - Persisted `/preset use none` / `off` opt-out.
74
59
  - Invalid stacks with error diagnostics are skipped by automatic selection.
75
60
  - Raw stack fields are shape-checked before recovery normalization, including behavior-changing booleans/enums, defaults, context, variables, and item fields.
@@ -104,7 +89,7 @@ This file tracks the currently implemented feature surface for agent profiles, t
104
89
  - `effect: "outgoing"` is active for model-bound prompt text.
105
90
  - `effect: "finalize"` is active for completed assistant messages at `stage: "compiled"` / `targets: ["messages"]`.
106
91
  - `effect: "finalize"` is destructive: it replaces the finalized assistant message in Pi's stored transcript, so the original model output is not preserved.
107
- - `effect: "display"` and `"both"` validate with warnings and are ignored until true display transforms are implemented.
92
+ - `effect: "outgoing"` and `"finalize"` are the only valid effects; `"display"` and `"both"` are rejected during validation.
108
93
  - Streaming display is not transformed; raw text may be visible until the final message replacement happens.
109
94
  - Message transforms support role filters, `maxMessages`, `maxChars`, `minDepth`, `maxDepth`, and `trimStrings`. `$0` is supported as a full-match alias for `$&` in replacements.
110
95
  - Compiled-stage transforms support `targets: ["system"]`, `["messages"]`, or both.
@@ -124,7 +109,6 @@ This file tracks the currently implemented feature surface for agent profiles, t
124
109
  - `date-cwd`
125
110
  - `active-model`
126
111
  - `pi-docs`
127
- - `variables`
128
112
  - `date` and `date-cwd` slots can include `Current time: HH:MM:SS` with `includeTime: true`.
129
113
  - Runtime slots are registered through the same `registerSlot` definition interface used by trusted custom slots.
130
114
  - Trusted `~/.pi/forge/extensions` / `.pi/forge/extensions` modules and reusable Pi packages can register additional runtime slots through `registerSlot`, with declarative option schemas and shared render helpers.
@@ -138,36 +122,29 @@ This file tracks the currently implemented feature surface for agent profiles, t
138
122
  - Tool policy is enforced with `pi.setActiveTools()` and restored when prompt stacks are disabled or switched to an unrestricted stack.
139
123
  - Tool policy preserves later extension tool additions in the restorable baseline while keeping them filtered from an active restrictive stack.
140
124
  - A `tool_call` guard blocks tools outside the active stack policy even if another extension later changes Pi's active tool list.
141
- - Rendered `tools` slots, tool macros such as `{{tools}}`, and `tool-guidelines` respect stack tool policy.
125
+ - Rendered `tools` slots, template paths such as `{{ runtime.selectedToolsText }}`, and `tool-guidelines` respect stack tool policy.
142
126
  - Rendered `skills` slots respect stack skill policy and continue to hide skills marked `disableModelInvocation`.
143
127
  - Skill policy controls model-visible skill listings rendered by pi-forge; it does not disable explicit skill invocation and is not a security boundary.
144
128
  - Validation warns when skill policy is used with `append` or `prepend` mode because Pi's base prompt may already include unfiltered skills.
145
129
 
146
- ## Macros
130
+ ## Macros (forge-v1)
147
131
 
148
- - Built-in macros: `{{cwd}}`, `{{date}}`, `{{time}}`, `{{lastUserMessage}}`, `{{selectedTools}}`, `{{tools}}`, `{{activeModel}}`.
149
- - Built-in macros are registered through the same `registerMacro` definition interface used by trusted custom macros.
150
- - Parser-backed macro expansion supports nested `{{...}}` expressions and `::` argument splitting at the current macro depth.
151
- - Filter macros: `{{trim::value}}`, `{{upper::value}}`, `{{lower::value}}`, `{{json::value}}`, and `{{xml::value}}`.
152
- - Lazy conditional macros: `{{ifvar::name::then::else}}`, `{{ifeq::name::expected::then::else}}`, `{{iftools::tool::then::else}}`, and `{{ifslot::slot::then::else}}`. Only the selected branch is expanded.
153
- - Trusted `~/.pi/forge/extensions` / `.pi/forge/extensions` modules and reusable Pi packages can register additional macros through `registerMacro`, with argument metadata and shared runtime/variable/helper access.
154
- - `getRegisteredMacros()` and `getRegisteredSlots()` expose the active macro/slot definitions for implementation references and UI/resource inspection.
155
- - Static stack variables from `stack.variables`.
156
- - Turn/session/static lookup through `{{getvar::name}}`, `{{var::name}}`, and bare `{{name}}`.
157
- - Turn variable mutation through `{{setvar::name::value}}`, `{{setturnvar::name::value}}`, and `{{clearvar::name}}`.
158
- - Session variable mutation through `{{setsessionvar::name::value}}`, `{{setvar::session::name::value}}`, and `{{clearsessionvar::name}}`.
159
- - Unknown macro diagnostics with configurable keep/warn/error policy.
160
- - Non-string variable values stringify as JSON during macro substitution.
132
+ - Prompt text is compiled with the closed `forge-v1` template engine (parse → analyze → render).
133
+ - Runtime facts resolve through `{{ runtime.* }}` (cwd, date, time, lastUserMessage, selectedToolsText, activeModel, tool/slot booleans).
134
+ - Static values resolve through `{{ parameters.* }}`; schema v2 stores them in `parameters` while v1 stacks read legacy `variables`.
135
+ - Custom macros resolve through `{{ extensions.<name> }}` and are registered via the pure `registerMacro` extension port with declared dependencies and bounded output.
136
+ - Filters: `trim`, `upper`, `lower`, `json`, `xml`, composed with `|` pipelines.
137
+ - Conditionals: `{% if path %}...{% else %}...{% endif %}` with `==` / `!=` string comparisons over template paths.
138
+ - Undefined paths, unknown filters, parse errors, cycles, and output-limit breaches are compile errors; a failing block is omitted rather than re-injected.
139
+ - Legacy v1 stacks keep a bare-name compatibility fallback (`{{name}}`, `{{lastUserMessage}}`, `{{date}}`, ...) that maps to the corresponding parameter/runtime path.
140
+ - `getRegisteredMacros()` and `getRegisteredSlots()` expose active definitions for inspection.
161
141
 
162
- ## Template Variables
142
+ ## Parameters
163
143
 
164
- - Static string variables from `stack.variables`.
165
- - JSON-compatible session variable values: string, number, boolean, null, arrays, and objects.
166
- - Session variable snapshots restore from the current session tree branch, so tree navigation rolls macro variables back/forward with history.
167
- - Valid `<variables>` rendering from the `variables` slot.
168
- - XML variable entries rendered as `<var name="...">...</var>`.
169
- - Optional `format: "plain"` variables slot rendering.
170
- - Scope toggles with `includeStatic`, `includeSession`, and `includeTurn`.
144
+ - Schema v2 stacks store immutable JSON-compatible values in top-level `parameters`.
145
+ - Schema v1 / unversioned stacks read the legacy string-only `variables` field and support bare `{{name}}` fallback.
146
+ - Parameters resolve through `{{ parameters.<name> }}` and are available to trusted custom macros/slots through the frozen environment.
147
+ - Mutable turn/session stores, variable mutation macros, session variable entries, and the `variables` slot are removed in 0.5.0.
171
148
 
172
149
  ## Commands
173
150
 
@@ -179,9 +156,9 @@ This file tracks the currently implemented feature surface for agent profiles, t
179
156
  - `/profile validate [id]`
180
157
  - `/profile reload`
181
158
  - `/profile forget`
182
- - `/forge-agent backends`
183
- - `/forge-agent plan <profile> <task>`
184
- - `/forge-agent run <profile> <task>`
159
+ - `/forge-agent backends` (optional `@zihanw/pi-forge-subagents` package)
160
+ - `/forge-agent plan <profile> <task>` (optional package)
161
+ - `/forge-agent run <profile> <task>` (optional package)
185
162
  - `/preset list`
186
163
  - `/preset status`
187
164
  - `/preset use <id|none>`
@@ -191,29 +168,9 @@ This file tracks the currently implemented feature surface for agent profiles, t
191
168
  - `/preset reload`
192
169
  - `/preset ui [stop|restart]`
193
170
  - `/preset migrate-stacks [--dry-run] [--overwrite] [--delete-legacy]`
194
- - `/preset import-silly <path> [character_id] [--dry-run] [--overwrite]`
195
171
  - `/intercept`
196
172
  - `/payload next [save=<path>]`
197
173
 
198
- ## SillyTavern Import
199
-
200
- - Import SillyTavern preset JSON into `.pi/forge/prompt-stacks/<id>.json`.
201
- - Generate import reports under `.pi/forge/import-reports/<id>.md`.
202
- - Select a specific `character_id` when multiple prompt orders exist.
203
- - Protect existing generated stack/report files from accidental overwrite, with confirmation or `--overwrite`.
204
- - Preview generated output without writing files via `--dry-run`.
205
- - Convert prompt order into prompt stack items.
206
- - Preserve original SillyTavern identifiers in item source metadata.
207
- - Convert `chatHistory` marker to a movable `chat-history` slot.
208
- - Skip unsupported SillyTavern marker items and report omissions.
209
- - Detect `{{lastUserMessage}}` and configure chat history accordingly.
210
- - Strip SillyTavern comments and `{{trim}}` markers.
211
- - Report macros that need manual migration, including normalized camelCase SillyTavern macro names.
212
- - Report supported SillyTavern-style variable macros such as `setvar` and `getvar` as handled by pi-forge.
213
- - Report SillyTavern `extensions.regex_scripts` counts, prompt/display classification, script names, and migration notes.
214
- - Convert safe SillyTavern `promptOnly` regex scripts into pi-forge `regex.rules` with `stage: "history"`, `effect: "outgoing"`, JavaScript replacement syntax, trim strings, depth limits, clear placement role mappings, and preserved `source.sillytavern` metadata. History-stage depth is relative to the filtered chat history, matching SillyTavern's chat-relative depth.
215
- - Leave SillyTavern display-only, mixed prompt/display, DOM/browser, CSS/HTML decoration, JavaScript, unsupported-placement, unsupported-flag, and invalid regex scripts as report-only migration notes.
216
-
217
174
  ## Debugging and Tests
218
175
 
219
176
  - `/intercept` displays the next provider payload with redaction/truncation for secrets and large data.
@@ -222,10 +179,9 @@ This file tracks the currently implemented feature surface for agent profiles, t
222
179
  - The web editor can arm, poll, clear, and inspect the next redacted provider payload in a full-screen collapsible JSON inspector.
223
180
  - Runtime compile diagnostics are visible through a footer status and `/preset diagnostics`.
224
181
  - `/preset ui` starts a token-protected localhost web editor for stack management.
225
- - Node built-in tests cover agent-profile resolution/application/provenance, compiler, loader, SillyTavern importer, and the command/event harness.
226
- - Tests cover variable rendering, XML escaping, macro persistence, and typed macro stringification.
182
+ - Node built-in tests cover agent-profile resolution/application/provenance, compiler, loader, regex, and the command/event harness.
227
183
  - Tests cover regex validation, history-stage transforms, compiled-stage transforms, finalize transforms, replacement syntax, trim strings, depth limits, role/message/char limits, and preservation of non-text message parts.
228
- - Tests cover subagent host resolution, custom dependency detection, all access/required-limit/terminal-status matrices, effect-aware tool negotiation, context budgeting, protected media tasks, canonical fingerprint tamper detection, and malformed external contract values.
184
+ - Tests cover subagent host resolution, custom dependency detection, effect-aware tool negotiation, golden canonical fingerprint vectors, and malformed host-port wire values. Execution-contract matrices (access/required-limit/terminal-status, context budgeting, protected media tasks) moved to the optional package's contract tests.
229
185
  - A real headless-Chrome smoke test covers editor load, dirty state, metadata editing, policy and regex editing, validation, save, disk persistence, export, import, and browser-console errors.
230
186
  - TypeScript strict typecheck passes.
231
187
  - Package dry-run verifies published tarball contents.
@@ -264,16 +220,15 @@ This file tracks the currently implemented feature surface for agent profiles, t
264
220
  - Save existing stack JSON and immediately reload pi-forge stack data.
265
221
  - Save rejects attempts to change an existing stack ID before writing or changing active selection.
266
222
  - Keyboard shortcuts for new stack, save, validate, preview, and closing dialogs/inspectors.
267
- - Import native stack JSON or SillyTavern preset JSON into `.pi/forge/prompt-stacks`; SillyTavern uploads are converted automatically.
268
- - Show the SillyTavern import report in the web editor after import, with copy support.
223
+ - Import native pi-forge stack JSON into `.pi/forge/prompt-stacks`.
269
224
  - Export the current edited stack JSON from the browser, with clipboard fallback when download is unavailable.
270
225
  - Fork the current stack into a new stack file, with optional activation.
271
226
  - Delete stack files, disabling prompt-stack replacement if the deleted stack was active.
272
227
  - Trust and path guardrails for save/import/fork/delete writes.
273
228
  - Top-level navigation between prompt stacks and project agent profiles; stack drafts, selection, and active state survive surface switches.
274
- - Profile list shows ID, name, model/thinking/stack targets, validation state, `autoActivate` and last-applied badges, and a `subagent` badge for delegation-enabled profiles.
229
+ - Profile list shows ID, name, model/thinking/stack targets, validation state, and `autoActivate` and last-applied badges.
275
230
  - Profile create, edit, validate, save, one-shot apply, and delete reuse the shared resolver, transactional application service, and guarded repository; save rejects a second auto-activation profile and on-disk conflicts.
276
231
  - Profile form populates provider/model choices from the model registry and stack choices from the shared stack repository, and shows resolution diagnostics for missing models, authentication, unsupported thinking levels, invalid stacks, and unmatched tool policy.
277
232
  - A runtime/provenance card distinguishes current runtime, last-applied provenance, source-definition state, and per-field runtime drift after external model, thinking-level, or stack changes.
278
- - Per-profile delegation card toggles the trusted project's `subagents.profiles.<id>` opt-in with backend and timeout overrides, writing `.pi/forge/config.json` while preserving unrelated keys and removing emptied entries; the card reports the effective backend/timeout and source, warns about unregistered backends, and keeps project defaults and the unattended-invocation setting read-only.
279
- - Smoke tests cover editor server token checks, bundled page/script markers, save, payload arm/capture/clear, create/fork, SillyTavern JSON import conversion, collision handling, delete, and stop behavior.
233
+ - The main web editor no longer ships a delegation card; delegation configuration is owned by the optional `@zihanw/pi-forge-subagents` package through `.pi/forge/subagents.json`.
234
+ - Smoke tests cover editor server token checks, bundled page/script markers, save, payload arm/capture/clear, create/fork, native JSON import, collision handling, delete, and stop behavior.
@@ -1,56 +1,59 @@
1
- # Macros and runtime slots
1
+ # Forge-v1 templates and runtime slots
2
2
 
3
3
  [Documentation](../README.md)
4
4
 
5
- ## Value macros
5
+ Prompt text is compiled with the `forge-v1` engine: one closed grammar with no
6
+ includes, loops, function calls, or arbitrary expressions. Preview, runtime,
7
+ and subagent preparation use the same engine entry.
6
8
 
7
- | Macro | Value |
8
- |---|---|
9
- | `{{lastUserMessage}}` | Latest user message |
10
- | `{{date}}` | Current date as `YYYY-MM-DD` |
11
- | `{{time}}` | Current time as `HH:MM:SS` |
12
- | `{{cwd}}` | Current working directory |
13
- | `{{tools}}` | Comma-separated selected tool names |
14
- | `{{selectedTools}}` | Alias of `{{tools}}` |
15
- | `{{activeModel}}` | Current `provider/model` |
16
- | `{{name}}` | Turn, session, then static variable lookup |
17
- | `{{var::name}}` / `{{getvar::name}}` | Explicit scoped-fallback variable lookup |
18
- | `{{getturnvar::name}}` | Turn-only lookup |
19
- | `{{getsessionvar::name}}` | Session-only lookup |
20
-
21
- ## Variable mutation
9
+ ## Template interpolation
22
10
 
23
- ```text
24
- {{setvar::name::value}} set a turn variable
25
- {{setturnvar::name::value}} set a turn variable
26
- {{setsessionvar::name::value}} set a session variable
27
- {{setvar::session::name::value}} set a session variable
28
- {{clearvar::name}} clear using normal scope behavior
29
- {{clearturnvar::name}} clear a turn variable
30
- {{clearsessionvar::name}} clear a session variable
31
- ```
11
+ | Syntax | Value |
12
+ |---|---|
13
+ | `{{ runtime.cwd }}` | Current working directory |
14
+ | `{{ runtime.date }}` | Current date as `YYYY-MM-DD` |
15
+ | `{{ runtime.time }}` | Current time as `HH:MM:SS` |
16
+ | `{{ runtime.lastUserMessage }}` | Latest user message |
17
+ | `{{ runtime.selectedToolsText }}` | Comma-separated effective tool names |
18
+ | `{{ runtime.activeModel }}` | Current `provider/model` |
19
+ | `{{ parameters.<name> }}` | Static stack parameter |
20
+ | `{{ extensions.<name> }}` | Registered custom macro value |
32
21
 
33
- Turn variables reset for each message. Session variables follow Pi's active session-tree branch. Static variables come from top-level `stack.variables`. Non-string JSON-compatible values stringify as JSON during substitution.
22
+ Legacy v1 stacks keep a compatibility fallback: bare `{{name}}` resolves to a
23
+ static parameter, `{{lastUserMessage}}`/`{{date}}`/`{{time}}`/`{{cwd}}` resolve
24
+ to the matching `runtime.*` value, and registered custom macros resolve by
25
+ name. New v2 stacks use the explicit `parameters.*` / `runtime.*` paths.
34
26
 
35
- ## Filters and conditionals
27
+ ## Filters
36
28
 
37
- Nested macros are supported. `::` separators are parsed only at the current macro depth.
29
+ Nested pipelines are supported; filters are pure and versioned.
38
30
 
39
- | Macro | Result |
31
+ | Filter | Result |
40
32
  |---|---|
41
- | `{{trim::value}}` | Trim surrounding whitespace |
42
- | `{{upper::value}}` | Uppercase value |
43
- | `{{lower::value}}` | Lowercase value |
44
- | `{{json::value}}` | JSON string literal |
45
- | `{{xml::value}}` | XML-escaped value |
46
- | `{{ifvar::name::then::else}}` | Select by variable existence |
47
- | `{{ifeq::name::expected::then::else}}` | Select by equality |
48
- | `{{iftools::tool::then::else}}` | Select by effective tool name |
49
- | `{{ifslot::slot::then::else}}` | Select by enabled slot name |
33
+ | `{{ value \| trim }}` | Trim surrounding whitespace |
34
+ | `{{ value \| upper }}` | Uppercase |
35
+ | `{{ value \| lower }}` | Lowercase |
36
+ | `{{ value \| json }}` | JSON string literal |
37
+ | `{{ value \| xml }}` | XML-escaped |
38
+
39
+ ## Conditionals
40
+
41
+ ```text
42
+ {% if runtime.tool.read %}read is available{% else %}read is unavailable{% endif %}
43
+ {% if parameters.mode == "image-reader" %}image reader{% endif %}
44
+ {% if runtime.tool.bash != null %}bash visible{% endif %}
45
+ ```
50
46
 
51
- The final `else` is optional. Branches are lazy: skipped branches are not expanded and cannot mutate variables.
47
+ - `{% if path %}` selects the branch when the path exists and is truthy.
48
+ - `==` / `!=` compare against a quoted string, including empty strings.
49
+ - Nested `{% if %}` blocks are supported.
50
+ - An undefined output path is a strict compile error (no raw fallback); the
51
+ legacy `defaults.unresolvedMacroPolicy` is ignored.
52
+ - `runtime.tool.<name>` and `runtime.slot.<name>` booleans power tool/slot
53
+ conditionals without function calls.
52
54
 
53
- Unknown macro behavior is controlled by stack `defaults.unknownMacro`: keep, warn, or error according to schema validation.
55
+ When a block fails to parse, analyze, or render, pi-forge emits an error
56
+ diagnostic and omits that block rather than re-injecting raw template text.
54
57
 
55
58
  ## Built-in slots
56
59
 
@@ -62,21 +65,39 @@ Unknown macro behavior is controlled by stack `defaults.unknownMacro`: keep, war
62
65
  | `skills` | Model-visible loaded Pi skills |
63
66
  | `project-context` | Trusted project instructions/context |
64
67
  | `append-system-prompt` | Pi's appended system prompt text |
65
- | `variables` | Static/session/turn values |
66
68
  | `date` | Current date, optionally time |
67
69
  | `cwd` | Working directory |
68
70
  | `date-cwd` | Date and working directory, optionally time |
69
71
  | `active-model` | Selected provider/model |
70
72
  | `pi-docs` | Pi documentation guidance |
71
73
 
72
- Structured slots (`tools`, `tool-guidelines`, `skills`, `project-context`, `variables`) default to XML-style wrappers and support `"format": "plain"`.
73
-
74
- Notable Pi-mirror options include `tools.onlyWithSnippets`, `tool-guidelines.heading`, `tool-guidelines.includePiDefaultGuidelines`, `tool-guidelines.piStyle`, and `skills.requireReadTool`. `date` and `date-cwd` support `includeTime: true`.
74
+ Structured slots (`tools`, `tool-guidelines`, `skills`, `project-context`)
75
+ default to XML-style wrappers and support `"format": "plain"`.
75
76
 
76
- `variables` supports `includeStatic`, `includeSession`, `includeTurn`, and `format`.
77
+ ## Trusted custom definitions
77
78
 
78
- The complete `chat-history` option set is documented in [stack schema](stack-schema.md#chat-history-options).
79
+ Trusted global/project modules register macros (addressed as
80
+ `{{ extensions.<name> }}`) and slots through the pure extension port:
81
+
82
+ ```ts
83
+ api.registerMacro({
84
+ name: "ticketId",
85
+ description: "Current ticket id.",
86
+ dependencies: ["parameters.ticket.id"],
87
+ render: ({ env, helpers }) => String(env.parameters["ticket.id"]),
88
+ });
89
+
90
+ api.registerSlot({
91
+ name: "ticket-context",
92
+ description: "Render ticket context.",
93
+ dependencies: ["parameters.ticket.id"],
94
+ options: { heading: { type: "string", default: "Ticket context" } },
95
+ render: ({ item, options, env, helpers }) => "...",
96
+ });
97
+ ```
79
98
 
80
- ## Trusted custom definitions
99
+ Custom slots receive the same pure `{ item, options, env, helpers }` context and
100
+ declared-dependency resolution as macros, and their output is held to the same
101
+ 16,384-character extension limit.
81
102
 
82
- Trusted global/project modules and reusable Pi packages can register additional macro and slot names. The runtime exposes the active definitions through `getRegisteredMacros()` and `getRegisteredSlots()`. See [custom macros and slots](../guides/custom-macros-and-slots.md).
103
+ See [custom macros and slots](../guides/custom-macros-and-slots.md).