@code-yeongyu/senpi 2026.8.14 → 2026.8.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (490) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/README.md +1 -0
  3. package/dist/cli/args.d.ts +1 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +14 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/auth-command.d.ts.map +1 -1
  8. package/dist/cli/auth-command.js +5 -4
  9. package/dist/cli/auth-command.js.map +1 -1
  10. package/dist/core/agent-session.d.ts +79 -8
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +190 -30
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/auth-storage.d.ts.map +1 -1
  15. package/dist/core/auth-storage.js +19 -8
  16. package/dist/core/auth-storage.js.map +1 -1
  17. package/dist/core/experimental.d.ts +4 -0
  18. package/dist/core/experimental.d.ts.map +1 -1
  19. package/dist/core/experimental.js +4 -0
  20. package/dist/core/experimental.js.map +1 -1
  21. package/dist/core/export-html/template.js +31 -9
  22. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-environment.d.ts +4 -0
  23. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-environment.d.ts.map +1 -0
  24. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-environment.js +30 -0
  25. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-environment.js.map +1 -0
  26. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.d.ts +2 -0
  27. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.d.ts.map +1 -1
  28. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js +13 -47
  29. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js.map +1 -1
  30. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.d.ts +18 -1
  31. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.js +64 -2
  33. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.js.map +1 -1
  34. package/dist/core/extensions/builtin/claude-sdk-oauth/config-dir-credentials.d.ts +3 -0
  35. package/dist/core/extensions/builtin/claude-sdk-oauth/config-dir-credentials.d.ts.map +1 -0
  36. package/dist/core/extensions/builtin/claude-sdk-oauth/config-dir-credentials.js +27 -0
  37. package/dist/core/extensions/builtin/claude-sdk-oauth/config-dir-credentials.js.map +1 -0
  38. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts +15 -2
  39. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js +45 -11
  41. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js.map +1 -1
  42. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +1 -0
  43. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
  44. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -1
  45. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +17 -1
  46. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -1
  47. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -1
  48. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js +1 -0
  49. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -1
  50. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  51. package/dist/core/extensions/builtin/compaction/index.js +48 -6
  52. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  53. package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
  54. package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
  55. package/dist/core/extensions/builtin/compaction/log.js +2 -0
  56. package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
  57. package/dist/core/extensions/builtin/compaction/overflow-retry.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/compaction/overflow-retry.js +38 -4
  59. package/dist/core/extensions/builtin/compaction/overflow-retry.js.map +1 -1
  60. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  61. package/dist/core/extensions/builtin/compaction/speculative.js +2 -1
  62. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  63. package/dist/core/extensions/builtin/compaction/summarization-turn-order.d.ts +33 -0
  64. package/dist/core/extensions/builtin/compaction/summarization-turn-order.d.ts.map +1 -0
  65. package/dist/core/extensions/builtin/compaction/summarization-turn-order.js +67 -0
  66. package/dist/core/extensions/builtin/compaction/summarization-turn-order.js.map +1 -0
  67. package/dist/core/extensions/builtin/config-reload/index.d.ts.map +1 -1
  68. package/dist/core/extensions/builtin/config-reload/index.js +31 -8
  69. package/dist/core/extensions/builtin/config-reload/index.js.map +1 -1
  70. package/dist/core/extensions/builtin/config-reload/routine-settings.d.ts.map +1 -1
  71. package/dist/core/extensions/builtin/config-reload/routine-settings.js +11 -12
  72. package/dist/core/extensions/builtin/config-reload/routine-settings.js.map +1 -1
  73. package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts.map +1 -1
  74. package/dist/core/extensions/builtin/goal/terminal-provider-error.js +16 -0
  75. package/dist/core/extensions/builtin/goal/terminal-provider-error.js.map +1 -1
  76. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  77. package/dist/core/extensions/builtin/index.js +4 -0
  78. package/dist/core/extensions/builtin/index.js.map +1 -1
  79. package/dist/core/extensions/builtin/mcp/process-tree.js +6 -1
  80. package/dist/core/extensions/builtin/mcp/process-tree.js.map +1 -1
  81. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.d.ts +3 -0
  82. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.d.ts.map +1 -0
  83. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.js +14 -0
  84. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.js.map +1 -0
  85. package/dist/core/extensions/builtin/prompt-preset/grok-4.6.d.ts +3 -0
  86. package/dist/core/extensions/builtin/prompt-preset/grok-4.6.d.ts.map +1 -0
  87. package/dist/core/extensions/builtin/prompt-preset/grok-4.6.js +91 -0
  88. package/dist/core/extensions/builtin/prompt-preset/grok-4.6.js.map +1 -0
  89. package/dist/core/extensions/builtin/prompt-preset/index.d.ts.map +1 -1
  90. package/dist/core/extensions/builtin/prompt-preset/index.js +22 -2
  91. package/dist/core/extensions/builtin/prompt-preset/index.js.map +1 -1
  92. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  93. package/dist/core/extensions/builtin/prompt-preset/presets.js +25 -0
  94. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  95. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  96. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  97. package/dist/core/extensions/builtin/prompt-preset/settings.js +2 -0
  98. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  99. package/dist/core/extensions/builtin/reasoning/index.d.ts +3 -0
  100. package/dist/core/extensions/builtin/reasoning/index.d.ts.map +1 -0
  101. package/dist/core/extensions/builtin/reasoning/index.js +211 -0
  102. package/dist/core/extensions/builtin/reasoning/index.js.map +1 -0
  103. package/dist/core/extensions/builtin/service-tier.d.ts +44 -1
  104. package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
  105. package/dist/core/extensions/builtin/service-tier.js +176 -24
  106. package/dist/core/extensions/builtin/service-tier.js.map +1 -1
  107. package/dist/core/extensions/runner.d.ts.map +1 -1
  108. package/dist/core/extensions/runner.js +4 -4
  109. package/dist/core/extensions/runner.js.map +1 -1
  110. package/dist/core/extensions/types.d.ts +12 -0
  111. package/dist/core/extensions/types.d.ts.map +1 -1
  112. package/dist/core/extensions/types.js.map +1 -1
  113. package/dist/core/keybindings.d.ts +24 -0
  114. package/dist/core/keybindings.d.ts.map +1 -1
  115. package/dist/core/lockfile-policy.d.ts +15 -0
  116. package/dist/core/lockfile-policy.d.ts.map +1 -0
  117. package/dist/core/lockfile-policy.js +15 -0
  118. package/dist/core/lockfile-policy.js.map +1 -0
  119. package/dist/core/model-config.d.ts.map +1 -1
  120. package/dist/core/model-config.js +1 -0
  121. package/dist/core/model-config.js.map +1 -1
  122. package/dist/core/model-resolver.d.ts +34 -7
  123. package/dist/core/model-resolver.d.ts.map +1 -1
  124. package/dist/core/model-resolver.js +115 -27
  125. package/dist/core/model-resolver.js.map +1 -1
  126. package/dist/core/model-runtime.d.ts.map +1 -1
  127. package/dist/core/model-runtime.js +5 -3
  128. package/dist/core/model-runtime.js.map +1 -1
  129. package/dist/core/provider-api-key-auth.d.ts.map +1 -1
  130. package/dist/core/provider-api-key-auth.js +45 -2
  131. package/dist/core/provider-api-key-auth.js.map +1 -1
  132. package/dist/core/provider-composer.d.ts +12 -1
  133. package/dist/core/provider-composer.d.ts.map +1 -1
  134. package/dist/core/provider-composer.js.map +1 -1
  135. package/dist/core/provider-display-names.d.ts.map +1 -1
  136. package/dist/core/provider-display-names.js +1 -0
  137. package/dist/core/provider-display-names.js.map +1 -1
  138. package/dist/core/remote-catalog-provider.d.ts +13 -0
  139. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  140. package/dist/core/remote-catalog-provider.js +15 -0
  141. package/dist/core/remote-catalog-provider.js.map +1 -1
  142. package/dist/core/retry-fallback/controller.d.ts +1 -1
  143. package/dist/core/retry-fallback/controller.d.ts.map +1 -1
  144. package/dist/core/retry-fallback/controller.js +5 -3
  145. package/dist/core/retry-fallback/controller.js.map +1 -1
  146. package/dist/core/sdk.d.ts +5 -3
  147. package/dist/core/sdk.d.ts.map +1 -1
  148. package/dist/core/sdk.js +14 -8
  149. package/dist/core/sdk.js.map +1 -1
  150. package/dist/core/session-manager.d.ts.map +1 -1
  151. package/dist/core/session-manager.js +20 -4
  152. package/dist/core/session-manager.js.map +1 -1
  153. package/dist/core/settings-manager.d.ts +50 -1
  154. package/dist/core/settings-manager.d.ts.map +1 -1
  155. package/dist/core/settings-manager.js +258 -15
  156. package/dist/core/settings-manager.js.map +1 -1
  157. package/dist/core/system-prompt.js +1 -1
  158. package/dist/core/system-prompt.js.map +1 -1
  159. package/dist/core/thinking-levels.d.ts +22 -0
  160. package/dist/core/thinking-levels.d.ts.map +1 -1
  161. package/dist/core/thinking-levels.js +29 -0
  162. package/dist/core/thinking-levels.js.map +1 -1
  163. package/dist/core/tools/bash.d.ts.map +1 -1
  164. package/dist/core/tools/bash.js +2 -0
  165. package/dist/core/tools/bash.js.map +1 -1
  166. package/dist/core/tools/edit.d.ts.map +1 -1
  167. package/dist/core/tools/edit.js +2 -0
  168. package/dist/core/tools/edit.js.map +1 -1
  169. package/dist/core/tools/find.js +1 -1
  170. package/dist/core/tools/find.js.map +1 -1
  171. package/dist/core/tools/grep.js +1 -1
  172. package/dist/core/tools/grep.js.map +1 -1
  173. package/dist/core/tools/read.d.ts.map +1 -1
  174. package/dist/core/tools/read.js +2 -0
  175. package/dist/core/tools/read.js.map +1 -1
  176. package/dist/core/tools/write.d.ts.map +1 -1
  177. package/dist/core/tools/write.js +2 -0
  178. package/dist/core/tools/write.js.map +1 -1
  179. package/dist/index.d.ts +1 -1
  180. package/dist/index.d.ts.map +1 -1
  181. package/dist/index.js.map +1 -1
  182. package/dist/main.d.ts.map +1 -1
  183. package/dist/main.js +18 -1
  184. package/dist/main.js.map +1 -1
  185. package/dist/modes/interactive/components/model-favorites.d.ts +2 -1
  186. package/dist/modes/interactive/components/model-favorites.d.ts.map +1 -1
  187. package/dist/modes/interactive/components/model-favorites.js +72 -6
  188. package/dist/modes/interactive/components/model-favorites.js.map +1 -1
  189. package/dist/modes/interactive/components/model-selector.d.ts +5 -1
  190. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  191. package/dist/modes/interactive/components/model-selector.js +10 -6
  192. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  193. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  194. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  195. package/dist/modes/interactive/components/settings-selector.js +10 -0
  196. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  197. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  198. package/dist/modes/interactive/components/tool-execution.js +22 -1
  199. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  200. package/dist/modes/interactive/interactive-mode.d.ts +14 -4
  201. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  202. package/dist/modes/interactive/interactive-mode.js +109 -50
  203. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  204. package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
  205. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  206. package/dist/modes/interactive/model-catalog-refresh.js +36 -0
  207. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  208. package/dist/modes/interactive/theme/dark.json +2 -0
  209. package/dist/modes/interactive/theme/grok-day.json +2 -0
  210. package/dist/modes/interactive/theme/grok-night.json +2 -0
  211. package/dist/modes/interactive/theme/light.json +2 -0
  212. package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
  213. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  214. package/dist/modes/interactive/theme/theme-controller.js +23 -10
  215. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  216. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  217. package/dist/modes/interactive/theme/theme.d.ts +5 -3
  218. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  219. package/dist/modes/interactive/theme/theme.js +12 -2
  220. package/dist/modes/interactive/theme/theme.js.map +1 -1
  221. package/dist/modes/json-event.d.ts +4 -1
  222. package/dist/modes/json-event.d.ts.map +1 -1
  223. package/dist/modes/json-event.js +5 -2
  224. package/dist/modes/json-event.js.map +1 -1
  225. package/dist/modes/rpc/connection-handler.d.ts +10 -0
  226. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  227. package/dist/modes/rpc/connection-handler.js +87 -19
  228. package/dist/modes/rpc/connection-handler.js.map +1 -1
  229. package/dist/modes/rpc/multi-session-host.js +3 -3
  230. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  231. package/dist/modes/rpc/rpc-client.d.ts +26 -1
  232. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  233. package/dist/modes/rpc/rpc-client.js +25 -2
  234. package/dist/modes/rpc/rpc-client.js.map +1 -1
  235. package/dist/modes/rpc/rpc-types.d.ts +60 -0
  236. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  237. package/dist/modes/rpc/rpc-types.js.map +1 -1
  238. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  239. package/dist/modes/rpc/session-command-router.js +2 -14
  240. package/dist/modes/rpc/session-command-router.js.map +1 -1
  241. package/dist/modes/rpc/session-event-writer.d.ts +29 -10
  242. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  243. package/dist/modes/rpc/session-event-writer.js +229 -50
  244. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  245. package/dist/server/create-harness.d.ts.map +1 -1
  246. package/dist/server/create-harness.js +2 -0
  247. package/dist/server/create-harness.js.map +1 -1
  248. package/dist/utils/shell.d.ts +27 -0
  249. package/dist/utils/shell.d.ts.map +1 -1
  250. package/dist/utils/shell.js +79 -13
  251. package/dist/utils/shell.js.map +1 -1
  252. package/dist/utils/tools-manager.d.ts +10 -1
  253. package/dist/utils/tools-manager.d.ts.map +1 -1
  254. package/dist/utils/tools-manager.js +14 -19
  255. package/dist/utils/tools-manager.js.map +1 -1
  256. package/docs/compaction.md +3 -3
  257. package/docs/custom-provider.md +1 -1
  258. package/docs/environment-variables.md +8 -2
  259. package/docs/extensions.md +4 -0
  260. package/docs/json.md +6 -4
  261. package/docs/keybindings.md +8 -2
  262. package/docs/providers.md +7 -0
  263. package/docs/rpc.md +128 -6
  264. package/docs/sdk.md +9 -0
  265. package/docs/settings.md +93 -1
  266. package/docs/terminal-setup.md +23 -2
  267. package/docs/themes.md +24 -3
  268. package/docs/tui.md +2 -2
  269. package/docs/usage.md +24 -4
  270. package/examples/extensions/subagent/agents.ts +40 -9
  271. package/examples/extensions/subagent/index.ts +26 -3
  272. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +14 -0
  273. package/node_modules/@code-yeongyu/senpi-codemode/README.md +5 -0
  274. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  275. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +14 -1
  276. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/call-capture.ts +64 -0
  277. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +45 -61
  278. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-runtime.ts +6 -0
  279. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-execution-event.ts +201 -0
  280. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool-options.ts +2 -0
  281. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +22 -0
  282. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.d.ts +25 -0
  283. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  284. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js +77 -12
  285. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  286. package/node_modules/@earendil-works/pi-agent-core/dist/harness/events.d.ts +43 -0
  287. package/node_modules/@earendil-works/pi-agent-core/dist/harness/events.d.ts.map +1 -0
  288. package/node_modules/@earendil-works/pi-agent-core/dist/harness/events.js +67 -0
  289. package/node_modules/@earendil-works/pi-agent-core/dist/harness/events.js.map +1 -0
  290. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.d.ts +4 -2
  291. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.d.ts.map +1 -1
  292. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.js +127 -88
  293. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.js.map +1 -1
  294. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/errors.d.ts +5 -1
  295. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/errors.d.ts.map +1 -1
  296. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/errors.js +9 -2
  297. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/errors.js.map +1 -1
  298. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/repo.d.ts +12 -3
  299. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/repo.d.ts.map +1 -1
  300. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/repo.js +88 -45
  301. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/repo.js.map +1 -1
  302. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/storage.d.ts +1 -1
  303. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/storage.d.ts.map +1 -1
  304. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/storage.js +28 -19
  305. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/storage.js.map +1 -1
  306. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/types.d.ts +1 -1
  307. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/types.d.ts.map +1 -1
  308. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/types.js.map +1 -1
  309. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory.d.ts +1 -1
  310. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory.d.ts.map +1 -1
  311. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory.js.map +1 -1
  312. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts +6 -1
  313. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts.map +1 -1
  314. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js +7 -2
  315. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js.map +1 -1
  316. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/state.d.ts +1 -1
  317. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/state.d.ts.map +1 -1
  318. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/state.js.map +1 -1
  319. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/testing/conformance.d.ts.map +1 -1
  320. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/testing/conformance.js +19 -0
  321. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/testing/conformance.js.map +1 -1
  322. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/types.d.ts +18 -5
  323. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/types.d.ts.map +1 -1
  324. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/types.js.map +1 -1
  325. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +1 -1
  326. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
  327. package/node_modules/@earendil-works/pi-agent-core/dist/index.js +1 -1
  328. package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
  329. package/node_modules/@earendil-works/pi-agent-core/dist/proxy.d.ts +4 -1
  330. package/node_modules/@earendil-works/pi-agent-core/dist/proxy.d.ts.map +1 -1
  331. package/node_modules/@earendil-works/pi-agent-core/dist/proxy.js.map +1 -1
  332. package/node_modules/@earendil-works/pi-agent-core/dist/search/index.d.ts +21 -0
  333. package/node_modules/@earendil-works/pi-agent-core/dist/search/index.d.ts.map +1 -0
  334. package/node_modules/@earendil-works/pi-agent-core/dist/search/index.js +2 -0
  335. package/node_modules/@earendil-works/pi-agent-core/dist/search/index.js.map +1 -0
  336. package/node_modules/@earendil-works/pi-agent-core/dist/search/scanning.d.ts +29 -0
  337. package/node_modules/@earendil-works/pi-agent-core/dist/search/scanning.d.ts.map +1 -0
  338. package/node_modules/@earendil-works/pi-agent-core/dist/search/scanning.js +103 -0
  339. package/node_modules/@earendil-works/pi-agent-core/dist/search/scanning.js.map +1 -0
  340. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  341. package/node_modules/@earendil-works/pi-ai/README.md +2 -0
  342. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  343. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +40 -14
  344. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  345. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  346. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +16 -4
  347. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  348. package/node_modules/@earendil-works/pi-ai/dist/api/cloudflare-gateway-binding.d.ts +69 -0
  349. package/node_modules/@earendil-works/pi-ai/dist/api/cloudflare-gateway-binding.d.ts.map +1 -0
  350. package/node_modules/@earendil-works/pi-ai/dist/api/cloudflare-gateway-binding.js +159 -0
  351. package/node_modules/@earendil-works/pi-ai/dist/api/cloudflare-gateway-binding.js.map +1 -0
  352. package/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.d.ts +3 -0
  353. package/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.d.ts.map +1 -1
  354. package/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.js +125 -5
  355. package/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.js.map +1 -1
  356. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js +7 -3
  357. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js.map +1 -1
  358. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts +1 -1
  359. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts.map +1 -1
  360. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js +13 -9
  361. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js.map +1 -1
  362. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js +7 -3
  363. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js.map +1 -1
  364. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.d.ts +1 -1
  365. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.d.ts.map +1 -1
  366. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.js +208 -42
  367. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.js.map +1 -1
  368. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  369. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +13 -4
  370. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  371. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  372. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +10 -7
  373. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  374. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +1 -0
  375. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  376. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +31 -7
  377. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  378. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  379. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +8 -1
  380. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  381. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/cursor.d.ts +16 -0
  382. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/cursor.d.ts.map +1 -0
  383. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/cursor.js +234 -0
  384. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/cursor.js.map +1 -0
  385. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  386. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js +6 -3
  387. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js.map +1 -1
  388. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts +2 -0
  389. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts.map +1 -1
  390. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js +5 -0
  391. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js.map +1 -1
  392. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +44 -9
  393. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  394. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +2 -0
  395. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
  396. package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
  397. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.d.ts.map +1 -1
  398. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js +2 -0
  399. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js.map +1 -1
  400. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
  401. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +2 -0
  402. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
  403. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.d.ts +15 -0
  404. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.d.ts.map +1 -0
  405. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.js +32 -0
  406. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.js.map +1 -0
  407. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  408. package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
  409. package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
  410. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  411. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
  412. package/node_modules/@earendil-works/pi-ai/dist/providers/data/deepseek.json +1 -1
  413. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  414. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  415. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  416. package/node_modules/@earendil-works/pi-ai/dist/providers/data/kimi-coding.json +1 -1
  417. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  418. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
  419. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  420. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  421. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  422. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
  423. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
  424. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  425. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  426. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  427. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +14 -3
  428. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  429. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  430. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  431. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +2 -0
  432. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  433. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.d.ts +2 -0
  434. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.d.ts.map +1 -0
  435. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.js +12 -0
  436. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.js.map +1 -0
  437. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  438. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js +3 -2
  439. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js.map +1 -1
  440. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  441. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +1 -0
  442. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  443. package/node_modules/@earendil-works/pi-ai/dist/utils/validation.d.ts.map +1 -1
  444. package/node_modules/@earendil-works/pi-ai/dist/utils/validation.js +34 -0
  445. package/node_modules/@earendil-works/pi-ai/dist/utils/validation.js.map +1 -1
  446. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  447. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  448. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  449. package/node_modules/@earendil-works/pi-tui/README.md +1 -1
  450. package/node_modules/@earendil-works/pi-tui/dist/alt-screen-search.d.ts +26 -0
  451. package/node_modules/@earendil-works/pi-tui/dist/alt-screen-search.d.ts.map +1 -0
  452. package/node_modules/@earendil-works/pi-tui/dist/alt-screen-search.js +121 -0
  453. package/node_modules/@earendil-works/pi-tui/dist/alt-screen-search.js.map +1 -0
  454. package/node_modules/@earendil-works/pi-tui/dist/components/scroll-view.d.ts +6 -1
  455. package/node_modules/@earendil-works/pi-tui/dist/components/scroll-view.d.ts.map +1 -1
  456. package/node_modules/@earendil-works/pi-tui/dist/components/scroll-view.js +23 -7
  457. package/node_modules/@earendil-works/pi-tui/dist/components/scroll-view.js.map +1 -1
  458. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +4 -1
  459. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  460. package/node_modules/@earendil-works/pi-tui/dist/index.js +7 -1
  461. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  462. package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts +30 -0
  463. package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts.map +1 -1
  464. package/node_modules/@earendil-works/pi-tui/dist/keybindings.js +24 -0
  465. package/node_modules/@earendil-works/pi-tui/dist/keybindings.js.map +1 -1
  466. package/node_modules/@earendil-works/pi-tui/dist/layout.d.ts.map +1 -1
  467. package/node_modules/@earendil-works/pi-tui/dist/layout.js +9 -2
  468. package/node_modules/@earendil-works/pi-tui/dist/layout.js.map +1 -1
  469. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +8 -2
  470. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  471. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +6 -2
  472. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -1
  473. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +6 -0
  474. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  475. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +18 -1
  476. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  477. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.d.ts +21 -0
  478. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.d.ts.map +1 -1
  479. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js +243 -5
  480. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js.map +1 -1
  481. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +2 -0
  482. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  483. package/node_modules/@earendil-works/pi-tui/dist/tui.js +33 -8
  484. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  485. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  486. package/package.json +7 -7
  487. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/search.d.ts +0 -19
  488. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/search.d.ts.map +0 -1
  489. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/search.js +0 -41
  490. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/search.js.map +0 -1
@@ -37,6 +37,7 @@ import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
37
37
  import { buildDynamicSystemPrompt } from "./dynamic-prompt/index.js";
38
38
  import { exportSessionToHtml } from "./export-html/index.js";
39
39
  import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
40
+ import { CODEX_RESPONSES_API } from "./extensions/builtin/service-tier.js";
40
41
  import { deriveExtensionRegistrationId } from "./extensions/builtin/tool-search/engine/marker.js";
41
42
  import { getToolSearchService } from "./extensions/builtin/tool-search/service.js";
42
43
  import { ExecuteToolError, ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
@@ -70,19 +71,48 @@ import { createAllToolDefinitions } from "./tools/index.js";
70
71
  import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
71
72
  import { addUsageToTotals, createUsageTotals } from "./usage-totals.js";
72
73
  const TURN_RETRY_SUPPRESSION_PREFIX = "senpi:no-turn-retry:";
74
+ /** Format the user-attributed payload for one or more explicit skill invocations. */
75
+ export function formatSkillInvocationPrompt(skills, userRequest) {
76
+ const skillBlocks = skills.map((skill) => `The user explicitly invoked the "${skill.name}" skill. Follow the instructions in <skill-instruction> as binding for this request, while respecting higher-priority instructions.\n\n<skill-instruction name="${skill.name}" location="${skill.filePath}">\nReferences are relative to ${skill.baseDir}.\n\n${skill.body}\n</skill-instruction>`);
77
+ const expandedSkills = skillBlocks.join("\n\n");
78
+ const trimmedRequest = userRequest?.trim();
79
+ return trimmedRequest ? `${expandedSkills}\n\n<user-request>\n${trimmedRequest}\n</user-request>` : expandedSkills;
80
+ }
73
81
  /**
74
82
  * Parse a skill block from message text.
75
83
  * Returns null if the text doesn't contain a skill block.
76
84
  */
77
85
  export function parseSkillBlock(text) {
78
- const match = text.match(/^<skill name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill>(?:\n\n([\s\S]+))?$/);
79
- if (!match)
86
+ const instructionPattern = /^The user explicitly invoked the "([^"]+)" skill\. Follow the instructions in <skill-instruction> as binding for this request, while respecting higher-priority instructions\.\n\n<skill-instruction name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill-instruction>/;
87
+ const instructionMatch = text.match(instructionPattern);
88
+ if (instructionMatch) {
89
+ if (instructionMatch[1] !== instructionMatch[2])
90
+ return null;
91
+ let remainder = text.slice(instructionMatch[0].length);
92
+ while (remainder.startsWith("\n\nThe user explicitly invoked the ")) {
93
+ const chainedMatch = remainder.slice(2).match(instructionPattern);
94
+ if (!chainedMatch || chainedMatch[1] !== chainedMatch[2])
95
+ return null;
96
+ remainder = remainder.slice(chainedMatch[0].length + 2);
97
+ }
98
+ const requestMatch = remainder.match(/^\n\n<user-request>\n([\s\S]*?)\n<\/user-request>$/);
99
+ if (remainder && !requestMatch)
100
+ return null;
101
+ return {
102
+ name: instructionMatch[1],
103
+ location: instructionMatch[3],
104
+ content: instructionMatch[4],
105
+ userMessage: requestMatch?.[1].trim() || undefined,
106
+ };
107
+ }
108
+ const legacyMatch = text.match(/^<skill name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill>(?:\n\n([\s\S]+))?$/);
109
+ if (!legacyMatch)
80
110
  return null;
81
111
  return {
82
- name: match[1],
83
- location: match[2],
84
- content: match[3],
85
- userMessage: match[4]?.trim() || undefined,
112
+ name: legacyMatch[1],
113
+ location: legacyMatch[2],
114
+ content: legacyMatch[3],
115
+ userMessage: legacyMatch[4]?.trim() || undefined,
86
116
  };
87
117
  }
88
118
  // ============================================================================
@@ -328,6 +358,9 @@ export class AgentSession {
328
358
  this.agent = config.agent;
329
359
  this.sessionManager = config.sessionManager;
330
360
  this.settingsManager = config.settingsManager;
361
+ this._unsubscribeSettingsSource = this.settingsManager.subscribeToSourceSelection((source) => {
362
+ this._emit({ type: "settings_source_selected", ...source });
363
+ });
331
364
  const noModelFallback = config.resourceLoader.getExtensions().runtime.flagValues.get("no-model-fallback") === true ||
332
365
  envValue("NO_FALLBACK") === "1";
333
366
  if (noModelFallback) {
@@ -381,6 +414,7 @@ export class AgentSession {
381
414
  });
382
415
  this._extensionRunnerRef = config.extensionRunnerRef;
383
416
  this._initialActiveToolNames = config.initialActiveToolNames;
417
+ this._defaultToolNames = config.defaultToolNames ? new Set(config.defaultToolNames) : undefined;
384
418
  this._allowedToolNames = config.allowedToolNames ? new Set(config.allowedToolNames) : undefined;
385
419
  this._excludedToolNames = config.excludedToolNames ? new Set(config.excludedToolNames) : undefined;
386
420
  this._baseToolsOverride = config.baseToolsOverride;
@@ -788,6 +822,13 @@ export class AgentSession {
788
822
  get agentDir() {
789
823
  return this._agentDir;
790
824
  }
825
+ /**
826
+ * Working directory this session resolves settings against — the same value extensions
827
+ * receive as `ctx.cwd`, so a host surface (RPC) reads project settings identically.
828
+ */
829
+ get cwd() {
830
+ return this._cwd;
831
+ }
791
832
  async _waitForSettledSessionWork() {
792
833
  await this._sessionWorkBarrier.waitForSettled(() => this._agentEventQueue);
793
834
  }
@@ -1545,6 +1586,9 @@ export class AgentSession {
1545
1586
  */
1546
1587
  subscribe(listener) {
1547
1588
  this._eventListeners.push(listener);
1589
+ for (const source of this.settingsManager.getSelectedSettingsSources()) {
1590
+ listener({ type: "settings_source_selected", ...source });
1591
+ }
1548
1592
  // Return unsubscribe function for this specific listener
1549
1593
  return () => {
1550
1594
  const index = this._eventListeners.indexOf(listener);
@@ -1592,6 +1636,8 @@ export class AgentSession {
1592
1636
  }
1593
1637
  this._extensionRunner.invalidate("This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().");
1594
1638
  this._disconnectFromAgent();
1639
+ this._unsubscribeSettingsSource?.();
1640
+ this._unsubscribeSettingsSource = undefined;
1595
1641
  this._eventListeners = [];
1596
1642
  cleanupSessionResources(this.sessionId);
1597
1643
  }
@@ -1625,13 +1671,54 @@ export class AgentSession {
1625
1671
  isFastModeActive() {
1626
1672
  return this._sessionFastMode || this._currentServiceTier === "priority";
1627
1673
  }
1628
- /** Session-scoped fast-mode indicator; never persisted, reset on session start. */
1674
+ /**
1675
+ * The tier a request would carry right now: `serviceTier`, promoted to `"priority"` while
1676
+ * session fast mode is on (which is exactly what the service-tier extension puts on the
1677
+ * wire). Reported to clients so `serviceTier` and `fastMode` can never disagree.
1678
+ */
1679
+ get effectiveServiceTier() {
1680
+ return this.isFastModeActive() ? "priority" : this._currentServiceTier;
1681
+ }
1682
+ /**
1683
+ * Session-scoped fast-mode indicator; never persisted, reset on session start.
1684
+ *
1685
+ * Turning fast OFF also clears the cached priority tier: `/fast off` writes a remembered
1686
+ * `"auto"` that must override an inherited catalog-priority tier immediately (display and
1687
+ * request side), not only on the next session. Only codex-response models are touched, and
1688
+ * never when an explicit scoped/favorite `:priority` pin is in force — those are pinned by
1689
+ * the user's model selection, not by `/fast`.
1690
+ */
1629
1691
  setSessionFastMode(enabled) {
1692
+ const previousFastMode = this.isFastModeActive();
1693
+ const previousTier = this._currentServiceTier;
1630
1694
  this._sessionFastMode = enabled;
1695
+ if (!enabled && this._currentServiceTier === "priority" && this.model?.api === CODEX_RESPONSES_API) {
1696
+ // Only an INHERITED (catalog) priority is cleared. A priority the catalog does not
1697
+ // explain came from an explicit scoped/favorite `:priority` pin, which `/fast` must not undo.
1698
+ if (this._modelRuntime.getCompatibilityRequestConfig(this.model).serviceTier === "priority") {
1699
+ this._currentServiceTier = undefined;
1700
+ }
1701
+ }
1702
+ this._emitServiceTierChangeIfNeeded(previousTier, previousFastMode);
1703
+ }
1704
+ /**
1705
+ * Emit `service_tier_changed` when the effective tier or the fast-mode indicator actually
1706
+ * moved. Both are observable state for RPC clients (`get_state.serviceTier` / `.fastMode`),
1707
+ * and they can move independently: a session fast-mode toggle need not change the resolved
1708
+ * tier, and a model switch can change the tier with fast mode untouched.
1709
+ */
1710
+ _emitServiceTierChangeIfNeeded(previousTier, previousFastMode) {
1711
+ const fastMode = this.isFastModeActive();
1712
+ if (previousTier === this._currentServiceTier && previousFastMode === fastMode)
1713
+ return;
1714
+ this._emit({ type: "service_tier_changed", tier: this.effectiveServiceTier, fastMode });
1631
1715
  }
1632
1716
  /**
1633
1717
  * Explicit scoped/favorite tiers win; otherwise fall back to the model's
1634
- * configured serviceTier from models.json/extension compatibility config.
1718
+ * configured serviceTier from models.json/extension compatibility config. The per-model
1719
+ * `/fast` memory is honored by the service-tier extension (`liveMemoryTier` + the session
1720
+ * flag in `before_provider_request`), not cached here: caching it would survive a same-session
1721
+ * `/fast off` (no model switch to re-resolve) and leak an inherited priority onto the wire.
1635
1722
  */
1636
1723
  _resolveServiceTier(model, explicit) {
1637
1724
  if (explicit)
@@ -1913,6 +2000,8 @@ export class AgentSession {
1913
2000
  selectedTools: validToolNames,
1914
2001
  toolSnippets,
1915
2002
  promptGuidelines,
2003
+ customPrompt: loaderSystemPrompt,
2004
+ appendSystemPrompt: loaderAppendSystemPrompt.length > 0 ? loaderAppendSystemPrompt.join("\n\n") : undefined,
1916
2005
  };
1917
2006
  const basePrompt = loaderSystemPrompt ?? buildDynamicSystemPrompt(this._baseSystemPromptOptions);
1918
2007
  return loaderAppendSystemPrompt.length > 0
@@ -2306,7 +2395,12 @@ export class AgentSession {
2306
2395
  try {
2307
2396
  const content = readFileSync(skill.filePath, "utf-8");
2308
2397
  const body = stripFrontmatter(content).trim();
2309
- skillBlocks.push(`<skill name="${skill.name}" location="${skill.filePath}">\nReferences are relative to ${skill.baseDir}.\n\n${body}\n</skill>`);
2398
+ skillBlocks.push({
2399
+ name: skill.name,
2400
+ filePath: skill.filePath,
2401
+ baseDir: skill.baseDir,
2402
+ body,
2403
+ });
2310
2404
  expandedSkillNames.add(skill.name);
2311
2405
  }
2312
2406
  catch (err) {
@@ -2326,8 +2420,7 @@ export class AgentSession {
2326
2420
  if (skillBlocks.length === 0)
2327
2421
  return text;
2328
2422
  const args = text.slice(tokenStart).trim();
2329
- const expandedSkills = skillBlocks.join("\n\n");
2330
- return args ? `${expandedSkills}\n\n${args}` : expandedSkills;
2423
+ return formatSkillInvocationPrompt(skillBlocks, args);
2331
2424
  }
2332
2425
  /**
2333
2426
  * Queue a steering message while the agent is running.
@@ -2532,7 +2625,7 @@ export class AgentSession {
2532
2625
  if (options?.deliverAs === "nextTurn") {
2533
2626
  this._pendingNextTurnMessages.push(appMessage);
2534
2627
  }
2535
- else if (this.isStreaming) {
2628
+ else if (this.isStreaming && options?.triggerTurn !== false) {
2536
2629
  if (options?.deliverAs === "followUp") {
2537
2630
  this.agent.followUp(appMessage);
2538
2631
  }
@@ -2593,6 +2686,7 @@ export class AgentSession {
2593
2686
  *
2594
2687
  * @param content User message content (string or content array)
2595
2688
  * @param options.deliverAs Delivery mode when streaming: "steer" or "followUp"
2689
+ * @param options.expandPromptTemplates Whether to dispatch extension commands and expand skill commands and prompt templates. Default: false.
2596
2690
  */
2597
2691
  async sendUserMessage(content, options) {
2598
2692
  const bindingPromptReadiness = this._extensionBindingPromptReadiness;
@@ -2631,9 +2725,8 @@ export class AgentSession {
2631
2725
  let finishSessionWork;
2632
2726
  let disposition;
2633
2727
  try {
2634
- // Use prompt() with expandPromptTemplates: false to skip command handling and template expansion
2635
2728
  await this.prompt(text, {
2636
- expandPromptTemplates: false,
2729
+ expandPromptTemplates: options?.expandPromptTemplates ?? false,
2637
2730
  streamingBehavior: options?.deliverAs,
2638
2731
  images,
2639
2732
  source: "extension",
@@ -2840,7 +2933,7 @@ export class AgentSession {
2840
2933
  if (opts.invalidateCompaction && this._modelSelectionChangesContext(previousModel, model)) {
2841
2934
  this._invalidateCompactionForModelSelection();
2842
2935
  }
2843
- const thinkingLevel = this._getThinkingLevelForModelSwitch(opts.ephemeralThinkingLevel);
2936
+ const thinkingLevel = this._getThinkingLevelForModelSwitch(model, opts.ephemeralThinkingLevel);
2844
2937
  this.agent.state.model = model;
2845
2938
  this.agent.abortServerSideFallback =
2846
2939
  this.settingsManager.getAbortServerSideFallback() && this._retryFallback.hasConfiguredChain();
@@ -2851,6 +2944,8 @@ export class AgentSession {
2851
2944
  this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);
2852
2945
  }
2853
2946
  const scopedMatch = this._scopedModels.find((sm) => modelsAreEqual(sm.model, model));
2947
+ const previousTier = this._currentServiceTier;
2948
+ const previousFastMode = this.isFastModeActive();
2854
2949
  this._currentServiceTier = this._resolveServiceTier(model, scopedMatch?.serviceTier);
2855
2950
  if (opts.ephemeralThinkingLevel !== undefined) {
2856
2951
  this._applyEphemeralThinkingLevel(thinkingLevel);
@@ -2859,6 +2954,15 @@ export class AgentSession {
2859
2954
  this.setSessionThinkingLevel(thinkingLevel);
2860
2955
  }
2861
2956
  this._emitHighReasoningWarningIfNeeded();
2957
+ // Post-switch: the level reported here is the one actually in force (clamped, or restored
2958
+ // from this model's memory), not the level requested for the previous model.
2959
+ this._emit({
2960
+ type: "model_changed",
2961
+ model,
2962
+ thinkingLevel: this.thinkingLevel,
2963
+ source: opts.modelSelectSource,
2964
+ });
2965
+ this._emitServiceTierChangeIfNeeded(previousTier, previousFastMode);
2862
2966
  if (!opts.emitModelSelect)
2863
2967
  return undefined;
2864
2968
  return await this._emitModelSelect(model, previousModel, opts.modelSelectSource);
@@ -2903,16 +3007,26 @@ export class AgentSession {
2903
3007
  }
2904
3008
  this._probeBackScheduler.cancel("manual-model-change");
2905
3009
  this._retryFallback.clearForManualModelChange(next.model);
2906
- const thinkingLevel = this._getThinkingLevelForModelSwitch(next.thinkingLevel);
3010
+ const thinkingLevel = this._getThinkingLevelForModelSwitch(next.model, next.thinkingLevel);
2907
3011
  this.agent.state.model = next.model;
2908
3012
  this.sessionManager.appendModelChange(next.model.provider, next.model.id);
2909
3013
  this.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);
3014
+ const previousTier = this._currentServiceTier;
3015
+ const previousFastMode = this.isFastModeActive();
2910
3016
  this._currentServiceTier = this._resolveServiceTier(next.model, next.serviceTier);
2911
3017
  // Apply thinking level.
2912
3018
  // - Explicit favorite model thinking level overrides the effective session level
2913
3019
  // - Undefined favorite model thinking level restores the remembered user preference
2914
3020
  // setSessionThinkingLevel clamps without replacing that preference.
2915
3021
  this.setSessionThinkingLevel(thinkingLevel);
3022
+ // Post-switch, same contract as _switchActiveModel: the level in force AFTER the cycle.
3023
+ this._emit({
3024
+ type: "model_changed",
3025
+ model: next.model,
3026
+ thinkingLevel: this.thinkingLevel,
3027
+ source: "cycle",
3028
+ });
3029
+ this._emitServiceTierChangeIfNeeded(previousTier, previousFastMode);
2916
3030
  const systemPromptChange = await this._emitModelSelect(next.model, currentModel, "cycle");
2917
3031
  const cycleResult = { model: next.model, thinkingLevel: this.thinkingLevel, isScoped: true };
2918
3032
  if (systemPromptChange) {
@@ -2926,7 +3040,7 @@ export class AgentSession {
2926
3040
  /**
2927
3041
  * Set thinking level.
2928
3042
  * Clamps to model capabilities based on available thinking levels.
2929
- * Saves to session and settings only if the level actually changes.
3043
+ * Persistent calls refresh per-model memory; session entries and events are emitted only on change.
2930
3044
  */
2931
3045
  setThinkingLevel(level) {
2932
3046
  this._setThinkingLevel(level, true);
@@ -2948,6 +3062,12 @@ export class AgentSession {
2948
3062
  this._retryFallback.noteManualThinkingLevel();
2949
3063
  }
2950
3064
  this.agent.state.thinkingLevel = effectiveLevel;
3065
+ if (updateGlobalDefault) {
3066
+ const model = this.model;
3067
+ if (model) {
3068
+ this.settingsManager.setModelThinkingLevel(model.provider, model.id, effectiveLevel);
3069
+ }
3070
+ }
2951
3071
  if (isChanging) {
2952
3072
  this.sessionManager.appendThinkingLevelChange(effectiveLevel);
2953
3073
  if (updateGlobalDefault && (this.supportsThinking() || effectiveLevel !== "off")) {
@@ -3019,11 +3139,12 @@ export class AgentSession {
3019
3139
  supportsThinking() {
3020
3140
  return !!this.model?.reasoning;
3021
3141
  }
3022
- _getThinkingLevelForModelSwitch(explicitLevel) {
3023
- if (explicitLevel !== undefined) {
3024
- return explicitLevel;
3025
- }
3026
- return this.settingsManager.getDefaultThinkingLevel() ?? this.thinkingLevel ?? DEFAULT_THINKING_LEVEL;
3142
+ _getThinkingLevelForModelSwitch(model, explicitLevel) {
3143
+ const requestedLevel = explicitLevel ??
3144
+ this.settingsManager.getModelThinkingLevel(model.provider, model.id) ??
3145
+ this.settingsManager.getDefaultThinkingLevel() ??
3146
+ DEFAULT_THINKING_LEVEL;
3147
+ return this._clampThinkingLevel(requestedLevel, getSupportedThinkingLevels(model));
3027
3148
  }
3028
3149
  _clampThinkingLevel(level, availableLevels) {
3029
3150
  const available = new Set(availableLevels);
@@ -3687,8 +3808,9 @@ export class AgentSession {
3687
3808
  if (compacted)
3688
3809
  return true;
3689
3810
  }
3690
- if (this._isCompactionOnCooldown() || this._isCompactionDelegated())
3811
+ if (this._isCompactionOnCooldown() || this._isCompactionDelegated() || this._hasSupersedingCompactionClaim()) {
3691
3812
  return false;
3813
+ }
3692
3814
  throw new RequiredCompactionError();
3693
3815
  }
3694
3816
  /**
@@ -3729,6 +3851,8 @@ export class AgentSession {
3729
3851
  const compacted = await this._runPrePromptCompaction(lastAssistantMessage, false, "pre_prompt");
3730
3852
  if (!compacted && this._isCompactionDelegated())
3731
3853
  return;
3854
+ if (!compacted && this._hasSupersedingCompactionClaim())
3855
+ return;
3732
3856
  if (!compacted && !isOversized() && this._isCompactionOnCooldown())
3733
3857
  return;
3734
3858
  if (!compacted || isOversized()) {
@@ -3819,7 +3943,7 @@ export class AgentSession {
3819
3943
  this._restoreAgentMessagesFromSession();
3820
3944
  this._incrementMessageRevision();
3821
3945
  }
3822
- if (!compacted && inlineReason && !this._isCompactionDelegated()) {
3946
+ if (!compacted && inlineReason && !this._isCompactionDelegated() && !this._hasSupersedingCompactionClaim()) {
3823
3947
  throw new RequiredCompactionError();
3824
3948
  }
3825
3949
  return compacted;
@@ -3888,6 +4012,17 @@ export class AgentSession {
3888
4012
  const state = this._compactionLifecycle.state;
3889
4013
  return state.status === "failed" && state.rejectionCause === "circuit-breaker";
3890
4014
  }
4015
+ /**
4016
+ * Compaction claims are last-writer-wins: a newer admission aborts the
4017
+ * incumbent controller (_claimCompactionController). When the failed attempt
4018
+ * lost that race, a live claimant now owns the route and re-gates admission
4019
+ * itself, so the loser must not surface RequiredCompactionError (issue #886).
4020
+ * A user abort leaves no live claimant behind and keeps throwing.
4021
+ */
4022
+ _hasSupersedingCompactionClaim() {
4023
+ const claimant = this._compactionAbortController ?? this._autoCompactionAbortController;
4024
+ return claimant !== undefined && !claimant.signal.aborted;
4025
+ }
3891
4026
  _isCompactionDelegated() {
3892
4027
  const state = this._compactionLifecycle.state;
3893
4028
  const model = this.model;
@@ -3961,8 +4096,9 @@ export class AgentSession {
3961
4096
  return;
3962
4097
  const compacted = await this._runPrePromptCompaction(this._findLastAssistantMessage(), true, "pre_prompt");
3963
4098
  if (!compacted) {
3964
- if (this._isCompactionOnCooldown() || this._isCompactionDelegated())
4099
+ if (this._isCompactionOnCooldown() || this._isCompactionDelegated() || this._hasSupersedingCompactionClaim()) {
3965
4100
  return;
4101
+ }
3966
4102
  throw new RequiredCompactionError();
3967
4103
  }
3968
4104
  this._scheduledContinuationRecompacted = true;
@@ -4208,6 +4344,7 @@ export class AgentSession {
4208
4344
  this._applyExtensionBindings(this._extensionRunner);
4209
4345
  this.syncPromptCacheSafeWaitEnv();
4210
4346
  await this._extensionRunner.emit(this._sessionStartEvent);
4347
+ this._enforceConfiguredDefaultTools();
4211
4348
  await this.extendResourcesFromExtensions(this._sessionStartEvent.reason === "reload" ? "reload" : "startup");
4212
4349
  }
4213
4350
  finally {
@@ -4541,6 +4678,22 @@ export class AgentSession {
4541
4678
  get fallbackValidationWarnings() {
4542
4679
  return this._fallbackValidationWarnings;
4543
4680
  }
4681
+ _isBuiltinExtensionPath(path) {
4682
+ return path.startsWith("<builtin:") || /[\\/]senpi-codemode[\\/]/u.test(path);
4683
+ }
4684
+ _enforceConfiguredDefaultTools() {
4685
+ const defaultToolNames = this._defaultToolNames;
4686
+ if (defaultToolNames === undefined)
4687
+ return;
4688
+ this.setActiveToolsByName(this.getActiveToolNames().filter((name) => {
4689
+ if (defaultToolNames.has(name))
4690
+ return true;
4691
+ const entry = this._toolDefinitions.get(name);
4692
+ return (entry !== undefined &&
4693
+ !this._isBuiltinExtensionPath(entry.sourceInfo.path) &&
4694
+ entry.sourceInfo.source !== "builtin");
4695
+ }));
4696
+ }
4544
4697
  _refreshToolRegistry(options) {
4545
4698
  const previousRegistryNames = new Set(this._toolRegistry.keys());
4546
4699
  const previousActiveToolNames = this.getActiveToolNames();
@@ -4548,8 +4701,12 @@ export class AgentSession {
4548
4701
  const excludedToolNames = this._excludedToolNames;
4549
4702
  const isAllowedTool = (name) => (!allowedToolNames || allowedToolNames.has(name)) && !excludedToolNames?.has(name);
4550
4703
  const registeredTools = this._extensionRunner.getAllRegisteredTools();
4704
+ const defaultToolNames = this._defaultToolNames;
4705
+ const isConfiguredBuiltinTool = (tool) => (tool.sourceInfo.source !== "builtin" && !this._isBuiltinExtensionPath(tool.sourceInfo.path)) ||
4706
+ defaultToolNames === undefined ||
4707
+ defaultToolNames.has(tool.definition.name);
4551
4708
  const allCustomTools = [
4552
- ...registeredTools,
4709
+ ...registeredTools.filter(isConfiguredBuiltinTool),
4553
4710
  ...this._customTools.map((definition) => ({
4554
4711
  definition,
4555
4712
  sourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: "sdk" }),
@@ -5192,7 +5349,10 @@ export class AgentSession {
5192
5349
  model &&
5193
5350
  shouldCompact(contextTokens, model.contextWindow, compactionSettings)) {
5194
5351
  const preRetryCompaction = await this._runPrePromptCompaction(message, true, "threshold", true, true);
5195
- if (!preRetryCompaction && !this._isCompactionOnCooldown() && !this._isCompactionDelegated()) {
5352
+ if (!preRetryCompaction &&
5353
+ !this._isCompactionOnCooldown() &&
5354
+ !this._isCompactionDelegated() &&
5355
+ !this._hasSupersedingCompactionClaim()) {
5196
5356
  const attempt = this._retryAttempt;
5197
5357
  this._retryAttempt = 0;
5198
5358
  this._resetHintTierState();
@@ -5681,11 +5841,11 @@ export class AgentSession {
5681
5841
  /**
5682
5842
  * Export session to HTML.
5683
5843
  * @param outputPath Optional output path (defaults to session directory)
5844
+ * @param options Optional export presentation settings
5684
5845
  * @returns Path to exported file
5685
5846
  */
5686
- async exportToHtml(outputPath) {
5687
- const configuredThemeName = this.settingsManager.getTheme();
5688
- const themeName = configuredThemeName && getThemeByName(configuredThemeName) ? configuredThemeName : undefined;
5847
+ async exportToHtml(outputPath, options = {}) {
5848
+ const themeName = [options.themeName, this.settingsManager.getTheme()].find((candidate) => candidate !== undefined && getThemeByName(candidate) !== undefined);
5689
5849
  // Create tool renderer if we have an extension runner (for custom tool HTML rendering)
5690
5850
  const toolRenderer = createToolHtmlRenderer({
5691
5851
  getToolDefinition: (name) => this.getToolDefinition(name),