@code-yeongyu/senpi 2026.8.18-3 → 2026.8.19

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 (353) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/cli/args.d.ts +1 -0
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +4 -0
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/core/agent-session.d.ts +33 -4
  7. package/dist/core/agent-session.d.ts.map +1 -1
  8. package/dist/core/agent-session.js +293 -55
  9. package/dist/core/agent-session.js.map +1 -1
  10. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  11. package/dist/core/compaction/branch-summarization.js +3 -0
  12. package/dist/core/compaction/branch-summarization.js.map +1 -1
  13. package/dist/core/compaction/compaction.d.ts +20 -3
  14. package/dist/core/compaction/compaction.d.ts.map +1 -1
  15. package/dist/core/compaction/compaction.js +182 -52
  16. package/dist/core/compaction/compaction.js.map +1 -1
  17. package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts +3 -0
  18. package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts.map +1 -1
  19. package/dist/core/extensions/builtin/claude-sdk-oauth/index.js +18 -1
  20. package/dist/core/extensions/builtin/claude-sdk-oauth/index.js.map +1 -1
  21. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts +1 -0
  22. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts.map +1 -1
  23. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js +7 -1
  24. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js.map +1 -1
  25. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts +8 -0
  26. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts.map +1 -1
  27. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js +18 -0
  28. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js.map +1 -1
  29. package/dist/core/extensions/builtin/cursor-cli-oauth/guardrails.d.ts +7 -0
  30. package/dist/core/extensions/builtin/cursor-cli-oauth/guardrails.d.ts.map +1 -1
  31. package/dist/core/extensions/builtin/cursor-cli-oauth/guardrails.js +10 -1
  32. package/dist/core/extensions/builtin/cursor-cli-oauth/guardrails.js.map +1 -1
  33. package/dist/core/extensions/builtin/cursor-cli-oauth/index.d.ts.map +1 -1
  34. package/dist/core/extensions/builtin/cursor-cli-oauth/index.js +12 -1
  35. package/dist/core/extensions/builtin/cursor-cli-oauth/index.js.map +1 -1
  36. package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.d.ts +12 -1
  37. package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.d.ts.map +1 -1
  38. package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.js +20 -1
  39. package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.js.map +1 -1
  40. package/dist/core/extensions/builtin/cursor-cli-oauth/settings.d.ts +11 -0
  41. package/dist/core/extensions/builtin/cursor-cli-oauth/settings.d.ts.map +1 -1
  42. package/dist/core/extensions/builtin/cursor-cli-oauth/settings.js +7 -2
  43. package/dist/core/extensions/builtin/cursor-cli-oauth/settings.js.map +1 -1
  44. package/dist/core/extensions/builtin/cursor-cli-oauth/stream.d.ts.map +1 -1
  45. package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js +7 -2
  46. package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js.map +1 -1
  47. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  48. package/dist/core/extensions/builtin/index.js +2 -0
  49. package/dist/core/extensions/builtin/index.js.map +1 -1
  50. package/dist/core/extensions/builtin/loop/command-registration.d.ts +7 -0
  51. package/dist/core/extensions/builtin/loop/command-registration.d.ts.map +1 -0
  52. package/dist/core/extensions/builtin/loop/command-registration.js +13 -0
  53. package/dist/core/extensions/builtin/loop/command-registration.js.map +1 -0
  54. package/dist/core/extensions/builtin/loop/command.d.ts +41 -0
  55. package/dist/core/extensions/builtin/loop/command.d.ts.map +1 -0
  56. package/dist/core/extensions/builtin/loop/command.js +281 -0
  57. package/dist/core/extensions/builtin/loop/command.js.map +1 -0
  58. package/dist/core/extensions/builtin/loop/cron-planner.d.ts +23 -0
  59. package/dist/core/extensions/builtin/loop/cron-planner.d.ts.map +1 -0
  60. package/dist/core/extensions/builtin/loop/cron-planner.js +88 -0
  61. package/dist/core/extensions/builtin/loop/cron-planner.js.map +1 -0
  62. package/dist/core/extensions/builtin/loop/index.d.ts +134 -0
  63. package/dist/core/extensions/builtin/loop/index.d.ts.map +1 -0
  64. package/dist/core/extensions/builtin/loop/index.js +742 -0
  65. package/dist/core/extensions/builtin/loop/index.js.map +1 -0
  66. package/dist/core/extensions/builtin/loop/loopfile.d.ts +40 -0
  67. package/dist/core/extensions/builtin/loop/loopfile.d.ts.map +1 -0
  68. package/dist/core/extensions/builtin/loop/loopfile.js +102 -0
  69. package/dist/core/extensions/builtin/loop/loopfile.js.map +1 -0
  70. package/dist/core/extensions/builtin/loop/parse.d.ts +45 -0
  71. package/dist/core/extensions/builtin/loop/parse.d.ts.map +1 -0
  72. package/dist/core/extensions/builtin/loop/parse.js +92 -0
  73. package/dist/core/extensions/builtin/loop/parse.js.map +1 -0
  74. package/dist/core/extensions/builtin/loop/scheduler.d.ts +225 -0
  75. package/dist/core/extensions/builtin/loop/scheduler.d.ts.map +1 -0
  76. package/dist/core/extensions/builtin/loop/scheduler.js +708 -0
  77. package/dist/core/extensions/builtin/loop/scheduler.js.map +1 -0
  78. package/dist/core/extensions/builtin/loop/status.d.ts +24 -0
  79. package/dist/core/extensions/builtin/loop/status.d.ts.map +1 -0
  80. package/dist/core/extensions/builtin/loop/status.js +113 -0
  81. package/dist/core/extensions/builtin/loop/status.js.map +1 -0
  82. package/dist/core/extensions/builtin/loop/store.d.ts +49 -0
  83. package/dist/core/extensions/builtin/loop/store.d.ts.map +1 -0
  84. package/dist/core/extensions/builtin/loop/store.js +424 -0
  85. package/dist/core/extensions/builtin/loop/store.js.map +1 -0
  86. package/dist/core/extensions/builtin/loop/tick-prompt.d.ts +64 -0
  87. package/dist/core/extensions/builtin/loop/tick-prompt.d.ts.map +1 -0
  88. package/dist/core/extensions/builtin/loop/tick-prompt.js +183 -0
  89. package/dist/core/extensions/builtin/loop/tick-prompt.js.map +1 -0
  90. package/dist/core/extensions/builtin/loop/tools.d.ts +122 -0
  91. package/dist/core/extensions/builtin/loop/tools.d.ts.map +1 -0
  92. package/dist/core/extensions/builtin/loop/tools.js +155 -0
  93. package/dist/core/extensions/builtin/loop/tools.js.map +1 -0
  94. package/dist/core/extensions/builtin/loop/types.d.ts +206 -0
  95. package/dist/core/extensions/builtin/loop/types.d.ts.map +1 -0
  96. package/dist/core/extensions/builtin/loop/types.js +37 -0
  97. package/dist/core/extensions/builtin/loop/types.js.map +1 -0
  98. package/dist/core/extensions/index.d.ts +1 -1
  99. package/dist/core/extensions/index.d.ts.map +1 -1
  100. package/dist/core/extensions/index.js.map +1 -1
  101. package/dist/core/extensions/loader.d.ts.map +1 -1
  102. package/dist/core/extensions/loader.js +10 -5
  103. package/dist/core/extensions/loader.js.map +1 -1
  104. package/dist/core/extensions/types.d.ts +30 -3
  105. package/dist/core/extensions/types.d.ts.map +1 -1
  106. package/dist/core/extensions/types.js.map +1 -1
  107. package/dist/core/footer-data-provider.d.ts.map +1 -1
  108. package/dist/core/footer-data-provider.js +5 -10
  109. package/dist/core/footer-data-provider.js.map +1 -1
  110. package/dist/core/model-registry.d.ts +2 -0
  111. package/dist/core/model-registry.d.ts.map +1 -1
  112. package/dist/core/model-registry.js +4 -0
  113. package/dist/core/model-registry.js.map +1 -1
  114. package/dist/core/model-runtime.d.ts +7 -0
  115. package/dist/core/model-runtime.d.ts.map +1 -1
  116. package/dist/core/model-runtime.js +17 -0
  117. package/dist/core/model-runtime.js.map +1 -1
  118. package/dist/core/package-manager.d.ts.map +1 -1
  119. package/dist/core/package-manager.js +8 -4
  120. package/dist/core/package-manager.js.map +1 -1
  121. package/dist/core/provider-composer.d.ts +8 -0
  122. package/dist/core/provider-composer.d.ts.map +1 -1
  123. package/dist/core/provider-composer.js.map +1 -1
  124. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  125. package/dist/core/remote-catalog-provider.js +2 -1
  126. package/dist/core/remote-catalog-provider.js.map +1 -1
  127. package/dist/core/retry-fallback/chains.d.ts +1 -0
  128. package/dist/core/retry-fallback/chains.d.ts.map +1 -1
  129. package/dist/core/retry-fallback/chains.js +3 -0
  130. package/dist/core/retry-fallback/chains.js.map +1 -1
  131. package/dist/core/retry-fallback/controller.d.ts +2 -0
  132. package/dist/core/retry-fallback/controller.d.ts.map +1 -1
  133. package/dist/core/retry-fallback/controller.js.map +1 -1
  134. package/dist/core/retry-fallback/expansion.d.ts +8 -0
  135. package/dist/core/retry-fallback/expansion.d.ts.map +1 -1
  136. package/dist/core/retry-fallback/expansion.js +2 -0
  137. package/dist/core/retry-fallback/expansion.js.map +1 -1
  138. package/dist/core/settings-manager.d.ts +1 -1
  139. package/dist/core/settings-manager.d.ts.map +1 -1
  140. package/dist/core/settings-manager.js +14 -3
  141. package/dist/core/settings-manager.js.map +1 -1
  142. package/dist/core/skills.d.ts.map +1 -1
  143. package/dist/core/skills.js +51 -33
  144. package/dist/core/skills.js.map +1 -1
  145. package/dist/core/tools/edit.d.ts.map +1 -1
  146. package/dist/core/tools/edit.js +17 -2
  147. package/dist/core/tools/edit.js.map +1 -1
  148. package/dist/extensions/llama/index.d.ts.map +1 -1
  149. package/dist/extensions/llama/index.js +2 -0
  150. package/dist/extensions/llama/index.js.map +1 -1
  151. package/dist/extensions/llama/provider.d.ts.map +1 -1
  152. package/dist/extensions/llama/provider.js +6 -6
  153. package/dist/extensions/llama/provider.js.map +1 -1
  154. package/dist/index.d.ts +1 -1
  155. package/dist/index.d.ts.map +1 -1
  156. package/dist/index.js.map +1 -1
  157. package/dist/main.d.ts +4 -0
  158. package/dist/main.d.ts.map +1 -1
  159. package/dist/main.js +4 -4
  160. package/dist/main.js.map +1 -1
  161. package/dist/modes/interactive/components/settings-selector.js +1 -1
  162. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  163. package/dist/modes/interactive/editor-paste-transfer.d.ts +10 -1
  164. package/dist/modes/interactive/editor-paste-transfer.d.ts.map +1 -1
  165. package/dist/modes/interactive/editor-paste-transfer.js +27 -2
  166. package/dist/modes/interactive/editor-paste-transfer.js.map +1 -1
  167. package/dist/modes/interactive/interactive-mode.d.ts +69 -1
  168. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  169. package/dist/modes/interactive/interactive-mode.js +434 -63
  170. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  171. package/dist/modes/interactive/tips/catalog/dag-tips.d.ts +7 -0
  172. package/dist/modes/interactive/tips/catalog/dag-tips.d.ts.map +1 -0
  173. package/dist/modes/interactive/tips/catalog/dag-tips.js +57 -0
  174. package/dist/modes/interactive/tips/catalog/dag-tips.js.map +1 -0
  175. package/dist/modes/interactive/tips/catalog/memory-tips.d.ts +7 -0
  176. package/dist/modes/interactive/tips/catalog/memory-tips.d.ts.map +1 -0
  177. package/dist/modes/interactive/tips/catalog/memory-tips.js +100 -0
  178. package/dist/modes/interactive/tips/catalog/memory-tips.js.map +1 -0
  179. package/dist/modes/interactive/tips/registry.d.ts.map +1 -1
  180. package/dist/modes/interactive/tips/registry.js +4 -0
  181. package/dist/modes/interactive/tips/registry.js.map +1 -1
  182. package/dist/utils/management-http.d.ts +5 -3
  183. package/dist/utils/management-http.d.ts.map +1 -1
  184. package/dist/utils/management-http.js +14 -10
  185. package/dist/utils/management-http.js.map +1 -1
  186. package/docs/compaction.md +17 -0
  187. package/docs/custom-provider.md +5 -2
  188. package/docs/extensions.md +11 -2
  189. package/docs/llama-cpp.md +2 -0
  190. package/docs/models.md +8 -2
  191. package/docs/providers.md +5 -3
  192. package/docs/settings.md +22 -2
  193. package/docs/skills.md +4 -3
  194. package/examples/extensions/border-status-editor.ts +1 -1
  195. package/examples/extensions/git-checkpoint.ts +2 -2
  196. package/examples/extensions/notify.ts +3 -1
  197. package/examples/extensions/subagent/index.ts +6 -1
  198. package/examples/extensions/titlebar-spinner.ts +1 -1
  199. package/examples/rpc-extension-ui.ts +1 -1
  200. package/examples/sdk/06-extensions.ts +1 -1
  201. package/examples/sdk/README.md +1 -1
  202. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
  203. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  204. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts +3 -1
  205. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  206. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +51 -17
  207. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  208. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +4 -2
  209. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  210. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +5 -1
  211. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  212. package/node_modules/@earendil-works/pi-agent-core/dist/harness/skills.d.ts +3 -2
  213. package/node_modules/@earendil-works/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
  214. package/node_modules/@earendil-works/pi-agent-core/dist/harness/skills.js +13 -3
  215. package/node_modules/@earendil-works/pi-agent-core/dist/harness/skills.js.map +1 -1
  216. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.d.ts.map +1 -1
  217. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js +14 -1
  218. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js.map +1 -1
  219. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  220. package/node_modules/@earendil-works/pi-ai/README.md +5 -3
  221. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts +7 -1
  222. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  223. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +21 -4
  224. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  225. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts +2 -0
  226. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts.map +1 -1
  227. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +7 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  229. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  230. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +39 -2
  231. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  232. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/gen/agent_pb.d.ts +22 -1
  233. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/gen/agent_pb.d.ts.map +1 -1
  234. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/gen/agent_pb.js +1 -1
  235. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/gen/agent_pb.js.map +1 -1
  236. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +1 -0
  237. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
  238. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +51 -2
  239. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
  240. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.d.ts +2 -2
  241. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.d.ts.map +1 -1
  242. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js +14 -11
  243. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js.map +1 -1
  244. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts +5 -2
  245. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts.map +1 -1
  246. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js +16 -0
  247. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js.map +1 -1
  248. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.d.ts +2 -2
  249. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.d.ts.map +1 -1
  250. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js +13 -10
  251. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js.map +1 -1
  252. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.d.ts.map +1 -1
  253. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.js +4 -1
  254. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.js.map +1 -1
  255. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  256. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +4 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  258. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts +1 -1
  259. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  260. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +45 -29
  261. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  262. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  263. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +8 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  265. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.js +1 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.js.map +1 -1
  267. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.d.ts +4 -0
  268. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.d.ts.map +1 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js +18 -9
  270. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js.map +1 -1
  271. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/device-code.d.ts +1 -0
  272. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/device-code.d.ts.map +1 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/device-code.js +1 -1
  274. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/device-code.js.map +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  276. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js +22 -9
  277. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js.map +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +2 -1
  279. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  280. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
  281. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  283. package/node_modules/@earendil-works/pi-ai/dist/providers/data/anthropic.json +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
  285. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  286. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  287. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  288. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  289. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-individual.json +1 -1
  290. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  291. package/node_modules/@earendil-works/pi-ai/dist/providers/data/xai.json +1 -1
  292. package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
  293. package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
  294. package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
  295. package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi.json +1 -1
  296. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  297. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  298. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.d.ts +1 -1
  299. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.d.ts.map +1 -1
  300. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.js +1 -5
  301. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.js.map +1 -1
  302. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +28 -4
  303. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  304. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  305. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  306. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +15 -0
  307. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  308. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.d.ts +2 -0
  309. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.d.ts.map +1 -1
  310. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.js +7 -0
  311. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.js.map +1 -1
  312. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts +2 -1
  313. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  314. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js +2 -0
  315. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js.map +1 -1
  316. package/node_modules/@earendil-works/pi-ai/package.json +2 -3
  317. package/node_modules/@earendil-works/pi-pty/dist/loader.d.ts +6 -0
  318. package/node_modules/@earendil-works/pi-pty/dist/loader.d.ts.map +1 -1
  319. package/node_modules/@earendil-works/pi-pty/dist/loader.js +11 -0
  320. package/node_modules/@earendil-works/pi-pty/dist/loader.js.map +1 -1
  321. package/node_modules/@earendil-works/pi-pty/dist/quarantine.d.ts +15 -0
  322. package/node_modules/@earendil-works/pi-pty/dist/quarantine.d.ts.map +1 -0
  323. package/node_modules/@earendil-works/pi-pty/dist/quarantine.js +27 -0
  324. package/node_modules/@earendil-works/pi-pty/dist/quarantine.js.map +1 -0
  325. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  326. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  327. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +73 -1
  328. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  329. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +173 -17
  330. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  331. package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts.map +1 -1
  332. package/node_modules/@earendil-works/pi-tui/dist/components/text.js +5 -4
  333. package/node_modules/@earendil-works/pi-tui/dist/components/text.js.map +1 -1
  334. package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts +69 -0
  335. package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts.map +1 -1
  336. package/node_modules/@earendil-works/pi-tui/dist/editor-component.js.map +1 -1
  337. package/node_modules/@earendil-works/pi-tui/dist/image-markers.d.ts +46 -0
  338. package/node_modules/@earendil-works/pi-tui/dist/image-markers.d.ts.map +1 -0
  339. package/node_modules/@earendil-works/pi-tui/dist/image-markers.js +130 -0
  340. package/node_modules/@earendil-works/pi-tui/dist/image-markers.js.map +1 -0
  341. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -0
  342. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  343. package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -0
  344. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  345. package/node_modules/@earendil-works/pi-tui/dist/paste-markers.d.ts +3 -0
  346. package/node_modules/@earendil-works/pi-tui/dist/paste-markers.d.ts.map +1 -1
  347. package/node_modules/@earendil-works/pi-tui/dist/paste-markers.js +23 -7
  348. package/node_modules/@earendil-works/pi-tui/dist/paste-markers.js.map +1 -1
  349. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.d.ts.map +1 -1
  350. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js +5 -1
  351. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js.map +1 -1
  352. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  353. package/package.json +7 -7
@@ -0,0 +1,7 @@
1
+ export declare const DAG_TIPS: {
2
+ id: string;
3
+ bindings: never[];
4
+ requiresCommand: string;
5
+ render: () => string;
6
+ }[];
7
+ //# sourceMappingURL=dag-tips.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dag-tips.d.ts","sourceRoot":"","sources":["../../../../../src/modes/interactive/tips/catalog/dag-tips.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ;;;;;GA+De,CAAC"}
@@ -0,0 +1,57 @@
1
+ export const DAG_TIPS = [
2
+ {
3
+ id: "dag.one-keyword-mastery",
4
+ bindings: [],
5
+ requiresCommand: "dag",
6
+ render: () => 'One keyword makes you a master of graph engineering: say "mass-ulw" and your work becomes a dependency graph that schedules itself.',
7
+ },
8
+ {
9
+ id: "dag.what-it-is",
10
+ bindings: [],
11
+ requiresCommand: "dag",
12
+ render: () => 'Trigger "mass-ulw" when some tasks must wait for others - describe the work, get a graph that runs in the right order.',
13
+ },
14
+ {
15
+ id: "dag.parallel-waves",
16
+ bindings: [],
17
+ requiresCommand: "dag",
18
+ render: () => "A graph run executes in waves: everything with no pending dependency starts at once, the rest starts the moment it is unblocked.",
19
+ },
20
+ {
21
+ id: "dag.depends-on",
22
+ bindings: [],
23
+ requiresCommand: "dag",
24
+ render: () => "Say what needs what - review after implementation, docs after both - and the ordering is enforced for you.",
25
+ },
26
+ {
27
+ id: "dag.categories",
28
+ bindings: [],
29
+ requiresCommand: "dag",
30
+ render: () => "Each node in the graph picks its own worker category, so cheap steps stay cheap and hard steps get the strong model.",
31
+ },
32
+ {
33
+ id: "dag.status-view",
34
+ bindings: [],
35
+ requiresCommand: "dag",
36
+ render: () => "Use /dag to watch a run: which nodes finished, which are running, and which one failed.",
37
+ },
38
+ {
39
+ id: "dag.resume",
40
+ bindings: [],
41
+ requiresCommand: "dag",
42
+ render: () => "Graph runs are journaled - if the session dies mid-run it resumes later and never redoes the nodes that already finished.",
43
+ },
44
+ {
45
+ id: "dag.vs-parallel",
46
+ bindings: [],
47
+ requiresCommand: "dag",
48
+ render: () => "Fully independent jobs just need parallel subagents; reach for a graph when the ordering between them is the whole point.",
49
+ },
50
+ {
51
+ id: "dag.scale",
52
+ bindings: [],
53
+ requiresCommand: "dag",
54
+ render: () => "Stop hand-running steps in sequence. Describe the dependencies once and let a dozen agents fan out and rejoin on their own.",
55
+ },
56
+ ];
57
+ //# sourceMappingURL=dag-tips.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dag-tips.js","sourceRoot":"","sources":["../../../../../src/modes/interactive/tips/catalog/dag-tips.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAAG;IACvB;QACC,EAAE,EAAE,yBAAyB;QAC7B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,GAAG,EAAE,CACZ,qIAAqI;KACtI;IACD;QACC,EAAE,EAAE,gBAAgB;QACpB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,GAAG,EAAE,CACZ,wHAAwH;KACzH;IACD;QACC,EAAE,EAAE,oBAAoB;QACxB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,GAAG,EAAE,CACZ,kIAAkI;KACnI;IACD;QACC,EAAE,EAAE,gBAAgB;QACpB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,GAAG,EAAE,CACZ,4GAA4G;KAC7G;IACD;QACC,EAAE,EAAE,gBAAgB;QACpB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,GAAG,EAAE,CACZ,sHAAsH;KACvH;IACD;QACC,EAAE,EAAE,iBAAiB;QACrB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,GAAG,EAAE,CAAC,yFAAyF;KACvG;IACD;QACC,EAAE,EAAE,YAAY;QAChB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,GAAG,EAAE,CACZ,2HAA2H;KAC5H;IACD;QACC,EAAE,EAAE,iBAAiB;QACrB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,GAAG,EAAE,CACZ,2HAA2H;KAC5H;IACD;QACC,EAAE,EAAE,WAAW;QACf,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,GAAG,EAAE,CACZ,6HAA6H;KAC9H;CACkC,CAAC","sourcesContent":["import type { TipDefinition } from \"./types.ts\";\n\nexport const DAG_TIPS = [\n\t{\n\t\tid: \"dag.one-keyword-mastery\",\n\t\tbindings: [],\n\t\trequiresCommand: \"dag\",\n\t\trender: () =>\n\t\t\t'One keyword makes you a master of graph engineering: say \"mass-ulw\" and your work becomes a dependency graph that schedules itself.',\n\t},\n\t{\n\t\tid: \"dag.what-it-is\",\n\t\tbindings: [],\n\t\trequiresCommand: \"dag\",\n\t\trender: () =>\n\t\t\t'Trigger \"mass-ulw\" when some tasks must wait for others - describe the work, get a graph that runs in the right order.',\n\t},\n\t{\n\t\tid: \"dag.parallel-waves\",\n\t\tbindings: [],\n\t\trequiresCommand: \"dag\",\n\t\trender: () =>\n\t\t\t\"A graph run executes in waves: everything with no pending dependency starts at once, the rest starts the moment it is unblocked.\",\n\t},\n\t{\n\t\tid: \"dag.depends-on\",\n\t\tbindings: [],\n\t\trequiresCommand: \"dag\",\n\t\trender: () =>\n\t\t\t\"Say what needs what - review after implementation, docs after both - and the ordering is enforced for you.\",\n\t},\n\t{\n\t\tid: \"dag.categories\",\n\t\tbindings: [],\n\t\trequiresCommand: \"dag\",\n\t\trender: () =>\n\t\t\t\"Each node in the graph picks its own worker category, so cheap steps stay cheap and hard steps get the strong model.\",\n\t},\n\t{\n\t\tid: \"dag.status-view\",\n\t\tbindings: [],\n\t\trequiresCommand: \"dag\",\n\t\trender: () => \"Use /dag to watch a run: which nodes finished, which are running, and which one failed.\",\n\t},\n\t{\n\t\tid: \"dag.resume\",\n\t\tbindings: [],\n\t\trequiresCommand: \"dag\",\n\t\trender: () =>\n\t\t\t\"Graph runs are journaled - if the session dies mid-run it resumes later and never redoes the nodes that already finished.\",\n\t},\n\t{\n\t\tid: \"dag.vs-parallel\",\n\t\tbindings: [],\n\t\trequiresCommand: \"dag\",\n\t\trender: () =>\n\t\t\t\"Fully independent jobs just need parallel subagents; reach for a graph when the ordering between them is the whole point.\",\n\t},\n\t{\n\t\tid: \"dag.scale\",\n\t\tbindings: [],\n\t\trequiresCommand: \"dag\",\n\t\trender: () =>\n\t\t\t\"Stop hand-running steps in sequence. Describe the dependencies once and let a dozen agents fan out and rejoin on their own.\",\n\t},\n] satisfies readonly TipDefinition[];\n"]}
@@ -0,0 +1,7 @@
1
+ export declare const MEMORY_TIPS: {
2
+ id: string;
3
+ bindings: never[];
4
+ requiresCommand: string;
5
+ render: () => string;
6
+ }[];
7
+ //# sourceMappingURL=memory-tips.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-tips.d.ts","sourceRoot":"","sources":["../../../../../src/modes/interactive/tips/catalog/memory-tips.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW;;;;;GAqGY,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { APP_NAME } from "../../../../config.js";
2
+ export const MEMORY_TIPS = [
3
+ {
4
+ id: "memory.persistent",
5
+ bindings: [],
6
+ requiresCommand: "memory",
7
+ render: () => `${APP_NAME} remembers across sessions. Close the terminal, come back tomorrow, and the context is still there.`,
8
+ },
9
+ {
10
+ id: "memory.remember-command",
11
+ bindings: [],
12
+ requiresCommand: "remember",
13
+ render: () => "Use /remember to save something you want kept - a preference, a decision, a fact worth reusing.",
14
+ },
15
+ {
16
+ id: "memory.just-tell-it",
17
+ bindings: [],
18
+ requiresCommand: "remember",
19
+ render: () => 'You can also just say it: "remember that we deploy on Fridays" is enough. No syntax, no file to open.',
20
+ },
21
+ {
22
+ id: "memory.search-command",
23
+ bindings: [],
24
+ requiresCommand: "search",
25
+ render: () => "Use /search to look through everything remembered so far, in plain words.",
26
+ },
27
+ {
28
+ id: "memory.memory-command",
29
+ bindings: [],
30
+ requiresCommand: "memory",
31
+ render: () => "Use /memory to see what is currently remembered about you and this project.",
32
+ },
33
+ {
34
+ id: "memory.init-command",
35
+ bindings: [],
36
+ requiresCommand: "init",
37
+ render: () => "Use /init to start memory for a new project, so it learns this codebase from the first session.",
38
+ },
39
+ {
40
+ id: "memory.people-command",
41
+ bindings: [],
42
+ requiresCommand: "people",
43
+ render: () => "Use /people to keep notes on teammates - who owns what, who to ask, what they prefer.",
44
+ },
45
+ {
46
+ id: "memory.reflect-command",
47
+ bindings: [],
48
+ requiresCommand: "reflect",
49
+ render: () => "Use /reflect to have the session reviewed now and the parts worth keeping written down.",
50
+ },
51
+ {
52
+ id: "memory.dream-command",
53
+ bindings: [],
54
+ requiresCommand: "dream",
55
+ render: () => "Memory tidies itself in the background between turns - /dream shows that work and lets you start it yourself.",
56
+ },
57
+ {
58
+ id: "memory.sleeptime-command",
59
+ bindings: [],
60
+ requiresCommand: "sleeptime",
61
+ render: () => "Use /sleeptime to decide how often memory reorganizes itself while you are not looking.",
62
+ },
63
+ {
64
+ id: "memory.memfs-command",
65
+ bindings: [],
66
+ requiresCommand: "memfs",
67
+ render: () => "Memory is plain files you own - browse them with /memfs and edit anything that looks wrong.",
68
+ },
69
+ {
70
+ id: "memory.repository-command",
71
+ bindings: [],
72
+ requiresCommand: "memory-repository",
73
+ render: () => "Every memory change is a git commit - use /memory-repository to see the history and undo a bad one.",
74
+ },
75
+ {
76
+ id: "memory.doctor-command",
77
+ bindings: [],
78
+ requiresCommand: "doctor",
79
+ render: () => "Use /doctor when memory feels off; it checks the setup and tells you what to fix.",
80
+ },
81
+ {
82
+ id: "memory.facts-command",
83
+ bindings: [],
84
+ requiresCommand: "facts",
85
+ render: () => "Use /facts to see the individual things learned about you, and drop the ones that no longer hold.",
86
+ },
87
+ {
88
+ id: "memory.recompile-command",
89
+ bindings: [],
90
+ requiresCommand: "recompile",
91
+ render: () => "Edited memory files by hand? Run /recompile so this session picks the changes up right away.",
92
+ },
93
+ {
94
+ id: "memory.stop-repeating",
95
+ bindings: [],
96
+ requiresCommand: "memory",
97
+ render: () => "Explain your setup once. Memory means you stop re-explaining it at the start of every session.",
98
+ },
99
+ ];
100
+ //# sourceMappingURL=memory-tips.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-tips.js","sourceRoot":"","sources":["../../../../../src/modes/interactive/tips/catalog/memory-tips.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD,MAAM,CAAC,MAAM,WAAW,GAAG;IAC1B;QACC,EAAE,EAAE,mBAAmB;QACvB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,QAAQ;QACzB,MAAM,EAAE,GAAG,EAAE,CACZ,GAAG,QAAQ,qGAAqG;KACjH;IACD;QACC,EAAE,EAAE,yBAAyB;QAC7B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,UAAU;QAC3B,MAAM,EAAE,GAAG,EAAE,CAAC,iGAAiG;KAC/G;IACD;QACC,EAAE,EAAE,qBAAqB;QACzB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,UAAU;QAC3B,MAAM,EAAE,GAAG,EAAE,CACZ,uGAAuG;KACxG;IACD;QACC,EAAE,EAAE,uBAAuB;QAC3B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,QAAQ;QACzB,MAAM,EAAE,GAAG,EAAE,CAAC,2EAA2E;KACzF;IACD;QACC,EAAE,EAAE,uBAAuB;QAC3B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,QAAQ;QACzB,MAAM,EAAE,GAAG,EAAE,CAAC,6EAA6E;KAC3F;IACD;QACC,EAAE,EAAE,qBAAqB;QACzB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,MAAM;QACvB,MAAM,EAAE,GAAG,EAAE,CAAC,iGAAiG;KAC/G;IACD;QACC,EAAE,EAAE,uBAAuB;QAC3B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,QAAQ;QACzB,MAAM,EAAE,GAAG,EAAE,CAAC,uFAAuF;KACrG;IACD;QACC,EAAE,EAAE,wBAAwB;QAC5B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,SAAS;QAC1B,MAAM,EAAE,GAAG,EAAE,CAAC,yFAAyF;KACvG;IACD;QACC,EAAE,EAAE,sBAAsB;QAC1B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,OAAO;QACxB,MAAM,EAAE,GAAG,EAAE,CACZ,+GAA+G;KAChH;IACD;QACC,EAAE,EAAE,0BAA0B;QAC9B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,WAAW;QAC5B,MAAM,EAAE,GAAG,EAAE,CAAC,yFAAyF;KACvG;IACD;QACC,EAAE,EAAE,sBAAsB;QAC1B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,OAAO;QACxB,MAAM,EAAE,GAAG,EAAE,CAAC,6FAA6F;KAC3G;IACD;QACC,EAAE,EAAE,2BAA2B;QAC/B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,mBAAmB;QACpC,MAAM,EAAE,GAAG,EAAE,CACZ,qGAAqG;KACtG;IACD;QACC,EAAE,EAAE,uBAAuB;QAC3B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,QAAQ;QACzB,MAAM,EAAE,GAAG,EAAE,CAAC,mFAAmF;KACjG;IACD;QACC,EAAE,EAAE,sBAAsB;QAC1B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,OAAO;QACxB,MAAM,EAAE,GAAG,EAAE,CAAC,mGAAmG;KACjH;IACD;QACC,EAAE,EAAE,0BAA0B;QAC9B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,WAAW;QAC5B,MAAM,EAAE,GAAG,EAAE,CAAC,8FAA8F;KAC5G;IACD;QACC,EAAE,EAAE,uBAAuB;QAC3B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,QAAQ;QACzB,MAAM,EAAE,GAAG,EAAE,CAAC,gGAAgG;KAC9G;CACkC,CAAC","sourcesContent":["import { APP_NAME } from \"../../../../config.ts\";\nimport type { TipDefinition } from \"./types.ts\";\n\nexport const MEMORY_TIPS = [\n\t{\n\t\tid: \"memory.persistent\",\n\t\tbindings: [],\n\t\trequiresCommand: \"memory\",\n\t\trender: () =>\n\t\t\t`${APP_NAME} remembers across sessions. Close the terminal, come back tomorrow, and the context is still there.`,\n\t},\n\t{\n\t\tid: \"memory.remember-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"remember\",\n\t\trender: () => \"Use /remember to save something you want kept - a preference, a decision, a fact worth reusing.\",\n\t},\n\t{\n\t\tid: \"memory.just-tell-it\",\n\t\tbindings: [],\n\t\trequiresCommand: \"remember\",\n\t\trender: () =>\n\t\t\t'You can also just say it: \"remember that we deploy on Fridays\" is enough. No syntax, no file to open.',\n\t},\n\t{\n\t\tid: \"memory.search-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"search\",\n\t\trender: () => \"Use /search to look through everything remembered so far, in plain words.\",\n\t},\n\t{\n\t\tid: \"memory.memory-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"memory\",\n\t\trender: () => \"Use /memory to see what is currently remembered about you and this project.\",\n\t},\n\t{\n\t\tid: \"memory.init-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"init\",\n\t\trender: () => \"Use /init to start memory for a new project, so it learns this codebase from the first session.\",\n\t},\n\t{\n\t\tid: \"memory.people-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"people\",\n\t\trender: () => \"Use /people to keep notes on teammates - who owns what, who to ask, what they prefer.\",\n\t},\n\t{\n\t\tid: \"memory.reflect-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"reflect\",\n\t\trender: () => \"Use /reflect to have the session reviewed now and the parts worth keeping written down.\",\n\t},\n\t{\n\t\tid: \"memory.dream-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"dream\",\n\t\trender: () =>\n\t\t\t\"Memory tidies itself in the background between turns - /dream shows that work and lets you start it yourself.\",\n\t},\n\t{\n\t\tid: \"memory.sleeptime-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"sleeptime\",\n\t\trender: () => \"Use /sleeptime to decide how often memory reorganizes itself while you are not looking.\",\n\t},\n\t{\n\t\tid: \"memory.memfs-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"memfs\",\n\t\trender: () => \"Memory is plain files you own - browse them with /memfs and edit anything that looks wrong.\",\n\t},\n\t{\n\t\tid: \"memory.repository-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"memory-repository\",\n\t\trender: () =>\n\t\t\t\"Every memory change is a git commit - use /memory-repository to see the history and undo a bad one.\",\n\t},\n\t{\n\t\tid: \"memory.doctor-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"doctor\",\n\t\trender: () => \"Use /doctor when memory feels off; it checks the setup and tells you what to fix.\",\n\t},\n\t{\n\t\tid: \"memory.facts-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"facts\",\n\t\trender: () => \"Use /facts to see the individual things learned about you, and drop the ones that no longer hold.\",\n\t},\n\t{\n\t\tid: \"memory.recompile-command\",\n\t\tbindings: [],\n\t\trequiresCommand: \"recompile\",\n\t\trender: () => \"Edited memory files by hand? Run /recompile so this session picks the changes up right away.\",\n\t},\n\t{\n\t\tid: \"memory.stop-repeating\",\n\t\tbindings: [],\n\t\trequiresCommand: \"memory\",\n\t\trender: () => \"Explain your setup once. Memory means you stop re-explaining it at the start of every session.\",\n\t},\n] satisfies readonly TipDefinition[];\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/tips/registry.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EASnD,CAAC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/tips/registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EAWnD,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import { CLI_TIPS } from "./catalog/cli-tips.js";
2
+ import { DAG_TIPS } from "./catalog/dag-tips.js";
2
3
  import { ETHOS_TIPS } from "./catalog/ethos-tips.js";
3
4
  import { INPUT_TIPS } from "./catalog/input-tips.js";
5
+ import { MEMORY_TIPS } from "./catalog/memory-tips.js";
4
6
  import { MODEL_TIPS } from "./catalog/model-tips.js";
5
7
  import { SESSION_TIPS } from "./catalog/session-tips.js";
6
8
  import { SETTINGS_TIPS } from "./catalog/settings-tips.js";
@@ -14,6 +16,8 @@ export const TIP_DEFINITIONS = [
14
16
  ...SETTINGS_TIPS,
15
17
  ...CLI_TIPS,
16
18
  ...SUBAGENT_TIPS,
19
+ ...MEMORY_TIPS,
20
+ ...DAG_TIPS,
17
21
  ...ETHOS_TIPS,
18
22
  ];
19
23
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../src/modes/interactive/tips/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAI7D,MAAM,CAAC,MAAM,eAAe,GAA6B;IACxD,GAAG,UAAU;IACb,GAAG,UAAU;IACb,GAAG,YAAY;IACf,GAAG,cAAc;IACjB,GAAG,aAAa;IAChB,GAAG,QAAQ;IACX,GAAG,aAAa;IAChB,GAAG,UAAU;CACb,CAAC","sourcesContent":["import { CLI_TIPS } from \"./catalog/cli-tips.ts\";\nimport { ETHOS_TIPS } from \"./catalog/ethos-tips.ts\";\nimport { INPUT_TIPS } from \"./catalog/input-tips.ts\";\nimport { MODEL_TIPS } from \"./catalog/model-tips.ts\";\nimport { SESSION_TIPS } from \"./catalog/session-tips.ts\";\nimport { SETTINGS_TIPS } from \"./catalog/settings-tips.ts\";\nimport { SUBAGENT_TIPS } from \"./catalog/subagent-tips.ts\";\nimport type { TipDefinition } from \"./catalog/types.ts\";\nimport { WORKSPACE_TIPS } from \"./catalog/workspace-tips.ts\";\n\nexport type { TipDefinition } from \"./catalog/types.ts\";\n\nexport const TIP_DEFINITIONS: readonly TipDefinition[] = [\n\t...MODEL_TIPS,\n\t...INPUT_TIPS,\n\t...SESSION_TIPS,\n\t...WORKSPACE_TIPS,\n\t...SETTINGS_TIPS,\n\t...CLI_TIPS,\n\t...SUBAGENT_TIPS,\n\t...ETHOS_TIPS,\n];\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../src/modes/interactive/tips/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAI7D,MAAM,CAAC,MAAM,eAAe,GAA6B;IACxD,GAAG,UAAU;IACb,GAAG,UAAU;IACb,GAAG,YAAY;IACf,GAAG,cAAc;IACjB,GAAG,aAAa;IAChB,GAAG,QAAQ;IACX,GAAG,aAAa;IAChB,GAAG,WAAW;IACd,GAAG,QAAQ;IACX,GAAG,UAAU;CACb,CAAC","sourcesContent":["import { CLI_TIPS } from \"./catalog/cli-tips.ts\";\nimport { DAG_TIPS } from \"./catalog/dag-tips.ts\";\nimport { ETHOS_TIPS } from \"./catalog/ethos-tips.ts\";\nimport { INPUT_TIPS } from \"./catalog/input-tips.ts\";\nimport { MEMORY_TIPS } from \"./catalog/memory-tips.ts\";\nimport { MODEL_TIPS } from \"./catalog/model-tips.ts\";\nimport { SESSION_TIPS } from \"./catalog/session-tips.ts\";\nimport { SETTINGS_TIPS } from \"./catalog/settings-tips.ts\";\nimport { SUBAGENT_TIPS } from \"./catalog/subagent-tips.ts\";\nimport type { TipDefinition } from \"./catalog/types.ts\";\nimport { WORKSPACE_TIPS } from \"./catalog/workspace-tips.ts\";\n\nexport type { TipDefinition } from \"./catalog/types.ts\";\n\nexport const TIP_DEFINITIONS: readonly TipDefinition[] = [\n\t...MODEL_TIPS,\n\t...INPUT_TIPS,\n\t...SESSION_TIPS,\n\t...WORKSPACE_TIPS,\n\t...SETTINGS_TIPS,\n\t...CLI_TIPS,\n\t...SUBAGENT_TIPS,\n\t...MEMORY_TIPS,\n\t...DAG_TIPS,\n\t...ETHOS_TIPS,\n];\n"]}
@@ -4,8 +4,10 @@ export interface FetchRetryOptions {
4
4
  maxRetries?: number;
5
5
  /** Retry transient HTTP responses as well as transport failures. Defaults to true. */
6
6
  retryOnStatus?: boolean;
7
- /** Per-attempt timeout. A new timeout is created for every attempt. */
7
+ /** Overall time budget shared by all attempts. */
8
8
  timeoutMs?: number;
9
+ /** Per-attempt timeout. A new timeout is created for every attempt. */
10
+ attemptTimeoutMs?: number;
9
11
  }
10
12
  /**
11
13
  * Fetch a management HTTP resource with a bounded immediate retry.
@@ -15,8 +17,8 @@ export interface FetchRetryOptions {
15
17
  * agent/model operations: those can fail after the HTTP request starts and are
16
18
  * retried by their semantic caller instead.
17
19
  *
18
- * Caller cancellation is terminal. When timeoutMs is supplied, it is the
19
- * overall time budget shared by all attempts.
20
+ * Caller cancellation and timeoutMs are terminal. attemptTimeoutMs aborts
21
+ * only the current attempt so a hung connection can be retried.
20
22
  */
21
23
  export declare function fetchWithRetry(input: FetchInput, init?: RequestInit | undefined, options?: FetchRetryOptions): Promise<Response>;
22
24
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"management-http.d.ts","sourceRoot":"","sources":["../../src/utils/management-http.ts"],"names":[],"mappings":"AAAA,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAI9C,MAAM,WAAW,iBAAiB;IACjC,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sFAAsF;IACtF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CACnC,KAAK,EAAE,UAAU,EACjB,IAAI,GAAE,WAAW,GAAG,SAAqB,EACzC,OAAO,GAAE,iBAAsB,GAC7B,OAAO,CAAC,QAAQ,CAAC,CAuCnB"}
1
+ {"version":3,"file":"management-http.d.ts","sourceRoot":"","sources":["../../src/utils/management-http.ts"],"names":[],"mappings":"AAAA,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAI9C,MAAM,WAAW,iBAAiB;IACjC,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sFAAsF;IACtF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CACnC,KAAK,EAAE,UAAU,EACjB,IAAI,GAAE,WAAW,GAAG,SAAqB,EACzC,OAAO,GAAE,iBAAsB,GAC7B,OAAO,CAAC,QAAQ,CAAC,CA+CnB"}
@@ -7,23 +7,23 @@ const RETRYABLE_STATUS_CODES = new Set([408, 425, 429, 500, 502, 503, 504]);
7
7
  * agent/model operations: those can fail after the HTTP request starts and are
8
8
  * retried by their semantic caller instead.
9
9
  *
10
- * Caller cancellation is terminal. When timeoutMs is supplied, it is the
11
- * overall time budget shared by all attempts.
10
+ * Caller cancellation and timeoutMs are terminal. attemptTimeoutMs aborts
11
+ * only the current attempt so a hung connection can be retried.
12
12
  */
13
13
  export async function fetchWithRetry(input, init = undefined, options = {}) {
14
14
  const maxRetries = options.maxRetries === undefined || !Number.isFinite(options.maxRetries)
15
15
  ? 2
16
16
  : Math.max(0, Math.floor(options.maxRetries));
17
17
  const retryOnStatus = options.retryOnStatus ?? true;
18
- const parentSignal = init?.signal;
18
+ const parentSignal = init?.signal ?? undefined;
19
19
  const timeoutSignal = options.timeoutMs !== undefined && options.timeoutMs > 0 ? AbortSignal.timeout(options.timeoutMs) : undefined;
20
- const signal = timeoutSignal
21
- ? parentSignal
22
- ? AbortSignal.any([parentSignal, timeoutSignal])
23
- : timeoutSignal
24
- : parentSignal;
20
+ const attemptTimeoutMs = options.attemptTimeoutMs !== undefined && options.attemptTimeoutMs > 0 ? options.attemptTimeoutMs : undefined;
25
21
  for (let attempt = 0;; attempt++) {
26
- signal?.throwIfAborted();
22
+ parentSignal?.throwIfAborted();
23
+ timeoutSignal?.throwIfAborted();
24
+ const attemptTimeoutSignal = attemptTimeoutMs ? AbortSignal.timeout(attemptTimeoutMs) : undefined;
25
+ const signals = [parentSignal, timeoutSignal, attemptTimeoutSignal].filter((signal) => signal !== undefined);
26
+ const signal = signals.length > 1 ? AbortSignal.any(signals) : signals[0];
27
27
  try {
28
28
  const response = await fetch(input, signal ? { ...init, signal } : init);
29
29
  const shouldRetry = retryOnStatus && RETRYABLE_STATUS_CODES.has(response.status) && attempt < maxRetries;
@@ -38,9 +38,13 @@ export async function fetchWithRetry(input, init = undefined, options = {}) {
38
38
  }
39
39
  }
40
40
  catch (error) {
41
+ const attemptTimedOut = attemptTimeoutSignal?.aborted === true && !parentSignal?.aborted && !timeoutSignal?.aborted;
41
42
  if (parentSignal?.aborted ||
42
43
  timeoutSignal?.aborted ||
43
- (error instanceof Error && error.name === "AbortError" && timeoutSignal === undefined) ||
44
+ (error instanceof Error &&
45
+ error.name === "AbortError" &&
46
+ !attemptTimedOut &&
47
+ timeoutSignal === undefined) ||
44
48
  attempt >= maxRetries) {
45
49
  throw error;
46
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"management-http.js","sourceRoot":"","sources":["../../src/utils/management-http.ts"],"names":[],"mappings":"AAEA,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAW5E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,KAAiB,EACjB,OAAgC,SAAS,EACzC,UAA6B,EAAE;IAE/B,MAAM,UAAU,GACf,OAAO,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC;QACvE,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAChD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC;IACpD,MAAM,YAAY,GAAG,IAAI,EAAE,MAAM,CAAC;IAClC,MAAM,aAAa,GAClB,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/G,MAAM,MAAM,GAAG,aAAa;QAC3B,CAAC,CAAC,YAAY;YACb,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;YAChD,CAAC,CAAC,aAAa;QAChB,CAAC,CAAC,YAAY,CAAC;IAEhB,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QACnC,MAAM,EAAE,cAAc,EAAE,CAAC;QAEzB,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACzE,MAAM,WAAW,GAAG,aAAa,IAAI,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,GAAG,UAAU,CAAC;YACzG,IAAI,CAAC,WAAW;gBAAE,OAAO,QAAQ,CAAC;YAClC,IAAI,CAAC;gBACJ,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACR,6EAA6E;gBAC7E,wCAAwC;YACzC,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IACC,YAAY,EAAE,OAAO;gBACrB,aAAa,EAAE,OAAO;gBACtB,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,aAAa,KAAK,SAAS,CAAC;gBACtF,OAAO,IAAI,UAAU,EACpB,CAAC;gBACF,MAAM,KAAK,CAAC;YACb,CAAC;QACF,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["type FetchInput = Parameters<typeof fetch>[0];\n\nconst RETRYABLE_STATUS_CODES = new Set([408, 425, 429, 500, 502, 503, 504]);\n\nexport interface FetchRetryOptions {\n\t/** Number of additional attempts after the initial request. Defaults to two. */\n\tmaxRetries?: number;\n\t/** Retry transient HTTP responses as well as transport failures. Defaults to true. */\n\tretryOnStatus?: boolean;\n\t/** Per-attempt timeout. A new timeout is created for every attempt. */\n\ttimeoutMs?: number;\n}\n\n/**\n * Fetch a management HTTP resource with a bounded immediate retry.\n *\n * This is intentionally a transport-level helper for idempotent management\n * requests (version checks, catalogs, and downloads). It must not be used for\n * agent/model operations: those can fail after the HTTP request starts and are\n * retried by their semantic caller instead.\n *\n * Caller cancellation is terminal. When timeoutMs is supplied, it is the\n * overall time budget shared by all attempts.\n */\nexport async function fetchWithRetry(\n\tinput: FetchInput,\n\tinit: RequestInit | undefined = undefined,\n\toptions: FetchRetryOptions = {},\n): Promise<Response> {\n\tconst maxRetries =\n\t\toptions.maxRetries === undefined || !Number.isFinite(options.maxRetries)\n\t\t\t? 2\n\t\t\t: Math.max(0, Math.floor(options.maxRetries));\n\tconst retryOnStatus = options.retryOnStatus ?? true;\n\tconst parentSignal = init?.signal;\n\tconst timeoutSignal =\n\t\toptions.timeoutMs !== undefined && options.timeoutMs > 0 ? AbortSignal.timeout(options.timeoutMs) : undefined;\n\tconst signal = timeoutSignal\n\t\t? parentSignal\n\t\t\t? AbortSignal.any([parentSignal, timeoutSignal])\n\t\t\t: timeoutSignal\n\t\t: parentSignal;\n\n\tfor (let attempt = 0; ; attempt++) {\n\t\tsignal?.throwIfAborted();\n\n\t\ttry {\n\t\t\tconst response = await fetch(input, signal ? { ...init, signal } : init);\n\t\t\tconst shouldRetry = retryOnStatus && RETRYABLE_STATUS_CODES.has(response.status) && attempt < maxRetries;\n\t\t\tif (!shouldRetry) return response;\n\t\t\ttry {\n\t\t\t\tawait response.body?.cancel();\n\t\t\t} catch {\n\t\t\t\t// The response is being discarded before a retry. There is nothing useful to\n\t\t\t\t// do if cancelling its body also fails.\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\tparentSignal?.aborted ||\n\t\t\t\ttimeoutSignal?.aborted ||\n\t\t\t\t(error instanceof Error && error.name === \"AbortError\" && timeoutSignal === undefined) ||\n\t\t\t\tattempt >= maxRetries\n\t\t\t) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"management-http.js","sourceRoot":"","sources":["../../src/utils/management-http.ts"],"names":[],"mappings":"AAEA,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAa5E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,KAAiB,EACjB,OAAgC,SAAS,EACzC,UAA6B,EAAE;IAE/B,MAAM,UAAU,GACf,OAAO,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC;QACvE,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAChD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC;IACpD,MAAM,YAAY,GAAG,IAAI,EAAE,MAAM,IAAI,SAAS,CAAC;IAC/C,MAAM,aAAa,GAClB,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/G,MAAM,gBAAgB,GACrB,OAAO,CAAC,gBAAgB,KAAK,SAAS,IAAI,OAAO,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;IAE/G,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QACnC,YAAY,EAAE,cAAc,EAAE,CAAC;QAC/B,aAAa,EAAE,cAAc,EAAE,CAAC;QAChC,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClG,MAAM,OAAO,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,oBAAoB,CAAC,CAAC,MAAM,CACzE,CAAC,MAAM,EAAyB,EAAE,CAAC,MAAM,KAAK,SAAS,CACvD,CAAC;QACF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAE1E,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACzE,MAAM,WAAW,GAAG,aAAa,IAAI,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,GAAG,UAAU,CAAC;YACzG,IAAI,CAAC,WAAW;gBAAE,OAAO,QAAQ,CAAC;YAClC,IAAI,CAAC;gBACJ,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACR,6EAA6E;gBAC7E,wCAAwC;YACzC,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,eAAe,GACpB,oBAAoB,EAAE,OAAO,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,OAAO,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC;YAC7F,IACC,YAAY,EAAE,OAAO;gBACrB,aAAa,EAAE,OAAO;gBACtB,CAAC,KAAK,YAAY,KAAK;oBACtB,KAAK,CAAC,IAAI,KAAK,YAAY;oBAC3B,CAAC,eAAe;oBAChB,aAAa,KAAK,SAAS,CAAC;gBAC7B,OAAO,IAAI,UAAU,EACpB,CAAC;gBACF,MAAM,KAAK,CAAC;YACb,CAAC;QACF,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["type FetchInput = Parameters<typeof fetch>[0];\n\nconst RETRYABLE_STATUS_CODES = new Set([408, 425, 429, 500, 502, 503, 504]);\n\nexport interface FetchRetryOptions {\n\t/** Number of additional attempts after the initial request. Defaults to two. */\n\tmaxRetries?: number;\n\t/** Retry transient HTTP responses as well as transport failures. Defaults to true. */\n\tretryOnStatus?: boolean;\n\t/** Overall time budget shared by all attempts. */\n\ttimeoutMs?: number;\n\t/** Per-attempt timeout. A new timeout is created for every attempt. */\n\tattemptTimeoutMs?: number;\n}\n\n/**\n * Fetch a management HTTP resource with a bounded immediate retry.\n *\n * This is intentionally a transport-level helper for idempotent management\n * requests (version checks, catalogs, and downloads). It must not be used for\n * agent/model operations: those can fail after the HTTP request starts and are\n * retried by their semantic caller instead.\n *\n * Caller cancellation and timeoutMs are terminal. attemptTimeoutMs aborts\n * only the current attempt so a hung connection can be retried.\n */\nexport async function fetchWithRetry(\n\tinput: FetchInput,\n\tinit: RequestInit | undefined = undefined,\n\toptions: FetchRetryOptions = {},\n): Promise<Response> {\n\tconst maxRetries =\n\t\toptions.maxRetries === undefined || !Number.isFinite(options.maxRetries)\n\t\t\t? 2\n\t\t\t: Math.max(0, Math.floor(options.maxRetries));\n\tconst retryOnStatus = options.retryOnStatus ?? true;\n\tconst parentSignal = init?.signal ?? undefined;\n\tconst timeoutSignal =\n\t\toptions.timeoutMs !== undefined && options.timeoutMs > 0 ? AbortSignal.timeout(options.timeoutMs) : undefined;\n\tconst attemptTimeoutMs =\n\t\toptions.attemptTimeoutMs !== undefined && options.attemptTimeoutMs > 0 ? options.attemptTimeoutMs : undefined;\n\n\tfor (let attempt = 0; ; attempt++) {\n\t\tparentSignal?.throwIfAborted();\n\t\ttimeoutSignal?.throwIfAborted();\n\t\tconst attemptTimeoutSignal = attemptTimeoutMs ? AbortSignal.timeout(attemptTimeoutMs) : undefined;\n\t\tconst signals = [parentSignal, timeoutSignal, attemptTimeoutSignal].filter(\n\t\t\t(signal): signal is AbortSignal => signal !== undefined,\n\t\t);\n\t\tconst signal = signals.length > 1 ? AbortSignal.any(signals) : signals[0];\n\n\t\ttry {\n\t\t\tconst response = await fetch(input, signal ? { ...init, signal } : init);\n\t\t\tconst shouldRetry = retryOnStatus && RETRYABLE_STATUS_CODES.has(response.status) && attempt < maxRetries;\n\t\t\tif (!shouldRetry) return response;\n\t\t\ttry {\n\t\t\t\tawait response.body?.cancel();\n\t\t\t} catch {\n\t\t\t\t// The response is being discarded before a retry. There is nothing useful to\n\t\t\t\t// do if cancelling its body also fails.\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst attemptTimedOut =\n\t\t\t\tattemptTimeoutSignal?.aborted === true && !parentSignal?.aborted && !timeoutSignal?.aborted;\n\t\t\tif (\n\t\t\t\tparentSignal?.aborted ||\n\t\t\t\ttimeoutSignal?.aborted ||\n\t\t\t\t(error instanceof Error &&\n\t\t\t\t\terror.name === \"AbortError\" &&\n\t\t\t\t\t!attemptTimedOut &&\n\t\t\t\t\ttimeoutSignal === undefined) ||\n\t\t\t\tattempt >= maxRetries\n\t\t\t) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -281,7 +281,9 @@ pi.on("session_before_compact", async (event, ctx) => {
281
281
  const { preparation, branchEntries, customInstructions, reason, willRetry, signal } = event;
282
282
 
283
283
  // preparation.messagesToSummarize - messages to summarize
284
+ // preparation.sourceMessages - optional active-context history prefix, including any previous summary
284
285
  // preparation.turnPrefixMessages - split turn prefix (if isSplitTurn)
286
+ // preparation.turnPrefixSourceMessages - optional active-context prefix through the split turn
285
287
  // preparation.previousSummary - previous compaction summary
286
288
  // preparation.fileOps - extracted file operations
287
289
  // preparation.tokensBefore - context tokens before compaction
@@ -346,6 +348,21 @@ pi.on("session_before_compact", async (event, ctx) => {
346
348
 
347
349
  See [custom-compaction.ts](../examples/extensions/custom-compaction.ts) for a complete example using a different model.
348
350
 
351
+ ### session_compact_failed
352
+
353
+ Fired when manual or automatic compaction fails or is aborted. This is useful for telemetry extensions that need to pair `session_before_compact` attempts with terminal outcomes.
354
+
355
+ ```typescript
356
+ pi.on("session_compact_failed", async (event, ctx) => {
357
+ const { reason, errorMessage, aborted, willRetry, fromExtension } = event;
358
+ // reason - "manual" (/compact), "threshold", or "overflow"
359
+ // errorMessage - present for non-abort failures
360
+ // aborted - true for cancelled/aborted compactions
361
+ // willRetry - whether the aborted turn would have retried after compaction
362
+ // fromExtension - whether extension-provided compaction content was being used
363
+ });
364
+ ```
365
+
349
366
  ### session_before_tree
350
367
 
351
368
  Fired before `/tree` navigation. Always fires regardless of whether user chose to summarize. Can cancel navigation or provide custom summary.
@@ -765,8 +765,10 @@ interface ProviderModelConfig {
765
765
  requiresThinkingAsText?: boolean;
766
766
  requiresReasoningContentOnAssistantMessages?: boolean;
767
767
  thinkingFormat?: "openai" | "openrouter" | "deepseek" | "together" | "baseten" | "zai" | "qwen" | "chat-template" | "qwen-chat-template" | "string-thinking" | "ant-ling";
768
- chatTemplateKwargs?: Record<string, string | number | boolean | null | { "$var": "thinking.enabled" | "thinking.effort"; omitWhenOff?: boolean }>;
769
- chatTemplateArgs?: Record<string, string | number | boolean | null | { "$var": "thinking.enabled" | "thinking.effort"; omitWhenOff?: boolean }>;
768
+ chatTemplateKwargs?: Record<string, string | number | boolean | null | { "$var": "thinking.enabled" | "thinking.effort" | "thinking.budget"; omitWhenOff?: boolean }>;
769
+ chatTemplateArgs?: Record<string, string | number | boolean | null | { "$var": "thinking.enabled" | "thinking.effort" | "thinking.budget"; omitWhenOff?: boolean }>;
770
+ thinkingTokenBudgetField?: "thinking_token_budget" | "thinking_budget" | "thinking_budget_tokens";
771
+ supportsThinkingTokenBudget?: boolean;
770
772
  cacheControlFormat?: "anthropic";
771
773
  sessionAffinityFormat?: "openai" | "openai-nosession" | "openrouter";
772
774
  sendSessionAffinityHeaders?: boolean;
@@ -784,4 +786,5 @@ interface ProviderModelConfig {
784
786
  ```
785
787
 
786
788
  `openrouter` sends `reasoning: { effort }`. `deepseek` sends `thinking: { type: "enabled" | "disabled" }` and `reasoning_effort` when enabled. `together` sends `reasoning: { enabled }` and also `reasoning_effort` when `supportsReasoningEffort` is enabled. `qwen` is for DashScope-style top-level `enable_thinking`. Use `qwen-chat-template` for local Qwen-compatible servers that read `chat_template_kwargs.enable_thinking` and need `preserve_thinking`. Use `chat-template` for configurable `chat_template_kwargs`, for example DeepSeek V3.x behind vLLM with `chatTemplateKwargs: { "thinking": { "$var": "thinking.enabled" } }`. Use `thinkingFormat: "baseten"` with `chatTemplateArgs` when the provider expects toggle values under `chat_template_args` and optionally supports top-level `reasoning_effort`.
789
+ `thinkingTokenBudgetField` sends a clamped per-level thinking budget as a top-level request field (`thinking_token_budget` on vLLM, `thinking_budget` on Qwen/SGLang, `thinking_budget_tokens` on llama.cpp). `supportsThinkingTokenBudget: true` is an alias for the vLLM field name. Do not combine it with `reasoning_effort` on DashScope Qwen models.
787
790
  `cacheControlFormat: "anthropic"` applies Anthropic-style `cache_control` markers to the system prompt, last tool definition, and last user, assistant, or tool-result text content.
@@ -375,7 +375,8 @@ user sends another prompt ◄─────────────────
375
375
 
376
376
  /compact or auto-compaction
377
377
  ├─► session_before_compact (can cancel or customize)
378
- └─► session_compact
378
+ ├─► session_compact (success)
379
+ └─► session_compact_failed (failure or abort)
379
380
 
380
381
  /tree navigation
381
382
  ├─► session_before_tree (can cancel or customize)
@@ -510,7 +511,7 @@ pi.on("session_before_reload", () => {
510
511
 
511
512
  Use this to protect state a reload would destroy — for example running background children owned by the extension runtime. Keep handlers fast and side-effect free; hosts may consult the veto more than once per reload attempt.
512
513
 
513
- #### session_before_compact / session_compact
514
+ #### session_before_compact / session_compact / session_compact_failed
514
515
 
515
516
  Fired on compaction. See [compaction.md](compaction.md) for details.
516
517
 
@@ -547,6 +548,14 @@ pi.on("session_compact", async (event, ctx) => {
547
548
  // event.reason - "manual" (/compact), "threshold", or "overflow"
548
549
  // event.willRetry - whether the aborted turn is retried after compaction (overflow recovery)
549
550
  });
551
+
552
+ pi.on("session_compact_failed", async (event, ctx) => {
553
+ // event.reason - "manual" (/compact), "threshold", or "overflow"
554
+ // event.errorMessage - present for non-abort failures
555
+ // event.aborted - true for cancelled/aborted compactions
556
+ // event.willRetry - whether the aborted turn would have retried after compaction
557
+ // event.fromExtension - whether extension-provided compaction content was being used
558
+ });
550
559
  ```
551
560
 
552
561
  This accepted/rejected contract has been emitted since [#248](https://github.com/code-yeongyu/senpi/pull/248): accepted events carry `compactionEntry`, while rejected events carry `accepted: false` and `rejectionCause` with no compaction entry. Built-in handlers are required to guard on `event.accepted`; for example, the `claude-sdk-oauth` session registry now does so before recording a compaction fork.
package/docs/llama-cpp.md CHANGED
@@ -53,6 +53,8 @@ Start Pi and configure the provider:
53
53
 
54
54
  Enter the router URL and optional API key. The default URL is `http://127.0.0.1:8080`.
55
55
 
56
+ If you start the router with `--no-models-autoload`, `/login llama.cpp` only stores the connection. Run `/llama` to load a model, then `/model` to select the loaded model for the current session.
57
+
56
58
  Environment variables can configure the same values without `/login`:
57
59
 
58
60
  ```bash
package/docs/models.md CHANGED
@@ -357,6 +357,8 @@ expected.
357
357
 
358
358
  Only OpenAI-compatible APIs apply it (`openai-completions`, `openai-responses`, `azure-openai-responses`); other APIs ignore it. Keys override senpi's named request fields (for example a `temperature` key here beats the request-level temperature), so prefer it as the single source of sampling truth for a model. In `modelOverrides`, `samplingParams` merges per key with the base model's value.
359
359
 
360
+ A constant thinking-token cap can go here too, but it will not follow `thinkingBudgets` or leave room for the answer. Prefer `compat.thinkingTokenBudgetField` (or the `supportsThinkingTokenBudget` alias) for that.
361
+
360
362
  ### Thinking Level Map
361
363
 
362
364
  Use `thinkingLevelMap` on a model to describe model-specific thinking controls. Keys are senpi thinking levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`. Maps may contain holes; for example, a model can expose `high` and `max` without exposing `xhigh`.
@@ -570,8 +572,10 @@ For providers with partial OpenAI compatibility, use the `compat` field.
570
572
  | `requiresThinkingAsText` | Convert thinking blocks to plain text |
571
573
  | `requiresReasoningContentOnAssistantMessages` | Include empty `reasoning_content` on all replayed assistant messages when reasoning is enabled |
572
574
  | `thinkingFormat` | Use `reasoning_effort`, `openrouter`, `deepseek`, `together`, `baseten`, `zai`, `qwen`, `chat-template`, or `qwen-chat-template` thinking parameters |
573
- | `chatTemplateKwargs` | `chat_template_kwargs` values for `thinkingFormat: "chat-template"`; use `{ "$var": "thinking.enabled" }` or `{ "$var": "thinking.effort" }` for senpi-controlled thinking values |
574
- | `chatTemplateArgs` | `chat_template_args` values for `thinkingFormat: "baseten"`; use `{ "$var": "thinking.enabled" }` or `{ "$var": "thinking.effort" }` for senpi-controlled thinking values |
575
+ | `chatTemplateKwargs` | `chat_template_kwargs` values for `thinkingFormat: "chat-template"`; use `{ "$var": "thinking.enabled" }`, `{ "$var": "thinking.effort" }`, or `{ "$var": "thinking.budget" }` for senpi-controlled thinking values |
576
+ | `chatTemplateArgs` | `chat_template_args` values for `thinkingFormat: "baseten"`; use `{ "$var": "thinking.enabled" }`, `{ "$var": "thinking.effort" }`, or `{ "$var": "thinking.budget" }` for senpi-controlled thinking values |
577
+ | `thinkingTokenBudgetField` | Top-level request field used to cap reasoning tokens from `thinkingBudgets`, clamped so at least 1024 tokens remain for the answer. `"thinking_token_budget"` (vLLM), `"thinking_budget"` (Qwen/DashScope/SGLang), `"thinking_budget_tokens"` (llama.cpp). Off by default; not set on the generated catalog. |
578
+ | `supportsThinkingTokenBudget` | Alias for `thinkingTokenBudgetField: "thinking_token_budget"` (vLLM). Prefer `thinkingTokenBudgetField`. Default: `false`. |
575
579
  | `cacheControlFormat` | Use Anthropic-style `cache_control` markers on the system prompt, last tool definition, and last user, assistant, or tool-result text content. Currently only `anthropic` is supported. |
576
580
  | `sendSessionAffinityHeaders` | For `openai-completions`, send session-affinity headers from the session id when caching is enabled. Default: `false`. |
577
581
  | `sessionAffinityFormat` | For `openai-completions` and `openai-responses`, the session-affinity header format: `openai` sends `session_id`/`x-client-request-id` (completions also `x-session-affinity`), `openai-nosession` omits the underscore-containing `session_id` header, `openrouter` sends `x-session-id`. Does not affect the `prompt_cache_key` body param. Default: auto-detected. |
@@ -585,6 +589,8 @@ For providers with partial OpenAI compatibility, use the `compat` field.
585
589
 
586
590
  `openrouter` uses `reasoning: { effort }`. `together` uses `reasoning: { enabled }` and also `reasoning_effort` when `supportsReasoningEffort` is enabled. `qwen` uses top-level `enable_thinking`. Use `qwen-chat-template` for local Qwen-compatible servers that require `chat_template_kwargs.enable_thinking` and `preserve_thinking`. Use `chat-template` for vLLM/Hugging Face chat templates that need configurable `chat_template_kwargs`, such as `chatTemplateKwargs: { "thinking": { "$var": "thinking.enabled" } }` for DeepSeek V3.x templates. Use `thinkingFormat: "baseten"` with `chatTemplateArgs` for providers that expose toggle controls through `chat_template_args` and optionally support top-level `reasoning_effort`.
587
591
 
592
+ `thinkingTokenBudgetField` is independent of `thinkingFormat`. Do not enable it on the generated Qwen catalog: those models already send `reasoning_effort`, and DashScope rejects `thinking_budget` together with `reasoning_effort`.
593
+
588
594
  `cacheControlFormat: "anthropic"` is for OpenAI-compatible providers that expose Anthropic-style prompt caching through `cache_control` markers on text content and tool definitions.
589
595
 
590
596
  Example:
package/docs/providers.md CHANGED
@@ -44,10 +44,11 @@ The `claude-sdk-oauth` provider routes LLM calls through the official [Claude Ag
44
44
  - Multiple accounts: each `/login claude-sdk-oauth` adds another named account. `CLAUDE_CODE_OAUTH_TOKEN` (and `_2`..`_N`) are honored as read-only env accounts. `/claude-account` lists, adds, removes, and pins accounts; `--claude-account <name>` pins one for the session; `claudeSdkOauthProvider.pinnedAccount` pins one in settings.
45
45
  - Session affinity: one senpi session sticks to one account (rendezvous hashing), which keeps Anthropic's prompt cache warm - accounts never rotate mid-session except on automatic failover. Rate limits and auth errors block the account (with cooldown) and retry on the next account, before any visible output; once output has started, the error surfaces instead of replaying.
46
46
  - Default lane: **ambient** - with no `tokenInjection` setting the provider inherits the environment like the upstream extension (Claude Code CLI login or `ANTHROPIC_API_KEY`). Managed lanes (`oauth-slots`, `config-dir`) are opt-in via one settings line until the live subscription spike proves a managed default.
47
+ - Ambient lane is explicit opt-in: a Claude Code CLI login on the host is not consent to spend that subscription, so the ambient lane is gated by `claudeSdkOauthProvider.enabled` (default `false`, env override `SENPI_CLAUDE_SDK_OAUTH_ENABLED`). Before this gate existed, a logged-in Claude Code CLI made the provider available with no senpi-side action. An explicit senpi-side login is itself an opt-in: stored OAuth accounts in `auth.json` and `CLAUDE_CODE_OAUTH_TOKEN` / `CLAUDE_CODE_OAUTH_TOKEN_<n>` env accounts keep the provider available with the flag unset. Only the host-CLI-derived ambient lane requires the flag.
47
48
  - Settings (`claudeSdkOauthProvider`):
48
49
  - `systemPromptMode` — controls how the system prompt is delivered. **`full`** (default) sends senpi's composed system prompt verbatim; the lane no longer rebuilds from the SDK `claude_code` preset, so all prompt regions (project rules, response-language instructions, etc.) reach the model. **`preset-append`** is the previous behaviour (deprecated, kept for one release; emits a one-time warning). **`override`** loads the system prompt from a file (`systemPromptFile`). The legacy `appendSystemPrompt` key still works: `false` → `preset-append`, `true`/unset → `full`; setting both keys makes `systemPromptMode` win and warns.
49
50
  - In `full` and `override` modes, `settingSources` defaults to `[]` on every lane because senpi's prompt already carries project context — loading the SDK's own CLAUDE.md would double-inject it. The CLI always prepends its own `"You are a Claude agent, built on Anthropic's Claude Agent SDK."` block, which senpi cannot suppress; `full` means the prompt is delivered intact, not that it is the only system-prompt text.
50
- - `settingSources` (filesystem settings load only in the ambient lane, so they cannot override your selected account), `strictMcpConfig`, `pinnedAccount`, `tokenInjection` (`oauth-slots` | `config-dir` | `ambient`), `resumeMode` (`auto` default | `off` restores per-turn sessions), `systemPromptFile`.
51
+ - `settingSources` (filesystem settings load only in the ambient lane, so they cannot override your selected account), `strictMcpConfig`, `pinnedAccount`, `tokenInjection` (`oauth-slots` | `config-dir` | `ambient`), `resumeMode` (`auto` default | `off` restores per-turn sessions), `systemPromptFile`, `enabled` (default `false`; gates the ambient lane only).
51
52
  - **Environment overrides** (precedence: `env > project settings > global settings > default`; no new CLI flags):
52
53
 
53
54
  | Variable | Purpose |
@@ -55,6 +56,7 @@ The `claude-sdk-oauth` provider routes LLM calls through the official [Claude Ag
55
56
  | `SENPI_CLAUDE_SDK_OAUTH_SYSTEM_PROMPT_MODE` | `full` \| `preset-append` \| `override` |
56
57
  | `SENPI_CLAUDE_SDK_OAUTH_SYSTEM_PROMPT_FILE` | Path to the system prompt file (used with `override` mode) |
57
58
  | `SENPI_CLAUDE_SDK_OAUTH_RESUME` | `auto` (default) \| `off` — disables session reuse, restoring per-turn SDK queries |
59
+ | `SENPI_CLAUDE_SDK_OAUTH_ENABLED` | Overrides `enabled`; gates the ambient (host-CLI-derived) lane |
58
60
  | `SENPI_CLAUDE_SDK_OAUTH_TOKEN_INJECTION` | `oauth-slots` \| `config-dir` \| `ambient` |
59
61
  | `SENPI_CLAUDE_SDK_OAUTH_SETTING_SOURCES` | Overrides `settingSources` |
60
62
  | `SENPI_CLAUDE_SDK_OAUTH_PINNED_ACCOUNT` | Overrides `pinnedAccount` |
@@ -146,7 +148,7 @@ Radius is a dynamic `pi-messages` gateway. `/login radius` stores OAuth tokens i
146
148
 
147
149
  Use the native `cursor` provider above by default - it is the first-party, primary path.
148
150
 
149
- `cursor-cli-oauth` is a default-available fallback (never a replacement) that drives the locally installed `cursor-agent` CLI instead of Cursor's network protocol. It becomes usable automatically when `cursor-agent` is installed and Senpi has a native `cursor` OAuth credential. Fall back to this lane when:
151
+ `cursor-cli-oauth` is an opt-in fallback (never a replacement) that drives the locally installed `cursor-agent` CLI instead of Cursor's network protocol. It becomes usable when `cursor-agent` is installed, Senpi has a native `cursor` OAuth credential, and the lane has been explicitly enabled. Fall back to this lane when:
150
152
 
151
153
  - the native transport misbehaves on your setup - protocol drift after a Cursor update, Connect-RPC/HTTP2 failures the native provider cannot route around, or
152
154
  - you explicitly want Cursor's own agent harness - the model running inside the Cursor CLI with its built-in tools - rather than senpi executing the tools.
@@ -177,7 +179,7 @@ curl https://cursor.com/install -fsS | bash
177
179
  /cursor-account [list | add | remove <name> | pin <name> | unpin | import [local | native] | acknowledge | status]
178
180
  ```
179
181
 
180
- - The lane is enabled by default. Set `cursorCliOauthProvider.enabled: false` (or `SENPI_CURSOR_CLI_OAUTH_ENABLED=0`) to disable it and prevent automatic native credential bootstrap.
182
+ - The lane is disabled by default. A `cursor-agent` CLI being logged in on the machine is not consent to spend that subscription, so set `cursorCliOauthProvider.enabled: true` (or `SENPI_CURSOR_CLI_OAUTH_ENABLED=1`) to enable it and allow automatic native credential bootstrap. Before this gate existed, an installed and logged-in `cursor-agent` made the lane available with no senpi-side action.
181
183
  - `add`, `import local`, and `import native` explicitly persist enabled state and refresh model availability.
182
184
  - `import local` copies the locally logged-in Cursor desktop credential into a new slot: the source is read once, on this explicit request only, and copied - never referenced live.
183
185
  - `import native` copies the primary Senpi `cursor` provider's OAuth credential into a separate managed slot without moving, deleting, or refreshing the primary entry.
package/docs/settings.md CHANGED
@@ -89,8 +89,8 @@ Permission rules are a confirmation policy, not a sandbox. Senpi, extensions, pa
89
89
  | `modelServiceTiers` | object | - | Per-model service tier memory (`"provider/id": "auto" \| "priority"`) |
90
90
  | `promptPreset` | string | `"auto"` | Force a system prompt preset: `"auto"`, `"kimi-k2-6"`, `"kimi-k2-7"`, `"kimi-k3"`, `"glm-5.2"`, `"glm-5.3"`, `"grok-4.5"`, `"grok-4.6"`, `"claude-fable-5"`, `"claude-opus-5"`, `"claude-opus-4-5"`, `"claude-opus-4-6"`, `"claude-opus-4-7"`, `"claude-opus-4-8"`, `"deepseek-v4-flash"`, `"deepseek-v4-flash-0731"`, `"deepseek-v4-pro"`, `"gpt-5"`, `"gpt-5.2"`, `"gpt-5.3-codex"`, `"gpt-5.4"`, `"gpt-5.5"`, or `"gpt-5.6"` |
91
91
  | `hideThinkingBlock` | boolean | `false` | Hide thinking blocks in output |
92
- | `showCacheMissNotices` | boolean | `false` | Show transcript notices for significant prompt-cache misses |
93
- | `thinkingBudgets` | object | - | Custom token budgets per thinking level |
92
+ | `showCacheMissNotices` | boolean | `false` | Show transcript notices for significant prompt-cache misses and compaction or branch-summary usage |
93
+ | `thinkingBudgets` | object | - | Custom token budgets per thinking level. Anthropic, Google, and Bedrock use these natively. OpenAI-compatible models use them when `compat.thinkingTokenBudgetField` (or `supportsThinkingTokenBudget`) is set. |
94
94
 
95
95
  #### promptPreset
96
96
 
@@ -319,6 +319,26 @@ For diagnostics, Senpi writes sanitized NDJSON records for candidate skips, cool
319
319
 
320
320
  When unset, senpi leaves provider payloads unchanged. This setting currently applies only to the built-in OpenAI Responses provider path.
321
321
 
322
+ ### Providers
323
+
324
+ | Setting | Type | Default | Description |
325
+ |---------|------|---------|-------------|
326
+ | `claudeSdkOauthProvider.enabled` | boolean | `false` | Enable the ambient (host-CLI-derived) lane of `claude-sdk-oauth`. Env override: `SENPI_CLAUDE_SDK_OAUTH_ENABLED`. Explicit senpi-side logins (stored OAuth accounts in `auth.json`, `CLAUDE_CODE_OAUTH_TOKEN` / `CLAUDE_CODE_OAUTH_TOKEN_<n>` env accounts) keep the provider available with this unset |
327
+ | `cursorCliOauthProvider.enabled` | boolean | `false` | Enable the `cursor-cli-oauth` fallback lane and automatic native credential bootstrap. Env override: `SENPI_CURSOR_CLI_OAUTH_ENABLED` |
328
+
329
+ Both ambient-auth providers are explicit opt-in: a vendor CLI being logged in on the machine is not consent to spend that subscription. Before these gates existed, a logged-in Claude Code or `cursor-agent` CLI made the lane available with no senpi-side action, so subscription usage could flow through a provider you never configured. Env overrides follow the usual precedence (`env > project settings > global settings > default`). See [providers.md](providers.md) for the full lane documentation.
330
+
331
+ ```json
332
+ {
333
+ "claudeSdkOauthProvider": {
334
+ "enabled": true
335
+ },
336
+ "cursorCliOauthProvider": {
337
+ "enabled": true
338
+ }
339
+ }
340
+ ```
341
+
322
342
  ### Terminal & Images
323
343
 
324
344
  | Setting | Type | Default | Description |
package/docs/skills.md CHANGED
@@ -35,9 +35,10 @@ Senpi loads skills from:
35
35
  - CLI: `--skill <path>` (repeatable, additive even with `--no-skills`)
36
36
 
37
37
  Discovery rules:
38
- - In `~/.senpi/agent/skills/` and `.senpi/skills/`, direct root `.md` files are discovered as individual skills
38
+ - In `~/.senpi/agent/skills/` and `.senpi/skills/`, direct root `.md` files are discovered as individual skills when they have valid skill frontmatter with a non-empty `description`
39
39
  - In all skill locations, directories containing `SKILL.md` are discovered recursively
40
- - In `~/.agents/skills/` and project `.agents/skills/`, root `.md` files are ignored
40
+ - In `~/.agents/skills/` and project `.agents/skills/`, root `.md` files are ignored, but nested `.md` files in grouping folders are discovered when they declare skill frontmatter
41
+ - Root Markdown files other than `SKILL.md` that do not look like skills are ignored silently
41
42
 
42
43
  Disable discovery with `--no-skills` (explicit `--skill` paths still load).
43
44
 
@@ -223,7 +224,7 @@ Senpi validates skills against the Agent Skills standard. Most issues produce wa
223
224
 
224
225
  Unknown frontmatter fields are ignored.
225
226
 
226
- **Exception:** Skills with missing description are not loaded.
227
+ Declared skills with missing descriptions are not loaded. Malformed `SKILL.md` files and `SKILL.md` files without a description produce warnings and are not loaded. Other Markdown files without valid skill frontmatter are ignored.
227
228
 
228
229
  Name collisions (same name from different locations) warn and keep the first skill found.
229
230
 
@@ -92,7 +92,7 @@ export default function (pi: ExtensionAPI) {
92
92
  activeTui?.requestRender();
93
93
  });
94
94
 
95
- pi.on("agent_end", () => {
95
+ pi.on("agent_settled", () => {
96
96
  isWorking = false;
97
97
  stopSpinner();
98
98
  activeTui?.requestRender();
@@ -46,8 +46,8 @@ export default function (pi: ExtensionAPI) {
46
46
  }
47
47
  });
48
48
 
49
- pi.on("agent_end", async () => {
50
- // Clear checkpoints after agent completes
49
+ pi.on("agent_settled", async () => {
50
+ // Clear checkpoints after the full agent run completes
51
51
  checkpoints.clear();
52
52
  });
53
53
  }