@code-yeongyu/senpi 2026.7.30-2 → 2026.7.31-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 (367) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/dist/core/agent-session.d.ts +48 -12
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +110 -18
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  7. package/dist/core/dynamic-prompt/build.js +4 -0
  8. package/dist/core/dynamic-prompt/build.js.map +1 -1
  9. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.d.ts +2 -2
  10. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.d.ts.map +1 -1
  11. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.js +25 -25
  12. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.js.map +1 -1
  13. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.d.ts.map +1 -1
  14. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.js.map +1 -1
  15. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.d.ts +1 -1
  16. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.d.ts.map +1 -1
  17. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.js +2 -2
  18. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.js.map +1 -1
  19. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.d.ts +9 -9
  20. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.d.ts.map +1 -1
  21. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.js +2 -2
  22. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.js.map +1 -1
  23. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.d.ts +1 -1
  24. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.d.ts.map +1 -1
  25. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.js +3 -3
  26. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.js.map +1 -1
  27. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.d.ts +21 -0
  28. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.d.ts.map +1 -0
  29. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.js +30 -0
  30. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.js.map +1 -0
  31. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/auth-lane.d.ts +8 -4
  32. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.d.ts.map +1 -0
  33. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/auth-lane.js +34 -25
  34. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js.map +1 -0
  35. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.d.ts.map +1 -1
  36. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.js.map +1 -1
  37. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.d.ts.map +1 -1
  38. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.js.map +1 -1
  39. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.d.ts +1 -1
  40. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.d.ts.map +1 -1
  41. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.js +1 -1
  42. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.js.map +1 -1
  43. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.d.ts.map +1 -1
  44. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.js.map +1 -1
  45. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.d.ts.map +1 -1
  46. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.js +1 -1
  47. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.js.map +1 -1
  48. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.d.ts +14 -0
  49. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.d.ts.map +1 -0
  50. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/guidance.js +37 -1
  51. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.js.map +1 -0
  52. package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts +4 -0
  53. package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts.map +1 -0
  54. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/index.js +12 -10
  55. package/dist/core/extensions/builtin/claude-sdk-oauth/index.js.map +1 -0
  56. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/oauth-login.d.ts +3 -3
  57. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/oauth-login.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/oauth-login.js +2 -2
  59. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js.map +1 -0
  60. package/dist/core/extensions/builtin/claude-sdk-oauth/options.d.ts +18 -0
  61. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/options.d.ts.map +1 -1
  62. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/options.js +70 -10
  63. package/dist/core/extensions/builtin/claude-sdk-oauth/options.js.map +1 -0
  64. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/prompt-bridge.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/prompt-bridge.js +32 -19
  66. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.js.map +1 -0
  67. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.d.ts +1 -0
  68. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.js.map +1 -1
  70. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.d.ts +30 -0
  71. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.d.ts.map +1 -0
  72. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js +197 -0
  73. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js.map +1 -0
  74. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.d.ts +18 -0
  75. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.d.ts.map +1 -0
  76. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.js +33 -0
  77. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.js.map +1 -0
  78. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts +3 -0
  79. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts.map +1 -0
  80. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js +134 -0
  81. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js.map +1 -0
  82. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts +85 -0
  83. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts.map +1 -0
  84. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js +270 -0
  85. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js.map +1 -0
  86. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts +17 -0
  87. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -0
  88. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +217 -0
  89. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -0
  90. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts +49 -0
  91. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -0
  92. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +204 -0
  93. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -0
  94. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts +28 -0
  95. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts.map +1 -0
  96. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js +107 -0
  97. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js.map +1 -0
  98. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.d.ts +2 -0
  99. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.d.ts.map +1 -0
  100. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.js +10 -0
  101. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.js.map +1 -0
  102. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.d.ts.map +1 -1
  103. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.js.map +1 -1
  104. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream.d.ts +1 -1
  105. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -0
  106. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream.js +72 -53
  107. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -0
  108. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.d.ts +3 -0
  109. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.d.ts.map +1 -0
  110. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.js +25 -0
  111. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.js.map +1 -0
  112. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.d.ts +1 -1
  113. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.d.ts.map +1 -1
  114. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.js +2 -2
  115. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.js.map +1 -1
  116. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.d.ts.map +1 -1
  117. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.js.map +1 -1
  118. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +18 -0
  119. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -0
  120. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +69 -0
  121. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -0
  122. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  123. package/dist/core/extensions/builtin/compaction/index.js +28 -2
  124. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  125. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +3 -0
  126. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -1
  127. package/dist/core/extensions/builtin/compaction/openai-remote.js +15 -4
  128. package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -1
  129. package/dist/core/extensions/builtin/compaction/speculative.d.ts +4 -1
  130. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  131. package/dist/core/extensions/builtin/compaction/speculative.js +39 -20
  132. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  133. package/dist/core/extensions/builtin/compaction/task-intent.d.ts +2 -6
  134. package/dist/core/extensions/builtin/compaction/task-intent.d.ts.map +1 -1
  135. package/dist/core/extensions/builtin/compaction/task-intent.js +10 -9
  136. package/dist/core/extensions/builtin/compaction/task-intent.js.map +1 -1
  137. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +6 -0
  138. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -0
  139. package/dist/core/extensions/builtin/goal/continuation-recovery.js +20 -0
  140. package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -0
  141. package/dist/core/extensions/builtin/goal/continuation.d.ts +2 -4
  142. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  143. package/dist/core/extensions/builtin/goal/continuation.js +2 -8
  144. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  145. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.d.ts +19 -0
  146. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.d.ts.map +1 -0
  147. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +48 -0
  148. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js.map +1 -0
  149. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  150. package/dist/core/extensions/builtin/goal/index.js +17 -15
  151. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  152. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
  153. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +12 -10
  154. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
  155. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts +5 -1
  156. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  157. package/dist/core/extensions/builtin/goal/monitor-continuation.js +94 -52
  158. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  159. package/dist/core/extensions/builtin/goal/persistence.d.ts +1 -0
  160. package/dist/core/extensions/builtin/goal/persistence.d.ts.map +1 -1
  161. package/dist/core/extensions/builtin/goal/persistence.js +49 -7
  162. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -1
  163. package/dist/core/extensions/builtin/goal/ui.d.ts +1 -0
  164. package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -1
  165. package/dist/core/extensions/builtin/goal/ui.js +11 -2
  166. package/dist/core/extensions/builtin/goal/ui.js.map +1 -1
  167. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  168. package/dist/core/extensions/builtin/index.js +5 -2
  169. package/dist/core/extensions/builtin/index.js.map +1 -1
  170. package/dist/core/extensions/builtin/loop-guard/detectors.d.ts +31 -0
  171. package/dist/core/extensions/builtin/loop-guard/detectors.d.ts.map +1 -0
  172. package/dist/core/extensions/builtin/loop-guard/detectors.js +111 -0
  173. package/dist/core/extensions/builtin/loop-guard/detectors.js.map +1 -0
  174. package/dist/core/extensions/builtin/loop-guard/index.d.ts +3 -0
  175. package/dist/core/extensions/builtin/loop-guard/index.d.ts.map +1 -0
  176. package/dist/core/extensions/builtin/loop-guard/index.js +31 -0
  177. package/dist/core/extensions/builtin/loop-guard/index.js.map +1 -0
  178. package/dist/core/extensions/builtin/loop-guard/notice.d.ts +5 -0
  179. package/dist/core/extensions/builtin/loop-guard/notice.d.ts.map +1 -0
  180. package/dist/core/extensions/builtin/loop-guard/notice.js +42 -0
  181. package/dist/core/extensions/builtin/loop-guard/notice.js.map +1 -0
  182. package/dist/core/extensions/builtin/loop-guard/policy.d.ts +30 -0
  183. package/dist/core/extensions/builtin/loop-guard/policy.d.ts.map +1 -0
  184. package/dist/core/extensions/builtin/loop-guard/policy.js +30 -0
  185. package/dist/core/extensions/builtin/loop-guard/policy.js.map +1 -0
  186. package/dist/core/extensions/builtin/loop-guard/renderer.d.ts +4 -0
  187. package/dist/core/extensions/builtin/loop-guard/renderer.d.ts.map +1 -0
  188. package/dist/core/extensions/builtin/loop-guard/renderer.js +50 -0
  189. package/dist/core/extensions/builtin/loop-guard/renderer.js.map +1 -0
  190. package/dist/core/extensions/builtin/loop-guard/similarity.d.ts +13 -0
  191. package/dist/core/extensions/builtin/loop-guard/similarity.d.ts.map +1 -0
  192. package/dist/core/extensions/builtin/loop-guard/similarity.js +51 -0
  193. package/dist/core/extensions/builtin/loop-guard/similarity.js.map +1 -0
  194. package/dist/core/extensions/builtin/loop-guard/tracker.d.ts +13 -0
  195. package/dist/core/extensions/builtin/loop-guard/tracker.d.ts.map +1 -0
  196. package/dist/core/extensions/builtin/loop-guard/tracker.js +39 -0
  197. package/dist/core/extensions/builtin/loop-guard/tracker.js.map +1 -0
  198. package/dist/core/extensions/builtin/monitor-state-event.d.ts +10 -0
  199. package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
  200. package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
  201. package/dist/core/extensions/builtin/prompt-preset/index.d.ts.map +1 -1
  202. package/dist/core/extensions/builtin/prompt-preset/index.js +8 -4
  203. package/dist/core/extensions/builtin/prompt-preset/index.js.map +1 -1
  204. package/dist/core/extensions/builtin/rules/index.js +4 -3
  205. package/dist/core/extensions/builtin/rules/index.js.map +1 -1
  206. package/dist/core/extensions/builtin/rules/rules/constants.d.ts +11 -0
  207. package/dist/core/extensions/builtin/rules/rules/constants.d.ts.map +1 -1
  208. package/dist/core/extensions/builtin/rules/rules/constants.js +11 -0
  209. package/dist/core/extensions/builtin/rules/rules/constants.js.map +1 -1
  210. package/dist/core/extensions/builtin/rules/rules/formatter.d.ts.map +1 -1
  211. package/dist/core/extensions/builtin/rules/rules/formatter.js +15 -1
  212. package/dist/core/extensions/builtin/rules/rules/formatter.js.map +1 -1
  213. package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
  214. package/dist/core/extensions/builtin/service-tier.js +23 -21
  215. package/dist/core/extensions/builtin/service-tier.js.map +1 -1
  216. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  217. package/dist/core/extensions/builtin/terminal/extension.js +21 -7
  218. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  219. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +2 -0
  220. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
  221. package/dist/core/extensions/builtin/terminal/monitor-registry.js +2 -0
  222. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
  223. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.d.ts +37 -0
  224. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.d.ts.map +1 -0
  225. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.js +61 -0
  226. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.js.map +1 -0
  227. package/dist/core/extensions/builtin/terminal/monitor-status.d.ts +9 -1
  228. package/dist/core/extensions/builtin/terminal/monitor-status.d.ts.map +1 -1
  229. package/dist/core/extensions/builtin/terminal/monitor-status.js +35 -2
  230. package/dist/core/extensions/builtin/terminal/monitor-status.js.map +1 -1
  231. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.d.ts +1 -1
  232. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.d.ts.map +1 -1
  233. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.js +88 -29
  234. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.js.map +1 -1
  235. package/dist/core/extensions/builtin/ttsr/builtin-rules.d.ts +4 -0
  236. package/dist/core/extensions/builtin/ttsr/builtin-rules.d.ts.map +1 -0
  237. package/dist/core/extensions/builtin/ttsr/builtin-rules.js +20 -0
  238. package/dist/core/extensions/builtin/ttsr/builtin-rules.js.map +1 -0
  239. package/dist/core/extensions/builtin/ttsr/commands.js +9 -1
  240. package/dist/core/extensions/builtin/ttsr/commands.js.map +1 -1
  241. package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
  242. package/dist/core/extensions/builtin/ttsr/index.js +4 -3
  243. package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
  244. package/dist/core/extensions/builtin/ttsr/manager.js +1 -1
  245. package/dist/core/extensions/builtin/ttsr/manager.js.map +1 -1
  246. package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts.map +1 -1
  247. package/dist/core/extensions/builtin/websearch/websearch/renderers.js +1 -1
  248. package/dist/core/extensions/builtin/websearch/websearch/renderers.js.map +1 -1
  249. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts.map +1 -1
  250. package/dist/core/extensions/builtin/websearch/websearch/search.js +1 -3
  251. package/dist/core/extensions/builtin/websearch/websearch/search.js.map +1 -1
  252. package/dist/core/extensions/index.d.ts +1 -1
  253. package/dist/core/extensions/index.d.ts.map +1 -1
  254. package/dist/core/extensions/index.js.map +1 -1
  255. package/dist/core/extensions/loader.d.ts.map +1 -1
  256. package/dist/core/extensions/loader.js +5 -0
  257. package/dist/core/extensions/loader.js.map +1 -1
  258. package/dist/core/extensions/runner.d.ts +1 -1
  259. package/dist/core/extensions/runner.d.ts.map +1 -1
  260. package/dist/core/extensions/runner.js +3 -1
  261. package/dist/core/extensions/runner.js.map +1 -1
  262. package/dist/core/extensions/types.d.ts +22 -1
  263. package/dist/core/extensions/types.d.ts.map +1 -1
  264. package/dist/core/extensions/types.js.map +1 -1
  265. package/dist/core/thinking-levels.d.ts.map +1 -1
  266. package/dist/core/thinking-levels.js +23 -3
  267. package/dist/core/thinking-levels.js.map +1 -1
  268. package/dist/index.d.ts +1 -1
  269. package/dist/index.d.ts.map +1 -1
  270. package/dist/index.js.map +1 -1
  271. package/dist/modes/app-server/server/account.d.ts +1 -1
  272. package/dist/modes/app-server/server/account.js +1 -1
  273. package/dist/modes/app-server/server/account.js.map +1 -1
  274. package/dist/modes/app-server/server/server-core.js +1 -1
  275. package/dist/modes/app-server/server/server-core.js.map +1 -1
  276. package/dist/modes/interactive/compaction-queue-transfer.d.ts +2 -0
  277. package/dist/modes/interactive/compaction-queue-transfer.d.ts.map +1 -1
  278. package/dist/modes/interactive/compaction-queue-transfer.js.map +1 -1
  279. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/footer.js +9 -5
  281. package/dist/modes/interactive/components/footer.js.map +1 -1
  282. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  283. package/dist/modes/interactive/interactive-mode.js +37 -11
  284. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  285. package/dist/modes/rpc/connection-handler.js +3 -3
  286. package/dist/modes/rpc/connection-handler.js.map +1 -1
  287. package/docs/extensions.md +10 -0
  288. package/docs/providers.md +21 -5
  289. package/docs/release-guide.md +2 -2
  290. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +27 -0
  291. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  292. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-status-ticker.ts +79 -0
  293. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-status.ts +36 -3
  294. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +26 -12
  295. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +9 -0
  296. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  297. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +1 -0
  298. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  299. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  300. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  301. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +10 -15
  302. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  303. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +2 -2
  304. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  305. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +2 -2
  306. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  307. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +2 -2
  308. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  309. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +2 -2
  310. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  311. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +1 -0
  312. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  313. package/node_modules/@earendil-works/pi-ai/dist/models.js +69 -19
  314. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  315. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  316. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  317. package/node_modules/@earendil-works/pi-ai/dist/providers/data/azure-openai-responses.json +1 -1
  318. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  319. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  320. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  321. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  322. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  323. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  324. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +5 -0
  325. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  326. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  327. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.d.ts +3 -0
  328. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.d.ts.map +1 -0
  329. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.js +36 -0
  330. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.js.map +1 -0
  331. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  332. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  333. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  334. package/package.json +6 -6
  335. package/dist/core/extensions/builtin/claude-agent-sdk/auth-lane.d.ts.map +0 -1
  336. package/dist/core/extensions/builtin/claude-agent-sdk/auth-lane.js.map +0 -1
  337. package/dist/core/extensions/builtin/claude-agent-sdk/guidance.d.ts +0 -6
  338. package/dist/core/extensions/builtin/claude-agent-sdk/guidance.d.ts.map +0 -1
  339. package/dist/core/extensions/builtin/claude-agent-sdk/guidance.js.map +0 -1
  340. package/dist/core/extensions/builtin/claude-agent-sdk/index.d.ts +0 -4
  341. package/dist/core/extensions/builtin/claude-agent-sdk/index.d.ts.map +0 -1
  342. package/dist/core/extensions/builtin/claude-agent-sdk/index.js.map +0 -1
  343. package/dist/core/extensions/builtin/claude-agent-sdk/oauth-login.js.map +0 -1
  344. package/dist/core/extensions/builtin/claude-agent-sdk/options.d.ts +0 -16
  345. package/dist/core/extensions/builtin/claude-agent-sdk/options.js.map +0 -1
  346. package/dist/core/extensions/builtin/claude-agent-sdk/prompt-bridge.js.map +0 -1
  347. package/dist/core/extensions/builtin/claude-agent-sdk/settings.d.ts +0 -15
  348. package/dist/core/extensions/builtin/claude-agent-sdk/settings.d.ts.map +0 -1
  349. package/dist/core/extensions/builtin/claude-agent-sdk/settings.js +0 -41
  350. package/dist/core/extensions/builtin/claude-agent-sdk/settings.js.map +0 -1
  351. package/dist/core/extensions/builtin/claude-agent-sdk/stream.d.ts.map +0 -1
  352. package/dist/core/extensions/builtin/claude-agent-sdk/stream.js.map +0 -1
  353. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.d.ts +0 -0
  354. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.js +0 -0
  355. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.d.ts +0 -0
  356. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.js +0 -0
  357. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.d.ts +0 -0
  358. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.js +0 -0
  359. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.d.ts +0 -0
  360. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.js +0 -0
  361. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.d.ts +0 -0
  362. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/prompt-bridge.d.ts +0 -0
  363. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.js +0 -0
  364. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.d.ts +0 -0
  365. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.js +0 -0
  366. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.d.ts +0 -0
  367. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.js +0 -0
@@ -0,0 +1,31 @@
1
+ import { detectLoop, NoticeGate } from "./detectors.js";
2
+ import { buildLoopGuardReminder, LOOP_GUARD_NOTICE_CUSTOM_TYPE } from "./notice.js";
3
+ import { renderLoopGuardNotice } from "./renderer.js";
4
+ import { ToolCallTracker } from "./tracker.js";
5
+ export default function loopGuardExtension(pi) {
6
+ const tracker = new ToolCallTracker();
7
+ const gate = new NoticeGate();
8
+ const reset = () => {
9
+ tracker.reset();
10
+ gate.reset();
11
+ };
12
+ pi.registerMessageRenderer(LOOP_GUARD_NOTICE_CUSTOM_TYPE, renderLoopGuardNotice);
13
+ pi.on("session_start", () => reset());
14
+ pi.on("input", (event) => {
15
+ if (event.source !== "extension")
16
+ reset();
17
+ });
18
+ pi.on("tool_execution_start", (event) => {
19
+ tracker.record(event.toolName, event.args);
20
+ const detection = detectLoop(tracker.records, gate);
21
+ if (detection === undefined)
22
+ return;
23
+ pi.sendMessage({
24
+ customType: LOOP_GUARD_NOTICE_CUSTOM_TYPE,
25
+ content: buildLoopGuardReminder(detection),
26
+ display: true,
27
+ details: detection,
28
+ }, { triggerTurn: false, deliverAs: "steer" });
29
+ });
30
+ }
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EAAgB;IAC1D,MAAM,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;IAE9B,MAAM,KAAK,GAAG,GAAS,EAAE;QACxB,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,IAAI,CAAC,KAAK,EAAE,CAAC;IACd,CAAC,CAAC;IAEF,EAAE,CAAC,uBAAuB,CAAC,6BAA6B,EAAE,qBAAqB,CAAC,CAAC;IAEjF,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;IAEtC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QACxB,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;YAAE,KAAK,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,sBAAsB,EAAE,CAAC,KAAK,EAAE,EAAE;QACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACpD,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO;QACpC,EAAE,CAAC,WAAW,CACb;YACC,UAAU,EAAE,6BAA6B;YACzC,OAAO,EAAE,sBAAsB,CAAC,SAAS,CAAC;YAC1C,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,SAAS;SAClB,EACD,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAC1C,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { ExtensionAPI } from \"../../types.ts\";\nimport { detectLoop, NoticeGate } from \"./detectors.ts\";\nimport { buildLoopGuardReminder, LOOP_GUARD_NOTICE_CUSTOM_TYPE } from \"./notice.ts\";\nimport { renderLoopGuardNotice } from \"./renderer.ts\";\nimport { ToolCallTracker } from \"./tracker.ts\";\n\nexport default function loopGuardExtension(pi: ExtensionAPI): void {\n\tconst tracker = new ToolCallTracker();\n\tconst gate = new NoticeGate();\n\n\tconst reset = (): void => {\n\t\ttracker.reset();\n\t\tgate.reset();\n\t};\n\n\tpi.registerMessageRenderer(LOOP_GUARD_NOTICE_CUSTOM_TYPE, renderLoopGuardNotice);\n\n\tpi.on(\"session_start\", () => reset());\n\n\tpi.on(\"input\", (event) => {\n\t\tif (event.source !== \"extension\") reset();\n\t});\n\n\tpi.on(\"tool_execution_start\", (event) => {\n\t\ttracker.record(event.toolName, event.args);\n\t\tconst detection = detectLoop(tracker.records, gate);\n\t\tif (detection === undefined) return;\n\t\tpi.sendMessage(\n\t\t\t{\n\t\t\t\tcustomType: LOOP_GUARD_NOTICE_CUSTOM_TYPE,\n\t\t\t\tcontent: buildLoopGuardReminder(detection),\n\t\t\t\tdisplay: true,\n\t\t\t\tdetails: detection,\n\t\t\t},\n\t\t\t{ triggerTurn: false, deliverAs: \"steer\" },\n\t\t);\n\t});\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import type { LoopGuardDetection } from "./detectors.ts";
2
+ export declare const LOOP_GUARD_NOTICE_CUSTOM_TYPE = "loop-guard:notice";
3
+ export type LoopGuardNoticeDetails = LoopGuardDetection;
4
+ export declare function buildLoopGuardReminder(detection: LoopGuardDetection): string;
5
+ //# sourceMappingURL=notice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notice.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/notice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,eAAO,MAAM,6BAA6B,sBAAsB,CAAC;AAEjE,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,CAAC;AAExD,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,kBAAkB,GAAG,MAAM,CAuC5E"}
@@ -0,0 +1,42 @@
1
+ export const LOOP_GUARD_NOTICE_CUSTOM_TYPE = "loop-guard:notice";
2
+ export function buildLoopGuardReminder(detection) {
3
+ switch (detection.kind) {
4
+ case "identical": {
5
+ const { toolName, count } = detection;
6
+ return [
7
+ `<system-reminder>`,
8
+ `LOOP GUARD - IDENTICAL TOOL CALLS: you called \`${toolName}\` ${count} times in a row with the EXACT same arguments. This is the tool-call stream, not consecutive text - another tool ran between these calls and it changed nothing about your plan. Re-issuing the same call returns the same result. Snap out of it:`,
9
+ `- reuse the result you already received from this exact call;`,
10
+ `- if you were re-checking for new output or state, switch to the monitor/watch tool or change one parameter deliberately (filter, offset, query);`,
11
+ `- if nothing is actually changing, stop calling this tool, state what is blocking you, and try a different tool or ask the user.`,
12
+ `Do not call \`${toolName}\` again with identical arguments.`,
13
+ `</system-reminder>`,
14
+ ].join("\n");
15
+ }
16
+ case "similar": {
17
+ const { toolName, count, similarity } = detection;
18
+ const percent = Math.round(similarity * 100);
19
+ return [
20
+ `<system-reminder>`,
21
+ `LOOP GUARD - NEAR-IDENTICAL TOOL CALLS: your last ${count} calls to \`${toolName}\` had arguments about ${percent}% identical (bigram similarity over canonical args). This may be legitimate batch work - or it may be a lazy loop that only LOOKS like progress. Attention check:`,
22
+ `- if these calls target genuinely different inputs (distinct files, queries, offsets), continue deliberately - but consider batching or widening the scope instead of one call per tiny variation;`,
23
+ `- if you are scanning output incrementally (reads, peeks, polls), widen the window once or use the monitor/watch tool rather than nudging parameters;`,
24
+ `- if the results keep saying the same thing, change strategy now - a different tool, a wider query, or asking the user beats a sixth near-copy.`,
25
+ `</system-reminder>`,
26
+ ].join("\n");
27
+ }
28
+ case "cycle": {
29
+ const { period, count, cycleTools } = detection;
30
+ const pattern = cycleTools.join(" -> ");
31
+ return [
32
+ `<system-reminder>`,
33
+ `LOOP GUARD - REPEATING TOOL-CALL PATTERN: your recent tool calls repeat the cycle [${pattern}] ${count} times (period ${period}), with other calls possibly interleaved between repetitions. A fixed rotation usually means waiting, guessing, or searching without a discriminator:`,
34
+ `- if this is a wait/poll rotation (spawn then peek, write then check), replace the rotation with the monitor/watch tool and react to the decisive event instead;`,
35
+ `- if this is a search rotation, change ONE axis decisively: broader query, different tool, or a different source - repeating the same rotation at the same parameters will not find new information;`,
36
+ `- if the cycle is genuinely progressing (each rotation moves distinct work forward), keep going - but say what each rotation accomplished so the next rotation can end.`,
37
+ `</system-reminder>`,
38
+ ].join("\n");
39
+ }
40
+ }
41
+ }
42
+ //# sourceMappingURL=notice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notice.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/notice.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,6BAA6B,GAAG,mBAAmB,CAAC;AAIjE,MAAM,UAAU,sBAAsB,CAAC,SAA6B;IACnE,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;QACxB,KAAK,WAAW,EAAE,CAAC;YAClB,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;YACtC,OAAO;gBACN,mBAAmB;gBACnB,mDAAmD,QAAQ,MAAM,KAAK,oPAAoP;gBAC1T,+DAA+D;gBAC/D,mJAAmJ;gBACnJ,kIAAkI;gBAClI,iBAAiB,QAAQ,oCAAoC;gBAC7D,oBAAoB;aACpB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,CAAC;QACD,KAAK,SAAS,EAAE,CAAC;YAChB,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,SAAS,CAAC;YAClD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;YAC7C,OAAO;gBACN,mBAAmB;gBACnB,qDAAqD,KAAK,eAAe,QAAQ,0BAA0B,OAAO,mKAAmK;gBACrR,oMAAoM;gBACpM,uJAAuJ;gBACvJ,iJAAiJ;gBACjJ,oBAAoB;aACpB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,CAAC;QACD,KAAK,OAAO,EAAE,CAAC;YACd,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,SAAS,CAAC;YAChD,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACxC,OAAO;gBACN,mBAAmB;gBACnB,sFAAsF,OAAO,KAAK,KAAK,kBAAkB,MAAM,uJAAuJ;gBACtR,kKAAkK;gBAClK,sMAAsM;gBACtM,yKAAyK;gBACzK,oBAAoB;aACpB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["import type { LoopGuardDetection } from \"./detectors.ts\";\n\nexport const LOOP_GUARD_NOTICE_CUSTOM_TYPE = \"loop-guard:notice\";\n\nexport type LoopGuardNoticeDetails = LoopGuardDetection;\n\nexport function buildLoopGuardReminder(detection: LoopGuardDetection): string {\n\tswitch (detection.kind) {\n\t\tcase \"identical\": {\n\t\t\tconst { toolName, count } = detection;\n\t\t\treturn [\n\t\t\t\t`<system-reminder>`,\n\t\t\t\t`LOOP GUARD - IDENTICAL TOOL CALLS: you called \\`${toolName}\\` ${count} times in a row with the EXACT same arguments. This is the tool-call stream, not consecutive text - another tool ran between these calls and it changed nothing about your plan. Re-issuing the same call returns the same result. Snap out of it:`,\n\t\t\t\t`- reuse the result you already received from this exact call;`,\n\t\t\t\t`- if you were re-checking for new output or state, switch to the monitor/watch tool or change one parameter deliberately (filter, offset, query);`,\n\t\t\t\t`- if nothing is actually changing, stop calling this tool, state what is blocking you, and try a different tool or ask the user.`,\n\t\t\t\t`Do not call \\`${toolName}\\` again with identical arguments.`,\n\t\t\t\t`</system-reminder>`,\n\t\t\t].join(\"\\n\");\n\t\t}\n\t\tcase \"similar\": {\n\t\t\tconst { toolName, count, similarity } = detection;\n\t\t\tconst percent = Math.round(similarity * 100);\n\t\t\treturn [\n\t\t\t\t`<system-reminder>`,\n\t\t\t\t`LOOP GUARD - NEAR-IDENTICAL TOOL CALLS: your last ${count} calls to \\`${toolName}\\` had arguments about ${percent}% identical (bigram similarity over canonical args). This may be legitimate batch work - or it may be a lazy loop that only LOOKS like progress. Attention check:`,\n\t\t\t\t`- if these calls target genuinely different inputs (distinct files, queries, offsets), continue deliberately - but consider batching or widening the scope instead of one call per tiny variation;`,\n\t\t\t\t`- if you are scanning output incrementally (reads, peeks, polls), widen the window once or use the monitor/watch tool rather than nudging parameters;`,\n\t\t\t\t`- if the results keep saying the same thing, change strategy now - a different tool, a wider query, or asking the user beats a sixth near-copy.`,\n\t\t\t\t`</system-reminder>`,\n\t\t\t].join(\"\\n\");\n\t\t}\n\t\tcase \"cycle\": {\n\t\t\tconst { period, count, cycleTools } = detection;\n\t\t\tconst pattern = cycleTools.join(\" -> \");\n\t\t\treturn [\n\t\t\t\t`<system-reminder>`,\n\t\t\t\t`LOOP GUARD - REPEATING TOOL-CALL PATTERN: your recent tool calls repeat the cycle [${pattern}] ${count} times (period ${period}), with other calls possibly interleaved between repetitions. A fixed rotation usually means waiting, guessing, or searching without a discriminator:`,\n\t\t\t\t`- if this is a wait/poll rotation (spawn then peek, write then check), replace the rotation with the monitor/watch tool and react to the decisive event instead;`,\n\t\t\t\t`- if this is a search rotation, change ONE axis decisively: broader query, different tool, or a different source - repeating the same rotation at the same parameters will not find new information;`,\n\t\t\t\t`- if the cycle is genuinely progressing (each rotation moves distinct work forward), keep going - but say what each rotation accomplished so the next rotation can end.`,\n\t\t\t\t`</system-reminder>`,\n\t\t\t].join(\"\\n\");\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Loop-guard thresholds.
3
+ *
4
+ * Evidence base (see changes.md for the full rationale):
5
+ * - gemini-cli LoopDetectionService: sha256(name+args) signatures, cycle periods 1..5,
6
+ * threshold 5 repetitions — but it HALTS the run. Loop-guard only steers a reminder,
7
+ * so it can afford to fire earlier.
8
+ * - OpenHands stuck detector: 4+ identical action-observation pairs, 3+ error cycles,
9
+ * 6+ alternating ping-pong cycles — also halting behavior.
10
+ * - Corpus of 400 real senpi sessions: productive same-tool runs (bash/eval/edit/todo)
11
+ * show mean adjacent-args bigram-Dice ~0.52-0.55 (p90 <= 0.72), while repetitive
12
+ * classes (read pagination, bash_output/task_output polling) sit at 0.84-0.93.
13
+ * 0.85 cleanly separates distinct work from near-identical repetition.
14
+ */
15
+ /** Max tool-call records kept per prompt segment. Covers 6-period cycles at escalated counts. */
16
+ export declare const TRACK_WINDOW = 64;
17
+ /** Consecutive byte-identical (tool + canonical args) calls before the firm reminder fires. */
18
+ export declare const IDENTICAL_RUN_THRESHOLD = 3;
19
+ /** Consecutive same-tool calls with near-identical args before the caution fires. */
20
+ export declare const SIMILAR_RUN_THRESHOLD = 5;
21
+ /** Mean adjacent bigram-Dice similarity over canonical args that counts as "near-identical". */
22
+ export declare const SIMILARITY_THRESHOLD = 0.85;
23
+ /** Cycle period bounds (period 1 is the identical detector's job). */
24
+ export declare const CYCLE_MIN_PERIOD = 2;
25
+ export declare const CYCLE_MAX_PERIOD = 6;
26
+ /** Full cycle repetitions before the pattern notice fires. */
27
+ export declare const CYCLE_REPETITION_THRESHOLD = 3;
28
+ /** A pattern that keeps growing re-notifies only when its count reaches this multiple of the last notice. */
29
+ export declare const ESCALATION_FACTOR = 2;
30
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,iGAAiG;AACjG,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B,+FAA+F;AAC/F,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,gGAAgG;AAChG,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,8DAA8D;AAC9D,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C,6GAA6G;AAC7G,eAAO,MAAM,iBAAiB,IAAI,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Loop-guard thresholds.
3
+ *
4
+ * Evidence base (see changes.md for the full rationale):
5
+ * - gemini-cli LoopDetectionService: sha256(name+args) signatures, cycle periods 1..5,
6
+ * threshold 5 repetitions — but it HALTS the run. Loop-guard only steers a reminder,
7
+ * so it can afford to fire earlier.
8
+ * - OpenHands stuck detector: 4+ identical action-observation pairs, 3+ error cycles,
9
+ * 6+ alternating ping-pong cycles — also halting behavior.
10
+ * - Corpus of 400 real senpi sessions: productive same-tool runs (bash/eval/edit/todo)
11
+ * show mean adjacent-args bigram-Dice ~0.52-0.55 (p90 <= 0.72), while repetitive
12
+ * classes (read pagination, bash_output/task_output polling) sit at 0.84-0.93.
13
+ * 0.85 cleanly separates distinct work from near-identical repetition.
14
+ */
15
+ /** Max tool-call records kept per prompt segment. Covers 6-period cycles at escalated counts. */
16
+ export const TRACK_WINDOW = 64;
17
+ /** Consecutive byte-identical (tool + canonical args) calls before the firm reminder fires. */
18
+ export const IDENTICAL_RUN_THRESHOLD = 3;
19
+ /** Consecutive same-tool calls with near-identical args before the caution fires. */
20
+ export const SIMILAR_RUN_THRESHOLD = 5;
21
+ /** Mean adjacent bigram-Dice similarity over canonical args that counts as "near-identical". */
22
+ export const SIMILARITY_THRESHOLD = 0.85;
23
+ /** Cycle period bounds (period 1 is the identical detector's job). */
24
+ export const CYCLE_MIN_PERIOD = 2;
25
+ export const CYCLE_MAX_PERIOD = 6;
26
+ /** Full cycle repetitions before the pattern notice fires. */
27
+ export const CYCLE_REPETITION_THRESHOLD = 3;
28
+ /** A pattern that keeps growing re-notifies only when its count reaches this multiple of the last notice. */
29
+ export const ESCALATION_FACTOR = 2;
30
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,iGAAiG;AACjG,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAE/B,+FAA+F;AAC/F,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC,qFAAqF;AACrF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEvC,gGAAgG;AAChG,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAEzC,sEAAsE;AACtE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,8DAA8D;AAC9D,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAE5C,6GAA6G;AAC7G,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC","sourcesContent":["/**\n * Loop-guard thresholds.\n *\n * Evidence base (see changes.md for the full rationale):\n * - gemini-cli LoopDetectionService: sha256(name+args) signatures, cycle periods 1..5,\n * threshold 5 repetitions — but it HALTS the run. Loop-guard only steers a reminder,\n * so it can afford to fire earlier.\n * - OpenHands stuck detector: 4+ identical action-observation pairs, 3+ error cycles,\n * 6+ alternating ping-pong cycles — also halting behavior.\n * - Corpus of 400 real senpi sessions: productive same-tool runs (bash/eval/edit/todo)\n * show mean adjacent-args bigram-Dice ~0.52-0.55 (p90 <= 0.72), while repetitive\n * classes (read pagination, bash_output/task_output polling) sit at 0.84-0.93.\n * 0.85 cleanly separates distinct work from near-identical repetition.\n */\n\n/** Max tool-call records kept per prompt segment. Covers 6-period cycles at escalated counts. */\nexport const TRACK_WINDOW = 64;\n\n/** Consecutive byte-identical (tool + canonical args) calls before the firm reminder fires. */\nexport const IDENTICAL_RUN_THRESHOLD = 3;\n\n/** Consecutive same-tool calls with near-identical args before the caution fires. */\nexport const SIMILAR_RUN_THRESHOLD = 5;\n\n/** Mean adjacent bigram-Dice similarity over canonical args that counts as \"near-identical\". */\nexport const SIMILARITY_THRESHOLD = 0.85;\n\n/** Cycle period bounds (period 1 is the identical detector's job). */\nexport const CYCLE_MIN_PERIOD = 2;\nexport const CYCLE_MAX_PERIOD = 6;\n\n/** Full cycle repetitions before the pattern notice fires. */\nexport const CYCLE_REPETITION_THRESHOLD = 3;\n\n/** A pattern that keeps growing re-notifies only when its count reaches this multiple of the last notice. */\nexport const ESCALATION_FACTOR = 2;\n"]}
@@ -0,0 +1,4 @@
1
+ import type { MessageRenderer } from "../../types.ts";
2
+ import type { LoopGuardDetection } from "./detectors.ts";
3
+ export declare const renderLoopGuardNotice: MessageRenderer<LoopGuardDetection>;
4
+ //# sourceMappingURL=renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/renderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAKzD,eAAO,MAAM,qBAAqB,EAAE,eAAe,CAAC,kBAAkB,CAUrE,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { Box, Text } from "@earendil-works/pi-tui";
2
+ const BOLD = "\u001b[1m";
3
+ const BOLD_OFF = "\u001b[22m";
4
+ export const renderLoopGuardNotice = (message, options, theme) => {
5
+ const details = message.details;
6
+ if (details === undefined)
7
+ return undefined;
8
+ const box = new Box(1, 1, (text) => theme.bg("customMessageBg", text));
9
+ box.addChild(new Text(theme.fg("accent", `${BOLD}${titleLine(details)}${BOLD_OFF}`), 0, 0));
10
+ box.addChild(new Text(theme.fg("dim", whyLine(details)), 0, 0));
11
+ if (options.expanded) {
12
+ box.addChild(new Text(theme.fg("dim", expandedLine(details)), 0, 0));
13
+ }
14
+ return box;
15
+ };
16
+ function titleLine(detection) {
17
+ switch (detection.kind) {
18
+ case "identical":
19
+ return `⚠ Loop guard · identical calls ×${detection.count} (${detection.toolName})`;
20
+ case "similar":
21
+ return `⚠ Loop guard · near-identical calls ×${detection.count} (${detection.toolName})`;
22
+ case "cycle":
23
+ return `⚠ Loop guard · repeating pattern ×${detection.count} (period ${detection.period})`;
24
+ }
25
+ }
26
+ function whyLine(detection) {
27
+ switch (detection.kind) {
28
+ case "identical":
29
+ return "Same tool, same arguments, again. The agent was told to reuse the result or change the call.";
30
+ case "similar": {
31
+ const percent = Math.round(detection.similarity * 100);
32
+ return `Argument similarity ~${percent}%. The agent was told to verify this is distinct work, not a lazy loop.`;
33
+ }
34
+ case "cycle": {
35
+ const pattern = detection.cycleTools.join(" -> ");
36
+ return `Tool-call cycle [${pattern}]. The agent was told to break the rotation or justify the progress.`;
37
+ }
38
+ }
39
+ }
40
+ function expandedLine(detection) {
41
+ switch (detection.kind) {
42
+ case "identical":
43
+ return `tool ${detection.toolName} · ${detection.count} consecutive identical calls when the reminder fired`;
44
+ case "similar":
45
+ return `tool ${detection.toolName} · ${detection.count} consecutive same-tool calls at ~${Math.round(detection.similarity * 100)}% args similarity`;
46
+ case "cycle":
47
+ return `cycle ${detection.cycleTools.join(" -> ")} · ${detection.count} full repetitions in the tracked window`;
48
+ }
49
+ }
50
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { Box, Text } from \"@earendil-works/pi-tui\";\nimport type { MessageRenderer } from \"../../types.ts\";\nimport type { LoopGuardDetection } from \"./detectors.ts\";\n\nconst BOLD = \"\\u001b[1m\";\nconst BOLD_OFF = \"\\u001b[22m\";\n\nexport const renderLoopGuardNotice: MessageRenderer<LoopGuardDetection> = (message, options, theme) => {\n\tconst details = message.details;\n\tif (details === undefined) return undefined;\n\tconst box = new Box(1, 1, (text) => theme.bg(\"customMessageBg\", text));\n\tbox.addChild(new Text(theme.fg(\"accent\", `${BOLD}${titleLine(details)}${BOLD_OFF}`), 0, 0));\n\tbox.addChild(new Text(theme.fg(\"dim\", whyLine(details)), 0, 0));\n\tif (options.expanded) {\n\t\tbox.addChild(new Text(theme.fg(\"dim\", expandedLine(details)), 0, 0));\n\t}\n\treturn box;\n};\n\nfunction titleLine(detection: LoopGuardDetection): string {\n\tswitch (detection.kind) {\n\t\tcase \"identical\":\n\t\t\treturn `⚠ Loop guard · identical calls ×${detection.count} (${detection.toolName})`;\n\t\tcase \"similar\":\n\t\t\treturn `⚠ Loop guard · near-identical calls ×${detection.count} (${detection.toolName})`;\n\t\tcase \"cycle\":\n\t\t\treturn `⚠ Loop guard · repeating pattern ×${detection.count} (period ${detection.period})`;\n\t}\n}\n\nfunction whyLine(detection: LoopGuardDetection): string {\n\tswitch (detection.kind) {\n\t\tcase \"identical\":\n\t\t\treturn \"Same tool, same arguments, again. The agent was told to reuse the result or change the call.\";\n\t\tcase \"similar\": {\n\t\t\tconst percent = Math.round(detection.similarity * 100);\n\t\t\treturn `Argument similarity ~${percent}%. The agent was told to verify this is distinct work, not a lazy loop.`;\n\t\t}\n\t\tcase \"cycle\": {\n\t\t\tconst pattern = detection.cycleTools.join(\" -> \");\n\t\t\treturn `Tool-call cycle [${pattern}]. The agent was told to break the rotation or justify the progress.`;\n\t\t}\n\t}\n}\n\nfunction expandedLine(detection: LoopGuardDetection): string {\n\tswitch (detection.kind) {\n\t\tcase \"identical\":\n\t\t\treturn `tool ${detection.toolName} · ${detection.count} consecutive identical calls when the reminder fired`;\n\t\tcase \"similar\":\n\t\t\treturn `tool ${detection.toolName} · ${detection.count} consecutive same-tool calls at ~${Math.round(detection.similarity * 100)}% args similarity`;\n\t\tcase \"cycle\":\n\t\t\treturn `cycle ${detection.cycleTools.join(\" -> \")} · ${detection.count} full repetitions in the tracked window`;\n\t}\n}\n"]}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Character-bigram Sørensen–Dice similarity over canonical argument JSON.
3
+ *
4
+ * Chosen over token-level or edit-distance metrics because canonical JSON keeps
5
+ * structure stable (sorted keys, fixed separators), making bigram overlap a cheap
6
+ * and order-insensitive-enough proxy for "same call shape, slightly different values".
7
+ */
8
+ export type BigramCounts = Map<string, number>;
9
+ export declare function bigramCounts(text: string): BigramCounts;
10
+ export declare function diceSimilarity(a: BigramCounts, b: BigramCounts): number;
11
+ /** Mean similarity between each adjacent pair of argument strings. */
12
+ export declare function meanAdjacentSimilarity(argStrings: readonly string[]): number;
13
+ //# sourceMappingURL=similarity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"similarity.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/similarity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE/C,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAOvD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,MAAM,CAcvE;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAW5E"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Character-bigram Sørensen–Dice similarity over canonical argument JSON.
3
+ *
4
+ * Chosen over token-level or edit-distance metrics because canonical JSON keeps
5
+ * structure stable (sorted keys, fixed separators), making bigram overlap a cheap
6
+ * and order-insensitive-enough proxy for "same call shape, slightly different values".
7
+ */
8
+ export function bigramCounts(text) {
9
+ const counts = new Map();
10
+ for (let i = 0; i < text.length - 1; i++) {
11
+ const gram = text.slice(i, i + 2);
12
+ counts.set(gram, (counts.get(gram) ?? 0) + 1);
13
+ }
14
+ return counts;
15
+ }
16
+ export function diceSimilarity(a, b) {
17
+ let totalA = 0;
18
+ for (const count of a.values())
19
+ totalA += count;
20
+ let totalB = 0;
21
+ for (const count of b.values())
22
+ totalB += count;
23
+ if (totalA === 0 && totalB === 0)
24
+ return 1;
25
+ if (totalA === 0 || totalB === 0)
26
+ return 0;
27
+ let intersection = 0;
28
+ const [small, large] = a.size <= b.size ? [a, b] : [b, a];
29
+ for (const [gram, count] of small) {
30
+ const other = large.get(gram);
31
+ if (other !== undefined)
32
+ intersection += Math.min(count, other);
33
+ }
34
+ return (2 * intersection) / (totalA + totalB);
35
+ }
36
+ /** Mean similarity between each adjacent pair of argument strings. */
37
+ export function meanAdjacentSimilarity(argStrings) {
38
+ if (argStrings.length < 2)
39
+ return 1;
40
+ const grams = argStrings.map(bigramCounts);
41
+ let total = 0;
42
+ for (let i = 0; i < grams.length - 1; i++) {
43
+ const current = grams[i];
44
+ const next = grams[i + 1];
45
+ if (current === undefined || next === undefined)
46
+ continue;
47
+ total += diceSimilarity(current, next);
48
+ }
49
+ return total / (grams.length - 1);
50
+ }
51
+ //# sourceMappingURL=similarity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"similarity.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/similarity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,UAAU,YAAY,CAAC,IAAY;IACxC,MAAM,MAAM,GAAiB,IAAI,GAAG,EAAE,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAe,EAAE,CAAe;IAC9D,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,MAAM,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC;IAChD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,MAAM,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC;IAChD,IAAI,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,KAAK,KAAK,SAAS;YAAE,YAAY,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,sBAAsB,CAAC,UAA6B;IACnE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC3C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1B,IAAI,OAAO,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QAC1D,KAAK,IAAI,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,KAAK,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACnC,CAAC","sourcesContent":["/**\n * Character-bigram Sørensen–Dice similarity over canonical argument JSON.\n *\n * Chosen over token-level or edit-distance metrics because canonical JSON keeps\n * structure stable (sorted keys, fixed separators), making bigram overlap a cheap\n * and order-insensitive-enough proxy for \"same call shape, slightly different values\".\n */\n\nexport type BigramCounts = Map<string, number>;\n\nexport function bigramCounts(text: string): BigramCounts {\n\tconst counts: BigramCounts = new Map();\n\tfor (let i = 0; i < text.length - 1; i++) {\n\t\tconst gram = text.slice(i, i + 2);\n\t\tcounts.set(gram, (counts.get(gram) ?? 0) + 1);\n\t}\n\treturn counts;\n}\n\nexport function diceSimilarity(a: BigramCounts, b: BigramCounts): number {\n\tlet totalA = 0;\n\tfor (const count of a.values()) totalA += count;\n\tlet totalB = 0;\n\tfor (const count of b.values()) totalB += count;\n\tif (totalA === 0 && totalB === 0) return 1;\n\tif (totalA === 0 || totalB === 0) return 0;\n\tlet intersection = 0;\n\tconst [small, large] = a.size <= b.size ? [a, b] : [b, a];\n\tfor (const [gram, count] of small) {\n\t\tconst other = large.get(gram);\n\t\tif (other !== undefined) intersection += Math.min(count, other);\n\t}\n\treturn (2 * intersection) / (totalA + totalB);\n}\n\n/** Mean similarity between each adjacent pair of argument strings. */\nexport function meanAdjacentSimilarity(argStrings: readonly string[]): number {\n\tif (argStrings.length < 2) return 1;\n\tconst grams = argStrings.map(bigramCounts);\n\tlet total = 0;\n\tfor (let i = 0; i < grams.length - 1; i++) {\n\t\tconst current = grams[i];\n\t\tconst next = grams[i + 1];\n\t\tif (current === undefined || next === undefined) continue;\n\t\ttotal += diceSimilarity(current, next);\n\t}\n\treturn total / (grams.length - 1);\n}\n"]}
@@ -0,0 +1,13 @@
1
+ export interface ToolCallRecord {
2
+ readonly toolName: string;
3
+ readonly argsJson: string;
4
+ readonly signature: string;
5
+ }
6
+ export declare function canonicalizeArgs(args: unknown): string;
7
+ export declare class ToolCallTracker {
8
+ private calls;
9
+ record(toolName: string, args: unknown): void;
10
+ get records(): readonly ToolCallRecord[];
11
+ reset(): void;
12
+ }
13
+ //# sourceMappingURL=tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/tracker.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAEtD;AAgBD,qBAAa,eAAe;IAC3B,OAAO,CAAC,KAAK,CAAwB;IAErC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAM5C;IAED,IAAI,OAAO,IAAI,SAAS,cAAc,EAAE,CAEvC;IAED,KAAK,IAAI,IAAI,CAEZ;CACD"}
@@ -0,0 +1,39 @@
1
+ import { TRACK_WINDOW } from "./policy.js";
2
+ export function canonicalizeArgs(args) {
3
+ return stableStringify(args ?? {});
4
+ }
5
+ function stableStringify(value) {
6
+ if (value === null || typeof value !== "object")
7
+ return JSON.stringify(value) ?? "null";
8
+ if (Array.isArray(value))
9
+ return `[${value.map((item) => stableStringify(item)).join(",")}]`;
10
+ const record = value;
11
+ const keys = Object.keys(record).sort();
12
+ const parts = [];
13
+ for (const key of keys) {
14
+ const entry = record[key];
15
+ if (entry === undefined)
16
+ continue;
17
+ parts.push(`${JSON.stringify(key)}:${stableStringify(entry)}`);
18
+ }
19
+ return `{${parts.join(",")}}`;
20
+ }
21
+ export class ToolCallTracker {
22
+ constructor() {
23
+ this.calls = [];
24
+ }
25
+ record(toolName, args) {
26
+ const argsJson = canonicalizeArgs(args);
27
+ this.calls.push({ toolName, argsJson, signature: `${toolName}\u0000${argsJson}` });
28
+ if (this.calls.length > TRACK_WINDOW) {
29
+ this.calls = this.calls.slice(-TRACK_WINDOW);
30
+ }
31
+ }
32
+ get records() {
33
+ return this.calls;
34
+ }
35
+ reset() {
36
+ this.calls = [];
37
+ }
38
+ }
39
+ //# sourceMappingURL=tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/loop-guard/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,MAAM,UAAU,gBAAgB,CAAC,IAAa;IAC7C,OAAO,eAAe,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACtC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC;IACxF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7F,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAC/B,CAAC;AAED,MAAM,OAAO,eAAe;IAA5B;QACS,UAAK,GAAqB,EAAE,CAAC;IAiBtC,CAAC;IAfA,MAAM,CAAC,QAAgB,EAAE,IAAa;QACrC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,QAAQ,SAAS,QAAQ,EAAE,EAAE,CAAC,CAAC;QACnF,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;YACtC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC;QAC9C,CAAC;IACF,CAAC;IAED,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IACjB,CAAC;CACD","sourcesContent":["import { TRACK_WINDOW } from \"./policy.ts\";\n\nexport interface ToolCallRecord {\n\treadonly toolName: string;\n\treadonly argsJson: string;\n\treadonly signature: string;\n}\n\nexport function canonicalizeArgs(args: unknown): string {\n\treturn stableStringify(args ?? {});\n}\n\nfunction stableStringify(value: unknown): string {\n\tif (value === null || typeof value !== \"object\") return JSON.stringify(value) ?? \"null\";\n\tif (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(\",\")}]`;\n\tconst record = value as Record<string, unknown>;\n\tconst keys = Object.keys(record).sort();\n\tconst parts: string[] = [];\n\tfor (const key of keys) {\n\t\tconst entry = record[key];\n\t\tif (entry === undefined) continue;\n\t\tparts.push(`${JSON.stringify(key)}:${stableStringify(entry)}`);\n\t}\n\treturn `{${parts.join(\",\")}}`;\n}\n\nexport class ToolCallTracker {\n\tprivate calls: ToolCallRecord[] = [];\n\n\trecord(toolName: string, args: unknown): void {\n\t\tconst argsJson = canonicalizeArgs(args);\n\t\tthis.calls.push({ toolName, argsJson, signature: `${toolName}\\u0000${argsJson}` });\n\t\tif (this.calls.length > TRACK_WINDOW) {\n\t\t\tthis.calls = this.calls.slice(-TRACK_WINDOW);\n\t\t}\n\t}\n\n\tget records(): readonly ToolCallRecord[] {\n\t\treturn this.calls;\n\t}\n\n\treset(): void {\n\t\tthis.calls = [];\n\t}\n}\n"]}
@@ -1,6 +1,16 @@
1
1
  export declare const TERMINAL_MONITOR_STATE_EVENT = "terminal_monitor_state";
2
+ /** One live watch as broadcast on the monitor state event; mirrors MonitorSnapshotEntry. */
3
+ export interface TerminalMonitorStateMonitorEntry {
4
+ readonly id: string;
5
+ readonly description: string;
6
+ readonly paused: boolean;
7
+ /** Epoch milliseconds when the watch registered; lets consumers render their own elapsed labels. */
8
+ readonly startedAtMs: number;
9
+ }
2
10
  export interface TerminalMonitorStateEvent {
3
11
  readonly activeCount: number;
12
+ /** Per-watch detail for consumers that need more than the count; absent in pre-enrichment payloads. */
13
+ readonly monitors?: readonly TerminalMonitorStateMonitorEntry[];
4
14
  }
5
15
  export declare function isTerminalMonitorStateEvent(data: unknown): data is TerminalMonitorStateEvent;
6
16
  //# sourceMappingURL=monitor-state-event.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"monitor-state-event.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/monitor-state-event.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,2BAA2B,CAAC;AAErE,MAAM,WAAW,yBAAyB;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,yBAAyB,CAS5F"}
1
+ {"version":3,"file":"monitor-state-event.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/monitor-state-event.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,2BAA2B,CAAC;AAErE,4FAA4F;AAC5F,MAAM,WAAW,gCAAgC;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,oGAAoG;IACpG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,uGAAuG;IACvG,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,gCAAgC,EAAE,CAAC;CAChE;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,yBAAyB,CAS5F"}
@@ -1 +1 @@
1
- {"version":3,"file":"monitor-state-event.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/monitor-state-event.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG,wBAAwB,CAAC;AAMrE,MAAM,UAAU,2BAA2B,CAAC,IAAa;IACxD,OAAO,CACN,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,aAAa,IAAI,IAAI;QACrB,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;QACpC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC;QAClC,IAAI,CAAC,WAAW,IAAI,CAAC,CACrB,CAAC;AACH,CAAC","sourcesContent":["export const TERMINAL_MONITOR_STATE_EVENT = \"terminal_monitor_state\";\n\nexport interface TerminalMonitorStateEvent {\n\treadonly activeCount: number;\n}\n\nexport function isTerminalMonitorStateEvent(data: unknown): data is TerminalMonitorStateEvent {\n\treturn (\n\t\ttypeof data === \"object\" &&\n\t\tdata !== null &&\n\t\t\"activeCount\" in data &&\n\t\ttypeof data.activeCount === \"number\" &&\n\t\tNumber.isInteger(data.activeCount) &&\n\t\tdata.activeCount >= 0\n\t);\n}\n"]}
1
+ {"version":3,"file":"monitor-state-event.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/monitor-state-event.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG,wBAAwB,CAAC;AAiBrE,MAAM,UAAU,2BAA2B,CAAC,IAAa;IACxD,OAAO,CACN,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,aAAa,IAAI,IAAI;QACrB,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;QACpC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC;QAClC,IAAI,CAAC,WAAW,IAAI,CAAC,CACrB,CAAC;AACH,CAAC","sourcesContent":["export const TERMINAL_MONITOR_STATE_EVENT = \"terminal_monitor_state\";\n\n/** One live watch as broadcast on the monitor state event; mirrors MonitorSnapshotEntry. */\nexport interface TerminalMonitorStateMonitorEntry {\n\treadonly id: string;\n\treadonly description: string;\n\treadonly paused: boolean;\n\t/** Epoch milliseconds when the watch registered; lets consumers render their own elapsed labels. */\n\treadonly startedAtMs: number;\n}\n\nexport interface TerminalMonitorStateEvent {\n\treadonly activeCount: number;\n\t/** Per-watch detail for consumers that need more than the count; absent in pre-enrichment payloads. */\n\treadonly monitors?: readonly TerminalMonitorStateMonitorEntry[];\n}\n\nexport function isTerminalMonitorStateEvent(data: unknown): data is TerminalMonitorStateEvent {\n\treturn (\n\t\ttypeof data === \"object\" &&\n\t\tdata !== null &&\n\t\t\"activeCount\" in data &&\n\t\ttypeof data.activeCount === \"number\" &&\n\t\tNumber.isInteger(data.activeCount) &&\n\t\tdata.activeCount >= 0\n\t);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAsC,MAAM,gBAAgB,CAAC;AAgDvF,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA2BpE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAsC,MAAM,gBAAgB,CAAC;AAoDvF,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA2BpE"}
@@ -18,14 +18,18 @@ function getSettings(ctx) {
18
18
  function getPresetName(ctx, event) {
19
19
  const model = event?.model ?? ctx.model;
20
20
  if (!model) {
21
- return "fallback (senpi-current)";
21
+ return undefined;
22
22
  }
23
- return resolvePresetName(model, getSettings(ctx)) ?? "fallback (senpi-current)";
23
+ return resolvePresetName(model, getSettings(ctx));
24
24
  }
25
25
  function refreshHeader(ctx, event) {
26
26
  const presetName = getPresetName(ctx, event);
27
+ if (!presetName) {
28
+ ctx.ui.setHeader(undefined);
29
+ return;
30
+ }
27
31
  ctx.ui.setHeader((_tui, theme) => ({
28
- render: () => [theme.fg("accent", theme.bold(`Prompt preset: ${presetName}`))],
32
+ render: () => [theme.fg("accent", theme.bold(`Optimized system prompt applied: ${presetName}`))],
29
33
  invalidate: () => { },
30
34
  }));
31
35
  }
@@ -49,7 +53,7 @@ export default function promptPresetExtension(pi) {
49
53
  const preset = resolvePreset(event.model, getSettings(ctx), eventOptionsToBuilderInput(event, ctx));
50
54
  return {
51
55
  systemPrompt: preset?.prompt ?? null,
52
- systemPromptName: preset?.name ?? "fallback (senpi-current)",
56
+ systemPromptName: preset?.name,
53
57
  };
54
58
  });
55
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BuildDynamicSystemPromptOptions } from \"../../../dynamic-prompt/build.ts\";\nimport { SettingsManager } from \"../../../settings-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext, ModelSelectEvent } from \"../../types.ts\";\nimport { resolvePreset, resolvePresetName } from \"./presets.ts\";\nimport { loadPromptPresetSettings } from \"./settings.ts\";\n\ninterface SystemPromptOptionsLike {\n\tcwd?: string;\n\tselectedTools?: string[];\n\ttoolSnippets?: Record<string, string>;\n\tpromptGuidelines?: string[];\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\tskills?: BuildDynamicSystemPromptOptions[\"skills\"];\n}\n\nfunction eventOptionsToBuilderInput(\n\tevent: { systemPromptOptions: SystemPromptOptionsLike | undefined },\n\tctx: Pick<ExtensionContext, \"cwd\">,\n): Partial<BuildDynamicSystemPromptOptions> {\n\tconst options = event.systemPromptOptions ?? {};\n\treturn {\n\t\tcwd: options.cwd ?? ctx.cwd,\n\t\tselectedTools: options.selectedTools,\n\t\ttoolSnippets: options.toolSnippets,\n\t\tpromptGuidelines: options.promptGuidelines,\n\t\tcontextFiles: options.contextFiles,\n\t\tskills: options.skills,\n\t};\n}\n\nfunction getSettings(ctx: ExtensionContext): ReturnType<typeof loadPromptPresetSettings> {\n\treturn loadPromptPresetSettings(SettingsManager.create(ctx.cwd));\n}\n\nfunction getPresetName(ctx: ExtensionContext, event?: Pick<ModelSelectEvent, \"model\">): string {\n\tconst model = event?.model ?? ctx.model;\n\tif (!model) {\n\t\treturn \"fallback (senpi-current)\";\n\t}\n\treturn resolvePresetName(model, getSettings(ctx)) ?? \"fallback (senpi-current)\";\n}\n\nfunction refreshHeader(ctx: ExtensionContext, event?: Pick<ModelSelectEvent, \"model\">): void {\n\tconst presetName = getPresetName(ctx, event);\n\tctx.ui.setHeader((_tui, theme) => ({\n\t\trender: () => [theme.fg(\"accent\", theme.bold(`Prompt preset: ${presetName}`))],\n\t\tinvalidate: () => {},\n\t}));\n}\n\nexport default function promptPresetExtension(pi: ExtensionAPI): void {\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tconst model = ctx.model;\n\t\tif (!model) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst preset = resolvePreset(model, getSettings(ctx), eventOptionsToBuilderInput(event, ctx));\n\t\tif (!preset) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn { systemPrompt: preset.prompt };\n\t});\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\trefreshHeader(ctx);\n\t});\n\n\tpi.on(\"model_select\", async (event, ctx) => {\n\t\trefreshHeader(ctx, event);\n\t\tconst preset = resolvePreset(event.model, getSettings(ctx), eventOptionsToBuilderInput(event, ctx));\n\t\treturn {\n\t\t\tsystemPrompt: preset?.prompt ?? null,\n\t\t\tsystemPromptName: preset?.name ?? \"fallback (senpi-current)\",\n\t\t};\n\t});\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BuildDynamicSystemPromptOptions } from \"../../../dynamic-prompt/build.ts\";\nimport { SettingsManager } from \"../../../settings-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext, ModelSelectEvent } from \"../../types.ts\";\nimport { resolvePreset, resolvePresetName } from \"./presets.ts\";\nimport { loadPromptPresetSettings } from \"./settings.ts\";\n\ninterface SystemPromptOptionsLike {\n\tcwd?: string;\n\tselectedTools?: string[];\n\ttoolSnippets?: Record<string, string>;\n\tpromptGuidelines?: string[];\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\tskills?: BuildDynamicSystemPromptOptions[\"skills\"];\n}\n\nfunction eventOptionsToBuilderInput(\n\tevent: { systemPromptOptions: SystemPromptOptionsLike | undefined },\n\tctx: Pick<ExtensionContext, \"cwd\">,\n): Partial<BuildDynamicSystemPromptOptions> {\n\tconst options = event.systemPromptOptions ?? {};\n\treturn {\n\t\tcwd: options.cwd ?? ctx.cwd,\n\t\tselectedTools: options.selectedTools,\n\t\ttoolSnippets: options.toolSnippets,\n\t\tpromptGuidelines: options.promptGuidelines,\n\t\tcontextFiles: options.contextFiles,\n\t\tskills: options.skills,\n\t};\n}\n\nfunction getSettings(ctx: ExtensionContext): ReturnType<typeof loadPromptPresetSettings> {\n\treturn loadPromptPresetSettings(SettingsManager.create(ctx.cwd));\n}\n\nfunction getPresetName(ctx: ExtensionContext, event?: Pick<ModelSelectEvent, \"model\">): string | undefined {\n\tconst model = event?.model ?? ctx.model;\n\tif (!model) {\n\t\treturn undefined;\n\t}\n\treturn resolvePresetName(model, getSettings(ctx));\n}\n\nfunction refreshHeader(ctx: ExtensionContext, event?: Pick<ModelSelectEvent, \"model\">): void {\n\tconst presetName = getPresetName(ctx, event);\n\tif (!presetName) {\n\t\tctx.ui.setHeader(undefined);\n\t\treturn;\n\t}\n\tctx.ui.setHeader((_tui, theme) => ({\n\t\trender: () => [theme.fg(\"accent\", theme.bold(`Optimized system prompt applied: ${presetName}`))],\n\t\tinvalidate: () => {},\n\t}));\n}\n\nexport default function promptPresetExtension(pi: ExtensionAPI): void {\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tconst model = ctx.model;\n\t\tif (!model) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst preset = resolvePreset(model, getSettings(ctx), eventOptionsToBuilderInput(event, ctx));\n\t\tif (!preset) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn { systemPrompt: preset.prompt };\n\t});\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\trefreshHeader(ctx);\n\t});\n\n\tpi.on(\"model_select\", async (event, ctx) => {\n\t\trefreshHeader(ctx, event);\n\t\tconst preset = resolvePreset(event.model, getSettings(ctx), eventOptionsToBuilderInput(event, ctx));\n\t\treturn {\n\t\t\tsystemPrompt: preset?.prompt ?? null,\n\t\t\tsystemPromptName: preset?.name,\n\t\t};\n\t});\n}\n"]}
@@ -71,9 +71,10 @@ export default function piRulesExtension(pi) {
71
71
  engine.markStaticInjected(rule);
72
72
  }
73
73
  }
74
- const rules = loaded.rules.filter((rule) => !nativeContextPaths.has(rule.path) &&
75
- !nativeContextPaths.has(rule.realPath) &&
76
- !engine.isStaticInjected(rule));
74
+ // Deliberately NOT gated on isStaticInjected: the host re-emits this from the BASE prompt
75
+ // every user prompt, so a prior turn's mark would drop the block from turn 2 onward. The
76
+ // marks below serve only the dynamic tool_result path.
77
+ const rules = loaded.rules.filter((rule) => !nativeContextPaths.has(rule.path) && !nativeContextPaths.has(rule.realPath));
77
78
  if (rules.length === 0) {
78
79
  return undefined;
79
80
  }
@@ -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 { registerSlashCommands } from \"./commands.ts\";\nimport { createEngine, defaultConfig } 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\"]);\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 = defaultConfig();\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\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;\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\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);\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(firstTargetPath, 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 block = engine.formatDynamic(rules, displayPath(ctx.cwd, firstPendingTarget));\n\t\tfor (const rule of rules) {\n\t\t\tengine.markDynamicInjected(firstTargetPath, rule);\n\t\t}\n\n\t\treturn { content: [...event.content, { type: \"text\", text: block }] };\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 { registerSlashCommands } from \"./commands.ts\";\nimport { createEngine, defaultConfig } 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\"]);\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 = defaultConfig();\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\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;\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(firstTargetPath, 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 block = engine.formatDynamic(rules, displayPath(ctx.cwd, firstPendingTarget));\n\t\tfor (const rule of rules) {\n\t\t\tengine.markDynamicInjected(firstTargetPath, rule);\n\t\t}\n\n\t\treturn { content: [...event.content, { type: \"text\", text: block }] };\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"]}
@@ -50,6 +50,17 @@ export declare const TRUNCATION_NOTICE = "\n\n[Rule truncated. Read full rule: {
50
50
  */
51
51
  export declare const TRACKED_BUILTIN_TOOLS: readonly string[];
52
52
  export declare const TRACKED_BUILTIN_TOOL_SET: ReadonlySet<string>;
53
+ /** Addressed to the model; never used to locate the block. */
54
+ export declare const PROJECT_RULES_START_MARKER = "<project_rules>";
55
+ export declare const PROJECT_RULES_END_MARKER = "</project_rules>";
56
+ export declare const PROJECT_RULES_HEADING = "## Project Instructions";
57
+ /**
58
+ * How provider lanes that rebuild the system prompt (see the Claude SDK OAuth builtin) locate the
59
+ * block. The semantic markers cannot: prompt content this builtin does not own - context files
60
+ * before it, extensions appending after it - may legitimately contain them and be extracted instead.
61
+ */
62
+ export declare const PROJECT_RULES_REGION_START_MARKER = "<!--senpi:project-rules:1:start-->";
63
+ export declare const PROJECT_RULES_REGION_END_MARKER = "<!--senpi:project-rules:1:end-->";
53
64
  /**
54
65
  * Directories excluded by the recursive scanner regardless of glob settings.
55
66
  */
@@ -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;;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,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"}