@astralyn/pi 0.82.7 → 0.84.0

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 (781) hide show
  1. package/CHANGELOG.md +78 -5099
  2. package/README.md +12 -111
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/bun/register-bedrock.d.ts.map +1 -1
  6. package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
  7. package/dist/bun/restore-sandbox-env.js.map +1 -1
  8. package/dist/cli/args.d.ts +2 -0
  9. package/dist/cli/args.d.ts.map +1 -1
  10. package/dist/cli/args.js +28 -2
  11. package/dist/cli/args.js.map +1 -1
  12. package/dist/cli/config-selector.d.ts.map +1 -1
  13. package/dist/cli/config-selector.js +2 -2
  14. package/dist/cli/config-selector.js.map +1 -1
  15. package/dist/cli/credential-print.d.ts +23 -0
  16. package/dist/cli/credential-print.d.ts.map +1 -0
  17. package/dist/cli/credential-print.js +117 -0
  18. package/dist/cli/credential-print.js.map +1 -0
  19. package/dist/cli/experimental/auth.d.ts +16 -0
  20. package/dist/cli/experimental/auth.d.ts.map +1 -0
  21. package/dist/cli/experimental/auth.js +13 -0
  22. package/dist/cli/experimental/auth.js.map +1 -0
  23. package/dist/cli/experimental/cli.d.ts +6 -0
  24. package/dist/cli/experimental/cli.d.ts.map +1 -0
  25. package/dist/cli/experimental/cli.js +5 -0
  26. package/dist/cli/experimental/cli.js.map +1 -0
  27. package/dist/cli/experimental/command-options.d.ts +17 -0
  28. package/dist/cli/experimental/command-options.d.ts.map +1 -0
  29. package/dist/cli/experimental/command-options.js +35 -0
  30. package/dist/cli/experimental/command-options.js.map +1 -0
  31. package/dist/cli/experimental/command.d.ts +63 -0
  32. package/dist/cli/experimental/command.d.ts.map +1 -0
  33. package/dist/cli/experimental/command.js +127 -0
  34. package/dist/cli/experimental/command.js.map +1 -0
  35. package/dist/cli/experimental/commands/client.d.ts +13 -0
  36. package/dist/cli/experimental/commands/client.d.ts.map +1 -0
  37. package/dist/cli/experimental/commands/client.js +25 -0
  38. package/dist/cli/experimental/commands/client.js.map +1 -0
  39. package/dist/cli/experimental/commands/pi.d.ts +15 -0
  40. package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
  41. package/dist/cli/experimental/commands/pi.js +28 -0
  42. package/dist/cli/experimental/commands/pi.js.map +1 -0
  43. package/dist/cli/experimental/commands/server.d.ts +13 -0
  44. package/dist/cli/experimental/commands/server.d.ts.map +1 -0
  45. package/dist/cli/experimental/commands/server.js +25 -0
  46. package/dist/cli/experimental/commands/server.js.map +1 -0
  47. package/dist/cli/experimental/transport-address.d.ts +10 -0
  48. package/dist/cli/experimental/transport-address.d.ts.map +1 -0
  49. package/dist/cli/experimental/transport-address.js +38 -0
  50. package/dist/cli/experimental/transport-address.js.map +1 -0
  51. package/dist/cli/file-processor.d.ts.map +1 -1
  52. package/dist/cli/file-processor.js.map +1 -1
  53. package/dist/cli/initial-message.d.ts +1 -1
  54. package/dist/cli/initial-message.d.ts.map +1 -1
  55. package/dist/cli/initial-message.js.map +1 -1
  56. package/dist/cli/list-models.d.ts +1 -1
  57. package/dist/cli/list-models.d.ts.map +1 -1
  58. package/dist/cli/list-models.js +2 -2
  59. package/dist/cli/list-models.js.map +1 -1
  60. package/dist/cli/project-trust.d.ts.map +1 -1
  61. package/dist/cli/project-trust.js.map +1 -1
  62. package/dist/cli/session-picker.d.ts.map +1 -1
  63. package/dist/cli/session-picker.js.map +1 -1
  64. package/dist/cli/startup-ui.d.ts +1 -1
  65. package/dist/cli/startup-ui.d.ts.map +1 -1
  66. package/dist/cli/startup-ui.js +2 -2
  67. package/dist/cli/startup-ui.js.map +1 -1
  68. package/dist/cli.d.ts.map +1 -1
  69. package/dist/cli.js +1 -0
  70. package/dist/cli.js.map +1 -1
  71. package/dist/client/index.d.ts +3 -0
  72. package/dist/client/index.d.ts.map +1 -0
  73. package/dist/client/index.js +3 -0
  74. package/dist/client/index.js.map +1 -0
  75. package/dist/client/remote-session.d.ts +53 -0
  76. package/dist/client/remote-session.d.ts.map +1 -0
  77. package/dist/client/remote-session.js +340 -0
  78. package/dist/client/remote-session.js.map +1 -0
  79. package/dist/client/transcript.d.ts +12 -0
  80. package/dist/client/transcript.d.ts.map +1 -0
  81. package/dist/client/transcript.js +98 -0
  82. package/dist/client/transcript.js.map +1 -0
  83. package/dist/config.d.ts.map +1 -1
  84. package/dist/config.js.map +1 -1
  85. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  86. package/dist/core/agent-session-runtime.js +3 -8
  87. package/dist/core/agent-session-runtime.js.map +1 -1
  88. package/dist/core/agent-session-services.d.ts +1 -0
  89. package/dist/core/agent-session-services.d.ts.map +1 -1
  90. package/dist/core/agent-session-services.js +1 -0
  91. package/dist/core/agent-session-services.js.map +1 -1
  92. package/dist/core/agent-session.d.ts +31 -11
  93. package/dist/core/agent-session.d.ts.map +1 -1
  94. package/dist/core/agent-session.js +189 -192
  95. package/dist/core/agent-session.js.map +1 -1
  96. package/dist/core/auth-guidance.d.ts.map +1 -1
  97. package/dist/core/auth-guidance.js.map +1 -1
  98. package/dist/core/auth-storage.d.ts +15 -9
  99. package/dist/core/auth-storage.d.ts.map +1 -1
  100. package/dist/core/auth-storage.js +159 -41
  101. package/dist/core/auth-storage.js.map +1 -1
  102. package/dist/core/bash-executor.d.ts.map +1 -1
  103. package/dist/core/bash-executor.js.map +1 -1
  104. package/dist/core/cache-stats.d.ts.map +1 -1
  105. package/dist/core/cache-stats.js.map +1 -1
  106. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  107. package/dist/core/compaction/branch-summarization.js.map +1 -1
  108. package/dist/core/compaction/compaction.d.ts.map +1 -1
  109. package/dist/core/compaction/compaction.js.map +1 -1
  110. package/dist/core/compaction/index.d.ts.map +1 -1
  111. package/dist/core/compaction/utils.d.ts.map +1 -1
  112. package/dist/core/compaction/utils.js.map +1 -1
  113. package/dist/core/defaults.d.ts.map +1 -1
  114. package/dist/core/diagnostics.d.ts.map +1 -1
  115. package/dist/core/event-bus.d.ts.map +1 -1
  116. package/dist/core/event-bus.js.map +1 -1
  117. package/dist/core/exec.d.ts.map +1 -1
  118. package/dist/core/exec.js.map +1 -1
  119. package/dist/core/experimental.d.ts.map +1 -1
  120. package/dist/core/experimental.js.map +1 -1
  121. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  122. package/dist/core/export-html/ansi-to-html.js.map +1 -1
  123. package/dist/core/export-html/index.d.ts.map +1 -1
  124. package/dist/core/export-html/index.js.map +1 -1
  125. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  126. package/dist/core/export-html/tool-renderer.js.map +1 -1
  127. package/dist/core/extensions/index.d.ts +1 -1
  128. package/dist/core/extensions/index.d.ts.map +1 -1
  129. package/dist/core/extensions/index.js.map +1 -1
  130. package/dist/core/extensions/loader.d.ts.map +1 -1
  131. package/dist/core/extensions/loader.js +43 -20
  132. package/dist/core/extensions/loader.js.map +1 -1
  133. package/dist/core/extensions/runner.d.ts +3 -1
  134. package/dist/core/extensions/runner.d.ts.map +1 -1
  135. package/dist/core/extensions/runner.js +31 -28
  136. package/dist/core/extensions/runner.js.map +1 -1
  137. package/dist/core/extensions/types.d.ts +28 -3
  138. package/dist/core/extensions/types.d.ts.map +1 -1
  139. package/dist/core/extensions/types.js.map +1 -1
  140. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  141. package/dist/core/extensions/wrapper.js.map +1 -1
  142. package/dist/core/footer-data-provider.d.ts +10 -0
  143. package/dist/core/footer-data-provider.d.ts.map +1 -1
  144. package/dist/core/footer-data-provider.js +18 -19
  145. package/dist/core/footer-data-provider.js.map +1 -1
  146. package/dist/core/http-dispatcher.d.ts.map +1 -1
  147. package/dist/core/http-dispatcher.js +5 -0
  148. package/dist/core/http-dispatcher.js.map +1 -1
  149. package/dist/core/index.d.ts.map +1 -1
  150. package/dist/core/keybindings.d.ts +157 -125
  151. package/dist/core/keybindings.d.ts.map +1 -1
  152. package/dist/core/keybindings.js +0 -1
  153. package/dist/core/keybindings.js.map +1 -1
  154. package/dist/core/messages.d.ts.map +1 -1
  155. package/dist/core/messages.js.map +1 -1
  156. package/dist/core/model-config.d.ts +37 -13
  157. package/dist/core/model-config.d.ts.map +1 -1
  158. package/dist/core/model-config.js +4 -2
  159. package/dist/core/model-config.js.map +1 -1
  160. package/dist/core/model-registry.d.ts +5 -3
  161. package/dist/core/model-registry.d.ts.map +1 -1
  162. package/dist/core/model-registry.js +13 -11
  163. package/dist/core/model-registry.js.map +1 -1
  164. package/dist/core/model-resolver.d.ts +4 -3
  165. package/dist/core/model-resolver.d.ts.map +1 -1
  166. package/dist/core/model-resolver.js +41 -10
  167. package/dist/core/model-resolver.js.map +1 -1
  168. package/dist/core/model-runtime.d.ts +30 -13
  169. package/dist/core/model-runtime.d.ts.map +1 -1
  170. package/dist/core/model-runtime.js +239 -91
  171. package/dist/core/model-runtime.js.map +1 -1
  172. package/dist/core/models-store.d.ts +12 -7
  173. package/dist/core/models-store.d.ts.map +1 -1
  174. package/dist/core/models-store.js +84 -16
  175. package/dist/core/models-store.js.map +1 -1
  176. package/dist/core/output-guard.d.ts.map +1 -1
  177. package/dist/core/output-guard.js.map +1 -1
  178. package/dist/core/package-manager.d.ts +4 -1
  179. package/dist/core/package-manager.d.ts.map +1 -1
  180. package/dist/core/package-manager.js +76 -48
  181. package/dist/core/package-manager.js.map +1 -1
  182. package/dist/core/pi-manifest.d.ts +8 -0
  183. package/dist/core/pi-manifest.d.ts.map +1 -0
  184. package/dist/core/pi-manifest.js +25 -0
  185. package/dist/core/pi-manifest.js.map +1 -0
  186. package/dist/core/project-trust.d.ts.map +1 -1
  187. package/dist/core/project-trust.js.map +1 -1
  188. package/dist/core/prompt-templates.d.ts.map +1 -1
  189. package/dist/core/prompt-templates.js.map +1 -1
  190. package/dist/core/provider-attribution.d.ts.map +1 -1
  191. package/dist/core/provider-attribution.js.map +1 -1
  192. package/dist/core/provider-composer.d.ts +4 -1
  193. package/dist/core/provider-composer.d.ts.map +1 -1
  194. package/dist/core/provider-composer.js +36 -15
  195. package/dist/core/provider-composer.js.map +1 -1
  196. package/dist/core/radius.d.ts.map +1 -1
  197. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  198. package/dist/core/remote-catalog-provider.js +73 -67
  199. package/dist/core/remote-catalog-provider.js.map +1 -1
  200. package/dist/core/resolve-config-value.d.ts.map +1 -1
  201. package/dist/core/resolve-config-value.js.map +1 -1
  202. package/dist/core/resource-loader.d.ts +15 -0
  203. package/dist/core/resource-loader.d.ts.map +1 -1
  204. package/dist/core/resource-loader.js +68 -51
  205. package/dist/core/resource-loader.js.map +1 -1
  206. package/dist/core/runtime-credentials.d.ts +5 -5
  207. package/dist/core/runtime-credentials.d.ts.map +1 -1
  208. package/dist/core/runtime-credentials.js +12 -10
  209. package/dist/core/runtime-credentials.js.map +1 -1
  210. package/dist/core/sdk.d.ts.map +1 -1
  211. package/dist/core/sdk.js.map +1 -1
  212. package/dist/core/session-cwd.d.ts.map +1 -1
  213. package/dist/core/session-cwd.js +0 -1
  214. package/dist/core/session-cwd.js.map +1 -1
  215. package/dist/core/session-manager.d.ts.map +1 -1
  216. package/dist/core/session-manager.js +10 -12
  217. package/dist/core/session-manager.js.map +1 -1
  218. package/dist/core/settings-manager.d.ts +12 -0
  219. package/dist/core/settings-manager.d.ts.map +1 -1
  220. package/dist/core/settings-manager.js +47 -33
  221. package/dist/core/settings-manager.js.map +1 -1
  222. package/dist/core/skills.d.ts.map +1 -1
  223. package/dist/core/skills.js.map +1 -1
  224. package/dist/core/slash-commands.d.ts.map +1 -1
  225. package/dist/core/source-info.d.ts.map +1 -1
  226. package/dist/core/source-info.js.map +1 -1
  227. package/dist/core/system-prompt.d.ts.map +1 -1
  228. package/dist/core/system-prompt.js.map +1 -1
  229. package/dist/core/telemetry.d.ts.map +1 -1
  230. package/dist/core/telemetry.js.map +1 -1
  231. package/dist/core/timings.d.ts.map +1 -1
  232. package/dist/core/timings.js.map +1 -1
  233. package/dist/core/tools/bash.d.ts.map +1 -1
  234. package/dist/core/tools/bash.js +12 -10
  235. package/dist/core/tools/bash.js.map +1 -1
  236. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  237. package/dist/core/tools/edit-diff.js.map +1 -1
  238. package/dist/core/tools/edit.d.ts.map +1 -1
  239. package/dist/core/tools/edit.js +4 -3
  240. package/dist/core/tools/edit.js.map +1 -1
  241. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  242. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  243. package/dist/core/tools/find.d.ts +3 -0
  244. package/dist/core/tools/find.d.ts.map +1 -1
  245. package/dist/core/tools/find.js +47 -20
  246. package/dist/core/tools/find.js.map +1 -1
  247. package/dist/core/tools/grep.d.ts.map +1 -1
  248. package/dist/core/tools/grep.js.map +1 -1
  249. package/dist/core/tools/index.d.ts.map +1 -1
  250. package/dist/core/tools/index.js.map +1 -1
  251. package/dist/core/tools/ls.d.ts.map +1 -1
  252. package/dist/core/tools/ls.js.map +1 -1
  253. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  254. package/dist/core/tools/output-accumulator.js +12 -18
  255. package/dist/core/tools/output-accumulator.js.map +1 -1
  256. package/dist/core/tools/path-utils.d.ts.map +1 -1
  257. package/dist/core/tools/path-utils.js.map +1 -1
  258. package/dist/core/tools/read.d.ts.map +1 -1
  259. package/dist/core/tools/read.js +1 -1
  260. package/dist/core/tools/read.js.map +1 -1
  261. package/dist/core/tools/render-utils.d.ts.map +1 -1
  262. package/dist/core/tools/render-utils.js.map +1 -1
  263. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  264. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  265. package/dist/core/tools/truncate.d.ts.map +1 -1
  266. package/dist/core/tools/truncate.js.map +1 -1
  267. package/dist/core/tools/write.d.ts.map +1 -1
  268. package/dist/core/tools/write.js +0 -1
  269. package/dist/core/tools/write.js.map +1 -1
  270. package/dist/core/trust-manager.d.ts.map +1 -1
  271. package/dist/core/trust-manager.js +48 -10
  272. package/dist/core/trust-manager.js.map +1 -1
  273. package/dist/core/usage-totals.d.ts.map +1 -1
  274. package/dist/core/usage-totals.js.map +1 -1
  275. package/dist/extensions/biu/index.d.ts +19 -0
  276. package/dist/extensions/biu/index.d.ts.map +1 -0
  277. package/dist/extensions/biu/index.js +350 -0
  278. package/dist/extensions/biu/index.js.map +1 -0
  279. package/dist/extensions/biu/prompts.d.ts +26 -0
  280. package/dist/extensions/biu/prompts.d.ts.map +1 -0
  281. package/dist/extensions/biu/prompts.js +260 -0
  282. package/dist/extensions/biu/prompts.js.map +1 -0
  283. package/dist/extensions/biu/workspace.d.ts +122 -0
  284. package/dist/extensions/biu/workspace.d.ts.map +1 -0
  285. package/dist/extensions/biu/workspace.js +404 -0
  286. package/dist/extensions/biu/workspace.js.map +1 -0
  287. package/dist/extensions/deepwiki/client.d.ts.map +1 -1
  288. package/dist/extensions/deepwiki/client.js.map +1 -1
  289. package/dist/extensions/deepwiki/constants.d.ts.map +1 -1
  290. package/dist/extensions/deepwiki/constants.js.map +1 -1
  291. package/dist/extensions/deepwiki/contents.d.ts.map +1 -1
  292. package/dist/extensions/deepwiki/contents.js.map +1 -1
  293. package/dist/extensions/deepwiki/execute.d.ts.map +1 -1
  294. package/dist/extensions/deepwiki/execute.js.map +1 -1
  295. package/dist/extensions/deepwiki/http.d.ts.map +1 -1
  296. package/dist/extensions/deepwiki/http.js.map +1 -1
  297. package/dist/extensions/deepwiki/index.d.ts.map +1 -1
  298. package/dist/extensions/deepwiki/index.js.map +1 -1
  299. package/dist/extensions/deepwiki/render.d.ts.map +1 -1
  300. package/dist/extensions/deepwiki/render.js.map +1 -1
  301. package/dist/extensions/deepwiki/schema.d.ts +1 -1
  302. package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
  303. package/dist/extensions/deepwiki/schema.js.map +1 -1
  304. package/dist/extensions/index.d.ts.map +1 -1
  305. package/dist/extensions/index.js +2 -2
  306. package/dist/extensions/index.js.map +1 -1
  307. package/dist/extensions/llama/client.d.ts.map +1 -1
  308. package/dist/extensions/llama/client.js +0 -2
  309. package/dist/extensions/llama/client.js.map +1 -1
  310. package/dist/extensions/llama/huggingface.d.ts.map +1 -1
  311. package/dist/extensions/llama/huggingface.js +0 -2
  312. package/dist/extensions/llama/huggingface.js.map +1 -1
  313. package/dist/extensions/llama/index.d.ts.map +1 -1
  314. package/dist/extensions/llama/index.js +11 -2
  315. package/dist/extensions/llama/index.js.map +1 -1
  316. package/dist/extensions/llama/provider.d.ts.map +1 -1
  317. package/dist/extensions/llama/provider.js +22 -8
  318. package/dist/extensions/llama/provider.js.map +1 -1
  319. package/dist/extensions/llama/ui.d.ts.map +1 -1
  320. package/dist/extensions/llama/ui.js +12 -28
  321. package/dist/extensions/llama/ui.js.map +1 -1
  322. package/dist/extensions/question/constants.d.ts.map +1 -1
  323. package/dist/extensions/question/constants.js.map +1 -1
  324. package/dist/extensions/question/dialog-primitives.d.ts.map +1 -1
  325. package/dist/extensions/question/dialog-primitives.js.map +1 -1
  326. package/dist/extensions/question/dialog.d.ts.map +1 -1
  327. package/dist/extensions/question/dialog.js.map +1 -1
  328. package/dist/extensions/question/index.d.ts.map +1 -1
  329. package/dist/extensions/question/index.js.map +1 -1
  330. package/dist/extensions/question/limits.d.ts.map +1 -1
  331. package/dist/extensions/question/render-cache.d.ts.map +1 -1
  332. package/dist/extensions/question/render-cache.js +3 -4
  333. package/dist/extensions/question/render-cache.js.map +1 -1
  334. package/dist/extensions/question/render.d.ts.map +1 -1
  335. package/dist/extensions/question/render.js.map +1 -1
  336. package/dist/extensions/question/results.d.ts.map +1 -1
  337. package/dist/extensions/question/results.js.map +1 -1
  338. package/dist/extensions/question/schema.d.ts.map +1 -1
  339. package/dist/extensions/question/schema.js.map +1 -1
  340. package/dist/extensions/question/state.d.ts.map +1 -1
  341. package/dist/extensions/question/state.js.map +1 -1
  342. package/dist/extensions/question/types.d.ts.map +1 -1
  343. package/dist/extensions/rewind/anchor.d.ts.map +1 -1
  344. package/dist/extensions/rewind/anchor.js.map +1 -1
  345. package/dist/extensions/rewind/config.d.ts.map +1 -1
  346. package/dist/extensions/rewind/config.js.map +1 -1
  347. package/dist/extensions/rewind/engine.d.ts.map +1 -1
  348. package/dist/extensions/rewind/engine.js.map +1 -1
  349. package/dist/extensions/rewind/gc.d.ts.map +1 -1
  350. package/dist/extensions/rewind/gc.js.map +1 -1
  351. package/dist/extensions/rewind/index.d.ts.map +1 -1
  352. package/dist/extensions/rewind/index.js.map +1 -1
  353. package/dist/extensions/rewind/menu.d.ts.map +1 -1
  354. package/dist/extensions/rewind/menu.js.map +1 -1
  355. package/dist/extensions/rewind/paths.d.ts.map +1 -1
  356. package/dist/extensions/rewind/paths.js.map +1 -1
  357. package/dist/extensions/rewind/restore.d.ts.map +1 -1
  358. package/dist/extensions/rewind/restore.js.map +1 -1
  359. package/dist/extensions/rewind/snapshot.d.ts.map +1 -1
  360. package/dist/extensions/rewind/snapshot.js.map +1 -1
  361. package/dist/extensions/rewind/storage.d.ts.map +1 -1
  362. package/dist/extensions/rewind/storage.js.map +1 -1
  363. package/dist/extensions/rewind/text.d.ts.map +1 -1
  364. package/dist/extensions/rewind/text.js.map +1 -1
  365. package/dist/extensions/rewind/tool-path.d.ts.map +1 -1
  366. package/dist/extensions/rewind/tool-path.js.map +1 -1
  367. package/dist/extensions/router/constants.d.ts +3 -0
  368. package/dist/extensions/router/constants.d.ts.map +1 -1
  369. package/dist/extensions/router/constants.js +3 -0
  370. package/dist/extensions/router/constants.js.map +1 -1
  371. package/dist/extensions/router/dialog.d.ts +14 -7
  372. package/dist/extensions/router/dialog.d.ts.map +1 -1
  373. package/dist/extensions/router/dialog.js +70 -132
  374. package/dist/extensions/router/dialog.js.map +1 -1
  375. package/dist/extensions/router/index.d.ts.map +1 -1
  376. package/dist/extensions/router/index.js.map +1 -1
  377. package/dist/extensions/router/presets.d.ts +8 -3
  378. package/dist/extensions/router/presets.d.ts.map +1 -1
  379. package/dist/extensions/router/presets.js +33 -17
  380. package/dist/extensions/router/presets.js.map +1 -1
  381. package/dist/extensions/router/probe.d.ts.map +1 -1
  382. package/dist/extensions/router/probe.js.map +1 -1
  383. package/dist/extensions/router/register.d.ts +3 -3
  384. package/dist/extensions/router/register.d.ts.map +1 -1
  385. package/dist/extensions/router/register.js.map +1 -1
  386. package/dist/extensions/router/store.d.ts.map +1 -1
  387. package/dist/extensions/router/store.js.map +1 -1
  388. package/dist/extensions/router/stream.d.ts.map +1 -1
  389. package/dist/extensions/router/stream.js.map +1 -1
  390. package/dist/extensions/router/types.d.ts.map +1 -1
  391. package/dist/extensions/router/ui.d.ts +11 -2
  392. package/dist/extensions/router/ui.d.ts.map +1 -1
  393. package/dist/extensions/router/ui.js +316 -171
  394. package/dist/extensions/router/ui.js.map +1 -1
  395. package/dist/extensions/statusline/index.d.ts.map +1 -1
  396. package/dist/extensions/statusline/index.js +17 -9
  397. package/dist/extensions/statusline/index.js.map +1 -1
  398. package/dist/extensions/subagent/activity.d.ts.map +1 -1
  399. package/dist/extensions/subagent/activity.js.map +1 -1
  400. package/dist/extensions/subagent/agents.d.ts.map +1 -1
  401. package/dist/extensions/subagent/agents.js.map +1 -1
  402. package/dist/extensions/subagent/constants.d.ts.map +1 -1
  403. package/dist/extensions/subagent/index.d.ts +3 -0
  404. package/dist/extensions/subagent/index.d.ts.map +1 -1
  405. package/dist/extensions/subagent/index.js +83 -12
  406. package/dist/extensions/subagent/index.js.map +1 -1
  407. package/dist/extensions/subagent/picker.d.ts.map +1 -1
  408. package/dist/extensions/subagent/picker.js +2 -9
  409. package/dist/extensions/subagent/picker.js.map +1 -1
  410. package/dist/extensions/subagent/render.d.ts.map +1 -1
  411. package/dist/extensions/subagent/render.js +33 -9
  412. package/dist/extensions/subagent/render.js.map +1 -1
  413. package/dist/extensions/subagent/resolve.d.ts.map +1 -1
  414. package/dist/extensions/subagent/resolve.js.map +1 -1
  415. package/dist/extensions/subagent/retry.d.ts.map +1 -1
  416. package/dist/extensions/subagent/retry.js.map +1 -1
  417. package/dist/extensions/subagent/runner.d.ts +2 -1
  418. package/dist/extensions/subagent/runner.d.ts.map +1 -1
  419. package/dist/extensions/subagent/runner.js +10 -12
  420. package/dist/extensions/subagent/runner.js.map +1 -1
  421. package/dist/extensions/subagent/schema.d.ts.map +1 -1
  422. package/dist/extensions/subagent/schema.js.map +1 -1
  423. package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
  424. package/dist/extensions/subagent/sdk-runner.js +41 -1
  425. package/dist/extensions/subagent/sdk-runner.js.map +1 -1
  426. package/dist/extensions/subagent/settings.d.ts.map +1 -1
  427. package/dist/extensions/subagent/settings.js +46 -36
  428. package/dist/extensions/subagent/settings.js.map +1 -1
  429. package/dist/extensions/subagent/types.d.ts +0 -1
  430. package/dist/extensions/subagent/types.d.ts.map +1 -1
  431. package/dist/extensions/subagent/types.js.map +1 -1
  432. package/dist/extensions/todo/constants.d.ts.map +1 -1
  433. package/dist/extensions/todo/constants.js.map +1 -1
  434. package/dist/extensions/todo/index.d.ts.map +1 -1
  435. package/dist/extensions/todo/index.js.map +1 -1
  436. package/dist/extensions/todo/overlay.d.ts.map +1 -1
  437. package/dist/extensions/todo/overlay.js +6 -10
  438. package/dist/extensions/todo/overlay.js.map +1 -1
  439. package/dist/extensions/todo/schema.d.ts +2 -2
  440. package/dist/extensions/todo/schema.d.ts.map +1 -1
  441. package/dist/extensions/todo/state.d.ts.map +1 -1
  442. package/dist/extensions/todo/state.js.map +1 -1
  443. package/dist/extensions/todo/view.d.ts.map +1 -1
  444. package/dist/extensions/todo/view.js.map +1 -1
  445. package/dist/index.d.ts +4 -4
  446. package/dist/index.d.ts.map +1 -1
  447. package/dist/index.js +1 -1
  448. package/dist/index.js.map +1 -1
  449. package/dist/main.d.ts.map +1 -1
  450. package/dist/main.js +57 -5
  451. package/dist/main.js.map +1 -1
  452. package/dist/migrations.d.ts.map +1 -1
  453. package/dist/migrations.js.map +1 -1
  454. package/dist/modes/index.d.ts +1 -0
  455. package/dist/modes/index.d.ts.map +1 -1
  456. package/dist/modes/index.js.map +1 -1
  457. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  458. package/dist/modes/interactive/components/armin.js +6 -10
  459. package/dist/modes/interactive/components/armin.js.map +1 -1
  460. package/dist/modes/interactive/components/assistant-message.d.ts +5 -2
  461. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  462. package/dist/modes/interactive/components/assistant-message.js +13 -11
  463. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  464. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  465. package/dist/modes/interactive/components/bash-execution.js +4 -10
  466. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  467. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  468. package/dist/modes/interactive/components/bordered-loader.js +0 -3
  469. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  470. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  471. package/dist/modes/interactive/components/branch-summary-message.js +1 -3
  472. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  473. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  474. package/dist/modes/interactive/components/compaction-summary-message.js +1 -3
  475. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  476. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  477. package/dist/modes/interactive/components/config-selector.js +5 -22
  478. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  479. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  480. package/dist/modes/interactive/components/countdown-timer.js +1 -7
  481. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  482. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  483. package/dist/modes/interactive/components/custom-editor.js +8 -8
  484. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  485. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  486. package/dist/modes/interactive/components/custom-entry.js +1 -4
  487. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  488. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  489. package/dist/modes/interactive/components/custom-message.js +1 -7
  490. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  491. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  492. package/dist/modes/interactive/components/daxnuts.js +6 -8
  493. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  494. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  495. package/dist/modes/interactive/components/diff.js.map +1 -1
  496. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  497. package/dist/modes/interactive/components/dynamic-border.js +0 -1
  498. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  499. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
  500. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
  501. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  502. package/dist/modes/interactive/components/extension-editor.js +1 -7
  503. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  504. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  505. package/dist/modes/interactive/components/extension-input.js +2 -8
  506. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  507. package/dist/modes/interactive/components/extension-selector.d.ts +1 -1
  508. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  509. package/dist/modes/interactive/components/extension-selector.js +1 -9
  510. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  511. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  512. package/dist/modes/interactive/components/first-time-setup.js +2 -4
  513. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  514. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  515. package/dist/modes/interactive/components/footer.js +2 -4
  516. package/dist/modes/interactive/components/footer.js.map +1 -1
  517. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  518. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  519. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  520. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  521. package/dist/modes/interactive/components/login-dialog.js +3 -9
  522. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  523. package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
  524. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  525. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  526. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  527. package/dist/modes/interactive/components/mermaid.d.ts +11 -0
  528. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  529. package/dist/modes/interactive/components/mermaid.js +75 -0
  530. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  531. package/dist/modes/interactive/components/model-selector.d.ts +1 -1
  532. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  533. package/dist/modes/interactive/components/model-selector.js +32 -30
  534. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  535. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  536. package/dist/modes/interactive/components/oauth-selector.js +3 -11
  537. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  538. package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
  539. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  540. package/dist/modes/interactive/components/scoped-models-selector.js +34 -13
  541. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  542. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  543. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  544. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  545. package/dist/modes/interactive/components/session-selector.js +35 -60
  546. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  547. package/dist/modes/interactive/components/settings-selector.d.ts +8 -2
  548. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  549. package/dist/modes/interactive/components/settings-selector.js +30 -14
  550. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  551. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  552. package/dist/modes/interactive/components/show-images-selector.js +0 -1
  553. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  554. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  555. package/dist/modes/interactive/components/skill-invocation-message.js +1 -3
  556. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  557. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  558. package/dist/modes/interactive/components/status-indicator.js +0 -2
  559. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  560. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  561. package/dist/modes/interactive/components/theme-selector.js +0 -2
  562. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  563. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  564. package/dist/modes/interactive/components/thinking-selector.js +0 -1
  565. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  566. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  567. package/dist/modes/interactive/components/tool-execution.js +18 -36
  568. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  569. package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
  570. package/dist/modes/interactive/components/tool-group.js +2 -3
  571. package/dist/modes/interactive/components/tool-group.js.map +1 -1
  572. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  573. package/dist/modes/interactive/components/tree-selector.js +19 -39
  574. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  575. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
  576. package/dist/modes/interactive/components/trust-selector.js +0 -6
  577. package/dist/modes/interactive/components/trust-selector.js.map +1 -1
  578. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  579. package/dist/modes/interactive/components/user-message-selector.js +3 -6
  580. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  581. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  582. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  583. package/dist/modes/interactive/components/user-message.js +8 -5
  584. package/dist/modes/interactive/components/user-message.js.map +1 -1
  585. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  586. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  587. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  588. package/dist/modes/interactive/external-editor.js +40 -3
  589. package/dist/modes/interactive/external-editor.js.map +1 -1
  590. package/dist/modes/interactive/interactive-mode.d.ts +46 -4
  591. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  592. package/dist/modes/interactive/interactive-mode.js +538 -275
  593. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  594. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  595. package/dist/modes/interactive/model-search.js.map +1 -1
  596. package/dist/modes/interactive/theme/dark.json +1 -0
  597. package/dist/modes/interactive/theme/light.json +1 -0
  598. package/dist/modes/interactive/theme/theme-controller.d.ts +3 -0
  599. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  600. package/dist/modes/interactive/theme/theme-controller.js +11 -8
  601. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  602. package/dist/modes/interactive/theme/theme-schema.json +5 -1
  603. package/dist/modes/interactive/theme/theme.d.ts +4 -4
  604. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  605. package/dist/modes/interactive/theme/theme.js +13 -9
  606. package/dist/modes/interactive/theme/theme.js.map +1 -1
  607. package/dist/modes/json-event.d.ts +28 -0
  608. package/dist/modes/json-event.d.ts.map +1 -0
  609. package/dist/modes/json-event.js +12 -0
  610. package/dist/modes/json-event.js.map +1 -0
  611. package/dist/modes/print-mode.d.ts.map +1 -1
  612. package/dist/modes/print-mode.js +12 -2
  613. package/dist/modes/print-mode.js.map +1 -1
  614. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  615. package/dist/modes/rpc/jsonl.js.map +1 -1
  616. package/dist/modes/rpc/rpc-client.d.ts +5 -4
  617. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  618. package/dist/modes/rpc/rpc-client.js +7 -8
  619. package/dist/modes/rpc/rpc-client.js.map +1 -1
  620. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  621. package/dist/modes/rpc/rpc-mode.js +17 -3
  622. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  623. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  624. package/dist/package-manager-cli.d.ts.map +1 -1
  625. package/dist/package-manager-cli.js +11 -9
  626. package/dist/package-manager-cli.js.map +1 -1
  627. package/dist/rpc-entry.d.ts.map +1 -1
  628. package/dist/rpc-entry.js +1 -0
  629. package/dist/rpc-entry.js.map +1 -1
  630. package/dist/utils/abort.d.ts +5 -0
  631. package/dist/utils/abort.d.ts.map +1 -0
  632. package/dist/utils/abort.js +48 -0
  633. package/dist/utils/abort.js.map +1 -0
  634. package/dist/utils/ansi.d.ts.map +1 -1
  635. package/dist/utils/ansi.js.map +1 -1
  636. package/dist/utils/changelog.d.ts.map +1 -1
  637. package/dist/utils/changelog.js.map +1 -1
  638. package/dist/utils/child-process.d.ts.map +1 -1
  639. package/dist/utils/child-process.js.map +1 -1
  640. package/dist/utils/clipboard-image.d.ts.map +1 -1
  641. package/dist/utils/clipboard-image.js.map +1 -1
  642. package/dist/utils/clipboard-native.d.ts.map +1 -1
  643. package/dist/utils/clipboard-native.js.map +1 -1
  644. package/dist/utils/clipboard.d.ts +1 -1
  645. package/dist/utils/clipboard.d.ts.map +1 -1
  646. package/dist/utils/clipboard.js +22 -2
  647. package/dist/utils/clipboard.js.map +1 -1
  648. package/dist/utils/coalescing-terminal.d.ts +1 -0
  649. package/dist/utils/coalescing-terminal.d.ts.map +1 -1
  650. package/dist/utils/coalescing-terminal.js +16 -8
  651. package/dist/utils/coalescing-terminal.js.map +1 -1
  652. package/dist/utils/deprecation.d.ts.map +1 -1
  653. package/dist/utils/deprecation.js.map +1 -1
  654. package/dist/utils/exif-orientation.d.ts.map +1 -1
  655. package/dist/utils/exif-orientation.js.map +1 -1
  656. package/dist/utils/frontmatter.d.ts.map +1 -1
  657. package/dist/utils/frontmatter.js.map +1 -1
  658. package/dist/utils/fs-watch.d.ts.map +1 -1
  659. package/dist/utils/fs-watch.js.map +1 -1
  660. package/dist/utils/git.d.ts.map +1 -1
  661. package/dist/utils/git.js.map +1 -1
  662. package/dist/utils/html.d.ts.map +1 -1
  663. package/dist/utils/html.js.map +1 -1
  664. package/dist/utils/image-convert.d.ts.map +1 -1
  665. package/dist/utils/image-convert.js.map +1 -1
  666. package/dist/utils/image-process.d.ts.map +1 -1
  667. package/dist/utils/image-process.js.map +1 -1
  668. package/dist/utils/image-resize-core.d.ts.map +1 -1
  669. package/dist/utils/image-resize-core.js.map +1 -1
  670. package/dist/utils/image-resize-worker.d.ts.map +1 -1
  671. package/dist/utils/image-resize-worker.js.map +1 -1
  672. package/dist/utils/image-resize.d.ts.map +1 -1
  673. package/dist/utils/image-resize.js.map +1 -1
  674. package/dist/utils/json.d.ts.map +1 -1
  675. package/dist/utils/json.js.map +1 -1
  676. package/dist/utils/management-http.d.ts +23 -0
  677. package/dist/utils/management-http.d.ts.map +1 -0
  678. package/dist/utils/management-http.js +50 -0
  679. package/dist/utils/management-http.js.map +1 -0
  680. package/dist/utils/mime.d.ts.map +1 -1
  681. package/dist/utils/mime.js.map +1 -1
  682. package/dist/utils/open-browser.d.ts.map +1 -1
  683. package/dist/utils/open-browser.js.map +1 -1
  684. package/dist/utils/paths.d.ts +5 -3
  685. package/dist/utils/paths.d.ts.map +1 -1
  686. package/dist/utils/paths.js +25 -4
  687. package/dist/utils/paths.js.map +1 -1
  688. package/dist/utils/photon.d.ts.map +1 -1
  689. package/dist/utils/photon.js.map +1 -1
  690. package/dist/utils/pi-user-agent.d.ts.map +1 -1
  691. package/dist/utils/pi-user-agent.js.map +1 -1
  692. package/dist/utils/shell.d.ts.map +1 -1
  693. package/dist/utils/shell.js.map +1 -1
  694. package/dist/utils/sleep.d.ts.map +1 -1
  695. package/dist/utils/sleep.js.map +1 -1
  696. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  697. package/dist/utils/syntax-highlight.js.map +1 -1
  698. package/dist/utils/tool-result-images.d.ts +19 -0
  699. package/dist/utils/tool-result-images.d.ts.map +1 -0
  700. package/dist/utils/tool-result-images.js +45 -0
  701. package/dist/utils/tool-result-images.js.map +1 -0
  702. package/dist/utils/tools-manager.d.ts.map +1 -1
  703. package/dist/utils/tools-manager.js +4 -6
  704. package/dist/utils/tools-manager.js.map +1 -1
  705. package/dist/utils/version-check.d.ts +4 -0
  706. package/dist/utils/version-check.d.ts.map +1 -1
  707. package/dist/utils/version-check.js +20 -2
  708. package/dist/utils/version-check.js.map +1 -1
  709. package/dist/utils/windows-self-update.d.ts.map +1 -1
  710. package/dist/utils/windows-self-update.js.map +1 -1
  711. package/docs/bundled/README.md +14 -16
  712. package/docs/bundled/extensions/biu.md +63 -0
  713. package/docs/bundled/extensions/router.md +20 -14
  714. package/docs/bundled/extensions/statusline.md +7 -5
  715. package/docs/bundled/themes.md +1 -1
  716. package/docs/compaction.md +25 -30
  717. package/docs/custom-provider.md +303 -467
  718. package/docs/development.md +83 -0
  719. package/docs/docs.json +6 -10
  720. package/docs/extensions.md +139 -119
  721. package/docs/index.md +18 -74
  722. package/docs/json.md +40 -15
  723. package/docs/keybindings.md +38 -10
  724. package/docs/models.md +210 -150
  725. package/docs/providers.md +3 -1
  726. package/docs/quickstart.md +5 -3
  727. package/docs/rpc.md +177 -134
  728. package/docs/sdk.md +165 -178
  729. package/docs/security.md +2 -2
  730. package/docs/session-format.md +139 -119
  731. package/docs/settings.md +4 -1
  732. package/docs/skills.md +0 -1
  733. package/docs/themes.md +5 -3
  734. package/docs/tui.md +411 -549
  735. package/docs/usage.md +11 -11
  736. package/examples/README.md +6 -1
  737. package/examples/extensions/README.md +13 -33
  738. package/examples/extensions/custom-compaction.ts +1 -16
  739. package/examples/extensions/custom-provider-anthropic/index.ts +11 -4
  740. package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -1
  741. package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
  742. package/examples/extensions/handoff.ts +2 -11
  743. package/examples/extensions/qna.ts +3 -7
  744. package/examples/extensions/summarize.ts +8 -18
  745. package/examples/extensions/truncated-tool.ts +2 -2
  746. package/examples/rpc-extension-ui.ts +11 -2
  747. package/examples/sdk/02-custom-model.ts +1 -2
  748. package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
  749. package/examples/sdk/12-full-control.ts +3 -1
  750. package/examples/sdk/README.md +1 -0
  751. package/npm-shrinkwrap.json +199 -270
  752. package/package.json +16 -9
  753. package/dist/extensions/plan/constants.d.ts +0 -68
  754. package/dist/extensions/plan/constants.d.ts.map +0 -1
  755. package/dist/extensions/plan/constants.js +0 -100
  756. package/dist/extensions/plan/constants.js.map +0 -1
  757. package/dist/extensions/plan/index.d.ts +0 -30
  758. package/dist/extensions/plan/index.d.ts.map +0 -1
  759. package/dist/extensions/plan/index.js +0 -429
  760. package/dist/extensions/plan/index.js.map +0 -1
  761. package/dist/extensions/plan/schema.d.ts +0 -20
  762. package/dist/extensions/plan/schema.d.ts.map +0 -1
  763. package/dist/extensions/plan/schema.js +0 -13
  764. package/dist/extensions/plan/schema.js.map +0 -1
  765. package/dist/extensions/plan/state.d.ts +0 -38
  766. package/dist/extensions/plan/state.d.ts.map +0 -1
  767. package/dist/extensions/plan/state.js +0 -96
  768. package/dist/extensions/plan/state.js.map +0 -1
  769. package/dist/extensions/plan/storage.d.ts +0 -26
  770. package/dist/extensions/plan/storage.d.ts.map +0 -1
  771. package/dist/extensions/plan/storage.js +0 -83
  772. package/dist/extensions/plan/storage.js.map +0 -1
  773. package/dist/extensions/plan/view.d.ts +0 -44
  774. package/dist/extensions/plan/view.d.ts.map +0 -1
  775. package/dist/extensions/plan/view.js +0 -149
  776. package/dist/extensions/plan/view.js.map +0 -1
  777. package/docs/bundled/extensions/README.md +0 -19
  778. package/docs/bundled/extensions/plan.md +0 -34
  779. package/examples/extensions/plan-mode/README.md +0 -66
  780. package/examples/extensions/plan-mode/index.ts +0 -390
  781. package/examples/extensions/plan-mode/utils.ts +0 -168
@@ -1 +1 @@
1
- {"version":3,"file":"auth-guidance.d.ts","sourceRoot":"","sources":["../../src/core/auth-guidance.ts"],"names":[],"mappings":"AAKA,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AAED,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGnE","sourcesContent":["import { join } from \"node:path\";\nimport { getDocsPath } from \"../config.ts\";\n\nconst UNKNOWN_PROVIDER = \"unknown\";\n\nexport function getProviderLoginHelp(): string {\n\treturn [\n\t\t\"Use /login to log into a provider via OAuth or API key. See:\",\n\t\t` ${join(getDocsPath(), \"providers.md\")}`,\n\t\t` ${join(getDocsPath(), \"models.md\")}`,\n\t].join(\"\\n\");\n}\n\nexport function formatNoModelsAvailableMessage(): string {\n\treturn `No models available. ${getProviderLoginHelp()}`;\n}\n\nexport function formatNoModelSelectedMessage(): string {\n\treturn `No model selected.\\n\\n${getProviderLoginHelp()}\\n\\nThen use /model to select a model.`;\n}\n\nexport function formatNoApiKeyFoundMessage(provider: string): string {\n\tconst providerDisplay = provider === UNKNOWN_PROVIDER ? \"the selected model\" : provider;\n\treturn `No API key found for ${providerDisplay}.\\n\\n${getProviderLoginHelp()}`;\n}\n"]}
1
+ {"version":3,"file":"auth-guidance.d.ts","sourceRoot":"","sources":["../../src/core/auth-guidance.ts"],"names":[],"mappings":"AAKA,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AAED,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGnE"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth-guidance.js","sourceRoot":"","sources":["../../src/core/auth-guidance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,gBAAgB,GAAG,SAAS,CAAC;AAEnC,MAAM,UAAU,oBAAoB,GAAW;IAC9C,OAAO;QACN,8DAA8D;QAC9D,KAAK,IAAI,CAAC,WAAW,EAAE,EAAE,cAAc,CAAC,EAAE;QAC1C,KAAK,IAAI,CAAC,WAAW,EAAE,EAAE,WAAW,CAAC,EAAE;KACvC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAAA,CACb;AAED,MAAM,UAAU,8BAA8B,GAAW;IACxD,OAAO,wBAAwB,oBAAoB,EAAE,EAAE,CAAC;AAAA,CACxD;AAED,MAAM,UAAU,4BAA4B,GAAW;IACtD,OAAO,yBAAyB,oBAAoB,EAAE,wCAAwC,CAAC;AAAA,CAC/F;AAED,MAAM,UAAU,0BAA0B,CAAC,QAAgB,EAAU;IACpE,MAAM,eAAe,GAAG,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC;IACxF,OAAO,wBAAwB,eAAe,QAAQ,oBAAoB,EAAE,EAAE,CAAC;AAAA,CAC/E","sourcesContent":["import { join } from \"node:path\";\nimport { getDocsPath } from \"../config.ts\";\n\nconst UNKNOWN_PROVIDER = \"unknown\";\n\nexport function getProviderLoginHelp(): string {\n\treturn [\n\t\t\"Use /login to log into a provider via OAuth or API key. See:\",\n\t\t` ${join(getDocsPath(), \"providers.md\")}`,\n\t\t` ${join(getDocsPath(), \"models.md\")}`,\n\t].join(\"\\n\");\n}\n\nexport function formatNoModelsAvailableMessage(): string {\n\treturn `No models available. ${getProviderLoginHelp()}`;\n}\n\nexport function formatNoModelSelectedMessage(): string {\n\treturn `No model selected.\\n\\n${getProviderLoginHelp()}\\n\\nThen use /model to select a model.`;\n}\n\nexport function formatNoApiKeyFoundMessage(provider: string): string {\n\tconst providerDisplay = provider === UNKNOWN_PROVIDER ? \"the selected model\" : provider;\n\treturn `No API key found for ${providerDisplay}.\\n\\n${getProviderLoginHelp()}`;\n}\n"]}
1
+ {"version":3,"file":"auth-guidance.js","sourceRoot":"","sources":["../../src/core/auth-guidance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,gBAAgB,GAAG,SAAS,CAAC;AAEnC,MAAM,UAAU,oBAAoB;IACnC,OAAO;QACN,8DAA8D;QAC9D,KAAK,IAAI,CAAC,WAAW,EAAE,EAAE,cAAc,CAAC,EAAE;QAC1C,KAAK,IAAI,CAAC,WAAW,EAAE,EAAE,WAAW,CAAC,EAAE;KACvC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,8BAA8B;IAC7C,OAAO,wBAAwB,oBAAoB,EAAE,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC3C,OAAO,yBAAyB,oBAAoB,EAAE,wCAAwC,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IAC1D,MAAM,eAAe,GAAG,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC;IACxF,OAAO,wBAAwB,eAAe,QAAQ,oBAAoB,EAAE,EAAE,CAAC;AAChF,CAAC","sourcesContent":["import { join } from \"node:path\";\nimport { getDocsPath } from \"../config.ts\";\n\nconst UNKNOWN_PROVIDER = \"unknown\";\n\nexport function getProviderLoginHelp(): string {\n\treturn [\n\t\t\"Use /login to log into a provider via OAuth or API key. See:\",\n\t\t` ${join(getDocsPath(), \"providers.md\")}`,\n\t\t` ${join(getDocsPath(), \"models.md\")}`,\n\t].join(\"\\n\");\n}\n\nexport function formatNoModelsAvailableMessage(): string {\n\treturn `No models available. ${getProviderLoginHelp()}`;\n}\n\nexport function formatNoModelSelectedMessage(): string {\n\treturn `No model selected.\\n\\n${getProviderLoginHelp()}\\n\\nThen use /model to select a model.`;\n}\n\nexport function formatNoApiKeyFoundMessage(provider: string): string {\n\tconst providerDisplay = provider === UNKNOWN_PROVIDER ? \"the selected model\" : provider;\n\treturn `No API key found for ${providerDisplay}.\\n\\n${getProviderLoginHelp()}`;\n}\n"]}
@@ -2,7 +2,7 @@
2
2
  * CredentialStore implementation backed by auth.json.
3
3
  * Provider auth orchestration belongs to ModelRuntime and pi-ai Models.
4
4
  */
5
- import type { Credential, CredentialInfo, CredentialStore } from "@earendil-works/pi-ai";
5
+ import type { AuthOperationOptions, Credential, CredentialInfo, CredentialStore } from "@earendil-works/pi-ai";
6
6
  type AuthStorageData = Record<string, Credential>;
7
7
  type LockResult<T> = {
8
8
  result: T;
@@ -10,7 +10,7 @@ type LockResult<T> = {
10
10
  };
11
11
  export interface AuthStorageBackend {
12
12
  withLock<T>(fn: (current: string | undefined) => LockResult<T>): T;
13
- withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T>;
13
+ withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>, options?: AuthOperationOptions): Promise<T>;
14
14
  }
15
15
  export declare class FileAuthStorageBackend implements AuthStorageBackend {
16
16
  private authPath;
@@ -19,33 +19,39 @@ export declare class FileAuthStorageBackend implements AuthStorageBackend {
19
19
  private ensureFileExists;
20
20
  private acquireLockSyncWithRetry;
21
21
  withLock<T>(fn: (current: string | undefined) => LockResult<T>): T;
22
- withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T>;
22
+ private acquireLockAsync;
23
+ withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>, options?: AuthOperationOptions): Promise<T>;
23
24
  }
24
25
  export declare class InMemoryAuthStorageBackend implements AuthStorageBackend {
25
26
  private value;
27
+ private asyncChain;
26
28
  withLock<T>(fn: (current: string | undefined) => LockResult<T>): T;
27
- withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T>;
29
+ withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>, options?: AuthOperationOptions): Promise<T>;
28
30
  }
29
31
  /**
30
32
  * Credential storage backed by a JSON file.
31
33
  */
32
34
  export declare class AuthStorage implements CredentialStore {
33
- private data;
34
35
  private storage;
36
+ private authPath;
37
+ private readState;
35
38
  private constructor();
36
39
  static create(authPath?: string): AuthStorage;
37
40
  static fromStorage(storage: AuthStorageBackend): AuthStorage;
38
41
  static inMemory(data?: AuthStorageData): AuthStorage;
39
42
  private parseStorageData;
43
+ private updateReadState;
40
44
  /**
41
45
  * Reload credentials from storage.
42
46
  */
43
47
  reload(): void;
44
- read(provider: string): Promise<Credential | undefined>;
45
- modify(provider: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>): Promise<Credential | undefined>;
46
- delete(provider: string): Promise<void>;
48
+ private reloadFromStorageAsync;
49
+ private readLatestData;
50
+ read(provider: string, options?: AuthOperationOptions): Promise<Credential | undefined>;
51
+ modify(provider: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>, options?: AuthOperationOptions): Promise<Credential | undefined>;
52
+ delete(provider: string, options?: AuthOperationOptions): Promise<void>;
47
53
  /** List credential metadata without resolving configured key values. */
48
- list(): Promise<readonly CredentialInfo[]>;
54
+ list(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]>;
49
55
  }
50
56
  /**
51
57
  * One-off synchronous read of a stored credential from an auth.json file,
@@ -1 +1 @@
1
- {"version":3,"file":"auth-storage.d.ts","sourceRoot":"","sources":["../../src/core/auth-storage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CredentialStore implementation backed by auth.json.\n * Provider auth orchestration belongs to ModelRuntime and pi-ai Models.\n */\n\nimport type { Credential, CredentialInfo, CredentialStore } from \"@earendil-works/pi-ai\";\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport lockfile from \"proper-lockfile\";\nimport { getAgentDir } from \"../config.ts\";\nimport { normalizePath } from \"../utils/paths.ts\";\nimport { resolveConfigValue } from \"./resolve-config-value.ts\";\n\ntype AuthStorageData = Record<string, Credential>;\n\ntype LockResult<T> = {\n\tresult: T;\n\tnext?: string;\n};\n\nconst AUTH_FILE_WRITE_OPTIONS = { encoding: \"utf-8\", mode: 0o600 } as const;\n\nexport interface AuthStorageBackend {\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T;\n\twithLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T>;\n}\n\nexport class FileAuthStorageBackend implements AuthStorageBackend {\n\tprivate authPath: string;\n\n\tconstructor(authPath: string = join(getAgentDir(), \"auth.json\")) {\n\t\tthis.authPath = normalizePath(authPath);\n\t}\n\n\tprivate ensureParentDir(): void {\n\t\tconst dir = dirname(this.authPath);\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t\t}\n\t}\n\n\tprivate ensureFileExists(): void {\n\t\tif (!existsSync(this.authPath)) {\n\t\t\twriteFileSync(this.authPath, \"{}\", AUTH_FILE_WRITE_OPTIONS);\n\t\t\tchmodSync(this.authPath, 0o600);\n\t\t}\n\t}\n\n\tprivate acquireLockSyncWithRetry(path: string): () => void {\n\t\tconst maxAttempts = 10;\n\t\tconst delayMs = 20;\n\t\tlet lastError: unknown;\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn lockfile.lockSync(path, { realpath: false });\n\t\t\t} catch (error) {\n\t\t\t\tconst code =\n\t\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (code !== \"ELOCKED\" || attempt === maxAttempts) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tlastError = error;\n\t\t\t\tconst start = Date.now();\n\t\t\t\twhile (Date.now() - start < delayMs) {\n\t\t\t\t\t// Sleep synchronously to avoid changing callers to async.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow (lastError as Error) ?? new Error(\"Failed to acquire auth storage lock\");\n\t}\n\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T {\n\t\tthis.ensureParentDir();\n\t\tthis.ensureFileExists();\n\n\t\tlet release: (() => void) | undefined;\n\t\ttry {\n\t\t\trelease = this.acquireLockSyncWithRetry(this.authPath);\n\t\t\tconst current = existsSync(this.authPath) ? readFileSync(this.authPath, \"utf-8\") : undefined;\n\t\t\tconst { result, next } = fn(current);\n\t\t\tif (next !== undefined) {\n\t\t\t\twriteFileSync(this.authPath, next, AUTH_FILE_WRITE_OPTIONS);\n\t\t\t\tchmodSync(this.authPath, 0o600);\n\t\t\t}\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\trelease();\n\t\t\t}\n\t\t}\n\t}\n\n\tasync withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T> {\n\t\tthis.ensureParentDir();\n\t\tthis.ensureFileExists();\n\n\t\tlet release: (() => Promise<void>) | undefined;\n\t\tlet lockCompromised = false;\n\t\tlet lockCompromisedError: Error | undefined;\n\t\tconst throwIfCompromised = () => {\n\t\t\tif (lockCompromised) {\n\t\t\t\tthrow lockCompromisedError ?? new Error(\"Auth storage lock was compromised\");\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\trelease = await lockfile.lock(this.authPath, {\n\t\t\t\tretries: {\n\t\t\t\t\tretries: 10,\n\t\t\t\t\tfactor: 2,\n\t\t\t\t\tminTimeout: 100,\n\t\t\t\t\tmaxTimeout: 10000,\n\t\t\t\t\trandomize: true,\n\t\t\t\t},\n\t\t\t\tstale: 30000,\n\t\t\t\tonCompromised: (err) => {\n\t\t\t\t\tlockCompromised = true;\n\t\t\t\t\tlockCompromisedError = err;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthrowIfCompromised();\n\t\t\tconst current = existsSync(this.authPath) ? readFileSync(this.authPath, \"utf-8\") : undefined;\n\t\t\tconst { result, next } = await fn(current);\n\t\t\tthrowIfCompromised();\n\t\t\tif (next !== undefined) {\n\t\t\t\twriteFileSync(this.authPath, next, AUTH_FILE_WRITE_OPTIONS);\n\t\t\t\tchmodSync(this.authPath, 0o600);\n\t\t\t}\n\t\t\tthrowIfCompromised();\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\ttry {\n\t\t\t\t\tawait release();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore unlock errors when lock is compromised.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class InMemoryAuthStorageBackend implements AuthStorageBackend {\n\tprivate value: string | undefined;\n\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T {\n\t\tconst { result, next } = fn(this.value);\n\t\tif (next !== undefined) {\n\t\t\tthis.value = next;\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T> {\n\t\tconst { result, next } = await fn(this.value);\n\t\tif (next !== undefined) {\n\t\t\tthis.value = next;\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Credential storage backed by a JSON file.\n */\nexport class AuthStorage implements CredentialStore {\n\tprivate data: AuthStorageData = {};\n\tprivate storage: AuthStorageBackend;\n\n\tprivate constructor(storage: AuthStorageBackend) {\n\t\tthis.storage = storage;\n\t\tthis.reload();\n\t}\n\n\tstatic create(authPath?: string): AuthStorage {\n\t\treturn new AuthStorage(new FileAuthStorageBackend(authPath ?? join(getAgentDir(), \"auth.json\")));\n\t}\n\n\tstatic fromStorage(storage: AuthStorageBackend): AuthStorage {\n\t\treturn new AuthStorage(storage);\n\t}\n\n\tstatic inMemory(data: AuthStorageData = {}): AuthStorage {\n\t\tconst storage = new InMemoryAuthStorageBackend();\n\t\tstorage.withLock(() => ({ result: undefined, next: JSON.stringify(data, null, 2) }));\n\t\treturn AuthStorage.fromStorage(storage);\n\t}\n\n\tprivate parseStorageData(content: string | undefined): AuthStorageData {\n\t\tif (!content) {\n\t\t\treturn {};\n\t\t}\n\t\treturn JSON.parse(content) as AuthStorageData;\n\t}\n\n\t/**\n\t * Reload credentials from storage.\n\t */\n\treload(): void {\n\t\tlet content: string | undefined;\n\t\ttry {\n\t\t\tthis.storage.withLock((current) => {\n\t\t\t\tcontent = current;\n\t\t\t\treturn { result: undefined };\n\t\t\t});\n\t\t\tthis.data = this.parseStorageData(content);\n\t\t} catch {\n\t\t\t// Preserve the last valid in-memory snapshot.\n\t\t}\n\t}\n\n\tasync read(provider: string): Promise<Credential | undefined> {\n\t\tconst credential = this.data[provider];\n\t\tif (credential?.type !== \"api_key\") return credential;\n\t\tif (credential.key === undefined) return credential;\n\t\treturn { ...credential, key: resolveConfigValue(credential.key, credential.env) };\n\t}\n\n\tasync modify(\n\t\tprovider: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t): Promise<Credential | undefined> {\n\t\treturn this.storage.withLockAsync(async (content) => {\n\t\t\tconst currentData = this.parseStorageData(content);\n\t\t\tconst next = await fn(currentData[provider]);\n\t\t\tif (next === undefined) {\n\t\t\t\tthis.data = currentData;\n\t\t\t\treturn { result: currentData[provider] };\n\t\t\t}\n\n\t\t\tconst merged: AuthStorageData = { ...currentData, [provider]: next };\n\t\t\tthis.data = merged;\n\t\t\treturn { result: next, next: JSON.stringify(merged, null, 2) };\n\t\t});\n\t}\n\n\tasync delete(provider: string): Promise<void> {\n\t\tawait this.storage.withLockAsync(async (content) => {\n\t\t\tconst currentData = this.parseStorageData(content);\n\t\t\tdelete currentData[provider];\n\t\t\tthis.data = currentData;\n\t\t\treturn { result: undefined, next: JSON.stringify(currentData, null, 2) };\n\t\t});\n\t}\n\n\t/** List credential metadata without resolving configured key values. */\n\tasync list(): Promise<readonly CredentialInfo[]> {\n\t\treturn Object.entries(this.data).map(([providerId, credential]) => ({ providerId, type: credential.type }));\n\t}\n}\n\n/**\n * One-off synchronous read of a stored credential from an auth.json file,\n * without instantiating a store or resolving configured key values.\n */\nexport function readStoredCredential(\n\tproviderId: string,\n\tauthPath: string = join(getAgentDir(), \"auth.json\"),\n): Credential | undefined {\n\ttry {\n\t\tconst data = JSON.parse(readFileSync(normalizePath(authPath), \"utf-8\")) as AuthStorageData;\n\t\treturn data[providerId];\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"auth-storage.d.ts","sourceRoot":"","sources":["../../src/core/auth-storage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAU/G,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAElD,KAAK,UAAU,CAAC,CAAC,IAAI;IACpB,MAAM,EAAE,CAAC,CAAC;IACV,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAkBF,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACnE,aAAa,CAAC,CAAC,EACd,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAC3D,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,CAAC,CAAC,CAAC;CACd;AAED,qBAAa,sBAAuB,YAAW,kBAAkB;IAChE,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,GAAE,MAAyC;IAI/D,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,wBAAwB;IA2BhC,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;YAqBpD,gBAAgB;IAyCxB,aAAa,CAAC,CAAC,EACpB,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAC3D,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,CAAC,CAAC;CA0Cb;AAED,qBAAa,0BAA2B,YAAW,kBAAkB;IACpE,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAuC;IAEzD,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;IAQlE,aAAa,CAAC,CAAC,EACd,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAC3D,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,CAAC,CAAC;CAeb;AAED;;GAEG;AACH,qBAAa,WAAY,YAAW,eAAe;IAClD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,SAAS,CAAoB;IAErC,OAAO;IAeP,MAAM,CAAC,MAAM,CAAC,QAAQ,GAAE,MAAyC,GAAG,WAAW;IAK/E,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW;IAI5D,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,WAAW;IAMxD,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,MAAM,IAAI,IAAI;YAeA,sBAAsB;YAStB,cAAc;IAwCtB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAQvF,MAAM,CACX,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,EACxE,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAoB5B,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7E,wEAAwE;IAClE,IAAI,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC;CAK9E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAyC,GACjD,UAAU,GAAG,SAAS,CAOxB"}
@@ -5,12 +5,14 @@
5
5
  import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
6
6
  import { dirname, join } from "path";
7
7
  import lockfile from "proper-lockfile";
8
+ import { setTimeout as sleep } from "timers/promises";
8
9
  import { getAgentDir } from "../config.js";
9
- import { normalizePath } from "../utils/paths.js";
10
+ import { raceWithAbortSignal } from "../utils/abort.js";
11
+ import { getFileRevision, normalizePath } from "../utils/paths.js";
10
12
  import { resolveConfigValue } from "./resolve-config-value.js";
11
13
  const AUTH_FILE_WRITE_OPTIONS = { encoding: "utf-8", mode: 0o600 };
14
+ let sharedAuthFileReadState;
12
15
  export class FileAuthStorageBackend {
13
- authPath;
14
16
  constructor(authPath = join(getAgentDir(), "auth.json")) {
15
17
  this.authPath = normalizePath(authPath);
16
18
  }
@@ -70,7 +72,48 @@ export class FileAuthStorageBackend {
70
72
  }
71
73
  }
72
74
  }
73
- async withLockAsync(fn) {
75
+ async acquireLockAsync(signal, onCompromised) {
76
+ const staleMs = 30_000;
77
+ const maxDelayMs = 2_000;
78
+ const deadline = Date.now() + staleMs;
79
+ let retry = 0;
80
+ while (true) {
81
+ signal?.throwIfAborted();
82
+ let release;
83
+ try {
84
+ release = await lockfile.lock(this.authPath, {
85
+ realpath: false,
86
+ retries: 0,
87
+ stale: staleMs,
88
+ onCompromised,
89
+ });
90
+ }
91
+ catch (error) {
92
+ signal?.throwIfAborted();
93
+ const code = typeof error === "object" && error !== null && "code" in error
94
+ ? String(error.code)
95
+ : undefined;
96
+ const remainingMs = deadline - Date.now();
97
+ if (code !== "ELOCKED" || remainingMs <= 0)
98
+ throw error;
99
+ const baseDelayMs = Math.min(10 * 2 ** retry, maxDelayMs / 2);
100
+ retry++;
101
+ const delayMs = Math.min(Math.round(baseDelayMs * (1 + Math.random())), remainingMs);
102
+ if (signal)
103
+ await sleep(delayMs, undefined, { signal });
104
+ else
105
+ await sleep(delayMs);
106
+ continue;
107
+ }
108
+ if (signal?.aborted) {
109
+ await release();
110
+ signal.throwIfAborted();
111
+ }
112
+ return release;
113
+ }
114
+ }
115
+ async withLockAsync(fn, options) {
116
+ options?.signal?.throwIfAborted();
74
117
  this.ensureParentDir();
75
118
  this.ensureFileExists();
76
119
  let release;
@@ -82,24 +125,16 @@ export class FileAuthStorageBackend {
82
125
  }
83
126
  };
84
127
  try {
85
- release = await lockfile.lock(this.authPath, {
86
- retries: {
87
- retries: 10,
88
- factor: 2,
89
- minTimeout: 100,
90
- maxTimeout: 10000,
91
- randomize: true,
92
- },
93
- stale: 30000,
94
- onCompromised: (err) => {
95
- lockCompromised = true;
96
- lockCompromisedError = err;
97
- },
128
+ release = await this.acquireLockAsync(options?.signal, (error) => {
129
+ lockCompromised = true;
130
+ lockCompromisedError = error;
98
131
  });
99
132
  throwIfCompromised();
133
+ options?.signal?.throwIfAborted();
100
134
  const current = existsSync(this.authPath) ? readFileSync(this.authPath, "utf-8") : undefined;
101
135
  const { result, next } = await fn(current);
102
136
  throwIfCompromised();
137
+ options?.signal?.throwIfAborted();
103
138
  if (next !== undefined) {
104
139
  writeFileSync(this.authPath, next, AUTH_FILE_WRITE_OPTIONS);
105
140
  chmodSync(this.authPath, 0o600);
@@ -120,7 +155,9 @@ export class FileAuthStorageBackend {
120
155
  }
121
156
  }
122
157
  export class InMemoryAuthStorageBackend {
123
- value;
158
+ constructor() {
159
+ this.asyncChain = Promise.resolve();
160
+ }
124
161
  withLock(fn) {
125
162
  const { result, next } = fn(this.value);
126
163
  if (next !== undefined) {
@@ -128,26 +165,44 @@ export class InMemoryAuthStorageBackend {
128
165
  }
129
166
  return result;
130
167
  }
131
- async withLockAsync(fn) {
132
- const { result, next } = await fn(this.value);
133
- if (next !== undefined) {
134
- this.value = next;
135
- }
136
- return result;
168
+ withLockAsync(fn, options) {
169
+ const previous = this.asyncChain;
170
+ const operation = (async () => {
171
+ await previous.catch(() => { });
172
+ options?.signal?.throwIfAborted();
173
+ const { result, next } = await fn(this.value);
174
+ options?.signal?.throwIfAborted();
175
+ if (next !== undefined) {
176
+ this.value = next;
177
+ }
178
+ return result;
179
+ })();
180
+ this.asyncChain = operation.catch(() => { });
181
+ return raceWithAbortSignal(operation, options?.signal);
137
182
  }
138
183
  }
139
184
  /**
140
185
  * Credential storage backed by a JSON file.
141
186
  */
142
187
  export class AuthStorage {
143
- data = {};
144
- storage;
145
- constructor(storage) {
188
+ constructor(storage, authPath) {
146
189
  this.storage = storage;
190
+ this.authPath = authPath;
191
+ this.readState =
192
+ authPath && sharedAuthFileReadState?.authPath === authPath ? sharedAuthFileReadState.readState : { data: {} };
193
+ if (authPath && !sharedAuthFileReadState) {
194
+ sharedAuthFileReadState = { authPath, readState: this.readState };
195
+ }
196
+ if (authPath) {
197
+ const revision = getFileRevision(authPath);
198
+ if (revision !== undefined && revision === this.readState.revision)
199
+ return;
200
+ }
147
201
  this.reload();
148
202
  }
149
- static create(authPath) {
150
- return new AuthStorage(new FileAuthStorageBackend(authPath ?? join(getAgentDir(), "auth.json")));
203
+ static create(authPath = join(getAgentDir(), "auth.json")) {
204
+ const normalizedAuthPath = normalizePath(authPath);
205
+ return new AuthStorage(new FileAuthStorageBackend(normalizedAuthPath), normalizedAuthPath);
151
206
  }
152
207
  static fromStorage(storage) {
153
208
  return new AuthStorage(storage);
@@ -163,54 +218,117 @@ export class AuthStorage {
163
218
  }
164
219
  return JSON.parse(content);
165
220
  }
221
+ updateReadState(data, revision) {
222
+ this.readState.data = data;
223
+ this.readState.revision = revision;
224
+ }
166
225
  /**
167
226
  * Reload credentials from storage.
168
227
  */
169
228
  reload() {
170
229
  let content;
230
+ let revision;
171
231
  try {
172
232
  this.storage.withLock((current) => {
173
233
  content = current;
234
+ revision = this.authPath ? getFileRevision(this.authPath) : undefined;
174
235
  return { result: undefined };
175
236
  });
176
- this.data = this.parseStorageData(content);
237
+ this.updateReadState(this.parseStorageData(content), revision);
177
238
  }
178
239
  catch {
179
240
  // Preserve the last valid in-memory snapshot.
180
241
  }
181
242
  }
182
- async read(provider) {
183
- const credential = this.data[provider];
243
+ async reloadFromStorageAsync(options) {
244
+ return this.storage.withLockAsync(async (content) => {
245
+ const currentData = this.parseStorageData(content);
246
+ const revision = this.authPath ? getFileRevision(this.authPath) : undefined;
247
+ this.updateReadState(currentData, revision);
248
+ return { result: currentData };
249
+ }, options);
250
+ }
251
+ async readLatestData(options) {
252
+ options?.signal?.throwIfAborted();
253
+ if (!this.authPath) {
254
+ const reload = this.reloadFromStorageAsync(options);
255
+ return options?.signal ? reload : reload.catch(() => this.readState.data);
256
+ }
257
+ const revision = getFileRevision(this.authPath);
258
+ if (revision !== undefined && revision === this.readState.revision)
259
+ return this.readState.data;
260
+ if (!this.readState.reload) {
261
+ const controller = new AbortController();
262
+ const reload = {
263
+ controller,
264
+ promise: this.reloadFromStorageAsync({ signal: controller.signal }),
265
+ readers: 0,
266
+ };
267
+ this.readState.reload = reload;
268
+ void reload.promise.then(() => {
269
+ if (this.readState.reload === reload)
270
+ this.readState.reload = undefined;
271
+ }, () => {
272
+ if (this.readState.reload === reload)
273
+ this.readState.reload = undefined;
274
+ });
275
+ }
276
+ const reload = this.readState.reload;
277
+ reload.readers++;
278
+ try {
279
+ const result = raceWithAbortSignal(reload.promise, options?.signal);
280
+ return options?.signal ? await result : await result.catch(() => this.readState.data);
281
+ }
282
+ finally {
283
+ reload.readers--;
284
+ if (reload.readers === 0 && this.readState.reload === reload) {
285
+ this.readState.reload = undefined;
286
+ reload.controller.abort();
287
+ }
288
+ }
289
+ }
290
+ async read(provider, options) {
291
+ const credential = (await this.readLatestData(options))[provider];
292
+ options?.signal?.throwIfAborted();
184
293
  if (credential?.type !== "api_key")
185
294
  return credential;
186
295
  if (credential.key === undefined)
187
296
  return credential;
188
297
  return { ...credential, key: resolveConfigValue(credential.key, credential.env) };
189
298
  }
190
- async modify(provider, fn) {
191
- return this.storage.withLockAsync(async (content) => {
299
+ async modify(provider, fn, options) {
300
+ let latestData = this.readState.data;
301
+ let revision;
302
+ const result = await this.storage.withLockAsync(async (content) => {
192
303
  const currentData = this.parseStorageData(content);
193
304
  const next = await fn(currentData[provider]);
194
305
  if (next === undefined) {
195
- this.data = currentData;
306
+ latestData = currentData;
307
+ revision = this.authPath ? getFileRevision(this.authPath) : undefined;
196
308
  return { result: currentData[provider] };
197
309
  }
198
310
  const merged = { ...currentData, [provider]: next };
199
- this.data = merged;
311
+ latestData = merged;
200
312
  return { result: next, next: JSON.stringify(merged, null, 2) };
201
- });
313
+ }, options);
314
+ this.updateReadState(latestData, revision);
315
+ return result;
202
316
  }
203
- async delete(provider) {
317
+ async delete(provider, options) {
318
+ let latestData = this.readState.data;
204
319
  await this.storage.withLockAsync(async (content) => {
205
320
  const currentData = this.parseStorageData(content);
206
321
  delete currentData[provider];
207
- this.data = currentData;
322
+ latestData = currentData;
208
323
  return { result: undefined, next: JSON.stringify(currentData, null, 2) };
209
- });
324
+ }, options);
325
+ this.updateReadState(latestData);
210
326
  }
211
327
  /** List credential metadata without resolving configured key values. */
212
- async list() {
213
- return Object.entries(this.data).map(([providerId, credential]) => ({ providerId, type: credential.type }));
328
+ async list(options) {
329
+ const entries = Object.entries(await this.readLatestData(options));
330
+ options?.signal?.throwIfAborted();
331
+ return entries.map(([providerId, credential]) => ({ providerId, type: credential.type }));
214
332
  }
215
333
  }
216
334
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"auth-storage.js","sourceRoot":"","sources":["../../src/core/auth-storage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CredentialStore implementation backed by auth.json.\n * Provider auth orchestration belongs to ModelRuntime and pi-ai Models.\n */\n\nimport type { Credential, CredentialInfo, CredentialStore } from \"@earendil-works/pi-ai\";\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport lockfile from \"proper-lockfile\";\nimport { getAgentDir } from \"../config.ts\";\nimport { normalizePath } from \"../utils/paths.ts\";\nimport { resolveConfigValue } from \"./resolve-config-value.ts\";\n\ntype AuthStorageData = Record<string, Credential>;\n\ntype LockResult<T> = {\n\tresult: T;\n\tnext?: string;\n};\n\nconst AUTH_FILE_WRITE_OPTIONS = { encoding: \"utf-8\", mode: 0o600 } as const;\n\nexport interface AuthStorageBackend {\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T;\n\twithLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T>;\n}\n\nexport class FileAuthStorageBackend implements AuthStorageBackend {\n\tprivate authPath: string;\n\n\tconstructor(authPath: string = join(getAgentDir(), \"auth.json\")) {\n\t\tthis.authPath = normalizePath(authPath);\n\t}\n\n\tprivate ensureParentDir(): void {\n\t\tconst dir = dirname(this.authPath);\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t\t}\n\t}\n\n\tprivate ensureFileExists(): void {\n\t\tif (!existsSync(this.authPath)) {\n\t\t\twriteFileSync(this.authPath, \"{}\", AUTH_FILE_WRITE_OPTIONS);\n\t\t\tchmodSync(this.authPath, 0o600);\n\t\t}\n\t}\n\n\tprivate acquireLockSyncWithRetry(path: string): () => void {\n\t\tconst maxAttempts = 10;\n\t\tconst delayMs = 20;\n\t\tlet lastError: unknown;\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn lockfile.lockSync(path, { realpath: false });\n\t\t\t} catch (error) {\n\t\t\t\tconst code =\n\t\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (code !== \"ELOCKED\" || attempt === maxAttempts) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tlastError = error;\n\t\t\t\tconst start = Date.now();\n\t\t\t\twhile (Date.now() - start < delayMs) {\n\t\t\t\t\t// Sleep synchronously to avoid changing callers to async.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow (lastError as Error) ?? new Error(\"Failed to acquire auth storage lock\");\n\t}\n\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T {\n\t\tthis.ensureParentDir();\n\t\tthis.ensureFileExists();\n\n\t\tlet release: (() => void) | undefined;\n\t\ttry {\n\t\t\trelease = this.acquireLockSyncWithRetry(this.authPath);\n\t\t\tconst current = existsSync(this.authPath) ? readFileSync(this.authPath, \"utf-8\") : undefined;\n\t\t\tconst { result, next } = fn(current);\n\t\t\tif (next !== undefined) {\n\t\t\t\twriteFileSync(this.authPath, next, AUTH_FILE_WRITE_OPTIONS);\n\t\t\t\tchmodSync(this.authPath, 0o600);\n\t\t\t}\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\trelease();\n\t\t\t}\n\t\t}\n\t}\n\n\tasync withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T> {\n\t\tthis.ensureParentDir();\n\t\tthis.ensureFileExists();\n\n\t\tlet release: (() => Promise<void>) | undefined;\n\t\tlet lockCompromised = false;\n\t\tlet lockCompromisedError: Error | undefined;\n\t\tconst throwIfCompromised = () => {\n\t\t\tif (lockCompromised) {\n\t\t\t\tthrow lockCompromisedError ?? new Error(\"Auth storage lock was compromised\");\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\trelease = await lockfile.lock(this.authPath, {\n\t\t\t\tretries: {\n\t\t\t\t\tretries: 10,\n\t\t\t\t\tfactor: 2,\n\t\t\t\t\tminTimeout: 100,\n\t\t\t\t\tmaxTimeout: 10000,\n\t\t\t\t\trandomize: true,\n\t\t\t\t},\n\t\t\t\tstale: 30000,\n\t\t\t\tonCompromised: (err) => {\n\t\t\t\t\tlockCompromised = true;\n\t\t\t\t\tlockCompromisedError = err;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthrowIfCompromised();\n\t\t\tconst current = existsSync(this.authPath) ? readFileSync(this.authPath, \"utf-8\") : undefined;\n\t\t\tconst { result, next } = await fn(current);\n\t\t\tthrowIfCompromised();\n\t\t\tif (next !== undefined) {\n\t\t\t\twriteFileSync(this.authPath, next, AUTH_FILE_WRITE_OPTIONS);\n\t\t\t\tchmodSync(this.authPath, 0o600);\n\t\t\t}\n\t\t\tthrowIfCompromised();\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\ttry {\n\t\t\t\t\tawait release();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore unlock errors when lock is compromised.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class InMemoryAuthStorageBackend implements AuthStorageBackend {\n\tprivate value: string | undefined;\n\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T {\n\t\tconst { result, next } = fn(this.value);\n\t\tif (next !== undefined) {\n\t\t\tthis.value = next;\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T> {\n\t\tconst { result, next } = await fn(this.value);\n\t\tif (next !== undefined) {\n\t\t\tthis.value = next;\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Credential storage backed by a JSON file.\n */\nexport class AuthStorage implements CredentialStore {\n\tprivate data: AuthStorageData = {};\n\tprivate storage: AuthStorageBackend;\n\n\tprivate constructor(storage: AuthStorageBackend) {\n\t\tthis.storage = storage;\n\t\tthis.reload();\n\t}\n\n\tstatic create(authPath?: string): AuthStorage {\n\t\treturn new AuthStorage(new FileAuthStorageBackend(authPath ?? join(getAgentDir(), \"auth.json\")));\n\t}\n\n\tstatic fromStorage(storage: AuthStorageBackend): AuthStorage {\n\t\treturn new AuthStorage(storage);\n\t}\n\n\tstatic inMemory(data: AuthStorageData = {}): AuthStorage {\n\t\tconst storage = new InMemoryAuthStorageBackend();\n\t\tstorage.withLock(() => ({ result: undefined, next: JSON.stringify(data, null, 2) }));\n\t\treturn AuthStorage.fromStorage(storage);\n\t}\n\n\tprivate parseStorageData(content: string | undefined): AuthStorageData {\n\t\tif (!content) {\n\t\t\treturn {};\n\t\t}\n\t\treturn JSON.parse(content) as AuthStorageData;\n\t}\n\n\t/**\n\t * Reload credentials from storage.\n\t */\n\treload(): void {\n\t\tlet content: string | undefined;\n\t\ttry {\n\t\t\tthis.storage.withLock((current) => {\n\t\t\t\tcontent = current;\n\t\t\t\treturn { result: undefined };\n\t\t\t});\n\t\t\tthis.data = this.parseStorageData(content);\n\t\t} catch {\n\t\t\t// Preserve the last valid in-memory snapshot.\n\t\t}\n\t}\n\n\tasync read(provider: string): Promise<Credential | undefined> {\n\t\tconst credential = this.data[provider];\n\t\tif (credential?.type !== \"api_key\") return credential;\n\t\tif (credential.key === undefined) return credential;\n\t\treturn { ...credential, key: resolveConfigValue(credential.key, credential.env) };\n\t}\n\n\tasync modify(\n\t\tprovider: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t): Promise<Credential | undefined> {\n\t\treturn this.storage.withLockAsync(async (content) => {\n\t\t\tconst currentData = this.parseStorageData(content);\n\t\t\tconst next = await fn(currentData[provider]);\n\t\t\tif (next === undefined) {\n\t\t\t\tthis.data = currentData;\n\t\t\t\treturn { result: currentData[provider] };\n\t\t\t}\n\n\t\t\tconst merged: AuthStorageData = { ...currentData, [provider]: next };\n\t\t\tthis.data = merged;\n\t\t\treturn { result: next, next: JSON.stringify(merged, null, 2) };\n\t\t});\n\t}\n\n\tasync delete(provider: string): Promise<void> {\n\t\tawait this.storage.withLockAsync(async (content) => {\n\t\t\tconst currentData = this.parseStorageData(content);\n\t\t\tdelete currentData[provider];\n\t\t\tthis.data = currentData;\n\t\t\treturn { result: undefined, next: JSON.stringify(currentData, null, 2) };\n\t\t});\n\t}\n\n\t/** List credential metadata without resolving configured key values. */\n\tasync list(): Promise<readonly CredentialInfo[]> {\n\t\treturn Object.entries(this.data).map(([providerId, credential]) => ({ providerId, type: credential.type }));\n\t}\n}\n\n/**\n * One-off synchronous read of a stored credential from an auth.json file,\n * without instantiating a store or resolving configured key values.\n */\nexport function readStoredCredential(\n\tproviderId: string,\n\tauthPath: string = join(getAgentDir(), \"auth.json\"),\n): Credential | undefined {\n\ttry {\n\t\tconst data = JSON.parse(readFileSync(normalizePath(authPath), \"utf-8\")) as AuthStorageData;\n\t\treturn data[providerId];\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"auth-storage.js","sourceRoot":"","sources":["../../src/core/auth-storage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CredentialStore implementation backed by auth.json.\n * Provider auth orchestration belongs to ModelRuntime and pi-ai Models.\n */\n\nimport type { AuthOperationOptions, Credential, CredentialInfo, CredentialStore } from \"@earendil-works/pi-ai\";\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport lockfile from \"proper-lockfile\";\nimport { setTimeout as sleep } from \"timers/promises\";\nimport { getAgentDir } from \"../config.ts\";\nimport { raceWithAbortSignal } from \"../utils/abort.ts\";\nimport { getFileRevision, normalizePath } from \"../utils/paths.ts\";\nimport { resolveConfigValue } from \"./resolve-config-value.ts\";\n\ntype AuthStorageData = Record<string, Credential>;\n\ntype LockResult<T> = {\n\tresult: T;\n\tnext?: string;\n};\n\nconst AUTH_FILE_WRITE_OPTIONS = { encoding: \"utf-8\", mode: 0o600 } as const;\n\ntype AuthFileReload = {\n\tcontroller: AbortController;\n\tpromise: Promise<AuthStorageData>;\n\treaders: number;\n};\n\ntype AuthFileReadState = {\n\tdata: AuthStorageData;\n\trevision?: string;\n\treload?: AuthFileReload;\n};\n\nlet sharedAuthFileReadState: { authPath: string; readState: AuthFileReadState } | undefined;\n\nexport interface AuthStorageBackend {\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T;\n\twithLockAsync<T>(\n\t\tfn: (current: string | undefined) => Promise<LockResult<T>>,\n\t\toptions?: AuthOperationOptions,\n\t): Promise<T>;\n}\n\nexport class FileAuthStorageBackend implements AuthStorageBackend {\n\tprivate authPath: string;\n\n\tconstructor(authPath: string = join(getAgentDir(), \"auth.json\")) {\n\t\tthis.authPath = normalizePath(authPath);\n\t}\n\n\tprivate ensureParentDir(): void {\n\t\tconst dir = dirname(this.authPath);\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t\t}\n\t}\n\n\tprivate ensureFileExists(): void {\n\t\tif (!existsSync(this.authPath)) {\n\t\t\twriteFileSync(this.authPath, \"{}\", AUTH_FILE_WRITE_OPTIONS);\n\t\t\tchmodSync(this.authPath, 0o600);\n\t\t}\n\t}\n\n\tprivate acquireLockSyncWithRetry(path: string): () => void {\n\t\tconst maxAttempts = 10;\n\t\tconst delayMs = 20;\n\t\tlet lastError: unknown;\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn lockfile.lockSync(path, { realpath: false });\n\t\t\t} catch (error) {\n\t\t\t\tconst code =\n\t\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (code !== \"ELOCKED\" || attempt === maxAttempts) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tlastError = error;\n\t\t\t\tconst start = Date.now();\n\t\t\t\twhile (Date.now() - start < delayMs) {\n\t\t\t\t\t// Sleep synchronously to avoid changing callers to async.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow (lastError as Error) ?? new Error(\"Failed to acquire auth storage lock\");\n\t}\n\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T {\n\t\tthis.ensureParentDir();\n\t\tthis.ensureFileExists();\n\n\t\tlet release: (() => void) | undefined;\n\t\ttry {\n\t\t\trelease = this.acquireLockSyncWithRetry(this.authPath);\n\t\t\tconst current = existsSync(this.authPath) ? readFileSync(this.authPath, \"utf-8\") : undefined;\n\t\t\tconst { result, next } = fn(current);\n\t\t\tif (next !== undefined) {\n\t\t\t\twriteFileSync(this.authPath, next, AUTH_FILE_WRITE_OPTIONS);\n\t\t\t\tchmodSync(this.authPath, 0o600);\n\t\t\t}\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\trelease();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async acquireLockAsync(\n\t\tsignal: AbortSignal | undefined,\n\t\tonCompromised: (error: Error) => void,\n\t): Promise<() => Promise<void>> {\n\t\tconst staleMs = 30_000;\n\t\tconst maxDelayMs = 2_000;\n\t\tconst deadline = Date.now() + staleMs;\n\t\tlet retry = 0;\n\t\twhile (true) {\n\t\t\tsignal?.throwIfAborted();\n\t\t\tlet release: (() => Promise<void>) | undefined;\n\t\t\ttry {\n\t\t\t\trelease = await lockfile.lock(this.authPath, {\n\t\t\t\t\trealpath: false,\n\t\t\t\t\tretries: 0,\n\t\t\t\t\tstale: staleMs,\n\t\t\t\t\tonCompromised,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\tconst code =\n\t\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst remainingMs = deadline - Date.now();\n\t\t\t\tif (code !== \"ELOCKED\" || remainingMs <= 0) throw error;\n\t\t\t\tconst baseDelayMs = Math.min(10 * 2 ** retry, maxDelayMs / 2);\n\t\t\t\tretry++;\n\t\t\t\tconst delayMs = Math.min(Math.round(baseDelayMs * (1 + Math.random())), remainingMs);\n\t\t\t\tif (signal) await sleep(delayMs, undefined, { signal });\n\t\t\t\telse await sleep(delayMs);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (signal?.aborted) {\n\t\t\t\tawait release();\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t}\n\t\t\treturn release;\n\t\t}\n\t}\n\n\tasync withLockAsync<T>(\n\t\tfn: (current: string | undefined) => Promise<LockResult<T>>,\n\t\toptions?: AuthOperationOptions,\n\t): Promise<T> {\n\t\toptions?.signal?.throwIfAborted();\n\t\tthis.ensureParentDir();\n\t\tthis.ensureFileExists();\n\n\t\tlet release: (() => Promise<void>) | undefined;\n\t\tlet lockCompromised = false;\n\t\tlet lockCompromisedError: Error | undefined;\n\t\tconst throwIfCompromised = () => {\n\t\t\tif (lockCompromised) {\n\t\t\t\tthrow lockCompromisedError ?? new Error(\"Auth storage lock was compromised\");\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\trelease = await this.acquireLockAsync(options?.signal, (error) => {\n\t\t\t\tlockCompromised = true;\n\t\t\t\tlockCompromisedError = error;\n\t\t\t});\n\n\t\t\tthrowIfCompromised();\n\t\t\toptions?.signal?.throwIfAborted();\n\t\t\tconst current = existsSync(this.authPath) ? readFileSync(this.authPath, \"utf-8\") : undefined;\n\t\t\tconst { result, next } = await fn(current);\n\t\t\tthrowIfCompromised();\n\t\t\toptions?.signal?.throwIfAborted();\n\t\t\tif (next !== undefined) {\n\t\t\t\twriteFileSync(this.authPath, next, AUTH_FILE_WRITE_OPTIONS);\n\t\t\t\tchmodSync(this.authPath, 0o600);\n\t\t\t}\n\t\t\tthrowIfCompromised();\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\ttry {\n\t\t\t\t\tawait release();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore unlock errors when lock is compromised.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class InMemoryAuthStorageBackend implements AuthStorageBackend {\n\tprivate value: string | undefined;\n\tprivate asyncChain: Promise<unknown> = Promise.resolve();\n\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T {\n\t\tconst { result, next } = fn(this.value);\n\t\tif (next !== undefined) {\n\t\t\tthis.value = next;\n\t\t}\n\t\treturn result;\n\t}\n\n\twithLockAsync<T>(\n\t\tfn: (current: string | undefined) => Promise<LockResult<T>>,\n\t\toptions?: AuthOperationOptions,\n\t): Promise<T> {\n\t\tconst previous = this.asyncChain;\n\t\tconst operation = (async () => {\n\t\t\tawait previous.catch(() => {});\n\t\t\toptions?.signal?.throwIfAborted();\n\t\t\tconst { result, next } = await fn(this.value);\n\t\t\toptions?.signal?.throwIfAborted();\n\t\t\tif (next !== undefined) {\n\t\t\t\tthis.value = next;\n\t\t\t}\n\t\t\treturn result;\n\t\t})();\n\t\tthis.asyncChain = operation.catch(() => {});\n\t\treturn raceWithAbortSignal(operation, options?.signal);\n\t}\n}\n\n/**\n * Credential storage backed by a JSON file.\n */\nexport class AuthStorage implements CredentialStore {\n\tprivate storage: AuthStorageBackend;\n\tprivate authPath: string | undefined;\n\tprivate readState: AuthFileReadState;\n\n\tprivate constructor(storage: AuthStorageBackend, authPath?: string) {\n\t\tthis.storage = storage;\n\t\tthis.authPath = authPath;\n\t\tthis.readState =\n\t\t\tauthPath && sharedAuthFileReadState?.authPath === authPath ? sharedAuthFileReadState.readState : { data: {} };\n\t\tif (authPath && !sharedAuthFileReadState) {\n\t\t\tsharedAuthFileReadState = { authPath, readState: this.readState };\n\t\t}\n\t\tif (authPath) {\n\t\t\tconst revision = getFileRevision(authPath);\n\t\t\tif (revision !== undefined && revision === this.readState.revision) return;\n\t\t}\n\t\tthis.reload();\n\t}\n\n\tstatic create(authPath: string = join(getAgentDir(), \"auth.json\")): AuthStorage {\n\t\tconst normalizedAuthPath = normalizePath(authPath);\n\t\treturn new AuthStorage(new FileAuthStorageBackend(normalizedAuthPath), normalizedAuthPath);\n\t}\n\n\tstatic fromStorage(storage: AuthStorageBackend): AuthStorage {\n\t\treturn new AuthStorage(storage);\n\t}\n\n\tstatic inMemory(data: AuthStorageData = {}): AuthStorage {\n\t\tconst storage = new InMemoryAuthStorageBackend();\n\t\tstorage.withLock(() => ({ result: undefined, next: JSON.stringify(data, null, 2) }));\n\t\treturn AuthStorage.fromStorage(storage);\n\t}\n\n\tprivate parseStorageData(content: string | undefined): AuthStorageData {\n\t\tif (!content) {\n\t\t\treturn {};\n\t\t}\n\t\treturn JSON.parse(content) as AuthStorageData;\n\t}\n\n\tprivate updateReadState(data: AuthStorageData, revision?: string): void {\n\t\tthis.readState.data = data;\n\t\tthis.readState.revision = revision;\n\t}\n\n\t/**\n\t * Reload credentials from storage.\n\t */\n\treload(): void {\n\t\tlet content: string | undefined;\n\t\tlet revision: string | undefined;\n\t\ttry {\n\t\t\tthis.storage.withLock((current) => {\n\t\t\t\tcontent = current;\n\t\t\t\trevision = this.authPath ? getFileRevision(this.authPath) : undefined;\n\t\t\t\treturn { result: undefined };\n\t\t\t});\n\t\t\tthis.updateReadState(this.parseStorageData(content), revision);\n\t\t} catch {\n\t\t\t// Preserve the last valid in-memory snapshot.\n\t\t}\n\t}\n\n\tprivate async reloadFromStorageAsync(options?: AuthOperationOptions): Promise<AuthStorageData> {\n\t\treturn this.storage.withLockAsync(async (content) => {\n\t\t\tconst currentData = this.parseStorageData(content);\n\t\t\tconst revision = this.authPath ? getFileRevision(this.authPath) : undefined;\n\t\t\tthis.updateReadState(currentData, revision);\n\t\t\treturn { result: currentData };\n\t\t}, options);\n\t}\n\n\tprivate async readLatestData(options?: AuthOperationOptions): Promise<AuthStorageData> {\n\t\toptions?.signal?.throwIfAborted();\n\t\tif (!this.authPath) {\n\t\t\tconst reload = this.reloadFromStorageAsync(options);\n\t\t\treturn options?.signal ? reload : reload.catch(() => this.readState.data);\n\t\t}\n\t\tconst revision = getFileRevision(this.authPath);\n\t\tif (revision !== undefined && revision === this.readState.revision) return this.readState.data;\n\t\tif (!this.readState.reload) {\n\t\t\tconst controller = new AbortController();\n\t\t\tconst reload: AuthFileReload = {\n\t\t\t\tcontroller,\n\t\t\t\tpromise: this.reloadFromStorageAsync({ signal: controller.signal }),\n\t\t\t\treaders: 0,\n\t\t\t};\n\t\t\tthis.readState.reload = reload;\n\t\t\tvoid reload.promise.then(\n\t\t\t\t() => {\n\t\t\t\t\tif (this.readState.reload === reload) this.readState.reload = undefined;\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tif (this.readState.reload === reload) this.readState.reload = undefined;\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tconst reload = this.readState.reload;\n\t\treload.readers++;\n\t\ttry {\n\t\t\tconst result = raceWithAbortSignal(reload.promise, options?.signal);\n\t\t\treturn options?.signal ? await result : await result.catch(() => this.readState.data);\n\t\t} finally {\n\t\t\treload.readers--;\n\t\t\tif (reload.readers === 0 && this.readState.reload === reload) {\n\t\t\t\tthis.readState.reload = undefined;\n\t\t\t\treload.controller.abort();\n\t\t\t}\n\t\t}\n\t}\n\n\tasync read(provider: string, options?: AuthOperationOptions): Promise<Credential | undefined> {\n\t\tconst credential = (await this.readLatestData(options))[provider];\n\t\toptions?.signal?.throwIfAborted();\n\t\tif (credential?.type !== \"api_key\") return credential;\n\t\tif (credential.key === undefined) return credential;\n\t\treturn { ...credential, key: resolveConfigValue(credential.key, credential.env) };\n\t}\n\n\tasync modify(\n\t\tprovider: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t\toptions?: AuthOperationOptions,\n\t): Promise<Credential | undefined> {\n\t\tlet latestData = this.readState.data;\n\t\tlet revision: string | undefined;\n\t\tconst result = await this.storage.withLockAsync(async (content) => {\n\t\t\tconst currentData = this.parseStorageData(content);\n\t\t\tconst next = await fn(currentData[provider]);\n\t\t\tif (next === undefined) {\n\t\t\t\tlatestData = currentData;\n\t\t\t\trevision = this.authPath ? getFileRevision(this.authPath) : undefined;\n\t\t\t\treturn { result: currentData[provider] };\n\t\t\t}\n\n\t\t\tconst merged: AuthStorageData = { ...currentData, [provider]: next };\n\t\t\tlatestData = merged;\n\t\t\treturn { result: next, next: JSON.stringify(merged, null, 2) };\n\t\t}, options);\n\t\tthis.updateReadState(latestData, revision);\n\t\treturn result;\n\t}\n\n\tasync delete(provider: string, options?: AuthOperationOptions): Promise<void> {\n\t\tlet latestData = this.readState.data;\n\t\tawait this.storage.withLockAsync(async (content) => {\n\t\t\tconst currentData = this.parseStorageData(content);\n\t\t\tdelete currentData[provider];\n\t\t\tlatestData = currentData;\n\t\t\treturn { result: undefined, next: JSON.stringify(currentData, null, 2) };\n\t\t}, options);\n\t\tthis.updateReadState(latestData);\n\t}\n\n\t/** List credential metadata without resolving configured key values. */\n\tasync list(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]> {\n\t\tconst entries = Object.entries(await this.readLatestData(options));\n\t\toptions?.signal?.throwIfAborted();\n\t\treturn entries.map(([providerId, credential]) => ({ providerId, type: credential.type }));\n\t}\n}\n\n/**\n * One-off synchronous read of a stored credential from an auth.json file,\n * without instantiating a store or resolving configured key values.\n */\nexport function readStoredCredential(\n\tproviderId: string,\n\tauthPath: string = join(getAgentDir(), \"auth.json\"),\n): Credential | undefined {\n\ttry {\n\t\tconst data = JSON.parse(readFileSync(normalizePath(authPath), \"utf-8\")) as AuthStorageData;\n\t\treturn data[providerId];\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"bash-executor.d.ts","sourceRoot":"","sources":["../../src/core/bash-executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAOtD,MAAM,WAAW,mBAAmB;IACnC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,mCAAmC;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,mDAAmD;IACnD,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,yFAAyF;IACzF,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;GAGG;AACH,wBAAsB,yBAAyB,CAC9C,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,UAAU,CAAC,CAqGrB","sourcesContent":["/**\n * Bash command execution with streaming support and cancellation.\n *\n * This module provides a unified bash execution implementation used by:\n * - AgentSession.executeBash() for interactive and RPC modes\n * - Direct calls from modes that need bash execution\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport { createWriteStream, type WriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { stripAnsi } from \"../utils/ansi.ts\";\nimport { sanitizeBinaryOutput } from \"../utils/shell.ts\";\nimport type { BashOperations } from \"./tools/bash.ts\";\nimport { DEFAULT_MAX_BYTES, truncateTail } from \"./tools/truncate.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BashExecutorOptions {\n\t/** Callback for streaming output chunks (already sanitized) */\n\tonChunk?: (chunk: string) => void;\n\t/** AbortSignal for cancellation */\n\tsignal?: AbortSignal;\n}\n\nexport interface BashResult {\n\t/** Combined stdout + stderr output (sanitized, possibly truncated) */\n\toutput: string;\n\t/** Process exit code (undefined if killed/cancelled) */\n\texitCode: number | undefined;\n\t/** Whether the command was cancelled via signal */\n\tcancelled: boolean;\n\t/** Whether the output was truncated */\n\ttruncated: boolean;\n\t/** Path to temp file containing full output (if output exceeded truncation threshold) */\n\tfullOutputPath?: string;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Execute a bash command using custom BashOperations.\n * Used for remote execution (SSH, containers, etc.).\n */\nexport async function executeBashWithOperations(\n\tcommand: string,\n\tcwd: string,\n\toperations: BashOperations,\n\toptions?: BashExecutorOptions,\n): Promise<BashResult> {\n\tconst outputChunks: string[] = [];\n\tlet outputBytes = 0;\n\tconst maxOutputBytes = DEFAULT_MAX_BYTES * 2;\n\n\tlet tempFilePath: string | undefined;\n\tlet tempFileStream: WriteStream | undefined;\n\tlet totalBytes = 0;\n\n\tconst ensureTempFile = () => {\n\t\tif (tempFilePath) {\n\t\t\treturn;\n\t\t}\n\t\tconst id = randomBytes(8).toString(\"hex\");\n\t\ttempFilePath = join(tmpdir(), `pi-bash-${id}.log`);\n\t\ttempFileStream = createWriteStream(tempFilePath);\n\t\tfor (const chunk of outputChunks) {\n\t\t\ttempFileStream.write(chunk);\n\t\t}\n\t};\n\n\tconst decoder = new TextDecoder();\n\n\tconst onData = (data: Buffer) => {\n\t\ttotalBytes += data.length;\n\n\t\t// Sanitize: strip ANSI, replace binary garbage, normalize newlines\n\t\tconst text = sanitizeBinaryOutput(stripAnsi(decoder.decode(data, { stream: true }))).replace(/\\r/g, \"\");\n\n\t\t// Start writing to temp file if exceeds threshold\n\t\tif (totalBytes > DEFAULT_MAX_BYTES) {\n\t\t\tensureTempFile();\n\t\t}\n\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.write(text);\n\t\t}\n\n\t\t// Keep rolling buffer\n\t\toutputChunks.push(text);\n\t\toutputBytes += text.length;\n\t\twhile (outputBytes > maxOutputBytes && outputChunks.length > 1) {\n\t\t\tconst removed = outputChunks.shift()!;\n\t\t\toutputBytes -= removed.length;\n\t\t}\n\n\t\t// Stream to callback\n\t\tif (options?.onChunk) {\n\t\t\toptions.onChunk(text);\n\t\t}\n\t};\n\n\ttry {\n\t\tconst result = await operations.exec(command, cwd, {\n\t\t\tonData,\n\t\t\tsignal: options?.signal,\n\t\t});\n\n\t\tconst fullOutput = outputChunks.join(\"\");\n\t\tconst truncationResult = truncateTail(fullOutput);\n\t\tif (truncationResult.truncated) {\n\t\t\tensureTempFile();\n\t\t}\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.end();\n\t\t}\n\t\tconst cancelled = options?.signal?.aborted ?? false;\n\n\t\treturn {\n\t\t\toutput: truncationResult.truncated ? truncationResult.content : fullOutput,\n\t\t\texitCode: cancelled ? undefined : (result.exitCode ?? undefined),\n\t\t\tcancelled,\n\t\t\ttruncated: truncationResult.truncated,\n\t\t\tfullOutputPath: tempFilePath,\n\t\t};\n\t} catch (err) {\n\t\t// Check if it was an abort\n\t\tif (options?.signal?.aborted) {\n\t\t\tconst fullOutput = outputChunks.join(\"\");\n\t\t\tconst truncationResult = truncateTail(fullOutput);\n\t\t\tif (truncationResult.truncated) {\n\t\t\t\tensureTempFile();\n\t\t\t}\n\t\t\tif (tempFileStream) {\n\t\t\t\ttempFileStream.end();\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toutput: truncationResult.truncated ? truncationResult.content : fullOutput,\n\t\t\t\texitCode: undefined,\n\t\t\t\tcancelled: true,\n\t\t\t\ttruncated: truncationResult.truncated,\n\t\t\t\tfullOutputPath: tempFilePath,\n\t\t\t};\n\t\t}\n\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.end();\n\t\t}\n\n\t\tthrow err;\n\t}\n}\n"]}
1
+ {"version":3,"file":"bash-executor.d.ts","sourceRoot":"","sources":["../../src/core/bash-executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAOtD,MAAM,WAAW,mBAAmB;IACnC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,mCAAmC;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,mDAAmD;IACnD,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,yFAAyF;IACzF,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;GAGG;AACH,wBAAsB,yBAAyB,CAC9C,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,UAAU,CAAC,CAqGrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"bash-executor.js","sourceRoot":"","sources":["../../src/core/bash-executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bash command execution with streaming support and cancellation.\n *\n * This module provides a unified bash execution implementation used by:\n * - AgentSession.executeBash() for interactive and RPC modes\n * - Direct calls from modes that need bash execution\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport { createWriteStream, type WriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { stripAnsi } from \"../utils/ansi.ts\";\nimport { sanitizeBinaryOutput } from \"../utils/shell.ts\";\nimport type { BashOperations } from \"./tools/bash.ts\";\nimport { DEFAULT_MAX_BYTES, truncateTail } from \"./tools/truncate.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BashExecutorOptions {\n\t/** Callback for streaming output chunks (already sanitized) */\n\tonChunk?: (chunk: string) => void;\n\t/** AbortSignal for cancellation */\n\tsignal?: AbortSignal;\n}\n\nexport interface BashResult {\n\t/** Combined stdout + stderr output (sanitized, possibly truncated) */\n\toutput: string;\n\t/** Process exit code (undefined if killed/cancelled) */\n\texitCode: number | undefined;\n\t/** Whether the command was cancelled via signal */\n\tcancelled: boolean;\n\t/** Whether the output was truncated */\n\ttruncated: boolean;\n\t/** Path to temp file containing full output (if output exceeded truncation threshold) */\n\tfullOutputPath?: string;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Execute a bash command using custom BashOperations.\n * Used for remote execution (SSH, containers, etc.).\n */\nexport async function executeBashWithOperations(\n\tcommand: string,\n\tcwd: string,\n\toperations: BashOperations,\n\toptions?: BashExecutorOptions,\n): Promise<BashResult> {\n\tconst outputChunks: string[] = [];\n\tlet outputBytes = 0;\n\tconst maxOutputBytes = DEFAULT_MAX_BYTES * 2;\n\n\tlet tempFilePath: string | undefined;\n\tlet tempFileStream: WriteStream | undefined;\n\tlet totalBytes = 0;\n\n\tconst ensureTempFile = () => {\n\t\tif (tempFilePath) {\n\t\t\treturn;\n\t\t}\n\t\tconst id = randomBytes(8).toString(\"hex\");\n\t\ttempFilePath = join(tmpdir(), `pi-bash-${id}.log`);\n\t\ttempFileStream = createWriteStream(tempFilePath);\n\t\tfor (const chunk of outputChunks) {\n\t\t\ttempFileStream.write(chunk);\n\t\t}\n\t};\n\n\tconst decoder = new TextDecoder();\n\n\tconst onData = (data: Buffer) => {\n\t\ttotalBytes += data.length;\n\n\t\t// Sanitize: strip ANSI, replace binary garbage, normalize newlines\n\t\tconst text = sanitizeBinaryOutput(stripAnsi(decoder.decode(data, { stream: true }))).replace(/\\r/g, \"\");\n\n\t\t// Start writing to temp file if exceeds threshold\n\t\tif (totalBytes > DEFAULT_MAX_BYTES) {\n\t\t\tensureTempFile();\n\t\t}\n\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.write(text);\n\t\t}\n\n\t\t// Keep rolling buffer\n\t\toutputChunks.push(text);\n\t\toutputBytes += text.length;\n\t\twhile (outputBytes > maxOutputBytes && outputChunks.length > 1) {\n\t\t\tconst removed = outputChunks.shift()!;\n\t\t\toutputBytes -= removed.length;\n\t\t}\n\n\t\t// Stream to callback\n\t\tif (options?.onChunk) {\n\t\t\toptions.onChunk(text);\n\t\t}\n\t};\n\n\ttry {\n\t\tconst result = await operations.exec(command, cwd, {\n\t\t\tonData,\n\t\t\tsignal: options?.signal,\n\t\t});\n\n\t\tconst fullOutput = outputChunks.join(\"\");\n\t\tconst truncationResult = truncateTail(fullOutput);\n\t\tif (truncationResult.truncated) {\n\t\t\tensureTempFile();\n\t\t}\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.end();\n\t\t}\n\t\tconst cancelled = options?.signal?.aborted ?? false;\n\n\t\treturn {\n\t\t\toutput: truncationResult.truncated ? truncationResult.content : fullOutput,\n\t\t\texitCode: cancelled ? undefined : (result.exitCode ?? undefined),\n\t\t\tcancelled,\n\t\t\ttruncated: truncationResult.truncated,\n\t\t\tfullOutputPath: tempFilePath,\n\t\t};\n\t} catch (err) {\n\t\t// Check if it was an abort\n\t\tif (options?.signal?.aborted) {\n\t\t\tconst fullOutput = outputChunks.join(\"\");\n\t\t\tconst truncationResult = truncateTail(fullOutput);\n\t\t\tif (truncationResult.truncated) {\n\t\t\t\tensureTempFile();\n\t\t\t}\n\t\t\tif (tempFileStream) {\n\t\t\t\ttempFileStream.end();\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toutput: truncationResult.truncated ? truncationResult.content : fullOutput,\n\t\t\t\texitCode: undefined,\n\t\t\t\tcancelled: true,\n\t\t\t\ttruncated: truncationResult.truncated,\n\t\t\t\tfullOutputPath: tempFilePath,\n\t\t\t};\n\t\t}\n\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.end();\n\t\t}\n\n\t\tthrow err;\n\t}\n}\n"]}
1
+ {"version":3,"file":"bash-executor.js","sourceRoot":"","sources":["../../src/core/bash-executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bash command execution with streaming support and cancellation.\n *\n * This module provides a unified bash execution implementation used by:\n * - AgentSession.executeBash() for interactive and RPC modes\n * - Direct calls from modes that need bash execution\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport { createWriteStream, type WriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { stripAnsi } from \"../utils/ansi.ts\";\nimport { sanitizeBinaryOutput } from \"../utils/shell.ts\";\nimport type { BashOperations } from \"./tools/bash.ts\";\nimport { DEFAULT_MAX_BYTES, truncateTail } from \"./tools/truncate.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BashExecutorOptions {\n\t/** Callback for streaming output chunks (already sanitized) */\n\tonChunk?: (chunk: string) => void;\n\t/** AbortSignal for cancellation */\n\tsignal?: AbortSignal;\n}\n\nexport interface BashResult {\n\t/** Combined stdout + stderr output (sanitized, possibly truncated) */\n\toutput: string;\n\t/** Process exit code (undefined if killed/cancelled) */\n\texitCode: number | undefined;\n\t/** Whether the command was cancelled via signal */\n\tcancelled: boolean;\n\t/** Whether the output was truncated */\n\ttruncated: boolean;\n\t/** Path to temp file containing full output (if output exceeded truncation threshold) */\n\tfullOutputPath?: string;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Execute a bash command using custom BashOperations.\n * Used for remote execution (SSH, containers, etc.).\n */\nexport async function executeBashWithOperations(\n\tcommand: string,\n\tcwd: string,\n\toperations: BashOperations,\n\toptions?: BashExecutorOptions,\n): Promise<BashResult> {\n\tconst outputChunks: string[] = [];\n\tlet outputBytes = 0;\n\tconst maxOutputBytes = DEFAULT_MAX_BYTES * 2;\n\n\tlet tempFilePath: string | undefined;\n\tlet tempFileStream: WriteStream | undefined;\n\tlet totalBytes = 0;\n\n\tconst ensureTempFile = () => {\n\t\tif (tempFilePath) {\n\t\t\treturn;\n\t\t}\n\t\tconst id = randomBytes(8).toString(\"hex\");\n\t\ttempFilePath = join(tmpdir(), `pi-bash-${id}.log`);\n\t\ttempFileStream = createWriteStream(tempFilePath);\n\t\tfor (const chunk of outputChunks) {\n\t\t\ttempFileStream.write(chunk);\n\t\t}\n\t};\n\n\tconst decoder = new TextDecoder();\n\n\tconst onData = (data: Buffer) => {\n\t\ttotalBytes += data.length;\n\n\t\t// Sanitize: strip ANSI, replace binary garbage, normalize newlines\n\t\tconst text = sanitizeBinaryOutput(stripAnsi(decoder.decode(data, { stream: true }))).replace(/\\r/g, \"\");\n\n\t\t// Start writing to temp file if exceeds threshold\n\t\tif (totalBytes > DEFAULT_MAX_BYTES) {\n\t\t\tensureTempFile();\n\t\t}\n\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.write(text);\n\t\t}\n\n\t\t// Keep rolling buffer\n\t\toutputChunks.push(text);\n\t\toutputBytes += text.length;\n\t\twhile (outputBytes > maxOutputBytes && outputChunks.length > 1) {\n\t\t\tconst removed = outputChunks.shift()!;\n\t\t\toutputBytes -= removed.length;\n\t\t}\n\n\t\t// Stream to callback\n\t\tif (options?.onChunk) {\n\t\t\toptions.onChunk(text);\n\t\t}\n\t};\n\n\ttry {\n\t\tconst result = await operations.exec(command, cwd, {\n\t\t\tonData,\n\t\t\tsignal: options?.signal,\n\t\t});\n\n\t\tconst fullOutput = outputChunks.join(\"\");\n\t\tconst truncationResult = truncateTail(fullOutput);\n\t\tif (truncationResult.truncated) {\n\t\t\tensureTempFile();\n\t\t}\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.end();\n\t\t}\n\t\tconst cancelled = options?.signal?.aborted ?? false;\n\n\t\treturn {\n\t\t\toutput: truncationResult.truncated ? truncationResult.content : fullOutput,\n\t\t\texitCode: cancelled ? undefined : (result.exitCode ?? undefined),\n\t\t\tcancelled,\n\t\t\ttruncated: truncationResult.truncated,\n\t\t\tfullOutputPath: tempFilePath,\n\t\t};\n\t} catch (err) {\n\t\t// Check if it was an abort\n\t\tif (options?.signal?.aborted) {\n\t\t\tconst fullOutput = outputChunks.join(\"\");\n\t\t\tconst truncationResult = truncateTail(fullOutput);\n\t\t\tif (truncationResult.truncated) {\n\t\t\t\tensureTempFile();\n\t\t\t}\n\t\t\tif (tempFileStream) {\n\t\t\t\ttempFileStream.end();\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toutput: truncationResult.truncated ? truncationResult.content : fullOutput,\n\t\t\t\texitCode: undefined,\n\t\t\t\tcancelled: true,\n\t\t\t\ttruncated: truncationResult.truncated,\n\t\t\t\tfullOutputPath: tempFilePath,\n\t\t\t};\n\t\t}\n\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.end();\n\t\t}\n\n\t\tthrow err;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cache-stats.d.ts","sourceRoot":"","sources":["../../src/core/cache-stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAgB,CAAC;AAK1C,0DAA0D;AAC1D,MAAM,WAAW,SAAS;IACzB,qFAAqF;IACrF,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,YAAY,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GAAG,SAAS,CAAC;CACzF;AAmGD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAErG;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,MAAM,EAAE,gBAAgB,GACtB,GAAG,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAElC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,gBAAgB,GACtB,SAAS,GAAG,SAAS,CAEvB","sourcesContent":["import type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport type { SessionEntry } from \"./session-manager.ts\";\n\n/**\n * Prompt-cache TTL: idle gaps longer than this are worth mentioning as the\n * likely cause of a miss. Anthropic's default cache TTL is 5 minutes.\n */\nexport const CACHE_TTL_MS = 5 * 60 * 1000;\n\n/** Per-turn misses at or below this are cache breakpoint granularity noise. */\nconst NOISE_FLOOR_TOKENS = 1024;\n\n/** A counted cache miss on a single assistant message. */\nexport interface CacheMiss {\n\t/** Prompt tokens that were in the previous turn's prompt but not read from cache. */\n\tmissedTokens: number;\n\t/** Extra dollars paid vs. a full cache hit; 0 when pricing is unknown. */\n\tmissedCost: number;\n\t/** Milliseconds since the previous request (which last refreshed the cache). */\n\tidleMs: number;\n\t/** True when the model changed relative to the previous request. */\n\tmodelChanged: boolean;\n}\n\nexport interface CacheWasteTotals {\n\tmissedTokens: number;\n\tmissedCost: number;\n\t/** Number of counted misses (turns above the noise floor). */\n\tmissCount: number;\n}\n\n/** Minimal pricing lookup, satisfied by ModelRuntime. Cost is $/million tokens. */\nexport interface ModelPriceSource {\n\tgetModel(provider: string, modelId: string): { cost: { cacheRead: number } } | undefined;\n}\n\n/** The last request seen by the scan; everything in its prompt should be cached. */\ninterface PreviousRequest {\n\tpromptTokens: number;\n\tmodelKey: string;\n\ttimestamp: number;\n\t/**\n\t * Sticky: some earlier request in this scan segment reported cache activity.\n\t * Distinguishes a total miss on a cache-read-only provider (OpenAI-style,\n\t * writes unreported) from a provider that never reports caching at all.\n\t */\n\treportedCache: boolean;\n}\n\n/**\n * Compute the cache miss for one assistant message relative to the previous\n * request. Returns undefined when nothing is counted: first turn, after a\n * reset, no cache activity ever reported (provider without cache support), or\n * miss below the noise floor.\n */\nfunction detectMiss(\n\tprev: PreviousRequest | undefined,\n\tmessage: AssistantMessage,\n\tmodels: ModelPriceSource,\n): CacheMiss | undefined {\n\tconst usage = message.usage;\n\tconst promptTokens = usage.input + usage.cacheRead + usage.cacheWrite;\n\t// A zero-cache turn only counts when cache activity was reported before:\n\t// on cache-read-only providers that is a total miss, while on providers\n\t// that never report caching it means nothing.\n\tif (!prev || promptTokens <= 0 || (usage.cacheRead + usage.cacheWrite === 0 && !prev.reportedCache)) {\n\t\treturn undefined;\n\t}\n\n\tconst missedTokens = Math.min(prev.promptTokens, promptTokens) - usage.cacheRead;\n\tif (missedTokens <= NOISE_FLOOR_TOKENS) return undefined;\n\n\t// Extra cost = missed tokens billed at the actual paid rate (input/cacheWrite,\n\t// incl. write premium) instead of the cache-read rate. Missed tokens can only\n\t// land in the input or cacheWrite buckets, so the paid rate comes straight\n\t// from this message's own cost breakdown.\n\tconst paidTokens = usage.input + usage.cacheWrite;\n\tconst paidPerToken = paidTokens > 0 ? (usage.cost.input + usage.cost.cacheWrite) / paidTokens : 0;\n\tconst readPerToken =\n\t\tusage.cacheRead > 0\n\t\t\t? usage.cost.cacheRead / usage.cacheRead\n\t\t\t: (models.getModel(message.provider, message.model)?.cost.cacheRead ?? 0) / 1_000_000;\n\n\treturn {\n\t\tmissedTokens,\n\t\tmissedCost: missedTokens * Math.max(0, paidPerToken - readPerToken),\n\t\tidleMs: Math.max(0, message.timestamp - prev.timestamp),\n\t\tmodelChanged: `${message.provider}/${message.model}` !== prev.modelKey,\n\t};\n}\n\nfunction asPreviousRequest(message: AssistantMessage, reportedCache: boolean): PreviousRequest | undefined {\n\tconst usage = message.usage;\n\tconst promptTokens = usage.input + usage.cacheRead + usage.cacheWrite;\n\tif (promptTokens <= 0) return undefined;\n\treturn {\n\t\tpromptTokens,\n\t\tmodelKey: `${message.provider}/${message.model}`,\n\t\ttimestamp: message.timestamp,\n\t\treportedCache: reportedCache || usage.cacheRead + usage.cacheWrite > 0,\n\t};\n}\n\nfunction scan(\n\tentries: SessionEntry[],\n\tmodels: ModelPriceSource,\n): { prev: PreviousRequest | undefined; totals: CacheWasteTotals; misses: Map<AssistantMessage, CacheMiss> } {\n\tlet prev: PreviousRequest | undefined;\n\tconst totals: CacheWasteTotals = { missedTokens: 0, missedCost: 0, missCount: 0 };\n\tconst misses = new Map<AssistantMessage, CacheMiss>();\n\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t// The context legitimately changed; the next turn's prompt is new content,\n\t\t\t// not re-billed content. Model switches are NOT exempt: they re-bill the\n\t\t\t// full prompt and should be counted.\n\t\t\tprev = undefined;\n\t\t\tcontinue;\n\t\t}\n\t\tif (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tconst miss = detectMiss(prev, entry.message, models);\n\t\t\tif (miss) {\n\t\t\t\ttotals.missedTokens += miss.missedTokens;\n\t\t\t\ttotals.missedCost += miss.missedCost;\n\t\t\t\ttotals.missCount += 1;\n\t\t\t\tmisses.set(entry.message, miss);\n\t\t\t}\n\t\t\tprev = asPreviousRequest(entry.message, prev?.reportedCache ?? false) ?? prev;\n\t\t}\n\t}\n\treturn { prev, totals, misses };\n}\n\n/**\n * Cumulative cache waste across a session: prompt tokens that should have been\n * cache reads (they were in the previous turn's prompt) but were re-billed.\n */\nexport function computeCacheWaste(entries: SessionEntry[], models: ModelPriceSource): CacheWasteTotals {\n\treturn scan(entries, models).totals;\n}\n\n/**\n * All counted cache misses across a session, keyed by the assistant message\n * (by reference) that paid for them. Used to re-derive transcript notices when\n * rebuilding the chat from entries (resume, post-compaction rebuild).\n */\nexport function collectCacheMisses(\n\tentries: SessionEntry[],\n\tmodels: ModelPriceSource,\n): Map<AssistantMessage, CacheMiss> {\n\treturn scan(entries, models).misses;\n}\n\n/**\n * Detect a cache miss on a just-completed assistant message.\n * `entries` must not yet contain `message` (message_end fires before persistence).\n */\nexport function detectCacheMiss(\n\tentries: SessionEntry[],\n\tmessage: AssistantMessage,\n\tmodels: ModelPriceSource,\n): CacheMiss | undefined {\n\treturn detectMiss(scan(entries, models).prev, message, models);\n}\n"]}
1
+ {"version":3,"file":"cache-stats.d.ts","sourceRoot":"","sources":["../../src/core/cache-stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAgB,CAAC;AAK1C,0DAA0D;AAC1D,MAAM,WAAW,SAAS;IACzB,qFAAqF;IACrF,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,YAAY,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GAAG,SAAS,CAAC;CACzF;AAmGD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAErG;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,MAAM,EAAE,gBAAgB,GACtB,GAAG,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAElC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,gBAAgB,GACtB,SAAS,GAAG,SAAS,CAEvB"}