@code-yeongyu/senpi 2026.9.23-5 → 2026.9.24-2

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 (315) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/bundle/chunks/{anthropic-messages-77YBORJ5.js → anthropic-messages-UPLQFNTT.js} +2 -2
  3. package/dist/bundle/chunks/{app-server-command-BGT65PGC.js → app-server-command-UHPJ2C4D.js} +1 -1
  4. package/dist/bundle/chunks/{azure-openai-responses-PSESFNHN.js → azure-openai-responses-XAR2E66I.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-WXIRFRXY.js → chunk-2PLPSKHD.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-7PANH3NB.js → chunk-3WBSBDBX.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-BBOQ5H4W.js → chunk-6WBYI25N.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-RG3UEFSF.js → chunk-7DY7UYLL.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-VKBY4F76.js → chunk-BSOJHK4W.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-3XHWW7SQ.js → chunk-CLZVNQW3.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-ORCF262V.js → chunk-EJKCBRYK.js} +3 -3
  12. package/dist/bundle/chunks/chunk-J7IUURQ6.js +8 -0
  13. package/dist/bundle/chunks/{chunk-PSMTQDII.js → chunk-JRQSHZPP.js} +15 -9
  14. package/dist/bundle/chunks/{chunk-DUV3UFKX.js → chunk-MKAM7IRH.js} +1 -1
  15. package/dist/bundle/chunks/chunk-MO2U7YRX.js +11 -0
  16. package/dist/bundle/chunks/{chunk-ZEFQYQOU.js → chunk-NGHOUIPR.js} +1 -1
  17. package/dist/bundle/chunks/{chunk-XDSQYM4F.js → chunk-NKVUDCGZ.js} +2 -2
  18. package/dist/bundle/chunks/{chunk-J3QXPP4T.js → chunk-ONR57UMO.js} +1 -1
  19. package/dist/bundle/chunks/{chunk-TQDWU3ZQ.js → chunk-SYQVC7UM.js} +1 -1
  20. package/dist/bundle/chunks/chunk-TTHMOL5G.js +2 -0
  21. package/dist/bundle/chunks/{chunk-NNHFMZD5.js → chunk-UBPMXBOJ.js} +1 -1
  22. package/dist/bundle/chunks/chunk-WASCMT6Y.js +2 -0
  23. package/dist/bundle/chunks/{chunk-EN6KDFY2.js → chunk-WISJJQ4K.js} +1 -1
  24. package/dist/bundle/chunks/{chunk-IVYZMSFY.js → chunk-WL5EQYNL.js} +1 -1
  25. package/dist/bundle/chunks/{chunk-LC6SZTVE.js → chunk-WTSAB6AE.js} +1 -1
  26. package/dist/bundle/chunks/{chunk-HKE42SWX.js → chunk-Y54V65MS.js} +1 -1
  27. package/dist/bundle/chunks/{chunk-3RN6BFG2.js → chunk-YBC274GY.js} +4 -4
  28. package/dist/bundle/chunks/{chunk-RRSND33J.js → chunk-YKU45B65.js} +54 -54
  29. package/dist/bundle/chunks/{chunk-WUYBEF7C.js → chunk-YWO3OBYK.js} +1 -1
  30. package/dist/bundle/chunks/cli-main-O5Y3TBID.js +3 -0
  31. package/dist/bundle/chunks/{google-generative-ai-YJHSZAY5.js → google-generative-ai-B5QMFONL.js} +1 -1
  32. package/dist/bundle/chunks/{google-vertex-JTFWEDNJ.js → google-vertex-O2TGMVWF.js} +1 -1
  33. package/dist/bundle/chunks/{help-fast-path-QXVCHTP3.js → help-fast-path-Y33OIZBU.js} +1 -1
  34. package/dist/bundle/chunks/{host-command-3PUZYQOK.js → host-command-WJOL27Q7.js} +1 -1
  35. package/dist/bundle/chunks/{host-lifecycle-OHPSU5VU.js → host-lifecycle-YBFXYFZP.js} +1 -1
  36. package/dist/bundle/chunks/{interactive-host-runtime-57LEAJPU.js → interactive-host-runtime-XVTF3NUD.js} +1 -1
  37. package/dist/bundle/chunks/interactive-mode-OO3NGM4G.js +2 -0
  38. package/dist/bundle/chunks/{list-tips-Z62FXPOJ.js → list-tips-EBRNBPBM.js} +1 -1
  39. package/dist/bundle/chunks/{mistral-conversations-VJPMPQ5T.js → mistral-conversations-AS3SAWPA.js} +1 -1
  40. package/dist/bundle/chunks/{multi-session-host-GFSDQQUJ.js → multi-session-host-6MKBBOKF.js} +1 -1
  41. package/dist/bundle/chunks/{openai-codex-responses-IQ35QACK.js → openai-codex-responses-CK7T4WNM.js} +1 -1
  42. package/dist/bundle/chunks/{openai-completions-74OLE55U.js → openai-completions-OPQKN7FH.js} +3 -3
  43. package/dist/bundle/chunks/openai-responses-QHWM3KPO.js +2 -0
  44. package/dist/bundle/chunks/{openrouter-images-T4GY3JYM.js → openrouter-images-MW5TXV7L.js} +1 -1
  45. package/dist/bundle/chunks/{package-manager-cli-J7244EJE.js → package-manager-cli-BMEWLAI2.js} +1 -1
  46. package/dist/bundle/chunks/{rotation-stream-CZT4TRPD.js → rotation-stream-ZFA6ELXJ.js} +1 -1
  47. package/dist/bundle/chunks/{rpc-mode-75CRTY24.js → rpc-mode-5653CV65.js} +1 -1
  48. package/dist/bundle/chunks/{session-picker-ZIBANFBQ.js → session-picker-PPYK56TA.js} +1 -1
  49. package/dist/bundle/chunks/session-worker.js +265 -259
  50. package/dist/bundle/cli.js +1 -1
  51. package/dist/bundle/index.js +1 -1
  52. package/dist/bundle/rpc-entry.js +1 -1
  53. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  54. package/dist/core/agent-session-runtime.js +13 -0
  55. package/dist/core/agent-session-runtime.js.map +1 -1
  56. package/dist/core/agent-session.d.ts +28 -0
  57. package/dist/core/agent-session.d.ts.map +1 -1
  58. package/dist/core/agent-session.js +75 -12
  59. package/dist/core/agent-session.js.map +1 -1
  60. package/dist/core/dynamic-prompt/build.d.ts +6 -1
  61. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  62. package/dist/core/dynamic-prompt/build.js +0 -7
  63. package/dist/core/dynamic-prompt/build.js.map +1 -1
  64. package/dist/core/environment-context.d.ts +32 -0
  65. package/dist/core/environment-context.d.ts.map +1 -0
  66. package/dist/core/environment-context.js +63 -0
  67. package/dist/core/environment-context.js.map +1 -0
  68. package/dist/core/extensions/builtin/anthropic-subscription/session-sync.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/anthropic-subscription/session-sync.js +1 -15
  70. package/dist/core/extensions/builtin/anthropic-subscription/session-sync.js.map +1 -1
  71. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +3 -0
  72. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
  73. package/dist/core/extensions/builtin/goal/cache-warm.d.ts +19 -2
  74. package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
  75. package/dist/core/extensions/builtin/goal/cache-warm.js +28 -2
  76. package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
  77. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  78. package/dist/core/extensions/builtin/goal/monitor-continuation.js +4 -2
  79. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  80. package/dist/core/extensions/builtin/goal/parked-wait.js +2 -0
  81. package/dist/core/extensions/builtin/goal/parked-wait.js.map +1 -1
  82. package/dist/core/extensions/builtin/goal/prompt.js +1 -1
  83. package/dist/core/extensions/builtin/goal/prompt.js.map +1 -1
  84. package/dist/core/extensions/builtin/herdr/herdr-state.d.ts +5 -0
  85. package/dist/core/extensions/builtin/herdr/herdr-state.d.ts.map +1 -1
  86. package/dist/core/extensions/builtin/herdr/herdr-state.js +28 -3
  87. package/dist/core/extensions/builtin/herdr/herdr-state.js.map +1 -1
  88. package/dist/core/extensions/builtin/herdr/index.d.ts.map +1 -1
  89. package/dist/core/extensions/builtin/herdr/index.js +7 -1
  90. package/dist/core/extensions/builtin/herdr/index.js.map +1 -1
  91. package/dist/core/extensions/builtin/hooks/index.d.ts.map +1 -1
  92. package/dist/core/extensions/builtin/hooks/index.js +3 -15
  93. package/dist/core/extensions/builtin/hooks/index.js.map +1 -1
  94. package/dist/core/extensions/builtin/hooks/stop-lifecycle.d.ts +26 -0
  95. package/dist/core/extensions/builtin/hooks/stop-lifecycle.d.ts.map +1 -0
  96. package/dist/core/extensions/builtin/hooks/stop-lifecycle.js +88 -0
  97. package/dist/core/extensions/builtin/hooks/stop-lifecycle.js.map +1 -0
  98. package/dist/core/extensions/builtin/recommended-models/index.d.ts +1 -1
  99. package/dist/core/extensions/builtin/recommended-models/index.d.ts.map +1 -1
  100. package/dist/core/extensions/builtin/recommended-models/index.js +28 -10
  101. package/dist/core/extensions/builtin/recommended-models/index.js.map +1 -1
  102. package/dist/core/extensions/builtin/rules/commands.d.ts.map +1 -1
  103. package/dist/core/extensions/builtin/rules/commands.js +5 -1
  104. package/dist/core/extensions/builtin/rules/commands.js.map +1 -1
  105. package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -1
  106. package/dist/core/extensions/builtin/rules/index.js +25 -3
  107. package/dist/core/extensions/builtin/rules/index.js.map +1 -1
  108. package/dist/core/extensions/builtin/rules/rules/constants.d.ts.map +1 -1
  109. package/dist/core/extensions/builtin/rules/rules/constants.js +22 -14
  110. package/dist/core/extensions/builtin/rules/rules/constants.js.map +1 -1
  111. package/dist/core/extensions/builtin/rules/rules/engine.d.ts.map +1 -1
  112. package/dist/core/extensions/builtin/rules/rules/engine.js +39 -9
  113. package/dist/core/extensions/builtin/rules/rules/engine.js.map +1 -1
  114. package/dist/core/extensions/builtin/rules/rules/finder.js +3 -0
  115. package/dist/core/extensions/builtin/rules/rules/finder.js.map +1 -1
  116. package/dist/core/extensions/builtin/rules/rules/project-root.d.ts +17 -0
  117. package/dist/core/extensions/builtin/rules/rules/project-root.d.ts.map +1 -1
  118. package/dist/core/extensions/builtin/rules/rules/project-root.js +67 -5
  119. package/dist/core/extensions/builtin/rules/rules/project-root.js.map +1 -1
  120. package/dist/core/extensions/builtin/rules/rules/types.d.ts +2 -2
  121. package/dist/core/extensions/builtin/rules/rules/types.d.ts.map +1 -1
  122. package/dist/core/extensions/builtin/rules/rules/types.js.map +1 -1
  123. package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts +3 -1
  124. package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts.map +1 -1
  125. package/dist/core/extensions/builtin/rules/ui/rules-banner.js +1 -1
  126. package/dist/core/extensions/builtin/rules/ui/rules-banner.js.map +1 -1
  127. package/dist/core/extensions/builtin/todotools/todo-storage.d.ts.map +1 -1
  128. package/dist/core/extensions/builtin/todotools/todo-storage.js +10 -2
  129. package/dist/core/extensions/builtin/todotools/todo-storage.js.map +1 -1
  130. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
  131. package/dist/core/extensions/builtin/todotools/tools/todo.js +2 -1
  132. package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
  133. package/dist/core/extensions/builtin/websearch/websearch/config.d.ts.map +1 -1
  134. package/dist/core/extensions/builtin/websearch/websearch/config.js +2 -0
  135. package/dist/core/extensions/builtin/websearch/websearch/config.js.map +1 -1
  136. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts.map +1 -1
  137. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js +2 -0
  138. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js.map +1 -1
  139. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.d.ts +3 -0
  140. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.d.ts.map +1 -0
  141. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.js +34 -0
  142. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.js.map +1 -0
  143. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.d.ts +3 -0
  144. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.d.ts.map +1 -0
  145. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.js +22 -0
  146. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.js.map +1 -0
  147. package/dist/core/extensions/builtin/websearch/websearch/providers.d.ts.map +1 -1
  148. package/dist/core/extensions/builtin/websearch/websearch/providers.js +4 -0
  149. package/dist/core/extensions/builtin/websearch/websearch/providers.js.map +1 -1
  150. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +1 -1
  151. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -1
  152. package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -1
  153. package/dist/core/session-discovery.d.ts +9 -3
  154. package/dist/core/session-discovery.d.ts.map +1 -1
  155. package/dist/core/session-discovery.js +19 -8
  156. package/dist/core/session-discovery.js.map +1 -1
  157. package/dist/core/session-manager.d.ts.map +1 -1
  158. package/dist/core/session-manager.js +8 -4
  159. package/dist/core/session-manager.js.map +1 -1
  160. package/dist/core/session-summary-cache.d.ts +16 -3
  161. package/dist/core/session-summary-cache.d.ts.map +1 -1
  162. package/dist/core/session-summary-cache.js +19 -3
  163. package/dist/core/session-summary-cache.js.map +1 -1
  164. package/dist/core/session-summary-index-file.d.ts +38 -0
  165. package/dist/core/session-summary-index-file.d.ts.map +1 -0
  166. package/dist/core/session-summary-index-file.js +119 -0
  167. package/dist/core/session-summary-index-file.js.map +1 -0
  168. package/dist/core/session-summary-index.d.ts +52 -0
  169. package/dist/core/session-summary-index.d.ts.map +1 -0
  170. package/dist/core/session-summary-index.js +157 -0
  171. package/dist/core/session-summary-index.js.map +1 -0
  172. package/dist/core/session-summary.d.ts +21 -2
  173. package/dist/core/session-summary.d.ts.map +1 -1
  174. package/dist/core/session-summary.js +53 -14
  175. package/dist/core/session-summary.js.map +1 -1
  176. package/dist/core/timings.d.ts +1 -1
  177. package/dist/core/timings.d.ts.map +1 -1
  178. package/dist/core/timings.js.map +1 -1
  179. package/dist/core/tools/renderers/read.d.ts.map +1 -1
  180. package/dist/core/tools/renderers/read.js +7 -2
  181. package/dist/core/tools/renderers/read.js.map +1 -1
  182. package/dist/core/tools/renderers/skill-read-path.d.ts +9 -0
  183. package/dist/core/tools/renderers/skill-read-path.d.ts.map +1 -0
  184. package/dist/core/tools/renderers/skill-read-path.js +49 -0
  185. package/dist/core/tools/renderers/skill-read-path.js.map +1 -0
  186. package/dist/main.d.ts.map +1 -1
  187. package/dist/main.js +7 -0
  188. package/dist/main.js.map +1 -1
  189. package/dist/modes/interactive/components/exploration-call.d.ts +1 -1
  190. package/dist/modes/interactive/components/exploration-call.d.ts.map +1 -1
  191. package/dist/modes/interactive/components/exploration-call.js +3 -1
  192. package/dist/modes/interactive/components/exploration-call.js.map +1 -1
  193. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  194. package/dist/modes/interactive/components/session-selector-search.js +32 -16
  195. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  196. package/dist/modes/interactive/components/session-selector-tree.d.ts +32 -0
  197. package/dist/modes/interactive/components/session-selector-tree.d.ts.map +1 -0
  198. package/dist/modes/interactive/components/session-selector-tree.js +82 -0
  199. package/dist/modes/interactive/components/session-selector-tree.js.map +1 -0
  200. package/dist/modes/interactive/components/session-selector.d.ts +1 -0
  201. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  202. package/dist/modes/interactive/components/session-selector.js +6 -71
  203. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  204. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  205. package/dist/modes/interactive/interactive-mode.js +4 -1
  206. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  207. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +32 -0
  208. package/node_modules/@code-yeongyu/senpi-codemode/README.md +8 -4
  209. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  210. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/AGENTS.md +1 -0
  211. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/code-preview.ts +31 -0
  212. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-code.ts +34 -131
  213. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js-ast.ts +65 -0
  214. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js-layout.ts +90 -0
  215. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js-mask.ts +178 -0
  216. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js.ts +100 -0
  217. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-python-script.ts +127 -0
  218. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-python.ts +150 -0
  219. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-request.ts +18 -4
  220. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +1 -1
  221. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +9 -25
  222. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +16 -9
  223. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts +1 -1
  224. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  225. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +22 -2
  226. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  227. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  228. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +3 -1
  229. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  230. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.d.ts +6 -0
  231. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.d.ts.map +1 -1
  232. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.js +6 -19
  233. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.js.map +1 -1
  234. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +8 -0
  235. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  236. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  237. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  238. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts.map +1 -1
  239. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js +8 -35
  240. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js.map +1 -1
  241. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  242. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +10 -6
  243. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  244. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  245. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +4 -3
  246. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  247. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  248. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +53 -1
  249. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  250. package/node_modules/@earendil-works/pi-ai/dist/api/openrouter-images.js +1 -1
  251. package/node_modules/@earendil-works/pi-ai/dist/api/openrouter-images.js.map +1 -1
  252. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +30 -0
  253. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  254. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +30 -0
  255. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  256. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +2 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  258. package/node_modules/@earendil-works/pi-ai/dist/index.js +2 -1
  259. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  260. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +6 -0
  261. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  262. package/node_modules/@earendil-works/pi-ai/dist/models.js +15 -0
  263. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts +17 -0
  265. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts.map +1 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.js +4 -1
  267. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.js.map +1 -1
  268. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  270. package/node_modules/@earendil-works/pi-ai/dist/providers/data/chatgpt-subscription.json +1 -1
  271. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  272. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
  274. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax-cn.json +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax.json +1 -1
  276. package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai-cn.json +1 -1
  277. package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai.json +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  279. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  280. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  281. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  283. package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/providers/data/venice.json +1 -1
  285. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  286. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +6 -0
  287. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  288. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  289. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts +30 -0
  290. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  291. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js +71 -14
  292. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js.map +1 -1
  293. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.d.ts +30 -0
  294. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.d.ts.map +1 -0
  295. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.js +71 -0
  296. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.js.map +1 -0
  297. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  298. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  299. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  300. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +5 -0
  301. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts.map +1 -1
  302. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +7 -2
  303. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -1
  304. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
  305. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  306. package/node_modules/@earendil-works/pi-tui/dist/index.js +1 -1
  307. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  308. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  309. package/package.json +7 -7
  310. package/dist/bundle/chunks/chunk-KLDLZHHS.js +0 -11
  311. package/dist/bundle/chunks/chunk-LTIMMSDM.js +0 -8
  312. package/dist/bundle/chunks/chunk-XYM54ZWK.js +0 -2
  313. package/dist/bundle/chunks/cli-main-W55CWPEI.js +0 -3
  314. package/dist/bundle/chunks/interactive-mode-EDJZ4CSY.js +0 -2
  315. package/dist/bundle/chunks/openai-responses-7IGZSW33.js +0 -2
@@ -37,6 +37,14 @@ export default function piRulesExtension(pi) {
37
37
  });
38
38
  registerSlashCommands(pi, engine);
39
39
  registerRuleActivationRenderer(pi);
40
+ /**
41
+ * Absolute paths (and realpaths) of context files pi loaded natively into the system
42
+ * prompt. Rebuilt on every before_agent_start. Dynamic discovery walks to the repository
43
+ * root, so single-file rules (AGENTS.md/CLAUDE.md) from levels the agent has natively
44
+ * loaded must be deduplicated in the tool_result path as well — otherwise each matching
45
+ * read re-injects a context file that is already in the system prompt.
46
+ */
47
+ const nativeContextPaths = new Set();
40
48
  function syncConfigFromFlags() {
41
49
  const disabled = pi.getFlag("pi-rules-disabled");
42
50
  const mode = pi.getFlag("pi-rules-mode");
@@ -49,10 +57,10 @@ export default function piRulesExtension(pi) {
49
57
  }
50
58
  pi.on("session_start", async (event, ctx) => {
51
59
  syncConfigFromFlags();
60
+ engine.resetSession(ctx.cwd);
52
61
  if (engine.config.disabled) {
53
62
  return undefined;
54
63
  }
55
- engine.resetSession(ctx.cwd);
56
64
  pi.appendEntry("pi-rules.scan", { cwd: ctx.cwd, reason: event.reason });
57
65
  return undefined;
58
66
  });
@@ -70,7 +78,11 @@ export default function piRulesExtension(pi) {
70
78
  return undefined;
71
79
  }
72
80
  const loaded = engine.loadStaticRules(ctx.cwd);
73
- const nativeContextPaths = new Set(event.systemPromptOptions.contextFiles?.flatMap((contextFile) => pathKeys(contextFile.path)) ?? []);
81
+ nativeContextPaths.clear();
82
+ for (const path of event.systemPromptOptions.contextFiles?.flatMap((contextFile) => pathKeys(contextFile.path)) ??
83
+ []) {
84
+ nativeContextPaths.add(path);
85
+ }
74
86
  for (const rule of loaded.rules) {
75
87
  if (nativeContextPaths.has(rule.path) || nativeContextPaths.has(rule.realPath)) {
76
88
  engine.markStaticInjected(rule);
@@ -107,7 +119,17 @@ export default function piRulesExtension(pi) {
107
119
  }
108
120
  const loaded = engine.loadDynamicRules(ctx.cwd, pendingFingerprints.map((target) => target.targetPath));
109
121
  engine.commitDynamicTargetFingerprints(fingerprints);
110
- const rules = loaded.rules.filter((rule) => !engine.isStaticInjected(rule) && !engine.isDynamicInjected(DYNAMIC_CONTEXT_SCOPE, rule));
122
+ for (const rule of loaded.rules) {
123
+ if (nativeContextPaths.has(rule.path) || nativeContextPaths.has(rule.realPath)) {
124
+ engine.markStaticInjected(rule);
125
+ }
126
+ }
127
+ // DYNAMIC_CONTEXT_SCOPE already dedups every rule (single-file or glob) session-wide, which
128
+ // subsumes upstream's per-session single-file set.
129
+ const rules = loaded.rules.filter((rule) => !nativeContextPaths.has(rule.path) &&
130
+ !nativeContextPaths.has(rule.realPath) &&
131
+ !engine.isStaticInjected(rule) &&
132
+ !engine.isDynamicInjected(DYNAMIC_CONTEXT_SCOPE, rule));
111
133
  if (rules.length === 0) {
112
134
  return undefined;
113
135
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/rules/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, realpathSync } from \"node:fs\";\nimport { isAbsolute, relative } from \"node:path\";\n\nimport type { ExtensionAPI } from \"../../types.ts\";\n\nimport { appendRuleActivation, registerRuleActivationRenderer } from \"../rule-activation/index.ts\";\nimport { registerSlashCommands } from \"./commands.ts\";\nimport { configFromEnvironment } from \"./config.ts\";\nimport { createEngine } from \"./rules/engine.ts\";\nimport { findRuleCandidates } from \"./rules/finder.ts\";\nimport { findProjectRoot } from \"./rules/project-root.ts\";\nimport { extractToolPaths } from \"./rules/tool-paths.ts\";\nimport type { PiRulesConfig } from \"./rules/types.ts\";\n\ntype PiRulesMode = PiRulesConfig[\"mode\"];\n\nconst MODE_VALUES = new Set<string>([\"static\", \"dynamic\", \"both\", \"off\"]);\nconst DYNAMIC_CONTEXT_SCOPE = \"live-context\";\n\nexport default function piRulesExtension(pi: ExtensionAPI): void {\n\tpi.registerFlag(\"pi-rules-disabled\", {\n\t\ttype: \"boolean\",\n\t\tdefault: false,\n\t\tdescription: \"Disable pi-rules hooks.\",\n\t});\n\tpi.registerFlag(\"pi-rules-mode\", {\n\t\ttype: \"string\",\n\t\tdefault: \"both\",\n\t\tdescription: \"Rule injection mode: static, dynamic, both, or off.\",\n\t});\n\tconst config = configFromEnvironment();\n\tconst envDisabled = config.disabled;\n\tconst engine = createEngine(config, {\n\t\tfindCandidates: findRuleCandidates,\n\t\treadFile: (path) => {\n\t\t\ttry {\n\t\t\t\treturn readFileSync(path, \"utf-8\");\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\tfindProjectRoot,\n\t\textractToolPaths,\n\t});\n\tregisterSlashCommands(pi, engine);\n\tregisterRuleActivationRenderer(pi);\n\n\tfunction syncConfigFromFlags(): void {\n\t\tconst disabled = pi.getFlag(\"pi-rules-disabled\");\n\t\tconst mode = pi.getFlag(\"pi-rules-mode\");\n\n\t\tif (typeof disabled === \"boolean\") {\n\t\t\tengine.config.disabled = disabled || envDisabled;\n\t\t}\n\t\tif (typeof mode === \"string\" && isPiRulesMode(mode)) {\n\t\t\tengine.config.mode = mode;\n\t\t}\n\t}\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tsyncConfigFromFlags();\n\t\tif (engine.config.disabled) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tengine.resetSession(ctx.cwd);\n\t\tpi.appendEntry(\"pi-rules.scan\", { cwd: ctx.cwd, reason: event.reason });\n\t\treturn undefined;\n\t});\n\n\tpi.on(\"session_compact\", async (event, ctx) => {\n\t\t// Rejected compactions do not mutate session state; do not reset rules.\n\t\tif (!event.accepted) return undefined;\n\t\tengine.resetSession(ctx.cwd);\n\t\tpi.appendEntry(\"pi-rules.scan\", { cwd: ctx.cwd, reason: \"compact\" });\n\t\treturn undefined;\n\t});\n\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tsyncConfigFromFlags();\n\t\tif (engine.config.disabled || engine.config.mode === \"off\" || engine.config.mode === \"dynamic\") {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst loaded = engine.loadStaticRules(ctx.cwd);\n\t\tconst nativeContextPaths = new Set(\n\t\t\tevent.systemPromptOptions.contextFiles?.flatMap((contextFile) => pathKeys(contextFile.path)) ?? [],\n\t\t);\n\t\tfor (const rule of loaded.rules) {\n\t\t\tif (nativeContextPaths.has(rule.path) || nativeContextPaths.has(rule.realPath)) {\n\t\t\t\tengine.markStaticInjected(rule);\n\t\t\t}\n\t\t}\n\t\t// Deliberately NOT gated on isStaticInjected: the host re-emits this from the BASE prompt\n\t\t// every user prompt, so a prior turn's mark would drop the block from turn 2 onward. The\n\t\t// marks below serve only the dynamic tool_result path.\n\t\tconst rules = loaded.rules.filter(\n\t\t\t(rule) => !nativeContextPaths.has(rule.path) && !nativeContextPaths.has(rule.realPath),\n\t\t);\n\n\t\tif (rules.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst block = engine.formatStatic(rules);\n\t\tfor (const rule of rules) {\n\t\t\tengine.markStaticInjected(rule);\n\t\t}\n\n\t\treturn { systemPrompt: event.systemPrompt + block };\n\t});\n\n\tpi.on(\"tool_result\", async (event, ctx) => {\n\t\tsyncConfigFromFlags();\n\t\tif (engine.config.disabled || engine.config.mode === \"off\" || engine.config.mode === \"static\" || event.isError) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst targetPaths = extractToolPaths(event, ctx.cwd);\n\t\tconst firstTargetPath = targetPaths[0];\n\t\tif (firstTargetPath === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst fingerprints = engine.fingerprintDynamicTargets(ctx.cwd, targetPaths);\n\t\tconst pendingFingerprints = fingerprints.filter((target) => !engine.isDynamicTargetFingerprintCurrent(target));\n\t\tif (pendingFingerprints.length === 0) {\n\t\t\tengine.commitDynamicTargetFingerprints(fingerprints);\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst loaded = engine.loadDynamicRules(\n\t\t\tctx.cwd,\n\t\t\tpendingFingerprints.map((target) => target.targetPath),\n\t\t);\n\t\tengine.commitDynamicTargetFingerprints(fingerprints);\n\t\tconst rules = loaded.rules.filter(\n\t\t\t(rule) => !engine.isStaticInjected(rule) && !engine.isDynamicInjected(DYNAMIC_CONTEXT_SCOPE, rule),\n\t\t);\n\t\tif (rules.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst firstPendingTarget = pendingFingerprints[0]?.targetPath ?? firstTargetPath;\n\t\tconst targetPath = displayPath(ctx.cwd, firstPendingTarget);\n\t\tconst block = engine.formatDynamic(rules, targetPath);\n\t\tfor (const rule of rules) {\n\t\t\tengine.markDynamicInjected(DYNAMIC_CONTEXT_SCOPE, rule);\n\t\t}\n\t\tappendRuleActivation(pi, {\n\t\t\tkind: \"project-rules\",\n\t\t\ttargetPath,\n\t\t\trules: rules.map((rule) => rule.relativePath),\n\t\t\ttoolCallId: event.toolCallId,\n\t\t});\n\n\t\treturn { content: [...event.content, { type: \"text\", text: block, audience: \"model\" }] };\n\t});\n}\n\nfunction isPiRulesMode(value: string): value is PiRulesMode {\n\treturn MODE_VALUES.has(value);\n}\n\nfunction pathKeys(filePath: string): string[] {\n\ttry {\n\t\treturn [filePath, realpathSync.native(filePath)];\n\t} catch {\n\t\treturn [filePath];\n\t}\n}\n\nfunction displayPath(cwd: string, filePath: string): string {\n\treturn isAbsolute(filePath) ? relative(cwd, filePath) : filePath;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/rules/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, realpathSync } from \"node:fs\";\nimport { isAbsolute, relative } from \"node:path\";\n\nimport type { ExtensionAPI } from \"../../types.ts\";\n\nimport { appendRuleActivation, registerRuleActivationRenderer } from \"../rule-activation/index.ts\";\nimport { registerSlashCommands } from \"./commands.ts\";\nimport { configFromEnvironment } from \"./config.ts\";\nimport { createEngine } from \"./rules/engine.ts\";\nimport { findRuleCandidates } from \"./rules/finder.ts\";\nimport { findProjectRoot } from \"./rules/project-root.ts\";\nimport { extractToolPaths } from \"./rules/tool-paths.ts\";\nimport type { PiRulesConfig } from \"./rules/types.ts\";\n\ntype PiRulesMode = PiRulesConfig[\"mode\"];\n\nconst MODE_VALUES = new Set<string>([\"static\", \"dynamic\", \"both\", \"off\"]);\nconst DYNAMIC_CONTEXT_SCOPE = \"live-context\";\n\nexport default function piRulesExtension(pi: ExtensionAPI): void {\n\tpi.registerFlag(\"pi-rules-disabled\", {\n\t\ttype: \"boolean\",\n\t\tdefault: false,\n\t\tdescription: \"Disable pi-rules hooks.\",\n\t});\n\tpi.registerFlag(\"pi-rules-mode\", {\n\t\ttype: \"string\",\n\t\tdefault: \"both\",\n\t\tdescription: \"Rule injection mode: static, dynamic, both, or off.\",\n\t});\n\tconst config = configFromEnvironment();\n\tconst envDisabled = config.disabled;\n\tconst engine = createEngine(config, {\n\t\tfindCandidates: findRuleCandidates,\n\t\treadFile: (path) => {\n\t\t\ttry {\n\t\t\t\treturn readFileSync(path, \"utf-8\");\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\tfindProjectRoot,\n\t\textractToolPaths,\n\t});\n\tregisterSlashCommands(pi, engine);\n\tregisterRuleActivationRenderer(pi);\n\n\t/**\n\t * Absolute paths (and realpaths) of context files pi loaded natively into the system\n\t * prompt. Rebuilt on every before_agent_start. Dynamic discovery walks to the repository\n\t * root, so single-file rules (AGENTS.md/CLAUDE.md) from levels the agent has natively\n\t * loaded must be deduplicated in the tool_result path as well — otherwise each matching\n\t * read re-injects a context file that is already in the system prompt.\n\t */\n\tconst nativeContextPaths = new Set<string>();\n\n\tfunction syncConfigFromFlags(): void {\n\t\tconst disabled = pi.getFlag(\"pi-rules-disabled\");\n\t\tconst mode = pi.getFlag(\"pi-rules-mode\");\n\n\t\tif (typeof disabled === \"boolean\") {\n\t\t\tengine.config.disabled = disabled || envDisabled;\n\t\t}\n\t\tif (typeof mode === \"string\" && isPiRulesMode(mode)) {\n\t\t\tengine.config.mode = mode;\n\t\t}\n\t}\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tsyncConfigFromFlags();\n\t\tengine.resetSession(ctx.cwd);\n\t\tif (engine.config.disabled) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tpi.appendEntry(\"pi-rules.scan\", { cwd: ctx.cwd, reason: event.reason });\n\t\treturn undefined;\n\t});\n\n\tpi.on(\"session_compact\", async (event, ctx) => {\n\t\t// Rejected compactions do not mutate session state; do not reset rules.\n\t\tif (!event.accepted) return undefined;\n\t\tengine.resetSession(ctx.cwd);\n\t\tpi.appendEntry(\"pi-rules.scan\", { cwd: ctx.cwd, reason: \"compact\" });\n\t\treturn undefined;\n\t});\n\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tsyncConfigFromFlags();\n\t\tif (engine.config.disabled || engine.config.mode === \"off\" || engine.config.mode === \"dynamic\") {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst loaded = engine.loadStaticRules(ctx.cwd);\n\t\tnativeContextPaths.clear();\n\t\tfor (const path of event.systemPromptOptions.contextFiles?.flatMap((contextFile) => pathKeys(contextFile.path)) ??\n\t\t\t[]) {\n\t\t\tnativeContextPaths.add(path);\n\t\t}\n\t\tfor (const rule of loaded.rules) {\n\t\t\tif (nativeContextPaths.has(rule.path) || nativeContextPaths.has(rule.realPath)) {\n\t\t\t\tengine.markStaticInjected(rule);\n\t\t\t}\n\t\t}\n\t\t// Deliberately NOT gated on isStaticInjected: the host re-emits this from the BASE prompt\n\t\t// every user prompt, so a prior turn's mark would drop the block from turn 2 onward. The\n\t\t// marks below serve only the dynamic tool_result path.\n\t\tconst rules = loaded.rules.filter(\n\t\t\t(rule) => !nativeContextPaths.has(rule.path) && !nativeContextPaths.has(rule.realPath),\n\t\t);\n\n\t\tif (rules.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst block = engine.formatStatic(rules);\n\t\tfor (const rule of rules) {\n\t\t\tengine.markStaticInjected(rule);\n\t\t}\n\n\t\treturn { systemPrompt: event.systemPrompt + block };\n\t});\n\n\tpi.on(\"tool_result\", async (event, ctx) => {\n\t\tsyncConfigFromFlags();\n\t\tif (engine.config.disabled || engine.config.mode === \"off\" || engine.config.mode === \"static\" || event.isError) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst targetPaths = extractToolPaths(event, ctx.cwd);\n\t\tconst firstTargetPath = targetPaths[0];\n\t\tif (firstTargetPath === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst fingerprints = engine.fingerprintDynamicTargets(ctx.cwd, targetPaths);\n\t\tconst pendingFingerprints = fingerprints.filter((target) => !engine.isDynamicTargetFingerprintCurrent(target));\n\t\tif (pendingFingerprints.length === 0) {\n\t\t\tengine.commitDynamicTargetFingerprints(fingerprints);\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst loaded = engine.loadDynamicRules(\n\t\t\tctx.cwd,\n\t\t\tpendingFingerprints.map((target) => target.targetPath),\n\t\t);\n\t\tengine.commitDynamicTargetFingerprints(fingerprints);\n\t\tfor (const rule of loaded.rules) {\n\t\t\tif (nativeContextPaths.has(rule.path) || nativeContextPaths.has(rule.realPath)) {\n\t\t\t\tengine.markStaticInjected(rule);\n\t\t\t}\n\t\t}\n\t\t// DYNAMIC_CONTEXT_SCOPE already dedups every rule (single-file or glob) session-wide, which\n\t\t// subsumes upstream's per-session single-file set.\n\t\tconst rules = loaded.rules.filter(\n\t\t\t(rule) =>\n\t\t\t\t!nativeContextPaths.has(rule.path) &&\n\t\t\t\t!nativeContextPaths.has(rule.realPath) &&\n\t\t\t\t!engine.isStaticInjected(rule) &&\n\t\t\t\t!engine.isDynamicInjected(DYNAMIC_CONTEXT_SCOPE, rule),\n\t\t);\n\t\tif (rules.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst firstPendingTarget = pendingFingerprints[0]?.targetPath ?? firstTargetPath;\n\t\tconst targetPath = displayPath(ctx.cwd, firstPendingTarget);\n\t\tconst block = engine.formatDynamic(rules, targetPath);\n\t\tfor (const rule of rules) {\n\t\t\tengine.markDynamicInjected(DYNAMIC_CONTEXT_SCOPE, rule);\n\t\t}\n\t\tappendRuleActivation(pi, {\n\t\t\tkind: \"project-rules\",\n\t\t\ttargetPath,\n\t\t\trules: rules.map((rule) => rule.relativePath),\n\t\t\ttoolCallId: event.toolCallId,\n\t\t});\n\n\t\treturn { content: [...event.content, { type: \"text\", text: block, audience: \"model\" }] };\n\t});\n}\n\nfunction isPiRulesMode(value: string): value is PiRulesMode {\n\treturn MODE_VALUES.has(value);\n}\n\nfunction pathKeys(filePath: string): string[] {\n\ttry {\n\t\treturn [filePath, realpathSync.native(filePath)];\n\t} catch {\n\t\treturn [filePath];\n\t}\n}\n\nfunction displayPath(cwd: string, filePath: string): string {\n\treturn isAbsolute(filePath) ? relative(cwd, filePath) : filePath;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAQ5C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAKzE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAKjD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAAuD,CAAC;AAE5G;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAAwD,CAAC;AAE7G;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAAoB,CAAC;AAEvE;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,UAAU,EAAE,MAAM,CAc1D,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC;;GAEG;AACH,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAE5C;;GAEG;AACH,eAAO,MAAM,wBAAwB,QAAQ,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,iBAAiB,iDAAiD,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAA8B,CAAC;AAClF,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAAkC,CAAC;AAE5F,8DAA8D;AAC9D,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,wBAAwB,qBAAqB,CAAC;AAC3D,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,uCAAuC,CAAC;AACtF,eAAO,MAAM,+BAA+B,qCAAqC,CAAC;AAElF;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAQlD,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAQ5C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAMzE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAKjD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAKnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAAwD,CAAC;AAE7G;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAAoB,CAAC;AAEvE;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,UAAU,EAAE,MAAM,CAgB1D,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC;;GAEG;AACH,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAE5C;;GAEG;AACH,eAAO,MAAM,wBAAwB,QAAQ,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,iBAAiB,iDAAiD,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAA8B,CAAC;AAClF,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAAkC,CAAC;AAE5F,8DAA8D;AAC9D,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,wBAAwB,qBAAqB,CAAC;AAC3D,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,uCAAuC,CAAC;AACtF,eAAO,MAAM,+BAA+B,qCAAqC,CAAC;AAElF;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAQlD,CAAC"}
@@ -16,6 +16,7 @@ export const PROJECT_MARKERS = [
16
16
  * the project root, second is the subdir scanned recursively.
17
17
  */
18
18
  export const PROJECT_RULE_SUBDIRS = [
19
+ [".pi", "rules"],
19
20
  [".omo", "rules"],
20
21
  [".claude", "rules"],
21
22
  [".cursor", "rules"],
@@ -33,7 +34,12 @@ export const PROJECT_SINGLE_FILES = [
33
34
  /**
34
35
  * User-home rule directories.
35
36
  */
36
- export const USER_HOME_RULE_SUBDIRS = [".omo/rules", ".opencode/rules", ".claude/rules"];
37
+ export const USER_HOME_RULE_SUBDIRS = [
38
+ ".pi/rules",
39
+ ".omo/rules",
40
+ ".opencode/rules",
41
+ ".claude/rules",
42
+ ];
37
43
  /**
38
44
  * User-home single-file rules. The first one to exist wins per "first-match" semantics.
39
45
  */
@@ -46,19 +52,21 @@ export const RULE_FILE_EXTENSIONS = [".md", ".mdc"];
46
52
  * Per-rule source priority for deterministic ordering. Lower = earlier.
47
53
  */
48
54
  export const SOURCE_PRIORITY = new Map([
49
- [".omo/rules", 0],
50
- [".claude/rules", 1],
51
- [".cursor/rules", 2],
52
- [".github/instructions", 3],
53
- [".github/copilot-instructions.md", 4],
54
- ["AGENTS.md", 5],
55
- ["CLAUDE.md", 6],
56
- ["CONTEXT.md", 7],
57
- ["~/.omo/rules", 100],
58
- ["~/.opencode/rules", 101],
59
- ["~/.claude/rules", 102],
60
- ["~/.config/opencode/AGENTS.md", 103],
61
- ["~/.claude/CLAUDE.md", 104],
55
+ [".pi/rules", 0],
56
+ [".omo/rules", 1],
57
+ [".claude/rules", 2],
58
+ [".cursor/rules", 3],
59
+ [".github/instructions", 4],
60
+ [".github/copilot-instructions.md", 5],
61
+ ["AGENTS.md", 6],
62
+ ["CLAUDE.md", 7],
63
+ ["CONTEXT.md", 8],
64
+ ["~/.pi/rules", 100],
65
+ ["~/.omo/rules", 101],
66
+ ["~/.opencode/rules", 102],
67
+ ["~/.claude/rules", 103],
68
+ ["~/.config/opencode/AGENTS.md", 104],
69
+ ["~/.claude/CLAUDE.md", 105],
62
70
  ]);
63
71
  /**
64
72
  * Distance value assigned to global / user-home rules.
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/constants.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAsB;IACjD,MAAM;IACN,qBAAqB;IACrB,cAAc;IACd,gBAAgB;IAChB,YAAY;IACZ,QAAQ;IACR,OAAO;CACP,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA6C;IAC7E,CAAC,MAAM,EAAE,OAAO,CAAC;IACjB,CAAC,SAAS,EAAE,OAAO,CAAC;IACpB,CAAC,SAAS,EAAE,OAAO,CAAC;IACpB,CAAC,SAAS,EAAE,cAAc,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAsB;IACtD,iCAAiC;IACjC,WAAW;IACX,WAAW;IACX,YAAY;CACZ,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsB,CAAC,YAAY,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;AAE5G;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsB,CAAC,4BAA4B,EAAE,mBAAmB,CAAC,CAAC;AAE7G;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAEvE;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAoC,IAAI,GAAG,CAAC;IACvE,CAAC,YAAY,EAAE,CAAC,CAAC;IACjB,CAAC,eAAe,EAAE,CAAC,CAAC;IACpB,CAAC,eAAe,EAAE,CAAC,CAAC;IACpB,CAAC,sBAAsB,EAAE,CAAC,CAAC;IAC3B,CAAC,iCAAiC,EAAE,CAAC,CAAC;IACtC,CAAC,WAAW,EAAE,CAAC,CAAC;IAChB,CAAC,WAAW,EAAE,CAAC,CAAC;IAChB,CAAC,YAAY,EAAE,CAAC,CAAC;IACjB,CAAC,cAAc,EAAE,GAAG,CAAC;IACrB,CAAC,mBAAmB,EAAE,GAAG,CAAC;IAC1B,CAAC,iBAAiB,EAAE,GAAG,CAAC;IACxB,CAAC,8BAA8B,EAAE,GAAG,CAAC;IACrC,CAAC,qBAAqB,EAAE,GAAG,CAAC;CAC5B,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAE5C;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,CAAC;AAE9C;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,8CAA8C,CAAC;AAEhF;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAClF,MAAM,CAAC,MAAM,wBAAwB,GAAwB,IAAI,GAAG,CAAC,qBAAqB,CAAC,CAAC;AAE5F,8DAA8D;AAC9D,MAAM,CAAC,MAAM,0BAA0B,GAAG,iBAAiB,CAAC;AAC5D,MAAM,CAAC,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AAC3D,MAAM,CAAC,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AAE/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,oCAAoC,CAAC;AACtF,MAAM,CAAC,MAAM,+BAA+B,GAAG,kCAAkC,CAAC;AAElF;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAsB;IACvD,cAAc;IACd,MAAM;IACN,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;IACP,UAAU;CACV,CAAC","sourcesContent":["import type { RuleSource } from \"./types.ts\";\n\n/**\n * Project root marker files / directories used by `findProjectRoot`.\n * Walks UP from cwd until any of these is found in the directory.\n */\nexport const PROJECT_MARKERS: readonly string[] = [\n\t\".git\",\n\t\"pnpm-workspace.yaml\",\n\t\"package.json\",\n\t\"pyproject.toml\",\n\t\"Cargo.toml\",\n\t\"go.mod\",\n\t\".venv\",\n];\n\n/**\n * Project rule subdirectories. First tuple element is the parent dir under\n * the project root, second is the subdir scanned recursively.\n */\nexport const PROJECT_RULE_SUBDIRS: ReadonlyArray<readonly [string, string]> = [\n\t[\".omo\", \"rules\"],\n\t[\".claude\", \"rules\"],\n\t[\".cursor\", \"rules\"],\n\t[\".github\", \"instructions\"],\n];\n\n/**\n * Single-file project rules (always apply, frontmatter optional).\n */\nexport const PROJECT_SINGLE_FILES: readonly string[] = [\n\t\".github/copilot-instructions.md\",\n\t\"AGENTS.md\",\n\t\"CLAUDE.md\",\n\t\"CONTEXT.md\",\n];\n\n/**\n * User-home rule directories.\n */\nexport const USER_HOME_RULE_SUBDIRS: readonly string[] = [\".omo/rules\", \".opencode/rules\", \".claude/rules\"];\n\n/**\n * User-home single-file rules. The first one to exist wins per \"first-match\" semantics.\n */\nexport const USER_HOME_SINGLE_FILES: readonly string[] = [\".config/opencode/AGENTS.md\", \".claude/CLAUDE.md\"];\n\n/**\n * File extensions accepted as rule files in scanned directories.\n */\nexport const RULE_FILE_EXTENSIONS: readonly string[] = [\".md\", \".mdc\"];\n\n/**\n * Per-rule source priority for deterministic ordering. Lower = earlier.\n */\nexport const SOURCE_PRIORITY: ReadonlyMap<RuleSource, number> = new Map([\n\t[\".omo/rules\", 0],\n\t[\".claude/rules\", 1],\n\t[\".cursor/rules\", 2],\n\t[\".github/instructions\", 3],\n\t[\".github/copilot-instructions.md\", 4],\n\t[\"AGENTS.md\", 5],\n\t[\"CLAUDE.md\", 6],\n\t[\"CONTEXT.md\", 7],\n\t[\"~/.omo/rules\", 100],\n\t[\"~/.opencode/rules\", 101],\n\t[\"~/.claude/rules\", 102],\n\t[\"~/.config/opencode/AGENTS.md\", 103],\n\t[\"~/.claude/CLAUDE.md\", 104],\n]);\n\n/**\n * Distance value assigned to global / user-home rules.\n */\nexport const GLOBAL_DISTANCE = 9999;\n\n/**\n * Per-rule body character cap (default).\n */\nexport const DEFAULT_MAX_RULE_CHARS = 12000;\n\n/**\n * Total injected chars per tool result (default).\n */\nexport const DEFAULT_MAX_RESULT_CHARS = 40000;\n\n/**\n * Truncation marker template. `{path}` is replaced with the relative path.\n */\nexport const TRUNCATION_NOTICE = \"\\n\\n[Rule truncated. Read full rule: {path}]\";\n\n/**\n * Built-in tool names whose results trigger dynamic rule injection.\n */\nexport const TRACKED_BUILTIN_TOOLS: readonly string[] = [\"read\", \"edit\", \"write\"];\nexport const TRACKED_BUILTIN_TOOL_SET: ReadonlySet<string> = new Set(TRACKED_BUILTIN_TOOLS);\n\n/** Addressed to the model; never used to locate the block. */\nexport const PROJECT_RULES_START_MARKER = \"<project_rules>\";\nexport const PROJECT_RULES_END_MARKER = \"</project_rules>\";\nexport const PROJECT_RULES_HEADING = \"## Project Instructions\";\n\n/**\n * How provider lanes that rebuild the system prompt (see the Anthropic Subscription builtin) locate the\n * block. The semantic markers cannot: prompt content this builtin does not own - context files\n * before it, extensions appending after it - may legitimately contain them and be extracted instead.\n */\nexport const PROJECT_RULES_REGION_START_MARKER = \"<!--senpi:project-rules:1:start-->\";\nexport const PROJECT_RULES_REGION_END_MARKER = \"<!--senpi:project-rules:1:end-->\";\n\n/**\n * Directories excluded by the recursive scanner regardless of glob settings.\n */\nexport const SCANNER_EXCLUDED_DIRS: readonly string[] = [\n\t\"node_modules\",\n\t\".git\",\n\t\"dist\",\n\t\"build\",\n\t\".turbo\",\n\t\".next\",\n\t\"coverage\",\n];\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/constants.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAsB;IACjD,MAAM;IACN,qBAAqB;IACrB,cAAc;IACd,gBAAgB;IAChB,YAAY;IACZ,QAAQ;IACR,OAAO;CACP,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA6C;IAC7E,CAAC,KAAK,EAAE,OAAO,CAAC;IAChB,CAAC,MAAM,EAAE,OAAO,CAAC;IACjB,CAAC,SAAS,EAAE,OAAO,CAAC;IACpB,CAAC,SAAS,EAAE,OAAO,CAAC;IACpB,CAAC,SAAS,EAAE,cAAc,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAsB;IACtD,iCAAiC;IACjC,WAAW;IACX,WAAW;IACX,YAAY;CACZ,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsB;IACxD,WAAW;IACX,YAAY;IACZ,iBAAiB;IACjB,eAAe;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsB,CAAC,4BAA4B,EAAE,mBAAmB,CAAC,CAAC;AAE7G;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAEvE;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAoC,IAAI,GAAG,CAAC;IACvE,CAAC,WAAW,EAAE,CAAC,CAAC;IAChB,CAAC,YAAY,EAAE,CAAC,CAAC;IACjB,CAAC,eAAe,EAAE,CAAC,CAAC;IACpB,CAAC,eAAe,EAAE,CAAC,CAAC;IACpB,CAAC,sBAAsB,EAAE,CAAC,CAAC;IAC3B,CAAC,iCAAiC,EAAE,CAAC,CAAC;IACtC,CAAC,WAAW,EAAE,CAAC,CAAC;IAChB,CAAC,WAAW,EAAE,CAAC,CAAC;IAChB,CAAC,YAAY,EAAE,CAAC,CAAC;IACjB,CAAC,aAAa,EAAE,GAAG,CAAC;IACpB,CAAC,cAAc,EAAE,GAAG,CAAC;IACrB,CAAC,mBAAmB,EAAE,GAAG,CAAC;IAC1B,CAAC,iBAAiB,EAAE,GAAG,CAAC;IACxB,CAAC,8BAA8B,EAAE,GAAG,CAAC;IACrC,CAAC,qBAAqB,EAAE,GAAG,CAAC;CAC5B,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAE5C;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,CAAC;AAE9C;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,8CAA8C,CAAC;AAEhF;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAClF,MAAM,CAAC,MAAM,wBAAwB,GAAwB,IAAI,GAAG,CAAC,qBAAqB,CAAC,CAAC;AAE5F,8DAA8D;AAC9D,MAAM,CAAC,MAAM,0BAA0B,GAAG,iBAAiB,CAAC;AAC5D,MAAM,CAAC,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AAC3D,MAAM,CAAC,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AAE/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,oCAAoC,CAAC;AACtF,MAAM,CAAC,MAAM,+BAA+B,GAAG,kCAAkC,CAAC;AAElF;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAsB;IACvD,cAAc;IACd,MAAM;IACN,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;IACP,UAAU;CACV,CAAC","sourcesContent":["import type { RuleSource } from \"./types.ts\";\n\n/**\n * Project root marker files / directories used by `findProjectRoot`.\n * Walks UP from cwd until any of these is found in the directory.\n */\nexport const PROJECT_MARKERS: readonly string[] = [\n\t\".git\",\n\t\"pnpm-workspace.yaml\",\n\t\"package.json\",\n\t\"pyproject.toml\",\n\t\"Cargo.toml\",\n\t\"go.mod\",\n\t\".venv\",\n];\n\n/**\n * Project rule subdirectories. First tuple element is the parent dir under\n * the project root, second is the subdir scanned recursively.\n */\nexport const PROJECT_RULE_SUBDIRS: ReadonlyArray<readonly [string, string]> = [\n\t[\".pi\", \"rules\"],\n\t[\".omo\", \"rules\"],\n\t[\".claude\", \"rules\"],\n\t[\".cursor\", \"rules\"],\n\t[\".github\", \"instructions\"],\n];\n\n/**\n * Single-file project rules (always apply, frontmatter optional).\n */\nexport const PROJECT_SINGLE_FILES: readonly string[] = [\n\t\".github/copilot-instructions.md\",\n\t\"AGENTS.md\",\n\t\"CLAUDE.md\",\n\t\"CONTEXT.md\",\n];\n\n/**\n * User-home rule directories.\n */\nexport const USER_HOME_RULE_SUBDIRS: readonly string[] = [\n\t\".pi/rules\",\n\t\".omo/rules\",\n\t\".opencode/rules\",\n\t\".claude/rules\",\n];\n\n/**\n * User-home single-file rules. The first one to exist wins per \"first-match\" semantics.\n */\nexport const USER_HOME_SINGLE_FILES: readonly string[] = [\".config/opencode/AGENTS.md\", \".claude/CLAUDE.md\"];\n\n/**\n * File extensions accepted as rule files in scanned directories.\n */\nexport const RULE_FILE_EXTENSIONS: readonly string[] = [\".md\", \".mdc\"];\n\n/**\n * Per-rule source priority for deterministic ordering. Lower = earlier.\n */\nexport const SOURCE_PRIORITY: ReadonlyMap<RuleSource, number> = new Map([\n\t[\".pi/rules\", 0],\n\t[\".omo/rules\", 1],\n\t[\".claude/rules\", 2],\n\t[\".cursor/rules\", 3],\n\t[\".github/instructions\", 4],\n\t[\".github/copilot-instructions.md\", 5],\n\t[\"AGENTS.md\", 6],\n\t[\"CLAUDE.md\", 7],\n\t[\"CONTEXT.md\", 8],\n\t[\"~/.pi/rules\", 100],\n\t[\"~/.omo/rules\", 101],\n\t[\"~/.opencode/rules\", 102],\n\t[\"~/.claude/rules\", 103],\n\t[\"~/.config/opencode/AGENTS.md\", 104],\n\t[\"~/.claude/CLAUDE.md\", 105],\n]);\n\n/**\n * Distance value assigned to global / user-home rules.\n */\nexport const GLOBAL_DISTANCE = 9999;\n\n/**\n * Per-rule body character cap (default).\n */\nexport const DEFAULT_MAX_RULE_CHARS = 12000;\n\n/**\n * Total injected chars per tool result (default).\n */\nexport const DEFAULT_MAX_RESULT_CHARS = 40000;\n\n/**\n * Truncation marker template. `{path}` is replaced with the relative path.\n */\nexport const TRUNCATION_NOTICE = \"\\n\\n[Rule truncated. Read full rule: {path}]\";\n\n/**\n * Built-in tool names whose results trigger dynamic rule injection.\n */\nexport const TRACKED_BUILTIN_TOOLS: readonly string[] = [\"read\", \"edit\", \"write\"];\nexport const TRACKED_BUILTIN_TOOL_SET: ReadonlySet<string> = new Set(TRACKED_BUILTIN_TOOLS);\n\n/** Addressed to the model; never used to locate the block. */\nexport const PROJECT_RULES_START_MARKER = \"<project_rules>\";\nexport const PROJECT_RULES_END_MARKER = \"</project_rules>\";\nexport const PROJECT_RULES_HEADING = \"## Project Instructions\";\n\n/**\n * How provider lanes that rebuild the system prompt (see the Anthropic Subscription builtin) locate the\n * block. The semantic markers cannot: prompt content this builtin does not own - context files\n * before it, extensions appending after it - may legitimately contain them and be extracted instead.\n */\nexport const PROJECT_RULES_REGION_START_MARKER = \"<!--senpi:project-rules:1:start-->\";\nexport const PROJECT_RULES_REGION_END_MARKER = \"<!--senpi:project-rules:1:end-->\";\n\n/**\n * Directories excluded by the recursive scanner regardless of glob settings.\n */\nexport const SCANNER_EXCLUDED_DIRS: readonly string[] = [\n\t\"node_modules\",\n\t\".git\",\n\t\"dist\",\n\t\"build\",\n\t\".turbo\",\n\t\".next\",\n\t\"coverage\",\n];\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/engine.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ import { formatDynamicBlock, formatStaticBlock } from "./formatter.js";
7
7
  import { hashContent, matchRule } from "./matcher.js";
8
8
  import { sortCandidates } from "./ordering.js";
9
9
  import { parseRule } from "./parser.js";
10
+ import { widenToRepositoryRoot } from "./project-root.js";
10
11
  const MAX_DYNAMIC_MATCH_CACHE_ENTRIES = 4096;
11
12
  const ROOT_SINGLE_FILE_SOURCES = new Set(PROJECT_SINGLE_FILES.filter((source) => !source.includes("/")));
12
13
  export function defaultConfig() {
@@ -55,13 +56,21 @@ export function createEngine(config, deps) {
55
56
  const candidateDiscoveryCache = new Map();
56
57
  const projectRootCache = new Map();
57
58
  const realPathCache = new Map();
59
+ const rootSingleFileSelections = new Set();
58
60
  for (const targetFile of targetFiles) {
59
- const projectRoot = shouldCacheLookups
60
- ? findProjectRootCached(projectRootCache, targetFile, deps.findProjectRoot)
61
- : deps.findProjectRoot(targetFile);
61
+ // Cargo/pnpm workspaces nest project markers (e.g. a per-member Cargo.toml), so the
62
+ // marker-based root would stop the walk below workspace-level rule directories.
63
+ // Widen to the enclosing git repository root so rules at repository and workspace
64
+ // level participate; scopeRelative keeps globs keyed to the rule file's scope.
65
+ // Canonicalize so macOS /var vs /private/var (and other symlink roots) still sit
66
+ // inside the realpathed project root used by findProjectRoot.
67
+ const discoveryTarget = canonicalizePath(targetFile);
68
+ const projectRoot = widenToRepositoryRoot(shouldCacheLookups
69
+ ? findProjectRootCached(projectRootCache, discoveryTarget, deps.findProjectRoot)
70
+ : deps.findProjectRoot(discoveryTarget));
62
71
  const findOptions = {
63
72
  projectRoot,
64
- targetFile,
73
+ targetFile: discoveryTarget,
65
74
  ...(discoveryCache === undefined ? {} : { cache: discoveryCache }),
66
75
  ...(disabledSources === undefined ? {} : { disabledSources }),
67
76
  };
@@ -69,6 +78,10 @@ export function createEngine(config, deps) {
69
78
  ? findSortedCandidatesCached(candidateDiscoveryCache, deps.findCandidates, findOptions)
70
79
  : sortCandidates(deps.findCandidates(findOptions));
71
80
  for (const candidate of candidates) {
81
+ const rootSingleFileSelectionKey = rootSingleFileSelectionKeyFor(candidate, projectRoot);
82
+ if (rootSingleFileSelectionKey !== null && rootSingleFileSelections.has(rootSingleFileSelectionKey)) {
83
+ continue;
84
+ }
72
85
  const loadedRule = loadCandidate(candidate, deps, diagnostics, projectRoot, {
73
86
  loadedRuleContent,
74
87
  projectMembership,
@@ -77,10 +90,13 @@ export function createEngine(config, deps) {
77
90
  if (loadedRule === null) {
78
91
  continue;
79
92
  }
80
- const matchReason = matchDynamicRuleCached(dynamicMatchCache, projectRoot, targetFile, candidate, loadedRule, deps.matchRule ?? matchRule);
93
+ const matchReason = matchDynamicRuleCached(dynamicMatchCache, projectRoot, discoveryTarget, candidate, loadedRule, deps.matchRule ?? matchRule);
81
94
  if (matchReason === null) {
82
95
  continue;
83
96
  }
97
+ if (rootSingleFileSelectionKey !== null) {
98
+ rootSingleFileSelections.add(rootSingleFileSelectionKey);
99
+ }
84
100
  const dedupKey = ruleDedupKey(loadedRule);
85
101
  if (seenRules.has(dedupKey)) {
86
102
  continue;
@@ -104,12 +120,13 @@ export function createEngine(config, deps) {
104
120
  const cwdProjectRoot = deps.findProjectRoot(cwd);
105
121
  const fingerprints = [];
106
122
  for (const targetFile of uniqueStrings(targetPaths)) {
107
- const projectRoot = cwdProjectRoot !== null && isSameOrChildPath(targetFile, cwdProjectRoot)
123
+ const discoveryTarget = canonicalizePath(targetFile);
124
+ const projectRoot = widenToRepositoryRoot(cwdProjectRoot !== null && isSameOrChildPath(discoveryTarget, cwdProjectRoot)
108
125
  ? cwdProjectRoot
109
- : deps.findProjectRoot(targetFile);
126
+ : deps.findProjectRoot(discoveryTarget));
110
127
  const findOptions = {
111
128
  projectRoot,
112
- targetFile,
129
+ targetFile: discoveryTarget,
113
130
  cache: discoveryCache,
114
131
  ...(disabledSources === undefined ? {} : { disabledSources }),
115
132
  };
@@ -357,7 +374,12 @@ function isDedupedRootSingleFile(candidate, rootSingleFileSelected) {
357
374
  return rootSingleFileSelected && isRootSingleFile(candidate);
358
375
  }
359
376
  function isRootSingleFile(candidate) {
360
- return candidate.distance === 0 && candidate.isSingleFile && ROOT_SINGLE_FILE_SOURCES.has(candidate.source);
377
+ return (candidate.isSingleFile &&
378
+ ROOT_SINGLE_FILE_SOURCES.has(candidate.source) &&
379
+ candidate.relativePath === candidate.source);
380
+ }
381
+ function rootSingleFileSelectionKeyFor(candidate, projectRoot) {
382
+ return projectRoot !== null && isRootSingleFile(candidate) ? projectRoot : null;
361
383
  }
362
384
  function pathBasesForTarget(projectRoot, targetFile, candidate) {
363
385
  const targetBasename = basename(targetFile);
@@ -430,6 +452,14 @@ function fileStatFingerprint(filePath) {
430
452
  function uniqueStrings(values) {
431
453
  return [...new Set(values)];
432
454
  }
455
+ function canonicalizePath(path) {
456
+ try {
457
+ return realpathSync.native(path);
458
+ }
459
+ catch {
460
+ return resolve(path);
461
+ }
462
+ }
433
463
  function storeLastLoad(state, rules, diagnostics) {
434
464
  state.loadedRules.length = 0;
435
465
  state.loadedRules.push(...rules);
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/engine.ts"],"names":[],"mappings":"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","sourcesContent":["import { realpathSync, statSync } from \"node:fs\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"node:path\";\n\nimport type { ToolResultEvent } from \"../../../types.ts\";\n\nimport {\n\tclearSession,\n\tcreateSessionState,\n\tisDynamicInjected as isDynamicInjectedInState,\n\tisStaticInjected as isStaticInjectedInState,\n\tmarkDynamicInjected as markDynamicInjectedInState,\n\tmarkStaticInjected as markStaticInjectedInState,\n} from \"./cache.ts\";\nimport {\n\tDEFAULT_MAX_RESULT_CHARS,\n\tDEFAULT_MAX_RULE_CHARS,\n\tPROJECT_SINGLE_FILES,\n\tSOURCE_PRIORITY,\n} from \"./constants.ts\";\nimport { createRuleDiscoveryCache, type RuleDiscoveryCache } from \"./finder.ts\";\nimport { formatDynamicBlock, formatStaticBlock } from \"./formatter.ts\";\nimport { hashContent, matchRule } from \"./matcher.ts\";\nimport { sortCandidates } from \"./ordering.ts\";\nimport { parseRule } from \"./parser.ts\";\nimport type { LoadedRule, MatchReason, PiRulesConfig, RuleCandidate, RuleDiagnostic, SessionState } from \"./types.ts\";\n\ninterface LoadedRuleContent {\n\tfrontmatter: LoadedRule[\"frontmatter\"];\n\tbody: string;\n\tcontentHash: string;\n\tdiagnostic?: string;\n}\n\ninterface LoadCandidateCaches {\n\treadonly loadedRuleContent?: Map<string, LoadedRuleContent | null>;\n\treadonly projectMembership?: CandidateProjectMembership;\n\treadonly realPathCache?: RealPathCache;\n}\n\ntype CandidateProjectMembership = Map<string, boolean>;\ntype CandidateDiscoveryCache = Map<string, RuleCandidate[]>;\ntype DynamicMatchCache = Map<string, MatchReason | null>;\ntype RealPathCache = Map<string, string>;\n\nconst MAX_DYNAMIC_MATCH_CACHE_ENTRIES = 4096;\n\nexport interface EngineDeps {\n\tfindCandidates: (options: {\n\t\tprojectRoot: string | null;\n\t\ttargetFile: string | null;\n\t\thomeDir?: string;\n\t\tdisabledSources?: ReadonlySet<string>;\n\t\tskipUserHome?: boolean;\n\t\tcache?: RuleDiscoveryCache;\n\t}) => RuleCandidate[];\n\treadFile: (path: string) => string | null;\n\tfindProjectRoot: (startPath: string) => string | null;\n\textractToolPaths: (event: ToolResultEvent, cwd: string) => string[];\n\tmatchRule?: typeof matchRule;\n\t/**\n\t * Returns a stable identifier for a rule file. Default uses `statSync` mtime/ctime/size.\n\t * Tests may inject a content-based fingerprint when fixtures use synthetic paths.\n\t */\n\tfileFingerprint?: (filePath: string) => string;\n}\n\nexport interface DynamicTargetFingerprint {\n\ttargetPath: string;\n\tcacheKey: string;\n\tfingerprint: string;\n}\n\nexport interface Engine {\n\tstate: SessionState;\n\tconfig: PiRulesConfig;\n\tloadStaticRules(cwd: string): { rules: LoadedRule[]; diagnostics: RuleDiagnostic[] };\n\tloadDynamicRules(\n\t\tcwd: string,\n\t\ttargetPaths: ReadonlyArray<string>,\n\t): { rules: LoadedRule[]; diagnostics: RuleDiagnostic[] };\n\tformatStatic(rules: ReadonlyArray<LoadedRule>): string;\n\tformatDynamic(rules: ReadonlyArray<LoadedRule>, target: string): string;\n\tresetSession(cwd?: string): void;\n\tisStaticInjected(rule: LoadedRule): boolean;\n\tisDynamicInjected(scopeKey: string, rule: LoadedRule): boolean;\n\tmarkStaticInjected(rule: LoadedRule): boolean;\n\tmarkDynamicInjected(scopeKey: string, rule: LoadedRule): boolean;\n\t/**\n\t * Computes a fingerprint for each unique target derived from its discovered\n\t * candidates plus their on-disk fingerprints. Pure - does not mutate state.\n\t */\n\tfingerprintDynamicTargets(cwd: string, targetPaths: ReadonlyArray<string>): DynamicTargetFingerprint[];\n\t/**\n\t * Returns true when the fingerprint for a target already matches the value\n\t * stored on `state.dynamicTargetFingerprints`. The hook layer skips\n\t * `loadDynamicRules` entirely when every target is current.\n\t */\n\tisDynamicTargetFingerprintCurrent(target: DynamicTargetFingerprint): boolean;\n\t/**\n\t * Commits the supplied fingerprints to `state.dynamicTargetFingerprints`.\n\t * Always pass every fingerprint observed during a hook invocation so the\n\t * map mirrors the latest discovery.\n\t */\n\tcommitDynamicTargetFingerprints(fingerprints: ReadonlyArray<DynamicTargetFingerprint>): void;\n}\n\nconst ROOT_SINGLE_FILE_SOURCES = new Set(PROJECT_SINGLE_FILES.filter((source) => !source.includes(\"/\")));\n\nexport function defaultConfig(): PiRulesConfig {\n\treturn {\n\t\tdisabled: false,\n\t\tmode: \"both\",\n\t\tmaxRuleChars: DEFAULT_MAX_RULE_CHARS,\n\t\tmaxResultChars: DEFAULT_MAX_RESULT_CHARS,\n\t\tenabledSources: \"auto\",\n\t};\n}\n\nexport function createEngine(config: PiRulesConfig, deps: EngineDeps): Engine {\n\tconst state = createSessionState();\n\tconst dynamicMatchCache: DynamicMatchCache = new Map();\n\n\tfunction loadStaticRules(cwd: string): { rules: LoadedRule[]; diagnostics: RuleDiagnostic[] } {\n\t\tstate.cwd = cwd;\n\t\tif (config.disabled || config.mode === \"off\" || config.mode === \"dynamic\") {\n\t\t\treturn emptyLoadResult(state);\n\t\t}\n\n\t\tconst projectRoot = deps.findProjectRoot(cwd);\n\t\tconst disabledSources = disabledSourcesFor(config);\n\t\tconst candidates = deps.findCandidates({\n\t\t\tprojectRoot,\n\t\t\ttargetFile: null,\n\t\t\t...(disabledSources === undefined ? {} : { disabledSources }),\n\t\t});\n\t\tconst realPathCache: RealPathCache = new Map();\n\t\tconst result = loadStaticCandidates(candidates, deps, projectRoot, realPathCache);\n\t\tstoreLastLoad(state, result.rules, result.diagnostics);\n\t\treturn result;\n\t}\n\n\tfunction loadDynamicRules(\n\t\tcwd: string,\n\t\ttargetPaths: ReadonlyArray<string>,\n\t): { rules: LoadedRule[]; diagnostics: RuleDiagnostic[] } {\n\t\tstate.cwd = cwd;\n\t\tif (config.disabled || config.mode === \"off\" || config.mode === \"static\" || targetPaths.length === 0) {\n\t\t\treturn emptyLoadResult(state);\n\t\t}\n\n\t\tconst targetFiles = uniqueStrings(targetPaths);\n\t\tconst shouldCacheLookups = targetFiles.length > 1;\n\t\tconst rules: LoadedRule[] = [];\n\t\tconst diagnostics: RuleDiagnostic[] = [];\n\t\tconst seenRules = new Set<string>();\n\t\tconst loadedRuleContent = new Map<string, LoadedRuleContent | null>();\n\t\tconst projectMembership = new Map<string, boolean>();\n\t\tconst disabledSources = disabledSourcesFor(config);\n\t\tconst discoveryCache = shouldCacheLookups ? createRuleDiscoveryCache() : undefined;\n\t\tconst candidateDiscoveryCache: CandidateDiscoveryCache = new Map();\n\t\tconst projectRootCache = new Map<string, string | null>();\n\t\tconst realPathCache: RealPathCache = new Map();\n\t\tfor (const targetFile of targetFiles) {\n\t\t\tconst projectRoot = shouldCacheLookups\n\t\t\t\t? findProjectRootCached(projectRootCache, targetFile, deps.findProjectRoot)\n\t\t\t\t: deps.findProjectRoot(targetFile);\n\t\t\tconst findOptions: Parameters<EngineDeps[\"findCandidates\"]>[0] = {\n\t\t\t\tprojectRoot,\n\t\t\t\ttargetFile,\n\t\t\t\t...(discoveryCache === undefined ? {} : { cache: discoveryCache }),\n\t\t\t\t...(disabledSources === undefined ? {} : { disabledSources }),\n\t\t\t};\n\t\t\tconst candidates = shouldCacheLookups\n\t\t\t\t? findSortedCandidatesCached(candidateDiscoveryCache, deps.findCandidates, findOptions)\n\t\t\t\t: sortCandidates(deps.findCandidates(findOptions));\n\n\t\t\tfor (const candidate of candidates) {\n\t\t\t\tconst loadedRule = loadCandidate(candidate, deps, diagnostics, projectRoot, {\n\t\t\t\t\tloadedRuleContent,\n\t\t\t\t\tprojectMembership,\n\t\t\t\t\trealPathCache,\n\t\t\t\t});\n\t\t\t\tif (loadedRule === null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst matchReason = matchDynamicRuleCached(\n\t\t\t\t\tdynamicMatchCache,\n\t\t\t\t\tprojectRoot,\n\t\t\t\t\ttargetFile,\n\t\t\t\t\tcandidate,\n\t\t\t\t\tloadedRule,\n\t\t\t\t\tdeps.matchRule ?? matchRule,\n\t\t\t\t);\n\n\t\t\t\tif (matchReason === null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst dedupKey = ruleDedupKey(loadedRule);\n\t\t\t\tif (seenRules.has(dedupKey)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tseenRules.add(dedupKey);\n\t\t\t\trules.push({ ...loadedRule, matchReason });\n\t\t\t}\n\t\t}\n\n\t\tconst sortedRules = sortCandidates(rules);\n\t\tstoreLastLoad(state, sortedRules, diagnostics);\n\t\treturn { rules: sortedRules, diagnostics };\n\t}\n\n\tfunction fingerprintDynamicTargets(cwd: string, targetPaths: ReadonlyArray<string>): DynamicTargetFingerprint[] {\n\t\tstate.cwd = cwd;\n\t\tif (config.disabled || config.mode === \"off\" || config.mode === \"static\" || targetPaths.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst fingerprintFn = deps.fileFingerprint ?? fileStatFingerprint;\n\t\tconst disabledSources = disabledSourcesFor(config);\n\t\tconst discoveryCache = createRuleDiscoveryCache();\n\t\tconst cwdProjectRoot = deps.findProjectRoot(cwd);\n\t\tconst fingerprints: DynamicTargetFingerprint[] = [];\n\n\t\tfor (const targetFile of uniqueStrings(targetPaths)) {\n\t\t\tconst projectRoot =\n\t\t\t\tcwdProjectRoot !== null && isSameOrChildPath(targetFile, cwdProjectRoot)\n\t\t\t\t\t? cwdProjectRoot\n\t\t\t\t\t: deps.findProjectRoot(targetFile);\n\t\t\tconst findOptions: Parameters<EngineDeps[\"findCandidates\"]>[0] = {\n\t\t\t\tprojectRoot,\n\t\t\t\ttargetFile,\n\t\t\t\tcache: discoveryCache,\n\t\t\t\t...(disabledSources === undefined ? {} : { disabledSources }),\n\t\t\t};\n\t\t\tconst candidates = sortCandidates(deps.findCandidates(findOptions));\n\t\t\tconst cacheKey = dynamicTargetCacheKey(targetFile);\n\t\t\tfingerprints.push({\n\t\t\t\ttargetPath: targetFile,\n\t\t\t\tcacheKey,\n\t\t\t\tfingerprint: computeDynamicTargetFingerprint(targetFile, projectRoot, candidates, config, fingerprintFn),\n\t\t\t});\n\t\t}\n\n\t\treturn fingerprints;\n\t}\n\n\tfunction commitDynamicTargetFingerprints(fingerprints: ReadonlyArray<DynamicTargetFingerprint>): void {\n\t\tfor (const target of fingerprints) {\n\t\t\tstate.dynamicTargetFingerprints.set(target.cacheKey, target.fingerprint);\n\t\t}\n\t}\n\n\tfunction isDynamicTargetFingerprintCurrent(target: DynamicTargetFingerprint): boolean {\n\t\treturn state.dynamicTargetFingerprints.get(target.cacheKey) === target.fingerprint;\n\t}\n\n\treturn {\n\t\tstate,\n\t\tconfig,\n\t\tloadStaticRules,\n\t\tloadDynamicRules,\n\t\tformatStatic: (rules) =>\n\t\t\tformatStaticBlock(rules, { maxRuleChars: config.maxRuleChars, maxResultChars: config.maxResultChars }),\n\t\tformatDynamic: (rules, target) =>\n\t\t\tformatDynamicBlock(rules, target, {\n\t\t\t\tmaxRuleChars: config.maxRuleChars,\n\t\t\t\tmaxResultChars: config.maxResultChars,\n\t\t\t}),\n\t\tresetSession: (cwd) => {\n\t\t\tclearSession(state);\n\t\t\tdynamicMatchCache.clear();\n\t\t\tif (cwd !== undefined) {\n\t\t\t\tstate.cwd = cwd;\n\t\t\t}\n\t\t},\n\t\tisStaticInjected: (rule) => isStaticInjectedInState(state, rule),\n\t\tisDynamicInjected: (scopeKey, rule) => isDynamicInjectedInState(state, scopeKey, rule),\n\t\tmarkStaticInjected: (rule) => markStaticInjectedInState(state, rule),\n\t\tmarkDynamicInjected: (scopeKey, rule) => markDynamicInjectedInState(state, scopeKey, rule),\n\t\tfingerprintDynamicTargets,\n\t\tisDynamicTargetFingerprintCurrent,\n\t\tcommitDynamicTargetFingerprints,\n\t};\n}\n\nfunction isSameOrChildPath(childPath: string, parentPath: string): boolean {\n\tconst childRelativePath = relative(parentPath, resolve(childPath));\n\treturn childRelativePath === \"\" || (!childRelativePath.startsWith(\"..\") && !isAbsolute(childRelativePath));\n}\n\nfunction matchDynamicRuleCached(\n\tcache: DynamicMatchCache,\n\tprojectRoot: string | null,\n\ttargetFile: string,\n\tcandidate: RuleCandidate,\n\tloadedRule: LoadedRule,\n\tmatchRuleImpl: typeof matchRule,\n): MatchReason | null {\n\tconst cacheKey = dynamicMatchCacheKey(projectRoot, targetFile, candidate, loadedRule.contentHash);\n\tif (cache.has(cacheKey)) {\n\t\tconst cachedReason = cache.get(cacheKey) ?? null;\n\t\tcache.delete(cacheKey);\n\t\tcache.set(cacheKey, cachedReason);\n\t\treturn cachedReason;\n\t}\n\n\tconst matchResult = matchRuleImpl({\n\t\tfrontmatter: loadedRule.frontmatter,\n\t\tisSingleFile: candidate.isSingleFile,\n\t\tpathBases: pathBasesForTarget(projectRoot, targetFile, candidate),\n\t});\n\tconst reason = matchResult.matched ? matchResult.reason : null;\n\tsetDynamicMatchCacheEntry(cache, cacheKey, reason);\n\treturn reason;\n}\n\nfunction setDynamicMatchCacheEntry(cache: DynamicMatchCache, cacheKey: string, reason: MatchReason | null): void {\n\tif (cache.size >= MAX_DYNAMIC_MATCH_CACHE_ENTRIES) {\n\t\tconst oldestCacheKey = cache.keys().next().value;\n\t\tif (oldestCacheKey !== undefined) {\n\t\t\tcache.delete(oldestCacheKey);\n\t\t}\n\t}\n\tcache.set(cacheKey, reason);\n}\n\nfunction dynamicMatchCacheKey(\n\tprojectRoot: string | null,\n\ttargetFile: string,\n\tcandidate: RuleCandidate,\n\tcontentHash: string,\n): string {\n\treturn [\n\t\tprojectRoot ?? \"\",\n\t\ttoPosixPath(resolve(targetFile)),\n\t\tcandidate.realPath,\n\t\tcandidate.relativePath,\n\t\tcandidate.source,\n\t\tcandidate.isGlobal ? \"global\" : \"project\",\n\t\tcandidate.isSingleFile ? \"single\" : \"multi\",\n\t\tString(candidate.distance),\n\t\tcontentHash,\n\t].join(\"\\0\");\n}\n\nfunction loadStaticCandidates(\n\tcandidates: ReadonlyArray<RuleCandidate>,\n\tdeps: EngineDeps,\n\tprojectRoot: string | null,\n\trealPathCache: RealPathCache,\n) {\n\tconst rules: LoadedRule[] = [];\n\tconst diagnostics: RuleDiagnostic[] = [];\n\tlet rootSingleFileSelected = false;\n\n\tfor (const candidate of sortCandidates(candidates)) {\n\t\tif (isDedupedRootSingleFile(candidate, rootSingleFileSelected)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst loadedRule = loadCandidate(candidate, deps, diagnostics, projectRoot, { realPathCache });\n\t\tif (loadedRule === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst matchReason = staticMatchReason(loadedRule);\n\t\tif (matchReason === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isRootSingleFile(candidate)) {\n\t\t\trootSingleFileSelected = true;\n\t\t}\n\n\t\trules.push({ ...loadedRule, matchReason });\n\t}\n\n\treturn { rules: sortCandidates(rules), diagnostics };\n}\n\nfunction loadCandidate(\n\tcandidate: RuleCandidate,\n\tdeps: EngineDeps,\n\tdiagnostics: RuleDiagnostic[],\n\tprojectRoot: string | null,\n\tcaches: LoadCandidateCaches,\n): (LoadedRule & { matchReason: MatchReason }) | null {\n\tif (!isCandidateWithinProjectCached(candidate, projectRoot, caches.projectMembership, caches.realPathCache)) {\n\t\tdiagnostics.push({\n\t\t\tseverity: \"warning\",\n\t\t\tsource: candidate.path,\n\t\t\tmessage: \"Rule file resolves outside project root\",\n\t\t});\n\t\treturn null;\n\t}\n\n\tconst cachedContent = caches.loadedRuleContent?.get(candidate.realPath);\n\tif (cachedContent !== undefined) {\n\t\treturn loadedRuleFromContent(candidate, cachedContent, diagnostics);\n\t}\n\n\tconst content = deps.readFile(candidate.path);\n\tif (content === null) {\n\t\tcaches.loadedRuleContent?.set(candidate.realPath, null);\n\t\tdiagnostics.push({ severity: \"warning\", source: candidate.path, message: \"Unable to read rule file\" });\n\t\treturn null;\n\t}\n\n\tconst parsed = parseRule(content);\n\tconst loadedContent: LoadedRuleContent = {\n\t\tfrontmatter: parsed.frontmatter,\n\t\tbody: parsed.body,\n\t\tcontentHash: hashContent(content),\n\t};\n\tif (parsed.diagnostic !== undefined) loadedContent.diagnostic = parsed.diagnostic;\n\tcaches.loadedRuleContent?.set(candidate.realPath, loadedContent);\n\treturn loadedRuleFromContent(candidate, loadedContent, diagnostics);\n}\n\nfunction loadedRuleFromContent(\n\tcandidate: RuleCandidate,\n\tcontent: LoadedRuleContent | null,\n\tdiagnostics: RuleDiagnostic[],\n): (LoadedRule & { matchReason: MatchReason }) | null {\n\tif (content === null) {\n\t\tdiagnostics.push({ severity: \"warning\", source: candidate.path, message: \"Unable to read rule file\" });\n\t\treturn null;\n\t}\n\n\tif (content.diagnostic !== undefined) {\n\t\tdiagnostics.push({ severity: \"warning\", source: candidate.path, message: content.diagnostic });\n\t}\n\n\treturn {\n\t\t...candidate,\n\t\tfrontmatter: content.frontmatter,\n\t\tbody: content.body,\n\t\tcontentHash: content.contentHash,\n\t\tmatchReason: { kind: \"no-match\" },\n\t};\n}\n\nfunction ruleDedupKey(rule: LoadedRule): string {\n\treturn `${rule.realPath}::${rule.contentHash}`;\n}\n\nfunction isCandidateWithinProject(\n\tcandidate: RuleCandidate,\n\tprojectRoot: string | null,\n\trealPathCache: RealPathCache | undefined,\n): boolean {\n\tif (candidate.isGlobal) {\n\t\treturn true;\n\t}\n\n\tif (projectRoot === null) {\n\t\treturn false;\n\t}\n\n\tconst relativeRealPath = relative(realPathOrResolved(projectRoot, realPathCache), resolve(candidate.realPath));\n\treturn relativeRealPath === \"\" || (!relativeRealPath.startsWith(\"..\") && !isAbsolute(relativeRealPath));\n}\n\nfunction realPathOrResolved(path: string, cache: RealPathCache | undefined): string {\n\tconst cached = cache?.get(path);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\ttry {\n\t\tconst realPath = realpathSync.native(path);\n\t\tcache?.set(path, realPath);\n\t\treturn realPath;\n\t} catch {\n\t\tconst resolvedPath = resolve(path);\n\t\tcache?.set(path, resolvedPath);\n\t\treturn resolvedPath;\n\t}\n}\n\nfunction isCandidateWithinProjectCached(\n\tcandidate: RuleCandidate,\n\tprojectRoot: string | null,\n\tprojectMembership: CandidateProjectMembership | undefined,\n\trealPathCache: RealPathCache | undefined,\n): boolean {\n\tif (projectMembership === undefined) {\n\t\treturn isCandidateWithinProject(candidate, projectRoot, realPathCache);\n\t}\n\n\tconst cacheKey = `${projectRoot ?? \"\"}\\0${candidate.realPath}`;\n\tconst cached = projectMembership.get(cacheKey);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst isWithinProject = isCandidateWithinProject(candidate, projectRoot, realPathCache);\n\tprojectMembership.set(cacheKey, isWithinProject);\n\treturn isWithinProject;\n}\n\nfunction findSortedCandidatesCached(\n\tcache: CandidateDiscoveryCache,\n\tfindCandidates: EngineDeps[\"findCandidates\"],\n\toptions: Parameters<EngineDeps[\"findCandidates\"]>[0],\n): RuleCandidate[] {\n\tconst cacheKey = candidateDiscoveryCacheKey(options);\n\tconst cached = cache.get(cacheKey);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst candidates = sortCandidates(findCandidates(options));\n\tcache.set(cacheKey, candidates);\n\treturn candidates;\n}\n\nfunction candidateDiscoveryCacheKey(options: Parameters<EngineDeps[\"findCandidates\"]>[0]): string {\n\treturn [\n\t\toptions.projectRoot ?? \"\",\n\t\toptions.targetFile === null ? \"\" : dirname(resolve(options.targetFile)),\n\t\t...[...(options.disabledSources ?? [])].sort(),\n\t].join(\"\\0\");\n}\n\nfunction findProjectRootCached(\n\tcache: Map<string, string | null>,\n\ttargetFile: string,\n\tfindProjectRoot: EngineDeps[\"findProjectRoot\"],\n): string | null {\n\tconst cacheKey = dirname(resolve(targetFile));\n\tif (cache.has(cacheKey)) {\n\t\treturn cache.get(cacheKey) ?? null;\n\t}\n\n\tconst projectRoot = findProjectRoot(targetFile);\n\tcache.set(cacheKey, projectRoot);\n\treturn projectRoot;\n}\n\nfunction staticMatchReason(rule: LoadedRule): MatchReason | null {\n\tif (rule.frontmatter.alwaysApply === true) {\n\t\treturn \"alwaysApply\";\n\t}\n\n\tif (rule.isSingleFile) {\n\t\treturn \"single-file\";\n\t}\n\n\treturn null;\n}\n\nfunction disabledSourcesFor(config: PiRulesConfig): ReadonlySet<string> | undefined {\n\tif (config.enabledSources === \"auto\") {\n\t\treturn undefined;\n\t}\n\n\tconst enabledSources = new Set(config.enabledSources);\n\treturn new Set([...SOURCE_PRIORITY.keys()].filter((source) => !enabledSources.has(source)));\n}\n\nfunction isDedupedRootSingleFile(candidate: RuleCandidate, rootSingleFileSelected: boolean): boolean {\n\treturn rootSingleFileSelected && isRootSingleFile(candidate);\n}\n\nfunction isRootSingleFile(candidate: RuleCandidate): boolean {\n\treturn candidate.distance === 0 && candidate.isSingleFile && ROOT_SINGLE_FILE_SOURCES.has(candidate.source);\n}\n\nfunction pathBasesForTarget(\n\tprojectRoot: string | null,\n\ttargetFile: string,\n\tcandidate: RuleCandidate,\n): { projectRelative: string; scopeRelative?: string; basename: string } {\n\tconst targetBasename = basename(targetFile);\n\tif (projectRoot === null) {\n\t\treturn { projectRelative: targetBasename, basename: targetBasename };\n\t}\n\n\tconst projectRelative = toPosixPath(relative(projectRoot, targetFile));\n\tconst scopeDirectory = scopeDirectoryForCandidate(projectRoot, candidate);\n\tif (scopeDirectory === null) {\n\t\treturn { projectRelative, basename: targetBasename };\n\t}\n\n\treturn {\n\t\tprojectRelative,\n\t\tscopeRelative: toPosixPath(relative(scopeDirectory, targetFile)),\n\t\tbasename: targetBasename,\n\t};\n}\n\nfunction scopeDirectoryForCandidate(projectRoot: string, candidate: RuleCandidate): string | null {\n\tif (candidate.isGlobal) {\n\t\treturn null;\n\t}\n\n\tif (candidate.isSingleFile) {\n\t\treturn dirname(candidate.path);\n\t}\n\n\tconst sourceIndex = candidate.relativePath.indexOf(candidate.source);\n\tif (sourceIndex === -1) {\n\t\treturn projectRoot;\n\t}\n\n\tconst scopeRelativeDirectory = candidate.relativePath.slice(0, sourceIndex).replace(/\\/$/, \"\");\n\treturn scopeRelativeDirectory.length === 0 ? projectRoot : join(projectRoot, scopeRelativeDirectory);\n}\n\nfunction toPosixPath(path: string): string {\n\treturn path.replaceAll(\"\\\\\", \"/\");\n}\n\nfunction dynamicTargetCacheKey(targetFile: string): string {\n\treturn toPosixPath(resolve(targetFile));\n}\n\nfunction computeDynamicTargetFingerprint(\n\ttargetFile: string,\n\tprojectRoot: string | null,\n\tcandidates: ReadonlyArray<RuleCandidate>,\n\tconfig: PiRulesConfig,\n\tfileFingerprintFn: (filePath: string) => string,\n): string {\n\tconst candidateFingerprint = candidates\n\t\t.map((candidate) => fingerprintCandidate(candidate, fileFingerprintFn))\n\t\t.join(\"\\u0001\");\n\treturn hashContent(\n\t\t[\n\t\t\t\"v1\",\n\t\t\tconfig.enabledSources === \"auto\" ? \"auto\" : config.enabledSources.join(\",\"),\n\t\t\tprojectRoot ?? \"\",\n\t\t\tdynamicTargetCacheKey(targetFile),\n\t\t\tcandidateFingerprint,\n\t\t].join(\"\\u0000\"),\n\t);\n}\n\nfunction fingerprintCandidate(candidate: RuleCandidate, fileFingerprintFn: (filePath: string) => string): string {\n\treturn [\n\t\tcandidate.realPath,\n\t\tcandidate.relativePath,\n\t\tcandidate.source,\n\t\tcandidate.isGlobal ? \"global\" : \"project\",\n\t\tcandidate.isSingleFile ? \"single\" : \"multi\",\n\t\tString(candidate.distance),\n\t\tfileFingerprintFn(candidate.path),\n\t].join(\"\\u0000\");\n}\n\nfunction fileStatFingerprint(filePath: string): string {\n\ttry {\n\t\tconst stats = statSync(filePath, { bigint: true });\n\t\treturn `${stats.mtimeNs}:${stats.ctimeNs}:${stats.size}`;\n\t} catch {\n\t\treturn \"missing\";\n\t}\n}\n\nfunction uniqueStrings(values: ReadonlyArray<string>): string[] {\n\treturn [...new Set(values)];\n}\n\nfunction storeLastLoad(\n\tstate: SessionState,\n\trules: ReadonlyArray<LoadedRule>,\n\tdiagnostics: ReadonlyArray<RuleDiagnostic>,\n): void {\n\tstate.loadedRules.length = 0;\n\tstate.loadedRules.push(...rules);\n\tstate.diagnostics.length = 0;\n\tstate.diagnostics.push(...diagnostics);\n}\n\nfunction emptyLoadResult(state: SessionState): { rules: LoadedRule[]; diagnostics: RuleDiagnostic[] } {\n\tstoreLastLoad(state, [], []);\n\treturn { rules: [], diagnostics: [] };\n}\n"]}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/engine.ts"],"names":[],"mappings":"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","sourcesContent":["import { realpathSync, statSync } from \"node:fs\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"node:path\";\n\nimport type { ToolResultEvent } from \"../../../types.ts\";\n\nimport {\n\tclearSession,\n\tcreateSessionState,\n\tisDynamicInjected as isDynamicInjectedInState,\n\tisStaticInjected as isStaticInjectedInState,\n\tmarkDynamicInjected as markDynamicInjectedInState,\n\tmarkStaticInjected as markStaticInjectedInState,\n} from \"./cache.ts\";\nimport {\n\tDEFAULT_MAX_RESULT_CHARS,\n\tDEFAULT_MAX_RULE_CHARS,\n\tPROJECT_SINGLE_FILES,\n\tSOURCE_PRIORITY,\n} from \"./constants.ts\";\nimport { createRuleDiscoveryCache, type RuleDiscoveryCache } from \"./finder.ts\";\nimport { formatDynamicBlock, formatStaticBlock } from \"./formatter.ts\";\nimport { hashContent, matchRule } from \"./matcher.ts\";\nimport { sortCandidates } from \"./ordering.ts\";\nimport { parseRule } from \"./parser.ts\";\nimport { widenToRepositoryRoot } from \"./project-root.ts\";\nimport type { LoadedRule, MatchReason, PiRulesConfig, RuleCandidate, RuleDiagnostic, SessionState } from \"./types.ts\";\n\ninterface LoadedRuleContent {\n\tfrontmatter: LoadedRule[\"frontmatter\"];\n\tbody: string;\n\tcontentHash: string;\n\tdiagnostic?: string;\n}\n\ninterface LoadCandidateCaches {\n\treadonly loadedRuleContent?: Map<string, LoadedRuleContent | null>;\n\treadonly projectMembership?: CandidateProjectMembership;\n\treadonly realPathCache?: RealPathCache;\n}\n\ntype CandidateProjectMembership = Map<string, boolean>;\ntype CandidateDiscoveryCache = Map<string, RuleCandidate[]>;\ntype DynamicMatchCache = Map<string, MatchReason | null>;\ntype RealPathCache = Map<string, string>;\n\nconst MAX_DYNAMIC_MATCH_CACHE_ENTRIES = 4096;\n\nexport interface EngineDeps {\n\tfindCandidates: (options: {\n\t\tprojectRoot: string | null;\n\t\ttargetFile: string | null;\n\t\thomeDir?: string;\n\t\tdisabledSources?: ReadonlySet<string>;\n\t\tskipUserHome?: boolean;\n\t\tcache?: RuleDiscoveryCache;\n\t}) => RuleCandidate[];\n\treadFile: (path: string) => string | null;\n\tfindProjectRoot: (startPath: string) => string | null;\n\textractToolPaths: (event: ToolResultEvent, cwd: string) => string[];\n\tmatchRule?: typeof matchRule;\n\t/**\n\t * Returns a stable identifier for a rule file. Default uses `statSync` mtime/ctime/size.\n\t * Tests may inject a content-based fingerprint when fixtures use synthetic paths.\n\t */\n\tfileFingerprint?: (filePath: string) => string;\n}\n\nexport interface DynamicTargetFingerprint {\n\ttargetPath: string;\n\tcacheKey: string;\n\tfingerprint: string;\n}\n\nexport interface Engine {\n\tstate: SessionState;\n\tconfig: PiRulesConfig;\n\tloadStaticRules(cwd: string): { rules: LoadedRule[]; diagnostics: RuleDiagnostic[] };\n\tloadDynamicRules(\n\t\tcwd: string,\n\t\ttargetPaths: ReadonlyArray<string>,\n\t): { rules: LoadedRule[]; diagnostics: RuleDiagnostic[] };\n\tformatStatic(rules: ReadonlyArray<LoadedRule>): string;\n\tformatDynamic(rules: ReadonlyArray<LoadedRule>, target: string): string;\n\tresetSession(cwd?: string): void;\n\tisStaticInjected(rule: LoadedRule): boolean;\n\tisDynamicInjected(scopeKey: string, rule: LoadedRule): boolean;\n\tmarkStaticInjected(rule: LoadedRule): boolean;\n\tmarkDynamicInjected(scopeKey: string, rule: LoadedRule): boolean;\n\t/**\n\t * Computes a fingerprint for each unique target derived from its discovered\n\t * candidates plus their on-disk fingerprints. Pure - does not mutate state.\n\t */\n\tfingerprintDynamicTargets(cwd: string, targetPaths: ReadonlyArray<string>): DynamicTargetFingerprint[];\n\t/**\n\t * Returns true when the fingerprint for a target already matches the value\n\t * stored on `state.dynamicTargetFingerprints`. The hook layer skips\n\t * `loadDynamicRules` entirely when every target is current.\n\t */\n\tisDynamicTargetFingerprintCurrent(target: DynamicTargetFingerprint): boolean;\n\t/**\n\t * Commits the supplied fingerprints to `state.dynamicTargetFingerprints`.\n\t * Always pass every fingerprint observed during a hook invocation so the\n\t * map mirrors the latest discovery.\n\t */\n\tcommitDynamicTargetFingerprints(fingerprints: ReadonlyArray<DynamicTargetFingerprint>): void;\n}\n\nconst ROOT_SINGLE_FILE_SOURCES = new Set(PROJECT_SINGLE_FILES.filter((source) => !source.includes(\"/\")));\n\nexport function defaultConfig(): PiRulesConfig {\n\treturn {\n\t\tdisabled: false,\n\t\tmode: \"both\",\n\t\tmaxRuleChars: DEFAULT_MAX_RULE_CHARS,\n\t\tmaxResultChars: DEFAULT_MAX_RESULT_CHARS,\n\t\tenabledSources: \"auto\",\n\t};\n}\n\nexport function createEngine(config: PiRulesConfig, deps: EngineDeps): Engine {\n\tconst state = createSessionState();\n\tconst dynamicMatchCache: DynamicMatchCache = new Map();\n\n\tfunction loadStaticRules(cwd: string): { rules: LoadedRule[]; diagnostics: RuleDiagnostic[] } {\n\t\tstate.cwd = cwd;\n\t\tif (config.disabled || config.mode === \"off\" || config.mode === \"dynamic\") {\n\t\t\treturn emptyLoadResult(state);\n\t\t}\n\n\t\tconst projectRoot = deps.findProjectRoot(cwd);\n\t\tconst disabledSources = disabledSourcesFor(config);\n\t\tconst candidates = deps.findCandidates({\n\t\t\tprojectRoot,\n\t\t\ttargetFile: null,\n\t\t\t...(disabledSources === undefined ? {} : { disabledSources }),\n\t\t});\n\t\tconst realPathCache: RealPathCache = new Map();\n\t\tconst result = loadStaticCandidates(candidates, deps, projectRoot, realPathCache);\n\t\tstoreLastLoad(state, result.rules, result.diagnostics);\n\t\treturn result;\n\t}\n\n\tfunction loadDynamicRules(\n\t\tcwd: string,\n\t\ttargetPaths: ReadonlyArray<string>,\n\t): { rules: LoadedRule[]; diagnostics: RuleDiagnostic[] } {\n\t\tstate.cwd = cwd;\n\t\tif (config.disabled || config.mode === \"off\" || config.mode === \"static\" || targetPaths.length === 0) {\n\t\t\treturn emptyLoadResult(state);\n\t\t}\n\n\t\tconst targetFiles = uniqueStrings(targetPaths);\n\t\tconst shouldCacheLookups = targetFiles.length > 1;\n\t\tconst rules: LoadedRule[] = [];\n\t\tconst diagnostics: RuleDiagnostic[] = [];\n\t\tconst seenRules = new Set<string>();\n\t\tconst loadedRuleContent = new Map<string, LoadedRuleContent | null>();\n\t\tconst projectMembership = new Map<string, boolean>();\n\t\tconst disabledSources = disabledSourcesFor(config);\n\t\tconst discoveryCache = shouldCacheLookups ? createRuleDiscoveryCache() : undefined;\n\t\tconst candidateDiscoveryCache: CandidateDiscoveryCache = new Map();\n\t\tconst projectRootCache = new Map<string, string | null>();\n\t\tconst realPathCache: RealPathCache = new Map();\n\t\tconst rootSingleFileSelections = new Set<string>();\n\t\tfor (const targetFile of targetFiles) {\n\t\t\t// Cargo/pnpm workspaces nest project markers (e.g. a per-member Cargo.toml), so the\n\t\t\t// marker-based root would stop the walk below workspace-level rule directories.\n\t\t\t// Widen to the enclosing git repository root so rules at repository and workspace\n\t\t\t// level participate; scopeRelative keeps globs keyed to the rule file's scope.\n\t\t\t// Canonicalize so macOS /var vs /private/var (and other symlink roots) still sit\n\t\t\t// inside the realpathed project root used by findProjectRoot.\n\t\t\tconst discoveryTarget = canonicalizePath(targetFile);\n\t\t\tconst projectRoot = widenToRepositoryRoot(\n\t\t\t\tshouldCacheLookups\n\t\t\t\t\t? findProjectRootCached(projectRootCache, discoveryTarget, deps.findProjectRoot)\n\t\t\t\t\t: deps.findProjectRoot(discoveryTarget),\n\t\t\t);\n\t\t\tconst findOptions: Parameters<EngineDeps[\"findCandidates\"]>[0] = {\n\t\t\t\tprojectRoot,\n\t\t\t\ttargetFile: discoveryTarget,\n\t\t\t\t...(discoveryCache === undefined ? {} : { cache: discoveryCache }),\n\t\t\t\t...(disabledSources === undefined ? {} : { disabledSources }),\n\t\t\t};\n\t\t\tconst candidates = shouldCacheLookups\n\t\t\t\t? findSortedCandidatesCached(candidateDiscoveryCache, deps.findCandidates, findOptions)\n\t\t\t\t: sortCandidates(deps.findCandidates(findOptions));\n\n\t\t\tfor (const candidate of candidates) {\n\t\t\t\tconst rootSingleFileSelectionKey = rootSingleFileSelectionKeyFor(candidate, projectRoot);\n\t\t\t\tif (rootSingleFileSelectionKey !== null && rootSingleFileSelections.has(rootSingleFileSelectionKey)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst loadedRule = loadCandidate(candidate, deps, diagnostics, projectRoot, {\n\t\t\t\t\tloadedRuleContent,\n\t\t\t\t\tprojectMembership,\n\t\t\t\t\trealPathCache,\n\t\t\t\t});\n\t\t\t\tif (loadedRule === null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst matchReason = matchDynamicRuleCached(\n\t\t\t\t\tdynamicMatchCache,\n\t\t\t\t\tprojectRoot,\n\t\t\t\t\tdiscoveryTarget,\n\t\t\t\t\tcandidate,\n\t\t\t\t\tloadedRule,\n\t\t\t\t\tdeps.matchRule ?? matchRule,\n\t\t\t\t);\n\n\t\t\t\tif (matchReason === null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (rootSingleFileSelectionKey !== null) {\n\t\t\t\t\trootSingleFileSelections.add(rootSingleFileSelectionKey);\n\t\t\t\t}\n\n\t\t\t\tconst dedupKey = ruleDedupKey(loadedRule);\n\t\t\t\tif (seenRules.has(dedupKey)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tseenRules.add(dedupKey);\n\t\t\t\trules.push({ ...loadedRule, matchReason });\n\t\t\t}\n\t\t}\n\n\t\tconst sortedRules = sortCandidates(rules);\n\t\tstoreLastLoad(state, sortedRules, diagnostics);\n\t\treturn { rules: sortedRules, diagnostics };\n\t}\n\n\tfunction fingerprintDynamicTargets(cwd: string, targetPaths: ReadonlyArray<string>): DynamicTargetFingerprint[] {\n\t\tstate.cwd = cwd;\n\t\tif (config.disabled || config.mode === \"off\" || config.mode === \"static\" || targetPaths.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst fingerprintFn = deps.fileFingerprint ?? fileStatFingerprint;\n\t\tconst disabledSources = disabledSourcesFor(config);\n\t\tconst discoveryCache = createRuleDiscoveryCache();\n\t\tconst cwdProjectRoot = deps.findProjectRoot(cwd);\n\t\tconst fingerprints: DynamicTargetFingerprint[] = [];\n\n\t\tfor (const targetFile of uniqueStrings(targetPaths)) {\n\t\t\tconst discoveryTarget = canonicalizePath(targetFile);\n\t\t\tconst projectRoot = widenToRepositoryRoot(\n\t\t\t\tcwdProjectRoot !== null && isSameOrChildPath(discoveryTarget, cwdProjectRoot)\n\t\t\t\t\t? cwdProjectRoot\n\t\t\t\t\t: deps.findProjectRoot(discoveryTarget),\n\t\t\t);\n\t\t\tconst findOptions: Parameters<EngineDeps[\"findCandidates\"]>[0] = {\n\t\t\t\tprojectRoot,\n\t\t\t\ttargetFile: discoveryTarget,\n\t\t\t\tcache: discoveryCache,\n\t\t\t\t...(disabledSources === undefined ? {} : { disabledSources }),\n\t\t\t};\n\t\t\tconst candidates = sortCandidates(deps.findCandidates(findOptions));\n\t\t\tconst cacheKey = dynamicTargetCacheKey(targetFile);\n\t\t\tfingerprints.push({\n\t\t\t\ttargetPath: targetFile,\n\t\t\t\tcacheKey,\n\t\t\t\tfingerprint: computeDynamicTargetFingerprint(targetFile, projectRoot, candidates, config, fingerprintFn),\n\t\t\t});\n\t\t}\n\n\t\treturn fingerprints;\n\t}\n\n\tfunction commitDynamicTargetFingerprints(fingerprints: ReadonlyArray<DynamicTargetFingerprint>): void {\n\t\tfor (const target of fingerprints) {\n\t\t\tstate.dynamicTargetFingerprints.set(target.cacheKey, target.fingerprint);\n\t\t}\n\t}\n\n\tfunction isDynamicTargetFingerprintCurrent(target: DynamicTargetFingerprint): boolean {\n\t\treturn state.dynamicTargetFingerprints.get(target.cacheKey) === target.fingerprint;\n\t}\n\n\treturn {\n\t\tstate,\n\t\tconfig,\n\t\tloadStaticRules,\n\t\tloadDynamicRules,\n\t\tformatStatic: (rules) =>\n\t\t\tformatStaticBlock(rules, { maxRuleChars: config.maxRuleChars, maxResultChars: config.maxResultChars }),\n\t\tformatDynamic: (rules, target) =>\n\t\t\tformatDynamicBlock(rules, target, {\n\t\t\t\tmaxRuleChars: config.maxRuleChars,\n\t\t\t\tmaxResultChars: config.maxResultChars,\n\t\t\t}),\n\t\tresetSession: (cwd) => {\n\t\t\tclearSession(state);\n\t\t\tdynamicMatchCache.clear();\n\t\t\tif (cwd !== undefined) {\n\t\t\t\tstate.cwd = cwd;\n\t\t\t}\n\t\t},\n\t\tisStaticInjected: (rule) => isStaticInjectedInState(state, rule),\n\t\tisDynamicInjected: (scopeKey, rule) => isDynamicInjectedInState(state, scopeKey, rule),\n\t\tmarkStaticInjected: (rule) => markStaticInjectedInState(state, rule),\n\t\tmarkDynamicInjected: (scopeKey, rule) => markDynamicInjectedInState(state, scopeKey, rule),\n\t\tfingerprintDynamicTargets,\n\t\tisDynamicTargetFingerprintCurrent,\n\t\tcommitDynamicTargetFingerprints,\n\t};\n}\n\nfunction isSameOrChildPath(childPath: string, parentPath: string): boolean {\n\tconst childRelativePath = relative(parentPath, resolve(childPath));\n\treturn childRelativePath === \"\" || (!childRelativePath.startsWith(\"..\") && !isAbsolute(childRelativePath));\n}\n\nfunction matchDynamicRuleCached(\n\tcache: DynamicMatchCache,\n\tprojectRoot: string | null,\n\ttargetFile: string,\n\tcandidate: RuleCandidate,\n\tloadedRule: LoadedRule,\n\tmatchRuleImpl: typeof matchRule,\n): MatchReason | null {\n\tconst cacheKey = dynamicMatchCacheKey(projectRoot, targetFile, candidate, loadedRule.contentHash);\n\tif (cache.has(cacheKey)) {\n\t\tconst cachedReason = cache.get(cacheKey) ?? null;\n\t\tcache.delete(cacheKey);\n\t\tcache.set(cacheKey, cachedReason);\n\t\treturn cachedReason;\n\t}\n\n\tconst matchResult = matchRuleImpl({\n\t\tfrontmatter: loadedRule.frontmatter,\n\t\tisSingleFile: candidate.isSingleFile,\n\t\tpathBases: pathBasesForTarget(projectRoot, targetFile, candidate),\n\t});\n\tconst reason = matchResult.matched ? matchResult.reason : null;\n\tsetDynamicMatchCacheEntry(cache, cacheKey, reason);\n\treturn reason;\n}\n\nfunction setDynamicMatchCacheEntry(cache: DynamicMatchCache, cacheKey: string, reason: MatchReason | null): void {\n\tif (cache.size >= MAX_DYNAMIC_MATCH_CACHE_ENTRIES) {\n\t\tconst oldestCacheKey = cache.keys().next().value;\n\t\tif (oldestCacheKey !== undefined) {\n\t\t\tcache.delete(oldestCacheKey);\n\t\t}\n\t}\n\tcache.set(cacheKey, reason);\n}\n\nfunction dynamicMatchCacheKey(\n\tprojectRoot: string | null,\n\ttargetFile: string,\n\tcandidate: RuleCandidate,\n\tcontentHash: string,\n): string {\n\treturn [\n\t\tprojectRoot ?? \"\",\n\t\ttoPosixPath(resolve(targetFile)),\n\t\tcandidate.realPath,\n\t\tcandidate.relativePath,\n\t\tcandidate.source,\n\t\tcandidate.isGlobal ? \"global\" : \"project\",\n\t\tcandidate.isSingleFile ? \"single\" : \"multi\",\n\t\tString(candidate.distance),\n\t\tcontentHash,\n\t].join(\"\\0\");\n}\n\nfunction loadStaticCandidates(\n\tcandidates: ReadonlyArray<RuleCandidate>,\n\tdeps: EngineDeps,\n\tprojectRoot: string | null,\n\trealPathCache: RealPathCache,\n) {\n\tconst rules: LoadedRule[] = [];\n\tconst diagnostics: RuleDiagnostic[] = [];\n\tlet rootSingleFileSelected = false;\n\n\tfor (const candidate of sortCandidates(candidates)) {\n\t\tif (isDedupedRootSingleFile(candidate, rootSingleFileSelected)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst loadedRule = loadCandidate(candidate, deps, diagnostics, projectRoot, { realPathCache });\n\t\tif (loadedRule === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst matchReason = staticMatchReason(loadedRule);\n\t\tif (matchReason === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isRootSingleFile(candidate)) {\n\t\t\trootSingleFileSelected = true;\n\t\t}\n\n\t\trules.push({ ...loadedRule, matchReason });\n\t}\n\n\treturn { rules: sortCandidates(rules), diagnostics };\n}\n\nfunction loadCandidate(\n\tcandidate: RuleCandidate,\n\tdeps: EngineDeps,\n\tdiagnostics: RuleDiagnostic[],\n\tprojectRoot: string | null,\n\tcaches: LoadCandidateCaches,\n): (LoadedRule & { matchReason: MatchReason }) | null {\n\tif (!isCandidateWithinProjectCached(candidate, projectRoot, caches.projectMembership, caches.realPathCache)) {\n\t\tdiagnostics.push({\n\t\t\tseverity: \"warning\",\n\t\t\tsource: candidate.path,\n\t\t\tmessage: \"Rule file resolves outside project root\",\n\t\t});\n\t\treturn null;\n\t}\n\n\tconst cachedContent = caches.loadedRuleContent?.get(candidate.realPath);\n\tif (cachedContent !== undefined) {\n\t\treturn loadedRuleFromContent(candidate, cachedContent, diagnostics);\n\t}\n\n\tconst content = deps.readFile(candidate.path);\n\tif (content === null) {\n\t\tcaches.loadedRuleContent?.set(candidate.realPath, null);\n\t\tdiagnostics.push({ severity: \"warning\", source: candidate.path, message: \"Unable to read rule file\" });\n\t\treturn null;\n\t}\n\n\tconst parsed = parseRule(content);\n\tconst loadedContent: LoadedRuleContent = {\n\t\tfrontmatter: parsed.frontmatter,\n\t\tbody: parsed.body,\n\t\tcontentHash: hashContent(content),\n\t};\n\tif (parsed.diagnostic !== undefined) loadedContent.diagnostic = parsed.diagnostic;\n\tcaches.loadedRuleContent?.set(candidate.realPath, loadedContent);\n\treturn loadedRuleFromContent(candidate, loadedContent, diagnostics);\n}\n\nfunction loadedRuleFromContent(\n\tcandidate: RuleCandidate,\n\tcontent: LoadedRuleContent | null,\n\tdiagnostics: RuleDiagnostic[],\n): (LoadedRule & { matchReason: MatchReason }) | null {\n\tif (content === null) {\n\t\tdiagnostics.push({ severity: \"warning\", source: candidate.path, message: \"Unable to read rule file\" });\n\t\treturn null;\n\t}\n\n\tif (content.diagnostic !== undefined) {\n\t\tdiagnostics.push({ severity: \"warning\", source: candidate.path, message: content.diagnostic });\n\t}\n\n\treturn {\n\t\t...candidate,\n\t\tfrontmatter: content.frontmatter,\n\t\tbody: content.body,\n\t\tcontentHash: content.contentHash,\n\t\tmatchReason: { kind: \"no-match\" },\n\t};\n}\n\nfunction ruleDedupKey(rule: LoadedRule): string {\n\treturn `${rule.realPath}::${rule.contentHash}`;\n}\n\nfunction isCandidateWithinProject(\n\tcandidate: RuleCandidate,\n\tprojectRoot: string | null,\n\trealPathCache: RealPathCache | undefined,\n): boolean {\n\tif (candidate.isGlobal) {\n\t\treturn true;\n\t}\n\n\tif (projectRoot === null) {\n\t\treturn false;\n\t}\n\n\tconst relativeRealPath = relative(realPathOrResolved(projectRoot, realPathCache), resolve(candidate.realPath));\n\treturn relativeRealPath === \"\" || (!relativeRealPath.startsWith(\"..\") && !isAbsolute(relativeRealPath));\n}\n\nfunction realPathOrResolved(path: string, cache: RealPathCache | undefined): string {\n\tconst cached = cache?.get(path);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\ttry {\n\t\tconst realPath = realpathSync.native(path);\n\t\tcache?.set(path, realPath);\n\t\treturn realPath;\n\t} catch {\n\t\tconst resolvedPath = resolve(path);\n\t\tcache?.set(path, resolvedPath);\n\t\treturn resolvedPath;\n\t}\n}\n\nfunction isCandidateWithinProjectCached(\n\tcandidate: RuleCandidate,\n\tprojectRoot: string | null,\n\tprojectMembership: CandidateProjectMembership | undefined,\n\trealPathCache: RealPathCache | undefined,\n): boolean {\n\tif (projectMembership === undefined) {\n\t\treturn isCandidateWithinProject(candidate, projectRoot, realPathCache);\n\t}\n\n\tconst cacheKey = `${projectRoot ?? \"\"}\\0${candidate.realPath}`;\n\tconst cached = projectMembership.get(cacheKey);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst isWithinProject = isCandidateWithinProject(candidate, projectRoot, realPathCache);\n\tprojectMembership.set(cacheKey, isWithinProject);\n\treturn isWithinProject;\n}\n\nfunction findSortedCandidatesCached(\n\tcache: CandidateDiscoveryCache,\n\tfindCandidates: EngineDeps[\"findCandidates\"],\n\toptions: Parameters<EngineDeps[\"findCandidates\"]>[0],\n): RuleCandidate[] {\n\tconst cacheKey = candidateDiscoveryCacheKey(options);\n\tconst cached = cache.get(cacheKey);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst candidates = sortCandidates(findCandidates(options));\n\tcache.set(cacheKey, candidates);\n\treturn candidates;\n}\n\nfunction candidateDiscoveryCacheKey(options: Parameters<EngineDeps[\"findCandidates\"]>[0]): string {\n\treturn [\n\t\toptions.projectRoot ?? \"\",\n\t\toptions.targetFile === null ? \"\" : dirname(resolve(options.targetFile)),\n\t\t...[...(options.disabledSources ?? [])].sort(),\n\t].join(\"\\0\");\n}\n\nfunction findProjectRootCached(\n\tcache: Map<string, string | null>,\n\ttargetFile: string,\n\tfindProjectRoot: EngineDeps[\"findProjectRoot\"],\n): string | null {\n\tconst cacheKey = dirname(resolve(targetFile));\n\tif (cache.has(cacheKey)) {\n\t\treturn cache.get(cacheKey) ?? null;\n\t}\n\n\tconst projectRoot = findProjectRoot(targetFile);\n\tcache.set(cacheKey, projectRoot);\n\treturn projectRoot;\n}\n\nfunction staticMatchReason(rule: LoadedRule): MatchReason | null {\n\tif (rule.frontmatter.alwaysApply === true) {\n\t\treturn \"alwaysApply\";\n\t}\n\n\tif (rule.isSingleFile) {\n\t\treturn \"single-file\";\n\t}\n\n\treturn null;\n}\n\nfunction disabledSourcesFor(config: PiRulesConfig): ReadonlySet<string> | undefined {\n\tif (config.enabledSources === \"auto\") {\n\t\treturn undefined;\n\t}\n\n\tconst enabledSources = new Set(config.enabledSources);\n\treturn new Set([...SOURCE_PRIORITY.keys()].filter((source) => !enabledSources.has(source)));\n}\n\nfunction isDedupedRootSingleFile(candidate: RuleCandidate, rootSingleFileSelected: boolean): boolean {\n\treturn rootSingleFileSelected && isRootSingleFile(candidate);\n}\n\nfunction isRootSingleFile(candidate: RuleCandidate): boolean {\n\treturn (\n\t\tcandidate.isSingleFile &&\n\t\tROOT_SINGLE_FILE_SOURCES.has(candidate.source) &&\n\t\tcandidate.relativePath === candidate.source\n\t);\n}\n\nfunction rootSingleFileSelectionKeyFor(candidate: RuleCandidate, projectRoot: string | null): string | null {\n\treturn projectRoot !== null && isRootSingleFile(candidate) ? projectRoot : null;\n}\n\nfunction pathBasesForTarget(\n\tprojectRoot: string | null,\n\ttargetFile: string,\n\tcandidate: RuleCandidate,\n): { projectRelative: string; scopeRelative?: string; basename: string } {\n\tconst targetBasename = basename(targetFile);\n\tif (projectRoot === null) {\n\t\treturn { projectRelative: targetBasename, basename: targetBasename };\n\t}\n\n\tconst projectRelative = toPosixPath(relative(projectRoot, targetFile));\n\tconst scopeDirectory = scopeDirectoryForCandidate(projectRoot, candidate);\n\tif (scopeDirectory === null) {\n\t\treturn { projectRelative, basename: targetBasename };\n\t}\n\n\treturn {\n\t\tprojectRelative,\n\t\tscopeRelative: toPosixPath(relative(scopeDirectory, targetFile)),\n\t\tbasename: targetBasename,\n\t};\n}\n\nfunction scopeDirectoryForCandidate(projectRoot: string, candidate: RuleCandidate): string | null {\n\tif (candidate.isGlobal) {\n\t\treturn null;\n\t}\n\n\tif (candidate.isSingleFile) {\n\t\treturn dirname(candidate.path);\n\t}\n\n\tconst sourceIndex = candidate.relativePath.indexOf(candidate.source);\n\tif (sourceIndex === -1) {\n\t\treturn projectRoot;\n\t}\n\n\tconst scopeRelativeDirectory = candidate.relativePath.slice(0, sourceIndex).replace(/\\/$/, \"\");\n\treturn scopeRelativeDirectory.length === 0 ? projectRoot : join(projectRoot, scopeRelativeDirectory);\n}\n\nfunction toPosixPath(path: string): string {\n\treturn path.replaceAll(\"\\\\\", \"/\");\n}\n\nfunction dynamicTargetCacheKey(targetFile: string): string {\n\treturn toPosixPath(resolve(targetFile));\n}\n\nfunction computeDynamicTargetFingerprint(\n\ttargetFile: string,\n\tprojectRoot: string | null,\n\tcandidates: ReadonlyArray<RuleCandidate>,\n\tconfig: PiRulesConfig,\n\tfileFingerprintFn: (filePath: string) => string,\n): string {\n\tconst candidateFingerprint = candidates\n\t\t.map((candidate) => fingerprintCandidate(candidate, fileFingerprintFn))\n\t\t.join(\"\\u0001\");\n\treturn hashContent(\n\t\t[\n\t\t\t\"v1\",\n\t\t\tconfig.enabledSources === \"auto\" ? \"auto\" : config.enabledSources.join(\",\"),\n\t\t\tprojectRoot ?? \"\",\n\t\t\tdynamicTargetCacheKey(targetFile),\n\t\t\tcandidateFingerprint,\n\t\t].join(\"\\u0000\"),\n\t);\n}\n\nfunction fingerprintCandidate(candidate: RuleCandidate, fileFingerprintFn: (filePath: string) => string): string {\n\treturn [\n\t\tcandidate.realPath,\n\t\tcandidate.relativePath,\n\t\tcandidate.source,\n\t\tcandidate.isGlobal ? \"global\" : \"project\",\n\t\tcandidate.isSingleFile ? \"single\" : \"multi\",\n\t\tString(candidate.distance),\n\t\tfileFingerprintFn(candidate.path),\n\t].join(\"\\u0000\");\n}\n\nfunction fileStatFingerprint(filePath: string): string {\n\ttry {\n\t\tconst stats = statSync(filePath, { bigint: true });\n\t\treturn `${stats.mtimeNs}:${stats.ctimeNs}:${stats.size}`;\n\t} catch {\n\t\treturn \"missing\";\n\t}\n}\n\nfunction uniqueStrings(values: ReadonlyArray<string>): string[] {\n\treturn [...new Set(values)];\n}\n\nfunction canonicalizePath(path: string): string {\n\ttry {\n\t\treturn realpathSync.native(path);\n\t} catch {\n\t\treturn resolve(path);\n\t}\n}\n\nfunction storeLastLoad(\n\tstate: SessionState,\n\trules: ReadonlyArray<LoadedRule>,\n\tdiagnostics: ReadonlyArray<RuleDiagnostic>,\n): void {\n\tstate.loadedRules.length = 0;\n\tstate.loadedRules.push(...rules);\n\tstate.diagnostics.length = 0;\n\tstate.diagnostics.push(...diagnostics);\n}\n\nfunction emptyLoadResult(state: SessionState): { rules: LoadedRule[]; diagnostics: RuleDiagnostic[] } {\n\tstoreLastLoad(state, [], []);\n\treturn { rules: [], diagnostics: [] };\n}\n"]}
@@ -110,6 +110,7 @@ function findUserHomeCandidates(homeDirectory, disabledSources, cache) {
110
110
  isSingleFile: true,
111
111
  relativePath: toRelativePath(homeDirectory, filePath),
112
112
  });
113
+ break;
113
114
  }
114
115
  return candidates;
115
116
  }
@@ -197,6 +198,7 @@ function toRelativePath(rootDirectory, filePath) {
197
198
  function toProjectRuleSource(parentDirectory, subDirectory) {
198
199
  const source = `${parentDirectory}/${subDirectory}`;
199
200
  switch (source) {
201
+ case ".pi/rules":
200
202
  case ".omo/rules":
201
203
  case ".claude/rules":
202
204
  case ".cursor/rules":
@@ -220,6 +222,7 @@ function toProjectSingleFileSource(ruleFile) {
220
222
  function toUserHomeRuleSource(ruleSubdir) {
221
223
  const source = `~/${ruleSubdir}`;
222
224
  switch (source) {
225
+ case "~/.pi/rules":
223
226
  case "~/.omo/rules":
224
227
  case "~/.opencode/rules":
225
228
  case "~/.claude/rules":