@code-yeongyu/senpi 2026.6.14 → 2026.6.16

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 (317) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/dist/core/compaction/compaction.d.ts.map +1 -1
  3. package/dist/core/compaction/compaction.js +5 -0
  4. package/dist/core/compaction/compaction.js.map +1 -1
  5. package/dist/core/extensions/builtin/bash-timeout/index.d.ts.map +1 -1
  6. package/dist/core/extensions/builtin/bash-timeout/index.js +3 -1
  7. package/dist/core/extensions/builtin/bash-timeout/index.js.map +1 -1
  8. package/dist/core/extensions/builtin/bash-timeout/timeout.js +2 -2
  9. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  10. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  11. package/dist/core/extensions/builtin/compaction/speculative.js +24 -12
  12. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  13. package/dist/core/extensions/builtin/goal/command.d.ts +14 -0
  14. package/dist/core/extensions/builtin/goal/command.d.ts.map +1 -0
  15. package/dist/core/extensions/builtin/goal/command.js +16 -0
  16. package/dist/core/extensions/builtin/goal/command.js.map +1 -0
  17. package/dist/core/extensions/builtin/goal/continuation.d.ts +4 -0
  18. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -0
  19. package/dist/core/extensions/builtin/goal/continuation.js +7 -0
  20. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -0
  21. package/dist/core/extensions/builtin/goal/errors.d.ts +13 -0
  22. package/dist/core/extensions/builtin/goal/errors.d.ts.map +1 -0
  23. package/dist/core/extensions/builtin/goal/errors.js +25 -0
  24. package/dist/core/extensions/builtin/goal/errors.js.map +1 -0
  25. package/dist/core/extensions/builtin/goal/format.d.ts +8 -0
  26. package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -0
  27. package/dist/core/extensions/builtin/goal/format.js +71 -0
  28. package/dist/core/extensions/builtin/goal/format.js.map +1 -0
  29. package/dist/core/extensions/builtin/goal/index.d.ts +3 -0
  30. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -0
  31. package/dist/core/extensions/builtin/goal/index.js +322 -0
  32. package/dist/core/extensions/builtin/goal/index.js.map +1 -0
  33. package/dist/core/extensions/builtin/goal/prompt.d.ts +3 -0
  34. package/dist/core/extensions/builtin/goal/prompt.d.ts.map +1 -0
  35. package/dist/core/extensions/builtin/goal/prompt.js +34 -0
  36. package/dist/core/extensions/builtin/goal/prompt.js.map +1 -0
  37. package/dist/core/extensions/builtin/goal/store.d.ts +9 -0
  38. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -0
  39. package/dist/core/extensions/builtin/goal/store.js +173 -0
  40. package/dist/core/extensions/builtin/goal/store.js.map +1 -0
  41. package/dist/core/extensions/builtin/goal/types.d.ts +50 -0
  42. package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -0
  43. package/dist/core/extensions/builtin/goal/types.js +6 -0
  44. package/dist/core/extensions/builtin/goal/types.js.map +1 -0
  45. package/dist/core/extensions/builtin/goal/ui.d.ts +6 -0
  46. package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -0
  47. package/dist/core/extensions/builtin/goal/ui.js +20 -0
  48. package/dist/core/extensions/builtin/goal/ui.js.map +1 -0
  49. package/dist/core/extensions/builtin/goal/validation.d.ts +3 -0
  50. package/dist/core/extensions/builtin/goal/validation.d.ts.map +1 -0
  51. package/dist/core/extensions/builtin/goal/validation.js +13 -0
  52. package/dist/core/extensions/builtin/goal/validation.js.map +1 -0
  53. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/index.js +10 -2
  55. package/dist/core/extensions/builtin/index.js.map +1 -1
  56. package/dist/core/extensions/builtin/nested-agents-md/core/containment.d.ts +10 -0
  57. package/dist/core/extensions/builtin/nested-agents-md/core/containment.d.ts.map +1 -0
  58. package/dist/core/extensions/builtin/nested-agents-md/core/containment.js +23 -0
  59. package/dist/core/extensions/builtin/nested-agents-md/core/containment.js.map +1 -0
  60. package/dist/core/extensions/builtin/nested-agents-md/core/errors.d.ts +5 -0
  61. package/dist/core/extensions/builtin/nested-agents-md/core/errors.d.ts.map +1 -0
  62. package/dist/core/extensions/builtin/nested-agents-md/core/errors.js +9 -0
  63. package/dist/core/extensions/builtin/nested-agents-md/core/errors.js.map +1 -0
  64. package/dist/core/extensions/builtin/nested-agents-md/core/find-agents-md-up.d.ts +7 -0
  65. package/dist/core/extensions/builtin/nested-agents-md/core/find-agents-md-up.d.ts.map +1 -0
  66. package/dist/core/extensions/builtin/nested-agents-md/core/find-agents-md-up.js +44 -0
  67. package/dist/core/extensions/builtin/nested-agents-md/core/find-agents-md-up.js.map +1 -0
  68. package/dist/core/extensions/builtin/nested-agents-md/core/format.d.ts +7 -0
  69. package/dist/core/extensions/builtin/nested-agents-md/core/format.d.ts.map +1 -0
  70. package/dist/core/extensions/builtin/nested-agents-md/core/format.js +7 -0
  71. package/dist/core/extensions/builtin/nested-agents-md/core/format.js.map +1 -0
  72. package/dist/core/extensions/builtin/nested-agents-md/core/inject-directory-context.d.ts +11 -0
  73. package/dist/core/extensions/builtin/nested-agents-md/core/inject-directory-context.d.ts.map +1 -0
  74. package/dist/core/extensions/builtin/nested-agents-md/core/inject-directory-context.js +77 -0
  75. package/dist/core/extensions/builtin/nested-agents-md/core/inject-directory-context.js.map +1 -0
  76. package/dist/core/extensions/builtin/nested-agents-md/core/injection-cache.d.ts +11 -0
  77. package/dist/core/extensions/builtin/nested-agents-md/core/injection-cache.d.ts.map +1 -0
  78. package/dist/core/extensions/builtin/nested-agents-md/core/injection-cache.js +33 -0
  79. package/dist/core/extensions/builtin/nested-agents-md/core/injection-cache.js.map +1 -0
  80. package/dist/core/extensions/builtin/nested-agents-md/core/session-key.d.ts +8 -0
  81. package/dist/core/extensions/builtin/nested-agents-md/core/session-key.d.ts.map +1 -0
  82. package/dist/core/extensions/builtin/nested-agents-md/core/session-key.js +8 -0
  83. package/dist/core/extensions/builtin/nested-agents-md/core/session-key.js.map +1 -0
  84. package/dist/core/extensions/builtin/nested-agents-md/core/truncate.d.ts +8 -0
  85. package/dist/core/extensions/builtin/nested-agents-md/core/truncate.d.ts.map +1 -0
  86. package/dist/core/extensions/builtin/nested-agents-md/core/truncate.js +26 -0
  87. package/dist/core/extensions/builtin/nested-agents-md/core/truncate.js.map +1 -0
  88. package/dist/core/extensions/builtin/nested-agents-md/core/types.d.ts +25 -0
  89. package/dist/core/extensions/builtin/nested-agents-md/core/types.d.ts.map +1 -0
  90. package/dist/core/extensions/builtin/nested-agents-md/core/types.js +4 -0
  91. package/dist/core/extensions/builtin/nested-agents-md/core/types.js.map +1 -0
  92. package/dist/core/extensions/builtin/nested-agents-md/index.d.ts +3 -0
  93. package/dist/core/extensions/builtin/nested-agents-md/index.d.ts.map +1 -0
  94. package/dist/core/extensions/builtin/nested-agents-md/index.js +102 -0
  95. package/dist/core/extensions/builtin/nested-agents-md/index.js.map +1 -0
  96. package/dist/core/extensions/builtin/nested-agents-md/ui/reporter.d.ts +32 -0
  97. package/dist/core/extensions/builtin/nested-agents-md/ui/reporter.d.ts.map +1 -0
  98. package/dist/core/extensions/builtin/nested-agents-md/ui/reporter.js +66 -0
  99. package/dist/core/extensions/builtin/nested-agents-md/ui/reporter.js.map +1 -0
  100. package/dist/core/extensions/builtin/prompt-preset/presets.js +2 -2
  101. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  102. package/dist/core/extensions/builtin/rules/commands.d.ts +4 -0
  103. package/dist/core/extensions/builtin/rules/commands.d.ts.map +1 -0
  104. package/dist/core/extensions/builtin/rules/commands.js +87 -0
  105. package/dist/core/extensions/builtin/rules/commands.js.map +1 -0
  106. package/dist/core/extensions/builtin/rules/index.d.ts +3 -0
  107. package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -0
  108. package/dist/core/extensions/builtin/rules/index.js +127 -0
  109. package/dist/core/extensions/builtin/rules/index.js.map +1 -0
  110. package/dist/core/extensions/builtin/rules/rules/cache.d.ts +10 -0
  111. package/dist/core/extensions/builtin/rules/rules/cache.d.ts.map +1 -0
  112. package/dist/core/extensions/builtin/rules/rules/cache.js +51 -0
  113. package/dist/core/extensions/builtin/rules/rules/cache.js.map +1 -0
  114. package/dist/core/extensions/builtin/rules/rules/constants.d.ts +57 -0
  115. package/dist/core/extensions/builtin/rules/rules/constants.d.ts.map +1 -0
  116. package/dist/core/extensions/builtin/rules/rules/constants.js +96 -0
  117. package/dist/core/extensions/builtin/rules/rules/constants.js.map +1 -0
  118. package/dist/core/extensions/builtin/rules/rules/engine.d.ts +67 -0
  119. package/dist/core/extensions/builtin/rules/rules/engine.d.ts.map +1 -0
  120. package/dist/core/extensions/builtin/rules/rules/engine.js +443 -0
  121. package/dist/core/extensions/builtin/rules/rules/engine.js.map +1 -0
  122. package/dist/core/extensions/builtin/rules/rules/errors.d.ts +7 -0
  123. package/dist/core/extensions/builtin/rules/rules/errors.d.ts.map +1 -0
  124. package/dist/core/extensions/builtin/rules/rules/errors.js +13 -0
  125. package/dist/core/extensions/builtin/rules/rules/errors.js.map +1 -0
  126. package/dist/core/extensions/builtin/rules/rules/finder.d.ts +27 -0
  127. package/dist/core/extensions/builtin/rules/rules/finder.d.ts.map +1 -0
  128. package/dist/core/extensions/builtin/rules/rules/finder.js +241 -0
  129. package/dist/core/extensions/builtin/rules/rules/finder.js.map +1 -0
  130. package/dist/core/extensions/builtin/rules/rules/formatter.d.ts +8 -0
  131. package/dist/core/extensions/builtin/rules/rules/formatter.d.ts.map +1 -0
  132. package/dist/core/extensions/builtin/rules/rules/formatter.js +44 -0
  133. package/dist/core/extensions/builtin/rules/rules/formatter.js.map +1 -0
  134. package/dist/core/extensions/builtin/rules/rules/matcher.d.ts +25 -0
  135. package/dist/core/extensions/builtin/rules/rules/matcher.d.ts.map +1 -0
  136. package/dist/core/extensions/builtin/rules/rules/matcher.js +107 -0
  137. package/dist/core/extensions/builtin/rules/rules/matcher.js.map +1 -0
  138. package/dist/core/extensions/builtin/rules/rules/ordering.d.ts +4 -0
  139. package/dist/core/extensions/builtin/rules/rules/ordering.d.ts.map +1 -0
  140. package/dist/core/extensions/builtin/rules/rules/ordering.js +28 -0
  141. package/dist/core/extensions/builtin/rules/rules/ordering.js.map +1 -0
  142. package/dist/core/extensions/builtin/rules/rules/parser.d.ts +4 -0
  143. package/dist/core/extensions/builtin/rules/rules/parser.d.ts.map +1 -0
  144. package/dist/core/extensions/builtin/rules/rules/parser.js +290 -0
  145. package/dist/core/extensions/builtin/rules/rules/parser.js.map +1 -0
  146. package/dist/core/extensions/builtin/rules/rules/project-root.d.ts +2 -0
  147. package/dist/core/extensions/builtin/rules/rules/project-root.d.ts.map +1 -0
  148. package/dist/core/extensions/builtin/rules/rules/project-root.js +24 -0
  149. package/dist/core/extensions/builtin/rules/rules/project-root.js.map +1 -0
  150. package/dist/core/extensions/builtin/rules/rules/scanner.d.ts +14 -0
  151. package/dist/core/extensions/builtin/rules/rules/scanner.d.ts.map +1 -0
  152. package/dist/core/extensions/builtin/rules/rules/scanner.js +96 -0
  153. package/dist/core/extensions/builtin/rules/rules/scanner.js.map +1 -0
  154. package/dist/core/extensions/builtin/rules/rules/tool-paths.d.ts +4 -0
  155. package/dist/core/extensions/builtin/rules/rules/tool-paths.d.ts.map +1 -0
  156. package/dist/core/extensions/builtin/rules/rules/tool-paths.js +37 -0
  157. package/dist/core/extensions/builtin/rules/rules/tool-paths.js.map +1 -0
  158. package/dist/core/extensions/builtin/rules/rules/truncator.d.ts +18 -0
  159. package/dist/core/extensions/builtin/rules/rules/truncator.d.ts.map +1 -0
  160. package/dist/core/extensions/builtin/rules/rules/truncator.js +46 -0
  161. package/dist/core/extensions/builtin/rules/rules/truncator.js.map +1 -0
  162. package/dist/core/extensions/builtin/rules/rules/types.d.ts +124 -0
  163. package/dist/core/extensions/builtin/rules/rules/types.d.ts.map +1 -0
  164. package/dist/core/extensions/builtin/rules/rules/types.js +9 -0
  165. package/dist/core/extensions/builtin/rules/rules/types.js.map +1 -0
  166. package/dist/core/extensions/builtin/rules/ui/dynamic-border.d.ts +8 -0
  167. package/dist/core/extensions/builtin/rules/ui/dynamic-border.d.ts.map +1 -0
  168. package/dist/core/extensions/builtin/rules/ui/dynamic-border.js +10 -0
  169. package/dist/core/extensions/builtin/rules/ui/dynamic-border.js.map +1 -0
  170. package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts +22 -0
  171. package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts.map +1 -0
  172. package/dist/core/extensions/builtin/rules/ui/rules-banner.js +51 -0
  173. package/dist/core/extensions/builtin/rules/ui/rules-banner.js.map +1 -0
  174. package/dist/core/extensions/builtin/webfetch/index.d.ts +10 -0
  175. package/dist/core/extensions/builtin/webfetch/index.d.ts.map +1 -0
  176. package/dist/core/extensions/builtin/webfetch/index.js +53 -0
  177. package/dist/core/extensions/builtin/webfetch/index.js.map +1 -0
  178. package/dist/core/extensions/builtin/webfetch/webfetch/content.d.ts +4 -0
  179. package/dist/core/extensions/builtin/webfetch/webfetch/content.d.ts.map +1 -0
  180. package/dist/core/extensions/builtin/webfetch/webfetch/content.js +60 -0
  181. package/dist/core/extensions/builtin/webfetch/webfetch/content.js.map +1 -0
  182. package/dist/core/extensions/builtin/webfetch/webfetch/errors.d.ts +13 -0
  183. package/dist/core/extensions/builtin/webfetch/webfetch/errors.d.ts.map +1 -0
  184. package/dist/core/extensions/builtin/webfetch/webfetch/errors.js +25 -0
  185. package/dist/core/extensions/builtin/webfetch/webfetch/errors.js.map +1 -0
  186. package/dist/core/extensions/builtin/webfetch/webfetch/fetcher.d.ts +24 -0
  187. package/dist/core/extensions/builtin/webfetch/webfetch/fetcher.d.ts.map +1 -0
  188. package/dist/core/extensions/builtin/webfetch/webfetch/fetcher.js +148 -0
  189. package/dist/core/extensions/builtin/webfetch/webfetch/fetcher.js.map +1 -0
  190. package/dist/core/extensions/builtin/webfetch/webfetch/renderers.d.ts +15 -0
  191. package/dist/core/extensions/builtin/webfetch/webfetch/renderers.d.ts.map +1 -0
  192. package/dist/core/extensions/builtin/webfetch/webfetch/renderers.js +110 -0
  193. package/dist/core/extensions/builtin/webfetch/webfetch/renderers.js.map +1 -0
  194. package/dist/core/extensions/builtin/webfetch/webfetch/tool.d.ts +28 -0
  195. package/dist/core/extensions/builtin/webfetch/webfetch/tool.d.ts.map +1 -0
  196. package/dist/core/extensions/builtin/webfetch/webfetch/tool.js +79 -0
  197. package/dist/core/extensions/builtin/webfetch/webfetch/tool.js.map +1 -0
  198. package/dist/core/extensions/builtin/websearch/index.d.ts +3 -0
  199. package/dist/core/extensions/builtin/websearch/index.d.ts.map +1 -0
  200. package/dist/core/extensions/builtin/websearch/index.js +76 -0
  201. package/dist/core/extensions/builtin/websearch/index.js.map +1 -0
  202. package/dist/core/extensions/builtin/websearch/websearch/config.d.ts +12 -0
  203. package/dist/core/extensions/builtin/websearch/websearch/config.d.ts.map +1 -0
  204. package/dist/core/extensions/builtin/websearch/websearch/config.js +245 -0
  205. package/dist/core/extensions/builtin/websearch/websearch/config.js.map +1 -0
  206. package/dist/core/extensions/builtin/websearch/websearch/native.d.ts +19 -0
  207. package/dist/core/extensions/builtin/websearch/websearch/native.d.ts.map +1 -0
  208. package/dist/core/extensions/builtin/websearch/websearch/native.js +65 -0
  209. package/dist/core/extensions/builtin/websearch/websearch/native.js.map +1 -0
  210. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts +5 -0
  211. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts.map +1 -0
  212. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js +58 -0
  213. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js.map +1 -0
  214. package/dist/core/extensions/builtin/websearch/websearch/providers.d.ts +4 -0
  215. package/dist/core/extensions/builtin/websearch/websearch/providers.d.ts.map +1 -0
  216. package/dist/core/extensions/builtin/websearch/websearch/providers.js +464 -0
  217. package/dist/core/extensions/builtin/websearch/websearch/providers.js.map +1 -0
  218. package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts +26 -0
  219. package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts.map +1 -0
  220. package/dist/core/extensions/builtin/websearch/websearch/renderers.js +66 -0
  221. package/dist/core/extensions/builtin/websearch/websearch/renderers.js.map +1 -0
  222. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts +9 -0
  223. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts.map +1 -0
  224. package/dist/core/extensions/builtin/websearch/websearch/search.js +261 -0
  225. package/dist/core/extensions/builtin/websearch/websearch/search.js.map +1 -0
  226. package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts +18 -0
  227. package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts.map +1 -0
  228. package/dist/core/extensions/builtin/websearch/websearch/tool.js +88 -0
  229. package/dist/core/extensions/builtin/websearch/websearch/tool.js.map +1 -0
  230. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +115 -0
  231. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -0
  232. package/dist/core/extensions/builtin/websearch/websearch/types.js +2 -0
  233. package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -0
  234. package/dist/core/extensions/runner.d.ts.map +1 -1
  235. package/dist/core/extensions/runner.js +8 -1
  236. package/dist/core/extensions/runner.js.map +1 -1
  237. package/dist/core/tools/bash.d.ts.map +1 -1
  238. package/dist/core/tools/bash.js +4 -0
  239. package/dist/core/tools/bash.js.map +1 -1
  240. package/dist/main.d.ts +5 -0
  241. package/dist/main.d.ts.map +1 -1
  242. package/dist/main.js +8 -4
  243. package/dist/main.js.map +1 -1
  244. package/dist/modes/interactive/components/diff.d.ts +14 -0
  245. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  246. package/dist/modes/interactive/components/diff.js +65 -1
  247. package/dist/modes/interactive/components/diff.js.map +1 -1
  248. package/dist/modes/interactive/components/session-selector.d.ts +0 -1
  249. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  250. package/dist/modes/interactive/components/session-selector.js +0 -4
  251. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  252. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  253. package/dist/modes/interactive/components/tree-selector.js +87 -12
  254. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  255. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  256. package/dist/modes/interactive/interactive-mode.js +6 -17
  257. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  258. package/dist/utils/child-process.d.ts +7 -4
  259. package/dist/utils/child-process.d.ts.map +1 -1
  260. package/dist/utils/child-process.js +23 -5
  261. package/dist/utils/child-process.js.map +1 -1
  262. package/docs/containerization.md +36 -36
  263. package/docs/extensions.md +4 -4
  264. package/docs/index.md +1 -1
  265. package/docs/security.md +13 -13
  266. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  267. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  268. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  269. package/examples/extensions/gondolin/package-lock.json +2 -2
  270. package/examples/extensions/gondolin/package.json +1 -1
  271. package/examples/extensions/question.ts +39 -18
  272. package/examples/extensions/questionnaire.ts +49 -28
  273. package/examples/extensions/sandbox/package-lock.json +2 -2
  274. package/examples/extensions/sandbox/package.json +1 -1
  275. package/examples/extensions/with-deps/package-lock.json +2 -2
  276. package/examples/extensions/with-deps/package.json +1 -1
  277. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -1
  278. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +5 -0
  279. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js.map +1 -1
  280. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  281. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +140 -47
  283. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +169 -122
  285. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  286. package/node_modules/@earendil-works/pi-ai/dist/models.js +4 -1
  287. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  288. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  289. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +18 -1
  290. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
  291. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js +2 -1
  292. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js.map +1 -1
  293. package/node_modules/@earendil-works/pi-ai/dist/providers/google.js +2 -1
  294. package/node_modules/@earendil-works/pi-ai/dist/providers/google.js.map +1 -1
  295. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  296. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +20 -2
  297. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
  298. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +2 -0
  299. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  300. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  301. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.d.ts +5 -0
  302. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.d.ts.map +1 -0
  303. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.js +41 -0
  304. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.js.map +1 -0
  305. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  306. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  307. package/node_modules/@earendil-works/pi-tui/dist/tui.js +14 -1
  308. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  309. package/node_modules/@earendil-works/pi-tui/dist/utils.js +1 -1
  310. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
  311. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  312. package/npm-shrinkwrap.json +45 -12
  313. package/package.json +8 -4
  314. package/dist/core/extensions/builtin/kimi-web-search/index.d.ts +0 -3
  315. package/dist/core/extensions/builtin/kimi-web-search/index.d.ts.map +0 -1
  316. package/dist/core/extensions/builtin/kimi-web-search/index.js +0 -208
  317. package/dist/core/extensions/builtin/kimi-web-search/index.js.map +0 -1
@@ -0,0 +1,290 @@
1
+ import { RuleFrontmatterParseError } from "./errors.js";
2
+ const FRONTMATTER_OPENING = "---\n";
3
+ const FRONTMATTER_OPENING_CRLF = "---\r\n";
4
+ /** Parse markdown rule content and extract the supported YAML frontmatter subset. */
5
+ export function parseRule(content) {
6
+ const normalizedContent = stripBom(content);
7
+ const openingLength = getOpeningDelimiterLength(normalizedContent);
8
+ if (openingLength === 0) {
9
+ return { frontmatter: {}, body: normalizedContent };
10
+ }
11
+ const closingDelimiter = findClosingDelimiter(normalizedContent, openingLength);
12
+ if (closingDelimiter === null) {
13
+ return {
14
+ frontmatter: {},
15
+ body: normalizedContent,
16
+ diagnostic: "Missing closing frontmatter delimiter",
17
+ };
18
+ }
19
+ const yamlContent = normalizedContent.slice(openingLength, closingDelimiter.start);
20
+ const body = normalizedContent.slice(closingDelimiter.bodyStart);
21
+ try {
22
+ return { frontmatter: parseYamlFrontmatter(yamlContent), body };
23
+ }
24
+ catch (error) {
25
+ const message = error instanceof Error ? error.message : "Invalid YAML frontmatter";
26
+ return {
27
+ frontmatter: {},
28
+ body: normalizedContent,
29
+ diagnostic: `Malformed frontmatter: ${message}`,
30
+ };
31
+ }
32
+ }
33
+ function stripBom(content) {
34
+ return content.startsWith("\uFEFF") ? content.slice(1) : content;
35
+ }
36
+ function getOpeningDelimiterLength(content) {
37
+ if (content.startsWith(FRONTMATTER_OPENING_CRLF))
38
+ return FRONTMATTER_OPENING_CRLF.length;
39
+ if (content.startsWith(FRONTMATTER_OPENING))
40
+ return FRONTMATTER_OPENING.length;
41
+ return 0;
42
+ }
43
+ function findClosingDelimiter(content, openingLength) {
44
+ let lineStart = openingLength;
45
+ while (lineStart <= content.length) {
46
+ const nextNewline = content.indexOf("\n", lineStart);
47
+ const lineEnd = nextNewline === -1 ? content.length : nextNewline;
48
+ const line = content.slice(lineStart, lineEnd).replace(/\r$/, "");
49
+ if (line === "---") {
50
+ return {
51
+ start: lineStart,
52
+ bodyStart: nextNewline === -1 ? content.length : nextNewline + 1,
53
+ };
54
+ }
55
+ if (nextNewline === -1)
56
+ break;
57
+ lineStart = nextNewline + 1;
58
+ }
59
+ return null;
60
+ }
61
+ function parseYamlFrontmatter(yamlContent) {
62
+ const lines = yamlContent.replace(/\r\n/g, "\n").split("\n");
63
+ const frontmatter = {};
64
+ const globValues = [];
65
+ let lineIndex = 0;
66
+ while (lineIndex < lines.length) {
67
+ const rawLine = lines[lineIndex];
68
+ if (rawLine === undefined)
69
+ break;
70
+ const line = stripComment(rawLine).trim();
71
+ if (line.length === 0) {
72
+ lineIndex += 1;
73
+ continue;
74
+ }
75
+ const colonIndex = line.indexOf(":");
76
+ if (colonIndex === -1) {
77
+ throw new RuleFrontmatterParseError(`Expected key-value pair on line ${lineIndex + 1}`);
78
+ }
79
+ const key = line.slice(0, colonIndex).trim();
80
+ const rawValue = line.slice(colonIndex + 1).trim();
81
+ if (key === "description") {
82
+ frontmatter.description = parseStringValue(rawValue);
83
+ lineIndex += 1;
84
+ continue;
85
+ }
86
+ if (key === "alwaysApply") {
87
+ frontmatter.alwaysApply = parseBooleanValue(rawValue, lineIndex + 1);
88
+ lineIndex += 1;
89
+ continue;
90
+ }
91
+ if (key === "globs" || key === "paths" || key === "applyTo") {
92
+ const parsed = parseGlobValue(rawValue, lines, lineIndex);
93
+ for (const glob of parsed.values) {
94
+ if (!globValues.includes(glob))
95
+ globValues.push(glob);
96
+ }
97
+ lineIndex += parsed.consumed;
98
+ continue;
99
+ }
100
+ lineIndex += 1;
101
+ }
102
+ if (globValues.length === 1) {
103
+ const singleGlob = globValues[0];
104
+ if (singleGlob !== undefined)
105
+ frontmatter.globs = singleGlob;
106
+ }
107
+ else if (globValues.length > 1) {
108
+ frontmatter.globs = globValues;
109
+ }
110
+ return frontmatter;
111
+ }
112
+ function parseBooleanValue(value, lineNumber) {
113
+ if (value === "true")
114
+ return true;
115
+ if (value === "false")
116
+ return false;
117
+ throw new RuleFrontmatterParseError(`Expected boolean on line ${lineNumber}`);
118
+ }
119
+ function parseGlobValue(rawValue, lines, lineIndex) {
120
+ if (rawValue.startsWith("[")) {
121
+ return { values: parseInlineArray(rawValue), consumed: 1 };
122
+ }
123
+ if (rawValue.length === 0) {
124
+ return parseMultilineArray(lines, lineIndex);
125
+ }
126
+ const value = parseStringValue(rawValue);
127
+ if (value.includes(",")) {
128
+ return {
129
+ values: value
130
+ .split(",")
131
+ .map((item) => item.trim())
132
+ .filter(Boolean),
133
+ consumed: 1,
134
+ };
135
+ }
136
+ return { values: [value], consumed: 1 };
137
+ }
138
+ function parseMultilineArray(lines, lineIndex) {
139
+ const values = [];
140
+ let consumed = 1;
141
+ for (let index = lineIndex + 1; index < lines.length; index += 1) {
142
+ const rawLine = lines[index];
143
+ if (rawLine === undefined)
144
+ break;
145
+ const lineWithoutComment = stripComment(rawLine);
146
+ if (lineWithoutComment.trim().length === 0) {
147
+ consumed += 1;
148
+ continue;
149
+ }
150
+ const arrayItem = lineWithoutComment.match(/^\s+-\s*(.*)$/);
151
+ if (arrayItem === null)
152
+ break;
153
+ values.push(parseStringValue(arrayItem[1] ?? ""));
154
+ consumed += 1;
155
+ }
156
+ return { values: values.filter(Boolean), consumed };
157
+ }
158
+ function parseInlineArray(value) {
159
+ const closingBracketIndex = findClosingBracket(value);
160
+ if (closingBracketIndex === -1) {
161
+ throw new RuleFrontmatterParseError("Unclosed inline array");
162
+ }
163
+ const trailing = value.slice(closingBracketIndex + 1).trim();
164
+ if (trailing.length > 0) {
165
+ throw new RuleFrontmatterParseError("Unexpected content after inline array");
166
+ }
167
+ const content = value.slice(1, closingBracketIndex).trim();
168
+ if (content.length === 0)
169
+ return [];
170
+ return splitCommaSeparated(content).map(parseStringValue).filter(Boolean);
171
+ }
172
+ function findClosingBracket(value) {
173
+ let quote = null;
174
+ let escaped = false;
175
+ for (let index = 0; index < value.length; index += 1) {
176
+ const character = value[index];
177
+ if (character === undefined)
178
+ continue;
179
+ if (escaped) {
180
+ escaped = false;
181
+ continue;
182
+ }
183
+ if (quote !== null && character === "\\") {
184
+ escaped = true;
185
+ continue;
186
+ }
187
+ if (character === '"' || character === "'") {
188
+ if (quote === null)
189
+ quote = character;
190
+ else if (quote === character)
191
+ quote = null;
192
+ continue;
193
+ }
194
+ if (quote === null && character === "]")
195
+ return index;
196
+ }
197
+ return -1;
198
+ }
199
+ function splitCommaSeparated(value) {
200
+ const values = [];
201
+ let current = "";
202
+ let quote = null;
203
+ let escaped = false;
204
+ for (let index = 0; index < value.length; index += 1) {
205
+ const character = value[index];
206
+ if (character === undefined)
207
+ continue;
208
+ if (escaped) {
209
+ current += character;
210
+ escaped = false;
211
+ continue;
212
+ }
213
+ if (quote !== null && character === "\\") {
214
+ current += character;
215
+ escaped = true;
216
+ continue;
217
+ }
218
+ if (character === '"' || character === "'") {
219
+ if (quote === null)
220
+ quote = character;
221
+ else if (quote === character)
222
+ quote = null;
223
+ current += character;
224
+ continue;
225
+ }
226
+ if (quote === null && character === ",") {
227
+ values.push(current.trim());
228
+ current = "";
229
+ continue;
230
+ }
231
+ current += character;
232
+ }
233
+ if (quote !== null) {
234
+ throw new RuleFrontmatterParseError("Unclosed quoted value");
235
+ }
236
+ values.push(current.trim());
237
+ return values.filter(Boolean);
238
+ }
239
+ function parseStringValue(value) {
240
+ if (value.length === 0)
241
+ return "";
242
+ if (value.startsWith('"'))
243
+ return parseJsonString(value);
244
+ if (value.startsWith("'") && value.endsWith("'"))
245
+ return value.slice(1, -1);
246
+ if (value.startsWith("'"))
247
+ throw new RuleFrontmatterParseError("Unclosed quoted value");
248
+ return value;
249
+ }
250
+ function parseJsonString(value) {
251
+ let parsedValue;
252
+ try {
253
+ parsedValue = JSON.parse(value);
254
+ }
255
+ catch {
256
+ throw new RuleFrontmatterParseError("Invalid JSON-quoted string");
257
+ }
258
+ if (typeof parsedValue !== "string") {
259
+ throw new RuleFrontmatterParseError("Expected JSON-quoted string");
260
+ }
261
+ return parsedValue;
262
+ }
263
+ function stripComment(line) {
264
+ let quote = null;
265
+ let escaped = false;
266
+ for (let index = 0; index < line.length; index += 1) {
267
+ const character = line[index];
268
+ if (character === undefined)
269
+ continue;
270
+ if (escaped) {
271
+ escaped = false;
272
+ continue;
273
+ }
274
+ if (quote !== null && character === "\\") {
275
+ escaped = true;
276
+ continue;
277
+ }
278
+ if (character === '"' || character === "'") {
279
+ if (quote === null)
280
+ quote = character;
281
+ else if (quote === character)
282
+ quote = null;
283
+ continue;
284
+ }
285
+ if (quote === null && character === "#")
286
+ return line.slice(0, index);
287
+ }
288
+ return line;
289
+ }
290
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/parser.ts"],"names":[],"mappings":"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","sourcesContent":["import { RuleFrontmatterParseError } from \"./errors.ts\";\nimport type { ParsedRule, RuleFrontmatter } from \"./types.ts\";\n\nconst FRONTMATTER_OPENING = \"---\\n\";\nconst FRONTMATTER_OPENING_CRLF = \"---\\r\\n\";\n\n/** Parse markdown rule content and extract the supported YAML frontmatter subset. */\nexport function parseRule(content: string): ParsedRule {\n\tconst normalizedContent = stripBom(content);\n\tconst openingLength = getOpeningDelimiterLength(normalizedContent);\n\tif (openingLength === 0) {\n\t\treturn { frontmatter: {}, body: normalizedContent };\n\t}\n\n\tconst closingDelimiter = findClosingDelimiter(normalizedContent, openingLength);\n\tif (closingDelimiter === null) {\n\t\treturn {\n\t\t\tfrontmatter: {},\n\t\t\tbody: normalizedContent,\n\t\t\tdiagnostic: \"Missing closing frontmatter delimiter\",\n\t\t};\n\t}\n\n\tconst yamlContent = normalizedContent.slice(openingLength, closingDelimiter.start);\n\tconst body = normalizedContent.slice(closingDelimiter.bodyStart);\n\n\ttry {\n\t\treturn { frontmatter: parseYamlFrontmatter(yamlContent), body };\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : \"Invalid YAML frontmatter\";\n\t\treturn {\n\t\t\tfrontmatter: {},\n\t\t\tbody: normalizedContent,\n\t\t\tdiagnostic: `Malformed frontmatter: ${message}`,\n\t\t};\n\t}\n}\n\nfunction stripBom(content: string): string {\n\treturn content.startsWith(\"\\uFEFF\") ? content.slice(1) : content;\n}\n\nfunction getOpeningDelimiterLength(content: string): number {\n\tif (content.startsWith(FRONTMATTER_OPENING_CRLF)) return FRONTMATTER_OPENING_CRLF.length;\n\tif (content.startsWith(FRONTMATTER_OPENING)) return FRONTMATTER_OPENING.length;\n\treturn 0;\n}\n\nfunction findClosingDelimiter(content: string, openingLength: number): { start: number; bodyStart: number } | null {\n\tlet lineStart = openingLength;\n\n\twhile (lineStart <= content.length) {\n\t\tconst nextNewline = content.indexOf(\"\\n\", lineStart);\n\t\tconst lineEnd = nextNewline === -1 ? content.length : nextNewline;\n\t\tconst line = content.slice(lineStart, lineEnd).replace(/\\r$/, \"\");\n\n\t\tif (line === \"---\") {\n\t\t\treturn {\n\t\t\t\tstart: lineStart,\n\t\t\t\tbodyStart: nextNewline === -1 ? content.length : nextNewline + 1,\n\t\t\t};\n\t\t}\n\n\t\tif (nextNewline === -1) break;\n\t\tlineStart = nextNewline + 1;\n\t}\n\n\treturn null;\n}\n\nfunction parseYamlFrontmatter(yamlContent: string): RuleFrontmatter {\n\tconst lines = yamlContent.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n\tconst frontmatter: RuleFrontmatter = {};\n\tconst globValues: string[] = [];\n\tlet lineIndex = 0;\n\n\twhile (lineIndex < lines.length) {\n\t\tconst rawLine = lines[lineIndex];\n\t\tif (rawLine === undefined) break;\n\n\t\tconst line = stripComment(rawLine).trim();\n\t\tif (line.length === 0) {\n\t\t\tlineIndex += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst colonIndex = line.indexOf(\":\");\n\t\tif (colonIndex === -1) {\n\t\t\tthrow new RuleFrontmatterParseError(`Expected key-value pair on line ${lineIndex + 1}`);\n\t\t}\n\n\t\tconst key = line.slice(0, colonIndex).trim();\n\t\tconst rawValue = line.slice(colonIndex + 1).trim();\n\n\t\tif (key === \"description\") {\n\t\t\tfrontmatter.description = parseStringValue(rawValue);\n\t\t\tlineIndex += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (key === \"alwaysApply\") {\n\t\t\tfrontmatter.alwaysApply = parseBooleanValue(rawValue, lineIndex + 1);\n\t\t\tlineIndex += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (key === \"globs\" || key === \"paths\" || key === \"applyTo\") {\n\t\t\tconst parsed = parseGlobValue(rawValue, lines, lineIndex);\n\t\t\tfor (const glob of parsed.values) {\n\t\t\t\tif (!globValues.includes(glob)) globValues.push(glob);\n\t\t\t}\n\t\t\tlineIndex += parsed.consumed;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlineIndex += 1;\n\t}\n\n\tif (globValues.length === 1) {\n\t\tconst singleGlob = globValues[0];\n\t\tif (singleGlob !== undefined) frontmatter.globs = singleGlob;\n\t} else if (globValues.length > 1) {\n\t\tfrontmatter.globs = globValues;\n\t}\n\n\treturn frontmatter;\n}\n\nfunction parseBooleanValue(value: string, lineNumber: number): boolean {\n\tif (value === \"true\") return true;\n\tif (value === \"false\") return false;\n\tthrow new RuleFrontmatterParseError(`Expected boolean on line ${lineNumber}`);\n}\n\nfunction parseGlobValue(rawValue: string, lines: string[], lineIndex: number): { values: string[]; consumed: number } {\n\tif (rawValue.startsWith(\"[\")) {\n\t\treturn { values: parseInlineArray(rawValue), consumed: 1 };\n\t}\n\n\tif (rawValue.length === 0) {\n\t\treturn parseMultilineArray(lines, lineIndex);\n\t}\n\n\tconst value = parseStringValue(rawValue);\n\tif (value.includes(\",\")) {\n\t\treturn {\n\t\t\tvalues: value\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((item) => item.trim())\n\t\t\t\t.filter(Boolean),\n\t\t\tconsumed: 1,\n\t\t};\n\t}\n\n\treturn { values: [value], consumed: 1 };\n}\n\nfunction parseMultilineArray(lines: string[], lineIndex: number): { values: string[]; consumed: number } {\n\tconst values: string[] = [];\n\tlet consumed = 1;\n\n\tfor (let index = lineIndex + 1; index < lines.length; index += 1) {\n\t\tconst rawLine = lines[index];\n\t\tif (rawLine === undefined) break;\n\n\t\tconst lineWithoutComment = stripComment(rawLine);\n\t\tif (lineWithoutComment.trim().length === 0) {\n\t\t\tconsumed += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst arrayItem = lineWithoutComment.match(/^\\s+-\\s*(.*)$/);\n\t\tif (arrayItem === null) break;\n\n\t\tvalues.push(parseStringValue(arrayItem[1] ?? \"\"));\n\t\tconsumed += 1;\n\t}\n\n\treturn { values: values.filter(Boolean), consumed };\n}\n\nfunction parseInlineArray(value: string): string[] {\n\tconst closingBracketIndex = findClosingBracket(value);\n\tif (closingBracketIndex === -1) {\n\t\tthrow new RuleFrontmatterParseError(\"Unclosed inline array\");\n\t}\n\n\tconst trailing = value.slice(closingBracketIndex + 1).trim();\n\tif (trailing.length > 0) {\n\t\tthrow new RuleFrontmatterParseError(\"Unexpected content after inline array\");\n\t}\n\n\tconst content = value.slice(1, closingBracketIndex).trim();\n\tif (content.length === 0) return [];\n\n\treturn splitCommaSeparated(content).map(parseStringValue).filter(Boolean);\n}\n\nfunction findClosingBracket(value: string): number {\n\tlet quote: string | null = null;\n\tlet escaped = false;\n\n\tfor (let index = 0; index < value.length; index += 1) {\n\t\tconst character = value[index];\n\t\tif (character === undefined) continue;\n\n\t\tif (escaped) {\n\t\t\tescaped = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote !== null && character === \"\\\\\") {\n\t\t\tescaped = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (character === '\"' || character === \"'\") {\n\t\t\tif (quote === null) quote = character;\n\t\t\telse if (quote === character) quote = null;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote === null && character === \"]\") return index;\n\t}\n\n\treturn -1;\n}\n\nfunction splitCommaSeparated(value: string): string[] {\n\tconst values: string[] = [];\n\tlet current = \"\";\n\tlet quote: string | null = null;\n\tlet escaped = false;\n\n\tfor (let index = 0; index < value.length; index += 1) {\n\t\tconst character = value[index];\n\t\tif (character === undefined) continue;\n\n\t\tif (escaped) {\n\t\t\tcurrent += character;\n\t\t\tescaped = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote !== null && character === \"\\\\\") {\n\t\t\tcurrent += character;\n\t\t\tescaped = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (character === '\"' || character === \"'\") {\n\t\t\tif (quote === null) quote = character;\n\t\t\telse if (quote === character) quote = null;\n\t\t\tcurrent += character;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote === null && character === \",\") {\n\t\t\tvalues.push(current.trim());\n\t\t\tcurrent = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += character;\n\t}\n\n\tif (quote !== null) {\n\t\tthrow new RuleFrontmatterParseError(\"Unclosed quoted value\");\n\t}\n\n\tvalues.push(current.trim());\n\treturn values.filter(Boolean);\n}\n\nfunction parseStringValue(value: string): string {\n\tif (value.length === 0) return \"\";\n\tif (value.startsWith('\"')) return parseJsonString(value);\n\tif (value.startsWith(\"'\") && value.endsWith(\"'\")) return value.slice(1, -1);\n\tif (value.startsWith(\"'\")) throw new RuleFrontmatterParseError(\"Unclosed quoted value\");\n\treturn value;\n}\n\nfunction parseJsonString(value: string): string {\n\tlet parsedValue: unknown;\n\ttry {\n\t\tparsedValue = JSON.parse(value);\n\t} catch {\n\t\tthrow new RuleFrontmatterParseError(\"Invalid JSON-quoted string\");\n\t}\n\n\tif (typeof parsedValue !== \"string\") {\n\t\tthrow new RuleFrontmatterParseError(\"Expected JSON-quoted string\");\n\t}\n\n\treturn parsedValue;\n}\n\nfunction stripComment(line: string): string {\n\tlet quote: string | null = null;\n\tlet escaped = false;\n\n\tfor (let index = 0; index < line.length; index += 1) {\n\t\tconst character = line[index];\n\t\tif (character === undefined) continue;\n\n\t\tif (escaped) {\n\t\t\tescaped = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote !== null && character === \"\\\\\") {\n\t\t\tescaped = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (character === '\"' || character === \"'\") {\n\t\t\tif (quote === null) quote = character;\n\t\t\telse if (quote === character) quote = null;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote === null && character === \"#\") return line.slice(0, index);\n\t}\n\n\treturn line;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function findProjectRoot(startPath: string, markers?: ReadonlyArray<string>): string | null;
2
+ //# sourceMappingURL=project-root.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-root.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/project-root.ts"],"names":[],"mappings":"AAKA,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,aAAa,CAAC,MAAM,CAAmB,GAAG,MAAM,GAAG,IAAI,CAwBlH"}
@@ -0,0 +1,24 @@
1
+ import { existsSync, statSync } from "node:fs";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { PROJECT_MARKERS } from "./constants.js";
4
+ export function findProjectRoot(startPath, markers = PROJECT_MARKERS) {
5
+ const resolvedStartPath = resolve(startPath);
6
+ if (!existsSync(resolvedStartPath)) {
7
+ return null;
8
+ }
9
+ const startStats = statSync(resolvedStartPath);
10
+ let currentDirectory = startStats.isDirectory() ? resolvedStartPath : dirname(resolvedStartPath);
11
+ const filesystemRoot = resolve("/");
12
+ while (true) {
13
+ for (const marker of markers) {
14
+ if (existsSync(join(currentDirectory, marker))) {
15
+ return currentDirectory;
16
+ }
17
+ }
18
+ if (currentDirectory === filesystemRoot) {
19
+ return null;
20
+ }
21
+ currentDirectory = dirname(currentDirectory);
22
+ }
23
+ }
24
+ //# sourceMappingURL=project-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-root.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/project-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,OAAO,GAA0B,eAAe;IAClG,MAAM,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAE7C,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC/C,IAAI,gBAAgB,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACjG,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAEpC,OAAO,IAAI,EAAE,CAAC;QACb,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,IAAI,UAAU,CAAC,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;gBAChD,OAAO,gBAAgB,CAAC;YACzB,CAAC;QACF,CAAC;QAED,IAAI,gBAAgB,KAAK,cAAc,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QACb,CAAC;QAED,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC9C,CAAC;AACF,CAAC","sourcesContent":["import { existsSync, statSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\nimport { PROJECT_MARKERS } from \"./constants.ts\";\n\nexport function findProjectRoot(startPath: string, markers: ReadonlyArray<string> = PROJECT_MARKERS): string | null {\n\tconst resolvedStartPath = resolve(startPath);\n\n\tif (!existsSync(resolvedStartPath)) {\n\t\treturn null;\n\t}\n\n\tconst startStats = statSync(resolvedStartPath);\n\tlet currentDirectory = startStats.isDirectory() ? resolvedStartPath : dirname(resolvedStartPath);\n\tconst filesystemRoot = resolve(\"/\");\n\n\twhile (true) {\n\t\tfor (const marker of markers) {\n\t\t\tif (existsSync(join(currentDirectory, marker))) {\n\t\t\t\treturn currentDirectory;\n\t\t\t}\n\t\t}\n\n\t\tif (currentDirectory === filesystemRoot) {\n\t\t\treturn null;\n\t\t}\n\n\t\tcurrentDirectory = dirname(currentDirectory);\n\t}\n}\n"]}
@@ -0,0 +1,14 @@
1
+ export interface ScanOptions {
2
+ rootDir: string;
3
+ excludedDirs?: ReadonlyArray<string>;
4
+ /** Maximum recursion depth. Default: 10 */
5
+ maxDepth?: number;
6
+ }
7
+ export interface ScannedFile {
8
+ /** Absolute path as encountered (may be a symlink). */
9
+ path: string;
10
+ /** Real (resolved) path; same as path if not a symlink. */
11
+ realPath: string;
12
+ }
13
+ export declare function scanRuleFiles(options: ScanOptions): ScannedFile[];
14
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/scanner.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACrC,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC3B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,EAAE,CAwBjE"}
@@ -0,0 +1,96 @@
1
+ import { existsSync, lstatSync, readdirSync, realpathSync, statSync } from "node:fs";
2
+ import { isAbsolute, join, resolve } from "node:path";
3
+ import { RULE_FILE_EXTENSIONS, SCANNER_EXCLUDED_DIRS } from "./constants.js";
4
+ export function scanRuleFiles(options) {
5
+ const rootPath = toAbsolutePath(options.rootDir);
6
+ if (!existsSync(rootPath)) {
7
+ return [];
8
+ }
9
+ let rootStats;
10
+ try {
11
+ rootStats = statSync(rootPath);
12
+ }
13
+ catch {
14
+ return [];
15
+ }
16
+ if (!rootStats.isDirectory()) {
17
+ return [];
18
+ }
19
+ const results = [];
20
+ const visitedDirectories = new Set();
21
+ const excludedDirs = new Set(options.excludedDirs ?? SCANNER_EXCLUDED_DIRS);
22
+ const maxDepth = options.maxDepth ?? 10;
23
+ scanDirectory(rootPath, 0, maxDepth, excludedDirs, visitedDirectories, results);
24
+ return results;
25
+ }
26
+ function toAbsolutePath(filePath) {
27
+ return isAbsolute(filePath) ? filePath : resolve(filePath);
28
+ }
29
+ function scanDirectory(directoryPath, depth, maxDepth, excludedDirs, visitedDirectories, results) {
30
+ let realDirectoryPath;
31
+ try {
32
+ realDirectoryPath = realpathSync.native(directoryPath);
33
+ }
34
+ catch {
35
+ return;
36
+ }
37
+ if (visitedDirectories.has(realDirectoryPath)) {
38
+ return;
39
+ }
40
+ visitedDirectories.add(realDirectoryPath);
41
+ let entries;
42
+ try {
43
+ entries = readdirSync(directoryPath, { withFileTypes: true }).sort((leftEntry, rightEntry) => leftEntry.name.localeCompare(rightEntry.name));
44
+ }
45
+ catch {
46
+ return;
47
+ }
48
+ for (const entry of entries) {
49
+ const entryPath = join(directoryPath, entry.name);
50
+ if (entry.isDirectory()) {
51
+ if (!excludedDirs.has(entry.name) && depth < maxDepth) {
52
+ scanDirectory(entryPath, depth + 1, maxDepth, excludedDirs, visitedDirectories, results);
53
+ }
54
+ continue;
55
+ }
56
+ if (entry.isSymbolicLink()) {
57
+ scanSymbolicLink(entryPath, entry.name, depth, maxDepth, excludedDirs, visitedDirectories, results);
58
+ continue;
59
+ }
60
+ if (entry.isFile() && isRuleFile(entry.name)) {
61
+ results.push({ path: entryPath, realPath: resolveRealPath(entryPath) });
62
+ }
63
+ }
64
+ }
65
+ function scanSymbolicLink(linkPath, linkName, depth, maxDepth, excludedDirs, visitedDirectories, results) {
66
+ let targetStats;
67
+ try {
68
+ targetStats = statSync(linkPath);
69
+ }
70
+ catch {
71
+ return;
72
+ }
73
+ if (targetStats.isDirectory()) {
74
+ if (!excludedDirs.has(linkName) && depth < maxDepth) {
75
+ scanDirectory(linkPath, depth + 1, maxDepth, excludedDirs, visitedDirectories, results);
76
+ }
77
+ return;
78
+ }
79
+ if (targetStats.isFile() && isRuleFile(linkName)) {
80
+ results.push({ path: linkPath, realPath: resolveRealPath(linkPath) });
81
+ }
82
+ }
83
+ function isRuleFile(fileName) {
84
+ return RULE_FILE_EXTENSIONS.some((extension) => fileName.endsWith(extension));
85
+ }
86
+ function resolveRealPath(filePath) {
87
+ try {
88
+ const realPath = realpathSync.native(filePath);
89
+ const fileStats = lstatSync(filePath);
90
+ return fileStats.isSymbolicLink() ? realPath : filePath;
91
+ }
92
+ catch {
93
+ return filePath;
94
+ }
95
+ }
96
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/scanner.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Dirent, existsSync, lstatSync, readdirSync, realpathSync, type Stats, statSync } from \"node:fs\";\nimport { isAbsolute, join, resolve } from \"node:path\";\n\nimport { RULE_FILE_EXTENSIONS, SCANNER_EXCLUDED_DIRS } from \"./constants.ts\";\n\nexport interface ScanOptions {\n\trootDir: string;\n\texcludedDirs?: ReadonlyArray<string>;\n\t/** Maximum recursion depth. Default: 10 */\n\tmaxDepth?: number;\n}\n\nexport interface ScannedFile {\n\t/** Absolute path as encountered (may be a symlink). */\n\tpath: string;\n\t/** Real (resolved) path; same as path if not a symlink. */\n\trealPath: string;\n}\n\nexport function scanRuleFiles(options: ScanOptions): ScannedFile[] {\n\tconst rootPath = toAbsolutePath(options.rootDir);\n\tif (!existsSync(rootPath)) {\n\t\treturn [];\n\t}\n\n\tlet rootStats: Stats;\n\ttry {\n\t\trootStats = statSync(rootPath);\n\t} catch {\n\t\treturn [];\n\t}\n\n\tif (!rootStats.isDirectory()) {\n\t\treturn [];\n\t}\n\n\tconst results: ScannedFile[] = [];\n\tconst visitedDirectories = new Set<string>();\n\tconst excludedDirs = new Set(options.excludedDirs ?? SCANNER_EXCLUDED_DIRS);\n\tconst maxDepth = options.maxDepth ?? 10;\n\n\tscanDirectory(rootPath, 0, maxDepth, excludedDirs, visitedDirectories, results);\n\treturn results;\n}\n\nfunction toAbsolutePath(filePath: string): string {\n\treturn isAbsolute(filePath) ? filePath : resolve(filePath);\n}\n\nfunction scanDirectory(\n\tdirectoryPath: string,\n\tdepth: number,\n\tmaxDepth: number,\n\texcludedDirs: ReadonlySet<string>,\n\tvisitedDirectories: Set<string>,\n\tresults: ScannedFile[],\n): void {\n\tlet realDirectoryPath: string;\n\ttry {\n\t\trealDirectoryPath = realpathSync.native(directoryPath);\n\t} catch {\n\t\treturn;\n\t}\n\n\tif (visitedDirectories.has(realDirectoryPath)) {\n\t\treturn;\n\t}\n\tvisitedDirectories.add(realDirectoryPath);\n\n\tlet entries: Dirent[];\n\ttry {\n\t\tentries = readdirSync(directoryPath, { withFileTypes: true }).sort((leftEntry, rightEntry) =>\n\t\t\tleftEntry.name.localeCompare(rightEntry.name),\n\t\t);\n\t} catch {\n\t\treturn;\n\t}\n\n\tfor (const entry of entries) {\n\t\tconst entryPath = join(directoryPath, entry.name);\n\n\t\tif (entry.isDirectory()) {\n\t\t\tif (!excludedDirs.has(entry.name) && depth < maxDepth) {\n\t\t\t\tscanDirectory(entryPath, depth + 1, maxDepth, excludedDirs, visitedDirectories, results);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.isSymbolicLink()) {\n\t\t\tscanSymbolicLink(entryPath, entry.name, depth, maxDepth, excludedDirs, visitedDirectories, results);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.isFile() && isRuleFile(entry.name)) {\n\t\t\tresults.push({ path: entryPath, realPath: resolveRealPath(entryPath) });\n\t\t}\n\t}\n}\n\nfunction scanSymbolicLink(\n\tlinkPath: string,\n\tlinkName: string,\n\tdepth: number,\n\tmaxDepth: number,\n\texcludedDirs: ReadonlySet<string>,\n\tvisitedDirectories: Set<string>,\n\tresults: ScannedFile[],\n): void {\n\tlet targetStats: Stats;\n\ttry {\n\t\ttargetStats = statSync(linkPath);\n\t} catch {\n\t\treturn;\n\t}\n\n\tif (targetStats.isDirectory()) {\n\t\tif (!excludedDirs.has(linkName) && depth < maxDepth) {\n\t\t\tscanDirectory(linkPath, depth + 1, maxDepth, excludedDirs, visitedDirectories, results);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (targetStats.isFile() && isRuleFile(linkName)) {\n\t\tresults.push({ path: linkPath, realPath: resolveRealPath(linkPath) });\n\t}\n}\n\nfunction isRuleFile(fileName: string): boolean {\n\treturn RULE_FILE_EXTENSIONS.some((extension) => fileName.endsWith(extension));\n}\n\nfunction resolveRealPath(filePath: string): string {\n\ttry {\n\t\tconst realPath = realpathSync.native(filePath);\n\t\tconst fileStats = lstatSync(filePath);\n\t\treturn fileStats.isSymbolicLink() ? realPath : filePath;\n\t} catch {\n\t\treturn filePath;\n\t}\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { ToolResultEvent } from "../../../types.ts";
2
+ export declare function isTrackedTool(toolName: string): boolean;
3
+ export declare function extractToolPaths(event: ToolResultEvent, cwd: string): string[];
4
+ //# sourceMappingURL=tool-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-paths.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/tool-paths.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIzD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB9E"}
@@ -0,0 +1,37 @@
1
+ import { isAbsolute, resolve } from "node:path";
2
+ import { TRACKED_BUILTIN_TOOL_SET } from "./constants.js";
3
+ export function isTrackedTool(toolName) {
4
+ return TRACKED_BUILTIN_TOOL_SET.has(toolName);
5
+ }
6
+ export function extractToolPaths(event, cwd) {
7
+ if (event.isError || !isTrackedTool(event.toolName)) {
8
+ return [];
9
+ }
10
+ const filePaths = new Set();
11
+ if (event.toolName === "read" || event.toolName === "edit") {
12
+ addPath(filePaths, getStringProperty(event.details, "filePath"), cwd);
13
+ addPath(filePaths, getStringProperty(event.input, "path"), cwd);
14
+ }
15
+ if (event.toolName === "write") {
16
+ addPath(filePaths, getStringProperty(event.input, "filePath"), cwd);
17
+ addPath(filePaths, getStringProperty(event.input, "path"), cwd);
18
+ }
19
+ return [...filePaths];
20
+ }
21
+ function addPath(filePaths, filePath, cwd) {
22
+ if (filePath === undefined || filePath.length === 0) {
23
+ return;
24
+ }
25
+ filePaths.add(isAbsolute(filePath) ? filePath : resolve(cwd, filePath));
26
+ }
27
+ function getStringProperty(value, propertyName) {
28
+ if (!isRecord(value)) {
29
+ return undefined;
30
+ }
31
+ const propertyValue = value[propertyName];
32
+ return typeof propertyValue === "string" ? propertyValue : undefined;
33
+ }
34
+ function isRecord(value) {
35
+ return typeof value === "object" && value !== null;
36
+ }
37
+ //# sourceMappingURL=tool-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-paths.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/tool-paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIhD,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC7C,OAAO,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAsB,EAAE,GAAW;IACnE,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC5D,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,GAAG,CAAC,CAAC;QACtE,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,GAAG,CAAC,CAAC;QACpE,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,OAAO,CAAC,SAAsB,EAAE,QAA4B,EAAE,GAAW;IACjF,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO;IACR,CAAC;IAED,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc,EAAE,YAAoB;IAC9D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;IAC1C,OAAO,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACpD,CAAC","sourcesContent":["import { isAbsolute, resolve } from \"node:path\";\n\nimport type { ToolResultEvent } from \"../../../types.ts\";\n\nimport { TRACKED_BUILTIN_TOOL_SET } from \"./constants.ts\";\n\nexport function isTrackedTool(toolName: string): boolean {\n\treturn TRACKED_BUILTIN_TOOL_SET.has(toolName);\n}\n\nexport function extractToolPaths(event: ToolResultEvent, cwd: string): string[] {\n\tif (event.isError || !isTrackedTool(event.toolName)) {\n\t\treturn [];\n\t}\n\n\tconst filePaths = new Set<string>();\n\n\tif (event.toolName === \"read\" || event.toolName === \"edit\") {\n\t\taddPath(filePaths, getStringProperty(event.details, \"filePath\"), cwd);\n\t\taddPath(filePaths, getStringProperty(event.input, \"path\"), cwd);\n\t}\n\n\tif (event.toolName === \"write\") {\n\t\taddPath(filePaths, getStringProperty(event.input, \"filePath\"), cwd);\n\t\taddPath(filePaths, getStringProperty(event.input, \"path\"), cwd);\n\t}\n\n\treturn [...filePaths];\n}\n\nfunction addPath(filePaths: Set<string>, filePath: string | undefined, cwd: string): void {\n\tif (filePath === undefined || filePath.length === 0) {\n\t\treturn;\n\t}\n\n\tfilePaths.add(isAbsolute(filePath) ? filePath : resolve(cwd, filePath));\n}\n\nfunction getStringProperty(value: unknown, propertyName: string): string | undefined {\n\tif (!isRecord(value)) {\n\t\treturn undefined;\n\t}\n\n\tconst propertyValue = value[propertyName];\n\treturn typeof propertyValue === \"string\" ? propertyValue : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import type { TruncationResult } from "./types.ts";
2
+ type BudgetRule = {
3
+ body: string;
4
+ relativePath: string;
5
+ };
6
+ type BudgetResult = BudgetRule & {
7
+ truncated: boolean;
8
+ };
9
+ export declare function truncateRule(body: string, options: {
10
+ maxChars: number;
11
+ relativePath: string;
12
+ }): TruncationResult;
13
+ export declare function truncateBudget(input: {
14
+ rules: ReadonlyArray<BudgetRule>;
15
+ maxResultChars: number;
16
+ }): BudgetResult[];
17
+ export {};
18
+ //# sourceMappingURL=truncator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncator.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/truncator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,KAAK,UAAU,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,YAAY,GAAG,UAAU,GAAG;IAChC,SAAS,EAAE,OAAO,CAAC;CACnB,CAAC;AAmBF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,gBAAgB,CAYhH;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,EAAE,CAuBlH"}
@@ -0,0 +1,46 @@
1
+ import { TRUNCATION_NOTICE } from "./constants.js";
2
+ function truncationNotice(relativePath) {
3
+ return TRUNCATION_NOTICE.replace("{path}", relativePath);
4
+ }
5
+ function safeSliceEnd(body, end) {
6
+ if (end <= 0) {
7
+ return 0;
8
+ }
9
+ const lastCodeUnit = body.charCodeAt(end - 1);
10
+ if (lastCodeUnit >= 0xd800 && lastCodeUnit <= 0xdbff) {
11
+ return end - 1;
12
+ }
13
+ return end;
14
+ }
15
+ export function truncateRule(body, options) {
16
+ if (body.length <= options.maxChars) {
17
+ return { body, truncated: false, originalLength: body.length };
18
+ }
19
+ const notice = truncationNotice(options.relativePath);
20
+ if (options.maxChars < notice.length) {
21
+ return { body: notice, truncated: true, originalLength: body.length };
22
+ }
23
+ const sliceEnd = safeSliceEnd(body, options.maxChars - notice.length);
24
+ return { body: `${body.slice(0, sliceEnd)}${notice}`, truncated: true, originalLength: body.length };
25
+ }
26
+ export function truncateBudget(input) {
27
+ const results = [];
28
+ let remainingBudget = input.maxResultChars;
29
+ for (const rule of input.rules) {
30
+ if (remainingBudget >= rule.body.length) {
31
+ results.push({ body: rule.body, truncated: false, relativePath: rule.relativePath });
32
+ remainingBudget -= rule.body.length;
33
+ continue;
34
+ }
35
+ const notice = truncationNotice(rule.relativePath);
36
+ if (remainingBudget <= notice.length) {
37
+ break;
38
+ }
39
+ const sliceEnd = safeSliceEnd(rule.body, remainingBudget - notice.length);
40
+ const body = `${rule.body.slice(0, sliceEnd)}${notice}`;
41
+ results.push({ body, truncated: true, relativePath: rule.relativePath });
42
+ remainingBudget -= body.length;
43
+ }
44
+ return results;
45
+ }
46
+ //# sourceMappingURL=truncator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncator.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/truncator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAYnD,SAAS,gBAAgB,CAAC,YAAoB;IAC7C,OAAO,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,GAAW;IAC9C,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACd,OAAO,CAAC,CAAC;IACV,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC9C,IAAI,YAAY,IAAI,MAAM,IAAI,YAAY,IAAI,MAAM,EAAE,CAAC;QACtD,OAAO,GAAG,GAAG,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,OAAmD;IAC7F,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACtD,IAAI,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IACvE,CAAC;IAED,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACtE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AACtG,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAmE;IACjG,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,IAAI,eAAe,GAAG,KAAK,CAAC,cAAc,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;YACrF,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;YACpC,SAAS;QACV,CAAC;QAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACnD,IAAI,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACtC,MAAM;QACP,CAAC;QAED,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1E,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,MAAM,EAAE,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QACzE,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC;IAChC,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC","sourcesContent":["import { TRUNCATION_NOTICE } from \"./constants.ts\";\nimport type { TruncationResult } from \"./types.ts\";\n\ntype BudgetRule = {\n\tbody: string;\n\trelativePath: string;\n};\n\ntype BudgetResult = BudgetRule & {\n\ttruncated: boolean;\n};\n\nfunction truncationNotice(relativePath: string): string {\n\treturn TRUNCATION_NOTICE.replace(\"{path}\", relativePath);\n}\n\nfunction safeSliceEnd(body: string, end: number): number {\n\tif (end <= 0) {\n\t\treturn 0;\n\t}\n\n\tconst lastCodeUnit = body.charCodeAt(end - 1);\n\tif (lastCodeUnit >= 0xd800 && lastCodeUnit <= 0xdbff) {\n\t\treturn end - 1;\n\t}\n\n\treturn end;\n}\n\nexport function truncateRule(body: string, options: { maxChars: number; relativePath: string }): TruncationResult {\n\tif (body.length <= options.maxChars) {\n\t\treturn { body, truncated: false, originalLength: body.length };\n\t}\n\n\tconst notice = truncationNotice(options.relativePath);\n\tif (options.maxChars < notice.length) {\n\t\treturn { body: notice, truncated: true, originalLength: body.length };\n\t}\n\n\tconst sliceEnd = safeSliceEnd(body, options.maxChars - notice.length);\n\treturn { body: `${body.slice(0, sliceEnd)}${notice}`, truncated: true, originalLength: body.length };\n}\n\nexport function truncateBudget(input: { rules: ReadonlyArray<BudgetRule>; maxResultChars: number }): BudgetResult[] {\n\tconst results: BudgetResult[] = [];\n\tlet remainingBudget = input.maxResultChars;\n\n\tfor (const rule of input.rules) {\n\t\tif (remainingBudget >= rule.body.length) {\n\t\t\tresults.push({ body: rule.body, truncated: false, relativePath: rule.relativePath });\n\t\t\tremainingBudget -= rule.body.length;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst notice = truncationNotice(rule.relativePath);\n\t\tif (remainingBudget <= notice.length) {\n\t\t\tbreak;\n\t\t}\n\n\t\tconst sliceEnd = safeSliceEnd(rule.body, remainingBudget - notice.length);\n\t\tconst body = `${rule.body.slice(0, sliceEnd)}${notice}`;\n\t\tresults.push({ body, truncated: true, relativePath: rule.relativePath });\n\t\tremainingBudget -= body.length;\n\t}\n\n\treturn results;\n}\n"]}