@zihanw/pi-forge 0.4.1 → 0.5.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 (372) hide show
  1. package/CHANGELOG.md +79 -1
  2. package/README.md +12 -11
  3. package/README.zh-CN.md +3 -5
  4. package/SUBAGENT_ADAPTER_CONTRACT.md +3 -1
  5. package/dist/agent-profile.d.ts +18 -62
  6. package/dist/agent-profile.d.ts.map +1 -1
  7. package/dist/agent-profile.js +27 -249
  8. package/dist/agent-profile.js.map +1 -1
  9. package/dist/codecs/agent-profile.d.ts +53 -0
  10. package/dist/codecs/agent-profile.d.ts.map +1 -0
  11. package/dist/codecs/agent-profile.js +176 -0
  12. package/dist/codecs/agent-profile.js.map +1 -0
  13. package/dist/codecs/index.d.ts +5 -0
  14. package/dist/codecs/index.d.ts.map +1 -0
  15. package/dist/codecs/index.js +3 -0
  16. package/dist/codecs/index.js.map +1 -0
  17. package/dist/codecs/prompt-stack.d.ts +18 -0
  18. package/dist/codecs/prompt-stack.d.ts.map +1 -0
  19. package/dist/codecs/prompt-stack.js +479 -0
  20. package/dist/codecs/prompt-stack.js.map +1 -0
  21. package/dist/compile-cycle.d.ts +18 -0
  22. package/dist/compile-cycle.d.ts.map +1 -0
  23. package/dist/compile-cycle.js +13 -0
  24. package/dist/compile-cycle.js.map +1 -0
  25. package/dist/compiler.d.ts +10 -4
  26. package/dist/compiler.d.ts.map +1 -1
  27. package/dist/compiler.js +53 -19
  28. package/dist/compiler.js.map +1 -1
  29. package/dist/context-diff-history.d.ts +61 -0
  30. package/dist/context-diff-history.d.ts.map +1 -0
  31. package/dist/context-diff-history.js +84 -0
  32. package/dist/context-diff-history.js.map +1 -0
  33. package/dist/context-diff-snapshot.d.ts +19 -0
  34. package/dist/context-diff-snapshot.d.ts.map +1 -0
  35. package/dist/context-diff-snapshot.js +146 -0
  36. package/dist/context-diff-snapshot.js.map +1 -0
  37. package/dist/context-diff.d.ts +70 -0
  38. package/dist/context-diff.d.ts.map +1 -0
  39. package/dist/context-diff.js +259 -0
  40. package/dist/context-diff.js.map +1 -0
  41. package/dist/extension-registry.d.ts.map +1 -1
  42. package/dist/extension-registry.js +5 -2
  43. package/dist/extension-registry.js.map +1 -1
  44. package/dist/forge-config.d.ts +0 -105
  45. package/dist/forge-config.d.ts.map +1 -1
  46. package/dist/forge-config.js +1 -313
  47. package/dist/forge-config.js.map +1 -1
  48. package/dist/forge-v1/analyzer.d.ts +3 -0
  49. package/dist/forge-v1/analyzer.d.ts.map +1 -0
  50. package/dist/forge-v1/analyzer.js +50 -0
  51. package/dist/forge-v1/analyzer.js.map +1 -0
  52. package/dist/forge-v1/index.d.ts +6 -0
  53. package/dist/forge-v1/index.d.ts.map +1 -0
  54. package/dist/forge-v1/index.js +13 -0
  55. package/dist/forge-v1/index.js.map +1 -0
  56. package/dist/forge-v1/parser.d.ts +3 -0
  57. package/dist/forge-v1/parser.d.ts.map +1 -0
  58. package/dist/forge-v1/parser.js +186 -0
  59. package/dist/forge-v1/parser.js.map +1 -0
  60. package/dist/forge-v1/renderer.d.ts +9 -0
  61. package/dist/forge-v1/renderer.d.ts.map +1 -0
  62. package/dist/forge-v1/renderer.js +181 -0
  63. package/dist/forge-v1/renderer.js.map +1 -0
  64. package/dist/forge-v1/types.d.ts +87 -0
  65. package/dist/forge-v1/types.d.ts.map +1 -0
  66. package/dist/forge-v1/types.js +4 -0
  67. package/dist/forge-v1/types.js.map +1 -0
  68. package/dist/index.d.ts +12 -12
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +54 -83
  71. package/dist/index.js.map +1 -1
  72. package/dist/lifecycle.d.ts +8 -5
  73. package/dist/lifecycle.d.ts.map +1 -1
  74. package/dist/lifecycle.js +45 -112
  75. package/dist/lifecycle.js.map +1 -1
  76. package/dist/loader.d.ts +5 -8
  77. package/dist/loader.d.ts.map +1 -1
  78. package/dist/loader.js +10 -467
  79. package/dist/loader.js.map +1 -1
  80. package/dist/macro-engine.d.ts +9 -14
  81. package/dist/macro-engine.d.ts.map +1 -1
  82. package/dist/macro-engine.js +5 -238
  83. package/dist/macro-engine.js.map +1 -1
  84. package/dist/payload-capture.d.ts +10 -0
  85. package/dist/payload-capture.d.ts.map +1 -1
  86. package/dist/payload-capture.js +39 -9
  87. package/dist/payload-capture.js.map +1 -1
  88. package/dist/payload-command.d.ts +8 -6
  89. package/dist/payload-command.d.ts.map +1 -1
  90. package/dist/payload-command.js +36 -6
  91. package/dist/payload-command.js.map +1 -1
  92. package/dist/payload-state.d.ts +19 -0
  93. package/dist/payload-state.d.ts.map +1 -0
  94. package/dist/payload-state.js +19 -0
  95. package/dist/payload-state.js.map +1 -0
  96. package/dist/preset-command.d.ts +4 -4
  97. package/dist/preset-command.d.ts.map +1 -1
  98. package/dist/preset-command.js +33 -104
  99. package/dist/preset-command.js.map +1 -1
  100. package/dist/preview.d.ts +4 -4
  101. package/dist/preview.d.ts.map +1 -1
  102. package/dist/preview.js +34 -11
  103. package/dist/preview.js.map +1 -1
  104. package/dist/profile-command.d.ts +2 -2
  105. package/dist/profile-command.d.ts.map +1 -1
  106. package/dist/profile-command.js +15 -14
  107. package/dist/profile-command.js.map +1 -1
  108. package/dist/profile-service.d.ts.map +1 -1
  109. package/dist/profile-service.js +23 -39
  110. package/dist/profile-service.js.map +1 -1
  111. package/dist/prompt-analysis.d.ts +24 -0
  112. package/dist/prompt-analysis.d.ts.map +1 -0
  113. package/dist/prompt-analysis.js +84 -0
  114. package/dist/prompt-analysis.js.map +1 -0
  115. package/dist/prompt-runtime.d.ts +19 -0
  116. package/dist/prompt-runtime.d.ts.map +1 -0
  117. package/dist/prompt-runtime.js +30 -0
  118. package/dist/prompt-runtime.js.map +1 -0
  119. package/dist/regex.js +6 -12
  120. package/dist/regex.js.map +1 -1
  121. package/dist/render-helpers.d.ts +2 -10
  122. package/dist/render-helpers.d.ts.map +1 -1
  123. package/dist/render-helpers.js +3 -53
  124. package/dist/render-helpers.js.map +1 -1
  125. package/dist/repositories/agent-profile.d.ts +36 -0
  126. package/dist/repositories/agent-profile.d.ts.map +1 -0
  127. package/dist/repositories/agent-profile.js +153 -0
  128. package/dist/repositories/agent-profile.js.map +1 -0
  129. package/dist/repositories/index.d.ts +3 -0
  130. package/dist/repositories/index.d.ts.map +1 -0
  131. package/dist/repositories/index.js +3 -0
  132. package/dist/repositories/index.js.map +1 -0
  133. package/dist/repositories/prompt-stack.d.ts +57 -0
  134. package/dist/repositories/prompt-stack.d.ts.map +1 -0
  135. package/dist/repositories/prompt-stack.js +175 -0
  136. package/dist/repositories/prompt-stack.js.map +1 -0
  137. package/dist/runtime/profile-runtime.d.ts +2 -2
  138. package/dist/runtime/profile-runtime.d.ts.map +1 -1
  139. package/dist/runtime/profile-runtime.js +13 -10
  140. package/dist/runtime/profile-runtime.js.map +1 -1
  141. package/dist/runtime/prompt-stack-runtime.d.ts +4 -3
  142. package/dist/runtime/prompt-stack-runtime.d.ts.map +1 -1
  143. package/dist/runtime/prompt-stack-runtime.js +42 -57
  144. package/dist/runtime/prompt-stack-runtime.js.map +1 -1
  145. package/dist/runtime/tool-policy-runtime.d.ts +2 -2
  146. package/dist/runtime/tool-policy-runtime.d.ts.map +1 -1
  147. package/dist/runtime/tool-policy-runtime.js +16 -6
  148. package/dist/runtime/tool-policy-runtime.js.map +1 -1
  149. package/dist/runtime/web-editor-runtime.d.ts +2 -1
  150. package/dist/runtime/web-editor-runtime.d.ts.map +1 -1
  151. package/dist/runtime/web-editor-runtime.js +8 -3
  152. package/dist/runtime/web-editor-runtime.js.map +1 -1
  153. package/dist/session-adapter.d.ts +17 -0
  154. package/dist/session-adapter.d.ts.map +1 -0
  155. package/dist/session-adapter.js +57 -0
  156. package/dist/session-adapter.js.map +1 -0
  157. package/dist/slot-renderers.d.ts +16 -3
  158. package/dist/slot-renderers.d.ts.map +1 -1
  159. package/dist/slot-renderers.js +15 -63
  160. package/dist/slot-renderers.js.map +1 -1
  161. package/dist/stack-migration.d.ts +6 -0
  162. package/dist/stack-migration.d.ts.map +1 -1
  163. package/dist/stack-migration.js +49 -52
  164. package/dist/stack-migration.js.map +1 -1
  165. package/dist/subagent/fingerprints.d.ts +24 -0
  166. package/dist/subagent/fingerprints.d.ts.map +1 -0
  167. package/dist/subagent/fingerprints.js +81 -0
  168. package/dist/subagent/fingerprints.js.map +1 -0
  169. package/dist/subagent/host-port.d.ts +296 -0
  170. package/dist/subagent/host-port.d.ts.map +1 -0
  171. package/dist/subagent/host-port.js +560 -0
  172. package/dist/subagent/host-port.js.map +1 -0
  173. package/dist/subagent/index.d.ts +10 -10
  174. package/dist/subagent/index.d.ts.map +1 -1
  175. package/dist/subagent/index.js +9 -10
  176. package/dist/subagent/index.js.map +1 -1
  177. package/dist/subagent-host.d.ts +99 -18
  178. package/dist/subagent-host.d.ts.map +1 -1
  179. package/dist/subagent-host.js +143 -146
  180. package/dist/subagent-host.js.map +1 -1
  181. package/dist/template-render.d.ts +18 -0
  182. package/dist/template-render.d.ts.map +1 -0
  183. package/dist/template-render.js +232 -0
  184. package/dist/template-render.js.map +1 -0
  185. package/dist/types.d.ts +40 -27
  186. package/dist/types.d.ts.map +1 -1
  187. package/dist/types.js.map +1 -1
  188. package/dist/ui-contribution/contrib-port.d.ts +170 -0
  189. package/dist/ui-contribution/contrib-port.d.ts.map +1 -0
  190. package/dist/ui-contribution/contrib-port.js +640 -0
  191. package/dist/ui-contribution/contrib-port.js.map +1 -0
  192. package/dist/ui-contribution/index.d.ts +3 -0
  193. package/dist/ui-contribution/index.d.ts.map +1 -0
  194. package/dist/ui-contribution/index.js +2 -0
  195. package/dist/ui-contribution/index.js.map +1 -0
  196. package/dist/web-editor/client-script.generated.d.ts.map +1 -1
  197. package/dist/web-editor/client-script.generated.js +1 -1
  198. package/dist/web-editor/client-script.generated.js.map +1 -1
  199. package/dist/web-editor/client-styles.generated.d.ts.map +1 -1
  200. package/dist/web-editor/client-styles.generated.js +1 -1
  201. package/dist/web-editor/client-styles.generated.js.map +1 -1
  202. package/dist/web-editor/contrib-service.d.ts +41 -0
  203. package/dist/web-editor/contrib-service.d.ts.map +1 -0
  204. package/dist/web-editor/contrib-service.js +174 -0
  205. package/dist/web-editor/contrib-service.js.map +1 -0
  206. package/dist/web-editor/line-diff.d.ts +28 -0
  207. package/dist/web-editor/line-diff.d.ts.map +1 -0
  208. package/dist/web-editor/line-diff.js +216 -0
  209. package/dist/web-editor/line-diff.js.map +1 -0
  210. package/dist/web-editor/schema-form.d.ts +63 -0
  211. package/dist/web-editor/schema-form.d.ts.map +1 -0
  212. package/dist/web-editor/schema-form.js +213 -0
  213. package/dist/web-editor/schema-form.js.map +1 -0
  214. package/dist/web-editor/server.d.ts.map +1 -1
  215. package/dist/web-editor/server.js +72 -74
  216. package/dist/web-editor/server.js.map +1 -1
  217. package/dist/web-editor/styles.d.ts.map +1 -1
  218. package/dist/web-editor/styles.js +201 -21
  219. package/dist/web-editor/styles.js.map +1 -1
  220. package/dist/web-editor/types.d.ts +12 -35
  221. package/dist/web-editor/types.d.ts.map +1 -1
  222. package/dist/web-host.d.ts +6 -2
  223. package/dist/web-host.d.ts.map +1 -1
  224. package/dist/web-host.js +33 -103
  225. package/dist/web-host.js.map +1 -1
  226. package/dist/workspace.d.ts +74 -0
  227. package/dist/workspace.d.ts.map +1 -0
  228. package/dist/workspace.js +351 -0
  229. package/dist/workspace.js.map +1 -0
  230. package/docs/README.md +7 -4
  231. package/docs/concepts/agent-profiles.md +1 -1
  232. package/docs/concepts/prompt-stacks.md +5 -5
  233. package/docs/design/0.5.1-plan.md +237 -0
  234. package/docs/design/README.md +21 -3
  235. package/docs/design/architecture-0.5.md +222 -0
  236. package/docs/design/archive/0.5-full-proposal/0.5-consumer-audit.md +62 -0
  237. package/docs/design/archive/0.5-full-proposal/0.5-inventory.md +208 -0
  238. package/docs/design/archive/0.5-full-proposal/0.5-phase0-decision-drafts.md +237 -0
  239. package/docs/design/archive/0.5-full-proposal/README.md +12 -0
  240. package/docs/design/archive/0.5-full-proposal/architecture-0.5.md +423 -0
  241. package/docs/design/archive/0.5-full-proposal/host-discovery-spike.md +103 -0
  242. package/docs/design/archive/0.5-full-proposal/template-language-spike.md +156 -0
  243. package/docs/design/context-diff-plan.md +78 -0
  244. package/docs/design/decision-template.md +33 -0
  245. package/docs/design/roadmap-0.4-archive.md +1 -1
  246. package/docs/design/subagents/interface-design.md +1 -1
  247. package/docs/development/architecture-rules.md +148 -0
  248. package/docs/development/release.md +7 -1
  249. package/docs/development/roadmap.md +37 -5
  250. package/docs/development/scoped-global-profiles-stacks.md +1 -1
  251. package/docs/development/setup.md +6 -4
  252. package/docs/getting-started.md +5 -4
  253. package/docs/guides/custom-macros-and-slots.md +8 -7
  254. package/docs/guides/debugging.md +1 -1
  255. package/docs/guides/delegation.md +18 -22
  256. package/docs/guides/migrating-to-0.5.md +107 -0
  257. package/docs/guides/use-cases.md +7 -11
  258. package/docs/guides/web-editor.md +6 -10
  259. package/docs/reference/commands.md +4 -3
  260. package/docs/reference/configuration.md +17 -18
  261. package/docs/reference/features.md +34 -80
  262. package/docs/reference/macros-and-slots.md +70 -49
  263. package/docs/reference/public-api.md +76 -17
  264. package/docs/reference/stack-schema.md +15 -10
  265. package/docs/reference/subagent-host-port.md +49 -0
  266. package/docs/reference/ui-contribution-port.md +51 -0
  267. package/docs/zh-CN/README.md +3 -3
  268. package/docs/zh-CN/concepts/agent-profiles.md +1 -1
  269. package/docs/zh-CN/concepts/prompt-stacks.md +5 -5
  270. package/docs/zh-CN/getting-started.md +3 -2
  271. package/docs/zh-CN/guides/delegation.md +10 -12
  272. package/docs/zh-CN/guides/migrating-to-0.5.md +92 -0
  273. package/docs/zh-CN/guides/web-editor.md +4 -4
  274. package/docs/zh-CN/reference/commands.md +3 -2
  275. package/examples/custom-system-status-extension/README.md +3 -3
  276. package/examples/custom-system-status-extension/index.ts +2 -1
  277. package/examples/custom-system-status-extension/prompt-stack.json +4 -3
  278. package/examples/default-prompt-stack.json +9 -4
  279. package/examples/image-reader-prompt-stack.json +16 -26
  280. package/examples/reviewer-prompt-stack.json +13 -24
  281. package/package.json +106 -120
  282. package/dist/runtime/subagent-runtime.d.ts +0 -45
  283. package/dist/runtime/subagent-runtime.d.ts.map +0 -1
  284. package/dist/runtime/subagent-runtime.js +0 -343
  285. package/dist/runtime/subagent-runtime.js.map +0 -1
  286. package/dist/runtime-state.d.ts +0 -30
  287. package/dist/runtime-state.d.ts.map +0 -1
  288. package/dist/runtime-state.js +0 -17
  289. package/dist/runtime-state.js.map +0 -1
  290. package/dist/sillytavern-importer/items.d.ts +0 -3
  291. package/dist/sillytavern-importer/items.d.ts.map +0 -1
  292. package/dist/sillytavern-importer/items.js +0 -88
  293. package/dist/sillytavern-importer/items.js.map +0 -1
  294. package/dist/sillytavern-importer/macros.d.ts +0 -15
  295. package/dist/sillytavern-importer/macros.d.ts.map +0 -1
  296. package/dist/sillytavern-importer/macros.js +0 -141
  297. package/dist/sillytavern-importer/macros.js.map +0 -1
  298. package/dist/sillytavern-importer/prompt-order.d.ts +0 -6
  299. package/dist/sillytavern-importer/prompt-order.d.ts.map +0 -1
  300. package/dist/sillytavern-importer/prompt-order.js +0 -38
  301. package/dist/sillytavern-importer/prompt-order.js.map +0 -1
  302. package/dist/sillytavern-importer/regex.d.ts +0 -3
  303. package/dist/sillytavern-importer/regex.d.ts.map +0 -1
  304. package/dist/sillytavern-importer/regex.js +0 -275
  305. package/dist/sillytavern-importer/regex.js.map +0 -1
  306. package/dist/sillytavern-importer/report.d.ts +0 -21
  307. package/dist/sillytavern-importer/report.d.ts.map +0 -1
  308. package/dist/sillytavern-importer/report.js +0 -166
  309. package/dist/sillytavern-importer/report.js.map +0 -1
  310. package/dist/sillytavern-importer/types.d.ts +0 -106
  311. package/dist/sillytavern-importer/types.d.ts.map +0 -1
  312. package/dist/sillytavern-importer/types.js +0 -2
  313. package/dist/sillytavern-importer/types.js.map +0 -1
  314. package/dist/sillytavern-importer.d.ts +0 -5
  315. package/dist/sillytavern-importer.d.ts.map +0 -1
  316. package/dist/sillytavern-importer.js +0 -117
  317. package/dist/sillytavern-importer.js.map +0 -1
  318. package/dist/subagent/canonical.d.ts +0 -22
  319. package/dist/subagent/canonical.d.ts.map +0 -1
  320. package/dist/subagent/canonical.js +0 -24
  321. package/dist/subagent/canonical.js.map +0 -1
  322. package/dist/subagent/context.d.ts +0 -8
  323. package/dist/subagent/context.d.ts.map +0 -1
  324. package/dist/subagent/context.js +0 -125
  325. package/dist/subagent/context.js.map +0 -1
  326. package/dist/subagent/contract.d.ts +0 -10
  327. package/dist/subagent/contract.d.ts.map +0 -1
  328. package/dist/subagent/contract.js +0 -10
  329. package/dist/subagent/contract.js.map +0 -1
  330. package/dist/subagent/plan.d.ts +0 -18
  331. package/dist/subagent/plan.d.ts.map +0 -1
  332. package/dist/subagent/plan.js +0 -157
  333. package/dist/subagent/plan.js.map +0 -1
  334. package/dist/subagent/preflight.d.ts +0 -4
  335. package/dist/subagent/preflight.d.ts.map +0 -1
  336. package/dist/subagent/preflight.js +0 -108
  337. package/dist/subagent/preflight.js.map +0 -1
  338. package/dist/subagent/request.d.ts +0 -4
  339. package/dist/subagent/request.d.ts.map +0 -1
  340. package/dist/subagent/request.js +0 -154
  341. package/dist/subagent/request.js.map +0 -1
  342. package/dist/subagent/response.d.ts +0 -8
  343. package/dist/subagent/response.d.ts.map +0 -1
  344. package/dist/subagent/response.js +0 -155
  345. package/dist/subagent/response.js.map +0 -1
  346. package/dist/subagent/tools.d.ts +0 -4
  347. package/dist/subagent/tools.d.ts.map +0 -1
  348. package/dist/subagent/tools.js +0 -42
  349. package/dist/subagent/tools.js.map +0 -1
  350. package/dist/subagent/types.d.ts +0 -272
  351. package/dist/subagent/types.d.ts.map +0 -1
  352. package/dist/subagent/types.js +0 -3
  353. package/dist/subagent/types.js.map +0 -1
  354. package/dist/subagent/validation.d.ts +0 -35
  355. package/dist/subagent/validation.d.ts.map +0 -1
  356. package/dist/subagent/validation.js +0 -314
  357. package/dist/subagent/validation.js.map +0 -1
  358. package/dist/subagent-command.d.ts +0 -5
  359. package/dist/subagent-command.d.ts.map +0 -1
  360. package/dist/subagent-command.js +0 -249
  361. package/dist/subagent-command.js.map +0 -1
  362. package/dist/subagent-profile-tool.d.ts +0 -49
  363. package/dist/subagent-profile-tool.d.ts.map +0 -1
  364. package/dist/subagent-profile-tool.js +0 -125
  365. package/dist/subagent-profile-tool.js.map +0 -1
  366. package/dist/subagent-tool.d.ts +0 -77
  367. package/dist/subagent-tool.d.ts.map +0 -1
  368. package/dist/subagent-tool.js +0 -559
  369. package/dist/subagent-tool.js.map +0 -1
  370. package/docs/guides/sillytavern-import.md +0 -47
  371. package/docs/reference/subagent-adapter.md +0 -204
  372. package/examples/sillytavern-dm-writer-prompt-stack.json +0 -190
@@ -1,327 +1,15 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import { dirname, join } from "node:path";
3
- import { isValidAgentProfileId } from "./agent-profile.js";
4
- import { formatResourceKey, parseResourceSelector } from "./resource-identity.js";
1
+ import { join } from "node:path";
5
2
  import { globalForgeDir } from "./storage.js";
6
- /** Backend used when neither a per-run override nor a configured default applies. */
7
- export const DEFAULT_SUBAGENT_BACKEND_ID = "pi-subprocess-readonly";
8
- /** Preserve the original foreground-run timeout unless the user configures one. */
9
- export const DEFAULT_SUBAGENT_TIMEOUT_MS = 60_000;
10
- export const MIN_SUBAGENT_TIMEOUT_MS = 1_000;
11
- export const MAX_SUBAGENT_TIMEOUT_MS = 3_600_000;
12
3
  /**
13
4
  * Development/test override for the global config location. Keeps automated
14
5
  * tests hermetic regardless of the developer's real ~/.pi/forge/config.json.
15
6
  * Not part of the supported user-facing configuration surface.
16
7
  */
17
8
  export const GLOBAL_FORGE_CONFIG_PATH_ENV = "PI_FORGE_GLOBAL_CONFIG_PATH";
18
- /**
19
- * Resolve the effective backend for one run: explicit per-run override, then
20
- * a matching-scope per-profile override, then trusted-project/global defaults,
21
- * then the built-in subprocess backend. There is deliberately no fallback when
22
- * the resolved backend is missing or rejects the intent.
23
- */
24
- export function resolveSubagentBackend(settings, explicitBackend, profileId) {
25
- if (explicitBackend)
26
- return { id: explicitBackend, source: "explicit" };
27
- const profile = profileId ? configuredProfileForSelector(settings, profileId) : undefined;
28
- if (profile?.backend)
29
- return { id: profile.backend, source: profile.backendSource ?? "project-profile" };
30
- if (settings.backend)
31
- return { id: settings.backend, source: settings.backendSource ?? "global" };
32
- return { id: DEFAULT_SUBAGENT_BACKEND_ID, source: "built-in" };
33
- }
34
- export function resolveSubagentTimeout(settings, profileId) {
35
- const profile = profileId ? configuredProfileForSelector(settings, profileId) : undefined;
36
- if (profile?.timeoutMs !== undefined) {
37
- return { milliseconds: profile.timeoutMs, source: profile.timeoutSource ?? "project-profile" };
38
- }
39
- return { milliseconds: settings.timeoutMs, source: settings.timeoutSource };
40
- }
41
- export function resolveSubagentProfilePolicy(settings, profileId, explicitBackend) {
42
- const profile = configuredProfileForSelector(settings, profileId);
43
- return {
44
- profileId,
45
- enabled: profile?.enabled === true,
46
- enabledSource: profile?.enabledSource ?? "built-in",
47
- backend: resolveSubagentBackend(settings, explicitBackend, profileId),
48
- timeout: resolveSubagentTimeout(settings, profileId),
49
- };
50
- }
51
- export function loadForgeSubagentSettings(ctx) {
52
- const configPath = join(ctx.cwd, ".pi", "forge", "config.json");
53
- const globalConfigPath = process.env[GLOBAL_FORGE_CONFIG_PATH_ENV] ?? join(globalForgeDir(), "config.json");
54
- const settings = {
55
- allowAgentInvocationWithoutApproval: false,
56
- timeoutMs: DEFAULT_SUBAGENT_TIMEOUT_MS,
57
- timeoutSource: "built-in",
58
- summaryInToolDescription: false,
59
- profiles: Object.create(null),
60
- configPath,
61
- globalConfigPath,
62
- warnings: [],
63
- };
64
- // The global config is user-owned and always applies. Its `profiles` map
65
- // authorizes `global:<id>` profiles only. The project config is honored
66
- // only for trusted projects; its `profiles` map authorizes `project:<id>`
67
- // profiles only. Same-ID profiles never inherit policy from each other.
68
- const globalSection = readSubagentsSection(globalConfigPath, settings.warnings);
69
- applyBackend(globalSection, globalConfigPath, "global", settings);
70
- applyTimeout(globalSection, globalConfigPath, "global", settings);
71
- applyEmbedProfileSummary(globalSection, globalConfigPath, "global", settings);
72
- applyProfiles(globalSection, globalConfigPath, "global-profile", "global", settings);
73
- if (!ctx.isProjectTrusted())
74
- return settings;
75
- const projectSection = readSubagentsSection(configPath, settings.warnings);
76
- applyBackend(projectSection, configPath, "project", settings);
77
- applyTimeout(projectSection, configPath, "project", settings);
78
- applyEmbedProfileSummary(projectSection, configPath, "project", settings);
79
- applyProfiles(projectSection, configPath, "project-profile", "project", settings);
80
- applyUnattended(projectSection, configPath, settings);
81
- return settings;
82
- }
83
- function readSubagentsSection(configPath, warnings) {
84
- if (!existsSync(configPath))
85
- return undefined;
86
- let raw;
87
- try {
88
- raw = JSON.parse(readFileSync(configPath, "utf8"));
89
- }
90
- catch (error) {
91
- warnings.push(`pi-forge: failed to read ${configPath}; its subagent settings are ignored. ${error instanceof Error ? error.message : String(error)}`);
92
- return undefined;
93
- }
94
- if (!isPlainObject(raw)) {
95
- warnings.push(`pi-forge: ${configPath} must be a JSON object; its subagent settings are ignored.`);
96
- return undefined;
97
- }
98
- if (raw.subagents === undefined)
99
- return undefined;
100
- if (!isPlainObject(raw.subagents)) {
101
- warnings.push(`pi-forge: ${configPath} subagents must be a JSON object; its subagent settings are ignored.`);
102
- return undefined;
103
- }
104
- return raw.subagents;
105
- }
106
- function applyBackend(section, configPath, source, settings) {
107
- if (!section || section.backend === undefined)
108
- return;
109
- const value = section.backend;
110
- if (typeof value !== "string" || !value.trim()) {
111
- settings.warnings.push(`pi-forge: ${configPath} subagents.backend must be a non-empty string; the configured value is ignored.`);
112
- return;
113
- }
114
- settings.backend = value;
115
- settings.backendSource = source;
116
- }
117
- function applyTimeout(section, configPath, source, settings) {
118
- if (!section || section.timeoutMs === undefined)
119
- return;
120
- const value = section.timeoutMs;
121
- if (!isValidSubagentTimeoutMs(value)) {
122
- settings.warnings.push(`pi-forge: ${configPath} subagents.timeoutMs must be an integer from ${MIN_SUBAGENT_TIMEOUT_MS} to ${MAX_SUBAGENT_TIMEOUT_MS}; the configured value is ignored.`);
123
- return;
124
- }
125
- settings.timeoutMs = value;
126
- settings.timeoutSource = source;
127
- }
128
- function applyEmbedProfileSummary(section, configPath, source, settings) {
129
- if (!section || section.summaryInToolDescription === undefined)
130
- return;
131
- const value = section.summaryInToolDescription;
132
- if (typeof value !== "boolean") {
133
- settings.warnings.push(`pi-forge: ${configPath} subagents.summaryInToolDescription must be boolean; the configured value is ignored.`);
134
- return;
135
- }
136
- settings.summaryInToolDescription = value;
137
- settings.summaryInToolDescriptionSource = source;
138
- }
139
- function applyProfiles(section, configPath, source, scope, settings) {
140
- if (!section || section.profiles === undefined)
141
- return;
142
- if (!isPlainObject(section.profiles)) {
143
- settings.warnings.push(`pi-forge: ${configPath} subagents.profiles must be a JSON object; its per-profile settings are ignored.`);
144
- return;
145
- }
146
- for (const [profileId, rawProfile] of Object.entries(section.profiles)) {
147
- const path = `subagents.profiles.${profileId}`;
148
- if (!isValidAgentProfileId(profileId)) {
149
- settings.warnings.push(`pi-forge: ${configPath} ${path} has an invalid profile id; the entry is ignored.`);
150
- continue;
151
- }
152
- if (!isPlainObject(rawProfile)) {
153
- settings.warnings.push(`pi-forge: ${configPath} ${path} must be a JSON object; the entry is ignored.`);
154
- continue;
155
- }
156
- for (const field of Object.keys(rawProfile)) {
157
- if (field === "enabled" || field === "backend" || field === "timeoutMs")
158
- continue;
159
- settings.warnings.push(`pi-forge: ${configPath} ${path}.${field} is unsupported and ignored.`);
160
- }
161
- const key = formatResourceKey({ scope, id: profileId });
162
- const target = configuredProfile(settings, key) ?? {};
163
- if (rawProfile.enabled !== undefined) {
164
- if (typeof rawProfile.enabled !== "boolean") {
165
- settings.warnings.push(`pi-forge: ${configPath} ${path}.enabled must be boolean; the configured value is ignored.`);
166
- }
167
- else {
168
- target.enabled = rawProfile.enabled;
169
- target.enabledSource = source;
170
- }
171
- }
172
- if (rawProfile.backend !== undefined) {
173
- if (typeof rawProfile.backend !== "string" || !rawProfile.backend.trim()) {
174
- settings.warnings.push(`pi-forge: ${configPath} ${path}.backend must be a non-empty string; the configured value is ignored.`);
175
- }
176
- else {
177
- target.backend = rawProfile.backend;
178
- target.backendSource = source;
179
- }
180
- }
181
- if (rawProfile.timeoutMs !== undefined) {
182
- if (!isValidSubagentTimeoutMs(rawProfile.timeoutMs)) {
183
- settings.warnings.push(`pi-forge: ${configPath} ${path}.timeoutMs must be an integer from ${MIN_SUBAGENT_TIMEOUT_MS} to ${MAX_SUBAGENT_TIMEOUT_MS}; the configured value is ignored.`);
184
- }
185
- else {
186
- target.timeoutMs = rawProfile.timeoutMs;
187
- target.timeoutSource = source;
188
- }
189
- }
190
- if (Object.keys(target).length > 0)
191
- settings.profiles[key] = target;
192
- }
193
- }
194
- function applyUnattended(section, configPath, settings) {
195
- if (!section || section.allowAgentInvocationWithoutApproval === undefined)
196
- return;
197
- const value = section.allowAgentInvocationWithoutApproval;
198
- if (typeof value !== "boolean") {
199
- settings.warnings.push(`pi-forge: ${configPath} subagents.allowAgentInvocationWithoutApproval must be boolean; per-run subagent approval remains required.`);
200
- return;
201
- }
202
- settings.allowAgentInvocationWithoutApproval = value;
203
- }
204
- export function isValidSubagentTimeoutMs(value) {
205
- return Number.isSafeInteger(value)
206
- && value >= MIN_SUBAGENT_TIMEOUT_MS
207
- && value <= MAX_SUBAGENT_TIMEOUT_MS;
208
- }
209
9
  export function globalForgeConfigPath() {
210
10
  return process.env[GLOBAL_FORGE_CONFIG_PATH_ENV] ?? join(globalForgeDir(), "config.json");
211
11
  }
212
12
  export function projectForgeConfigPath(cwd) {
213
13
  return join(cwd, ".pi", "forge", "config.json");
214
14
  }
215
- /**
216
- * Update `subagents.profiles.<id>` in the selected scope's config file,
217
- * preserving unknown top-level, `subagents`, and per-entry fields. Project
218
- * config updates must be gated on project trust by the caller; global config
219
- * is user-owned and always writable.
220
- */
221
- export function updateForgeSubagentProfileConfig(cwd, profileId, update, options = {}) {
222
- const scope = options.scope ?? "project";
223
- if (!isValidAgentProfileId(profileId)) {
224
- return { ok: false, error: `Invalid agent profile id: ${profileId}` };
225
- }
226
- if (update.backend !== undefined && update.backend !== null && (typeof update.backend !== "string" || !update.backend.trim())) {
227
- return { ok: false, error: "subagent backend must be a non-empty string or null to clear the override." };
228
- }
229
- if (update.timeoutMs !== undefined && update.timeoutMs !== null && !isValidSubagentTimeoutMs(update.timeoutMs)) {
230
- return {
231
- ok: false,
232
- error: `subagent timeoutMs must be an integer from ${MIN_SUBAGENT_TIMEOUT_MS} to ${MAX_SUBAGENT_TIMEOUT_MS} or null to clear the override.`,
233
- };
234
- }
235
- const configPath = scope === "project" ? projectForgeConfigPath(cwd) : globalForgeConfigPath();
236
- let root = {};
237
- if (existsSync(configPath)) {
238
- let raw;
239
- try {
240
- raw = JSON.parse(readFileSync(configPath, "utf8"));
241
- }
242
- catch (error) {
243
- return {
244
- ok: false,
245
- error: `Refusing to update unreadable ${configPath}: ${error instanceof Error ? error.message : String(error)}`,
246
- };
247
- }
248
- if (!isPlainObject(raw)) {
249
- return { ok: false, error: `Refusing to update ${configPath}: the config root must be a JSON object.` };
250
- }
251
- root = raw;
252
- }
253
- if (root.subagents !== undefined && !isPlainObject(root.subagents)) {
254
- return { ok: false, error: `Refusing to update ${configPath}: subagents must be a JSON object.` };
255
- }
256
- const subagents = isPlainObject(root.subagents) ? root.subagents : {};
257
- if (subagents.profiles !== undefined && !isPlainObject(subagents.profiles)) {
258
- return { ok: false, error: `Refusing to update ${configPath}: subagents.profiles must be a JSON object.` };
259
- }
260
- const profiles = isPlainObject(subagents.profiles) ? subagents.profiles : {};
261
- if (profiles[profileId] !== undefined && !isPlainObject(profiles[profileId])) {
262
- return { ok: false, error: `Refusing to update ${configPath}: subagents.profiles.${profileId} must be a JSON object.` };
263
- }
264
- const entry = isPlainObject(profiles[profileId]) ? { ...profiles[profileId] } : {};
265
- if (update.enabled !== undefined) {
266
- if (update.enabled)
267
- entry.enabled = true;
268
- else
269
- delete entry.enabled;
270
- }
271
- if (update.backend !== undefined) {
272
- if (typeof update.backend === "string" && update.backend.trim())
273
- entry.backend = update.backend.trim();
274
- else
275
- delete entry.backend;
276
- }
277
- if (update.timeoutMs !== undefined) {
278
- if (update.timeoutMs === null)
279
- delete entry.timeoutMs;
280
- else
281
- entry.timeoutMs = update.timeoutMs;
282
- }
283
- if (Object.keys(entry).length > 0)
284
- profiles[profileId] = entry;
285
- else
286
- delete profiles[profileId];
287
- if (Object.keys(profiles).length > 0)
288
- subagents.profiles = profiles;
289
- else
290
- delete subagents.profiles;
291
- if (Object.keys(subagents).length > 0)
292
- root.subagents = subagents;
293
- else
294
- delete root.subagents;
295
- try {
296
- mkdirSync(dirname(configPath), { recursive: true });
297
- writeFileSync(configPath, `${JSON.stringify(root, null, 2)}\n`, "utf8");
298
- return { ok: true, configPath };
299
- }
300
- catch (error) {
301
- return { ok: false, error: `Failed to write ${configPath}: ${error instanceof Error ? error.message : String(error)}` };
302
- }
303
- }
304
- /**
305
- * Resolve the configured per-profile settings for a profile selector. Bare
306
- * selectors use project-first effective lookup; qualified selectors address
307
- * the exact scope. Returns undefined for unknown or malformed selectors.
308
- */
309
- export function configuredProfileForSelector(settings, profileId) {
310
- const parsed = parseResourceSelector(profileId);
311
- if (!parsed.ok)
312
- return undefined;
313
- if (parsed.selector.scope) {
314
- return configuredProfile(settings, formatResourceKey({ scope: parsed.selector.scope, id: parsed.selector.id }));
315
- }
316
- // A bare selector is intentionally project-only here. Callers that resolve
317
- // a bare ID to a loaded global profile must pass the exact `global:<id>`
318
- // selector; never infer global delegation authority from a bare ID.
319
- return configuredProfile(settings, formatResourceKey({ scope: "project", id: parsed.selector.id }));
320
- }
321
- function configuredProfile(settings, key) {
322
- return Object.hasOwn(settings.profiles, key) ? settings.profiles[key] : undefined;
323
- }
324
- function isPlainObject(value) {
325
- return !!value && typeof value === "object" && !Array.isArray(value);
326
- }
327
15
  //# sourceMappingURL=forge-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"forge-config.js","sourceRoot":"","sources":["../src/forge-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"forge-config.js","sourceRoot":"","sources":["../src/forge-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,6BAA6B,CAAC;AAE1E,MAAM,UAAU,qBAAqB;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,aAAa,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAAW;IACjD,OAAO,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { TemplateAnalyzeResult, TemplateNode } from "./types.ts";
2
+ export declare function analyze(nodes: readonly TemplateNode[]): TemplateAnalyzeResult;
3
+ //# sourceMappingURL=analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/forge-v1/analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,qBAAqB,EAErB,YAAY,EAGZ,MAAM,YAAY,CAAC;AAOpB,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,qBAAqB,CAwC7E"}
@@ -0,0 +1,50 @@
1
+ import { FORGE_V1_FILTERS } from "./types.js";
2
+ const ROOTS = new Set(["runtime", "parameters", "extensions"]);
3
+ const LEGACY_RUNTIME_FIELDS = new Set([
4
+ "cwd", "date", "time", "lastUserMessage", "selectedTools", "tools", "activeModel",
5
+ ]);
6
+ export function analyze(nodes) {
7
+ const dependencies = [];
8
+ const errors = [];
9
+ const walk = (nodeList) => {
10
+ for (const node of nodeList) {
11
+ if (node.kind === "text")
12
+ continue;
13
+ if (node.kind === "output") {
14
+ addDependency(node.path, node.span);
15
+ for (const filter of node.filters) {
16
+ if (!FORGE_V1_FILTERS.includes(filter)) {
17
+ errors.push({ kind: "filter", message: `Unknown forge-v1 filter: ${filter}`, span: node.span });
18
+ }
19
+ else {
20
+ dependencies.push({ kind: "filter", filter, span: node.span });
21
+ }
22
+ }
23
+ continue;
24
+ }
25
+ if (node.kind === "if") {
26
+ addDependency(node.predicate.path, node.predicate.span);
27
+ walk(node.thenBody);
28
+ if (node.elseBody)
29
+ walk(node.elseBody);
30
+ }
31
+ }
32
+ };
33
+ const addDependency = (path, span) => {
34
+ const root = path[0];
35
+ if (!root)
36
+ return;
37
+ if (ROOTS.has(root)) {
38
+ dependencies.push({ kind: root, path, span });
39
+ }
40
+ else if (path.length === 1 && LEGACY_RUNTIME_FIELDS.has(root)) {
41
+ dependencies.push({ kind: "legacy", path, span });
42
+ }
43
+ else {
44
+ dependencies.push({ kind: "legacy", path, span });
45
+ }
46
+ };
47
+ walk(nodes);
48
+ return { dependencies, errors };
49
+ }
50
+ //# sourceMappingURL=analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/forge-v1/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAS9C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;AAC/D,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACrC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,eAAe,EAAE,OAAO,EAAE,aAAa;CACjF,CAAC,CAAC;AAEH,MAAM,UAAU,OAAO,CAAC,KAA8B;IACrD,MAAM,YAAY,GAAyB,EAAE,CAAC;IAC9C,MAAM,MAAM,GAAoC,EAAE,CAAC;IAEnD,MAAM,IAAI,GAAG,CAAC,QAAiC,EAAQ,EAAE;QACxD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;gBAAE,SAAS;YACnC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC5B,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBACnC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAA2C,CAAC,EAAE,CAAC;wBAC7E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,4BAA4B,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBACjG,CAAC;yBAAM,CAAC;wBACP,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBAChE,CAAC;gBACF,CAAC;gBACD,SAAS;YACV,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBACxB,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACxD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACpB,IAAI,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxC,CAAC;QACF,CAAC;IACF,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,IAAuB,EAAE,IAAoC,EAAQ,EAAE;QAC7F,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAA+C,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1F,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACjE,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACP,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;IACF,CAAC,CAAC;IAEF,IAAI,CAAC,KAAK,CAAC,CAAC;IACZ,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { ForgeV1TemplateEngine } from "./types.ts";
2
+ import { FORGE_V1_FILTERS, FORGE_V1_MAX_EXTENSION_OUTPUT, FORGE_V1_MAX_TEMPLATE_OUTPUT } from "./types.ts";
3
+ export declare const forgeV1: ForgeV1TemplateEngine;
4
+ export { FORGE_V1_FILTERS, FORGE_V1_MAX_EXTENSION_OUTPUT, FORGE_V1_MAX_TEMPLATE_OUTPUT, };
5
+ export type { ForgeV1TemplateEngine, PromptEnvironment, PromptEnvironmentValue, TemplateAnalyzeResult, TemplateDependency, TemplateDependencyKind, TemplateNode, TemplateOutputNode, TemplateParseResult, TemplatePredicate, TemplateRenderResult, TemplateSourceSpan, TemplateTextNode, ForgeV1Error, ForgeV1ErrorKind, } from "./types.ts";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/forge-v1/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,qBAAqB,EAQrB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,gBAAgB,EAChB,6BAA6B,EAC7B,4BAA4B,EAC5B,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,OAAO,EAAE,qBAMrB,CAAC;AAEF,OAAO,EACN,gBAAgB,EAChB,6BAA6B,EAC7B,4BAA4B,GAC5B,CAAC;AACF,YAAY,EACX,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,GAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { analyze } from "./analyzer.js";
2
+ import { parse } from "./parser.js";
3
+ import { render } from "./renderer.js";
4
+ import { FORGE_V1_FILTERS, FORGE_V1_MAX_EXTENSION_OUTPUT, FORGE_V1_MAX_TEMPLATE_OUTPUT, } from "./types.js";
5
+ export const forgeV1 = {
6
+ id: "forge-v1",
7
+ version: 1,
8
+ parse: parse,
9
+ analyze: (nodes) => analyze(nodes),
10
+ render: render,
11
+ };
12
+ export { FORGE_V1_FILTERS, FORGE_V1_MAX_EXTENSION_OUTPUT, FORGE_V1_MAX_TEMPLATE_OUTPUT, };
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/forge-v1/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAWvC,OAAO,EACN,gBAAgB,EAChB,6BAA6B,EAC7B,4BAA4B,GAC5B,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,MAAM,OAAO,GAA0B;IAC7C,EAAE,EAAE,UAAU;IACd,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,CAAC,KAA8B,EAAyB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAClF,MAAM,EAAE,MAAM;CACd,CAAC;AAEF,OAAO,EACN,gBAAgB,EAChB,6BAA6B,EAC7B,4BAA4B,GAC5B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { TemplateParseResult } from "./types.ts";
2
+ export declare function parse(source: string): TemplateParseResult;
3
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/forge-v1/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIX,mBAAmB,EAInB,MAAM,YAAY,CAAC;AAIpB,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CASzD"}
@@ -0,0 +1,186 @@
1
+ const OPENING = new Set(["{{", "{%"]);
2
+ export function parse(source) {
3
+ const parser = new Parser(source);
4
+ try {
5
+ const ast = parser.parseTop();
6
+ return { ok: true, ast };
7
+ }
8
+ catch (error) {
9
+ if (isForgeError(error))
10
+ return { ok: false, error };
11
+ throw error;
12
+ }
13
+ }
14
+ class Parser {
15
+ source;
16
+ index = 0;
17
+ constructor(source) {
18
+ this.source = source;
19
+ }
20
+ parseTop() {
21
+ const result = this.parseUntil(new Set());
22
+ return result.nodes;
23
+ }
24
+ parseUntil(stop) {
25
+ const nodes = [];
26
+ while (this.index < this.source.length) {
27
+ const next = this.nextOpening();
28
+ if (!next) {
29
+ if (this.index < this.source.length) {
30
+ nodes.push(text(this.source.slice(this.index), this.index, this.source.length));
31
+ this.index = this.source.length;
32
+ }
33
+ break;
34
+ }
35
+ if (next.index > this.index) {
36
+ nodes.push(text(this.source.slice(this.index, next.index), this.index, next.index));
37
+ }
38
+ if (next.delimiter === "{{") {
39
+ nodes.push(this.parseOutput(next.index));
40
+ continue;
41
+ }
42
+ const end = this.source.indexOf("%}", next.index);
43
+ if (end === -1) {
44
+ throw parseError("Unclosed forge-v1 tag", next.index, this.source.length);
45
+ }
46
+ const raw = this.source.slice(next.index + 2, end).trim();
47
+ this.index = end + 2;
48
+ if (raw === "else" || raw === "endif") {
49
+ const kind = raw === "else" ? "else" : "endif";
50
+ if (!stop.has(kind)) {
51
+ throw parseError(`Unexpected {% ${raw} %}`, next.index, end + 2);
52
+ }
53
+ return { nodes, stop: kind };
54
+ }
55
+ if (raw.startsWith("if ")) {
56
+ const predicate = this.parsePredicate(raw.slice(3).trim(), next.index, end + 2);
57
+ const thenResult = this.parseUntil(new Set(["else", "endif"]));
58
+ let elseBody = null;
59
+ if (thenResult.stop === "else") {
60
+ elseBody = this.parseUntil(new Set(["endif"])).nodes;
61
+ }
62
+ nodes.push({
63
+ kind: "if",
64
+ predicate,
65
+ thenBody: thenResult.nodes,
66
+ elseBody,
67
+ span: { start: next.index, end },
68
+ });
69
+ continue;
70
+ }
71
+ throw parseError(`Unsupported forge-v1 tag: {% ${raw} %}`, next.index, end + 2);
72
+ }
73
+ if (stop.size > 0) {
74
+ const expected = [...stop][0];
75
+ throw parseError(`Missing {% ${expected} %}`, this.index, this.source.length);
76
+ }
77
+ return { nodes };
78
+ }
79
+ nextOpening() {
80
+ let best;
81
+ for (const delimiter of ["{{", "{%"]) {
82
+ const index = this.source.indexOf(delimiter, this.index);
83
+ if (index === -1)
84
+ continue;
85
+ if (!best || index < best.index)
86
+ best = { delimiter, index };
87
+ }
88
+ return best;
89
+ }
90
+ parseOutput(start) {
91
+ const end = this.source.indexOf("}}", start);
92
+ if (end === -1) {
93
+ throw parseError("Unclosed output tag {{", start, this.source.length);
94
+ }
95
+ const expression = this.source.slice(start + 2, end).trim();
96
+ this.index = end + 2;
97
+ const parsed = parseOutputExpression(expression, start, end + 2);
98
+ if (parsed.error)
99
+ throw parsed.error;
100
+ return parsed.node;
101
+ }
102
+ parsePredicate(raw, start, end) {
103
+ const eq = matchComparison(raw, "==");
104
+ const ne = eq ? undefined : matchComparison(raw, "!=");
105
+ const op = eq ?? ne;
106
+ if (op) {
107
+ const path = parsePath(op.path);
108
+ if (!path)
109
+ throw parseError(`Invalid predicate path: ${op.path}`, start, end);
110
+ return {
111
+ kind: eq ? "eq" : "ne",
112
+ path,
113
+ expected: op.expected,
114
+ span: { start, end },
115
+ };
116
+ }
117
+ if (!raw)
118
+ throw parseError("Missing predicate in {% if %}", start, end);
119
+ const path = parsePath(raw);
120
+ if (!path)
121
+ throw parseError(`Invalid predicate path: ${raw}`, start, end);
122
+ return { kind: "truthy", path, span: { start, end } };
123
+ }
124
+ }
125
+ function parseOutputExpression(expression, start, end) {
126
+ if (!expression) {
127
+ return { error: parseError("Empty output tag {{}}", start, end) };
128
+ }
129
+ const parts = expression.split("|").map((part) => part.trim());
130
+ const path = parsePath(parts[0]);
131
+ if (!path) {
132
+ return { error: parseError(`Invalid path: ${parts[0]}`, start, end) };
133
+ }
134
+ const filters = parts.slice(1).filter(Boolean);
135
+ return {
136
+ node: {
137
+ kind: "output",
138
+ path,
139
+ filters,
140
+ span: { start, end },
141
+ },
142
+ };
143
+ }
144
+ function parsePath(raw) {
145
+ const identifiers = raw.split(".").map((part) => part.trim());
146
+ if (identifiers.length === 0)
147
+ return undefined;
148
+ for (const id of identifiers) {
149
+ if (!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(id))
150
+ return undefined;
151
+ }
152
+ return identifiers;
153
+ }
154
+ function matchComparison(raw, op) {
155
+ const index = raw.indexOf(op);
156
+ if (index <= 0)
157
+ return undefined;
158
+ const left = raw.slice(0, index).trim();
159
+ const right = raw.slice(index + op.length).trim();
160
+ if (!right)
161
+ return undefined;
162
+ const expected = parseQuotedString(right);
163
+ if (expected === undefined)
164
+ return undefined;
165
+ return { path: left, expected };
166
+ }
167
+ function parseQuotedString(value) {
168
+ if (value.length < 2)
169
+ return undefined;
170
+ const quote = value[0];
171
+ if (quote !== "\"" && quote !== "'")
172
+ return undefined;
173
+ if (value[value.length - 1] !== quote)
174
+ return undefined;
175
+ return value.slice(1, -1).replace(/\\"/g, "\"").replace(/\\'/g, "'").replace(/\\\\/g, "\\");
176
+ }
177
+ function text(text, start, end) {
178
+ return { kind: "text", text, span: { start, end } };
179
+ }
180
+ function parseError(message, start, end) {
181
+ return { kind: "parse", message, span: { start, end } };
182
+ }
183
+ function isForgeError(value) {
184
+ return !!value && typeof value === "object" && value.kind === "parse";
185
+ }
186
+ //# sourceMappingURL=parser.js.map