@astralyn/pi 0.83.0 → 0.84.1

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 (768) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/dist/bun/cli.d.ts.map +1 -1
  3. package/dist/bun/cli.js.map +1 -1
  4. package/dist/bun/register-bedrock.d.ts.map +1 -1
  5. package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
  6. package/dist/bun/restore-sandbox-env.js.map +1 -1
  7. package/dist/cli/args.d.ts +2 -0
  8. package/dist/cli/args.d.ts.map +1 -1
  9. package/dist/cli/args.js +22 -3
  10. package/dist/cli/args.js.map +1 -1
  11. package/dist/cli/auth-check.d.ts +19 -0
  12. package/dist/cli/auth-check.d.ts.map +1 -0
  13. package/dist/cli/auth-check.js +50 -0
  14. package/dist/cli/auth-check.js.map +1 -0
  15. package/dist/cli/auth-command.d.ts +24 -0
  16. package/dist/cli/auth-command.d.ts.map +1 -0
  17. package/dist/cli/auth-command.js +104 -0
  18. package/dist/cli/auth-command.js.map +1 -0
  19. package/dist/cli/config-selector.d.ts.map +1 -1
  20. package/dist/cli/config-selector.js +2 -2
  21. package/dist/cli/config-selector.js.map +1 -1
  22. package/dist/cli/credential-print.d.ts +5 -15
  23. package/dist/cli/credential-print.d.ts.map +1 -1
  24. package/dist/cli/credential-print.js +42 -82
  25. package/dist/cli/credential-print.js.map +1 -1
  26. package/dist/cli/experimental/auth.d.ts +16 -0
  27. package/dist/cli/experimental/auth.d.ts.map +1 -0
  28. package/dist/cli/experimental/auth.js +13 -0
  29. package/dist/cli/experimental/auth.js.map +1 -0
  30. package/dist/cli/experimental/cli.d.ts +6 -0
  31. package/dist/cli/experimental/cli.d.ts.map +1 -0
  32. package/dist/cli/experimental/cli.js +5 -0
  33. package/dist/cli/experimental/cli.js.map +1 -0
  34. package/dist/cli/experimental/command-options.d.ts +17 -0
  35. package/dist/cli/experimental/command-options.d.ts.map +1 -0
  36. package/dist/cli/experimental/command-options.js +35 -0
  37. package/dist/cli/experimental/command-options.js.map +1 -0
  38. package/dist/cli/experimental/command.d.ts +63 -0
  39. package/dist/cli/experimental/command.d.ts.map +1 -0
  40. package/dist/cli/experimental/command.js +127 -0
  41. package/dist/cli/experimental/command.js.map +1 -0
  42. package/dist/cli/experimental/commands/client.d.ts +13 -0
  43. package/dist/cli/experimental/commands/client.d.ts.map +1 -0
  44. package/dist/cli/experimental/commands/client.js +25 -0
  45. package/dist/cli/experimental/commands/client.js.map +1 -0
  46. package/dist/cli/experimental/commands/pi.d.ts +15 -0
  47. package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
  48. package/dist/cli/experimental/commands/pi.js +28 -0
  49. package/dist/cli/experimental/commands/pi.js.map +1 -0
  50. package/dist/cli/experimental/commands/server.d.ts +13 -0
  51. package/dist/cli/experimental/commands/server.d.ts.map +1 -0
  52. package/dist/cli/experimental/commands/server.js +25 -0
  53. package/dist/cli/experimental/commands/server.js.map +1 -0
  54. package/dist/cli/experimental/transport-address.d.ts +10 -0
  55. package/dist/cli/experimental/transport-address.d.ts.map +1 -0
  56. package/dist/cli/experimental/transport-address.js +38 -0
  57. package/dist/cli/experimental/transport-address.js.map +1 -0
  58. package/dist/cli/file-processor.d.ts.map +1 -1
  59. package/dist/cli/file-processor.js.map +1 -1
  60. package/dist/cli/initial-message.d.ts +1 -1
  61. package/dist/cli/initial-message.d.ts.map +1 -1
  62. package/dist/cli/initial-message.js.map +1 -1
  63. package/dist/cli/list-models.d.ts +1 -1
  64. package/dist/cli/list-models.d.ts.map +1 -1
  65. package/dist/cli/list-models.js +2 -2
  66. package/dist/cli/list-models.js.map +1 -1
  67. package/dist/cli/project-trust.d.ts.map +1 -1
  68. package/dist/cli/project-trust.js.map +1 -1
  69. package/dist/cli/session-picker.d.ts.map +1 -1
  70. package/dist/cli/session-picker.js.map +1 -1
  71. package/dist/cli/startup-ui.d.ts +1 -1
  72. package/dist/cli/startup-ui.d.ts.map +1 -1
  73. package/dist/cli/startup-ui.js +2 -2
  74. package/dist/cli/startup-ui.js.map +1 -1
  75. package/dist/cli.d.ts.map +1 -1
  76. package/dist/cli.js +1 -0
  77. package/dist/cli.js.map +1 -1
  78. package/dist/client/index.d.ts +3 -0
  79. package/dist/client/index.d.ts.map +1 -0
  80. package/dist/client/index.js +3 -0
  81. package/dist/client/index.js.map +1 -0
  82. package/dist/client/remote-session.d.ts +53 -0
  83. package/dist/client/remote-session.d.ts.map +1 -0
  84. package/dist/client/remote-session.js +340 -0
  85. package/dist/client/remote-session.js.map +1 -0
  86. package/dist/client/transcript.d.ts +12 -0
  87. package/dist/client/transcript.d.ts.map +1 -0
  88. package/dist/client/transcript.js +98 -0
  89. package/dist/client/transcript.js.map +1 -0
  90. package/dist/config.d.ts.map +1 -1
  91. package/dist/config.js.map +1 -1
  92. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  93. package/dist/core/agent-session-runtime.js +0 -8
  94. package/dist/core/agent-session-runtime.js.map +1 -1
  95. package/dist/core/agent-session-services.d.ts +1 -0
  96. package/dist/core/agent-session-services.d.ts.map +1 -1
  97. package/dist/core/agent-session-services.js +1 -0
  98. package/dist/core/agent-session-services.js.map +1 -1
  99. package/dist/core/agent-session.d.ts +30 -10
  100. package/dist/core/agent-session.d.ts.map +1 -1
  101. package/dist/core/agent-session.js +177 -187
  102. package/dist/core/agent-session.js.map +1 -1
  103. package/dist/core/auth-guidance.d.ts.map +1 -1
  104. package/dist/core/auth-guidance.js.map +1 -1
  105. package/dist/core/auth-storage.d.ts +25 -9
  106. package/dist/core/auth-storage.d.ts.map +1 -1
  107. package/dist/core/auth-storage.js +235 -42
  108. package/dist/core/auth-storage.js.map +1 -1
  109. package/dist/core/bash-executor.d.ts.map +1 -1
  110. package/dist/core/bash-executor.js.map +1 -1
  111. package/dist/core/cache-stats.d.ts.map +1 -1
  112. package/dist/core/cache-stats.js.map +1 -1
  113. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  114. package/dist/core/compaction/branch-summarization.js.map +1 -1
  115. package/dist/core/compaction/compaction.d.ts.map +1 -1
  116. package/dist/core/compaction/compaction.js.map +1 -1
  117. package/dist/core/compaction/index.d.ts.map +1 -1
  118. package/dist/core/compaction/utils.d.ts.map +1 -1
  119. package/dist/core/compaction/utils.js.map +1 -1
  120. package/dist/core/defaults.d.ts.map +1 -1
  121. package/dist/core/diagnostics.d.ts.map +1 -1
  122. package/dist/core/event-bus.d.ts.map +1 -1
  123. package/dist/core/event-bus.js.map +1 -1
  124. package/dist/core/exec.d.ts.map +1 -1
  125. package/dist/core/exec.js.map +1 -1
  126. package/dist/core/experimental.d.ts.map +1 -1
  127. package/dist/core/experimental.js.map +1 -1
  128. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  129. package/dist/core/export-html/ansi-to-html.js.map +1 -1
  130. package/dist/core/export-html/index.d.ts.map +1 -1
  131. package/dist/core/export-html/index.js.map +1 -1
  132. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  133. package/dist/core/export-html/tool-renderer.js.map +1 -1
  134. package/dist/core/extensions/index.d.ts +1 -1
  135. package/dist/core/extensions/index.d.ts.map +1 -1
  136. package/dist/core/extensions/index.js.map +1 -1
  137. package/dist/core/extensions/loader.d.ts.map +1 -1
  138. package/dist/core/extensions/loader.js +43 -20
  139. package/dist/core/extensions/loader.js.map +1 -1
  140. package/dist/core/extensions/runner.d.ts +2 -1
  141. package/dist/core/extensions/runner.d.ts.map +1 -1
  142. package/dist/core/extensions/runner.js +25 -29
  143. package/dist/core/extensions/runner.js.map +1 -1
  144. package/dist/core/extensions/types.d.ts +26 -3
  145. package/dist/core/extensions/types.d.ts.map +1 -1
  146. package/dist/core/extensions/types.js.map +1 -1
  147. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  148. package/dist/core/extensions/wrapper.js.map +1 -1
  149. package/dist/core/footer-data-provider.d.ts.map +1 -1
  150. package/dist/core/footer-data-provider.js +17 -18
  151. package/dist/core/footer-data-provider.js.map +1 -1
  152. package/dist/core/http-dispatcher.d.ts.map +1 -1
  153. package/dist/core/http-dispatcher.js +5 -0
  154. package/dist/core/http-dispatcher.js.map +1 -1
  155. package/dist/core/index.d.ts.map +1 -1
  156. package/dist/core/keybindings.d.ts +165 -125
  157. package/dist/core/keybindings.d.ts.map +1 -1
  158. package/dist/core/keybindings.js +0 -1
  159. package/dist/core/keybindings.js.map +1 -1
  160. package/dist/core/messages.d.ts.map +1 -1
  161. package/dist/core/messages.js.map +1 -1
  162. package/dist/core/model-config.d.ts +37 -13
  163. package/dist/core/model-config.d.ts.map +1 -1
  164. package/dist/core/model-config.js +4 -2
  165. package/dist/core/model-config.js.map +1 -1
  166. package/dist/core/model-registry.d.ts +5 -3
  167. package/dist/core/model-registry.d.ts.map +1 -1
  168. package/dist/core/model-registry.js +13 -11
  169. package/dist/core/model-registry.js.map +1 -1
  170. package/dist/core/model-resolver.d.ts +4 -3
  171. package/dist/core/model-resolver.d.ts.map +1 -1
  172. package/dist/core/model-resolver.js +42 -10
  173. package/dist/core/model-resolver.js.map +1 -1
  174. package/dist/core/model-runtime.d.ts +30 -13
  175. package/dist/core/model-runtime.d.ts.map +1 -1
  176. package/dist/core/model-runtime.js +241 -91
  177. package/dist/core/model-runtime.js.map +1 -1
  178. package/dist/core/models-store.d.ts +12 -7
  179. package/dist/core/models-store.d.ts.map +1 -1
  180. package/dist/core/models-store.js +84 -16
  181. package/dist/core/models-store.js.map +1 -1
  182. package/dist/core/output-guard.d.ts.map +1 -1
  183. package/dist/core/output-guard.js.map +1 -1
  184. package/dist/core/package-manager.d.ts +4 -1
  185. package/dist/core/package-manager.d.ts.map +1 -1
  186. package/dist/core/package-manager.js +63 -42
  187. package/dist/core/package-manager.js.map +1 -1
  188. package/dist/core/pi-manifest.d.ts +8 -0
  189. package/dist/core/pi-manifest.d.ts.map +1 -0
  190. package/dist/core/pi-manifest.js +25 -0
  191. package/dist/core/pi-manifest.js.map +1 -0
  192. package/dist/core/project-trust.d.ts.map +1 -1
  193. package/dist/core/project-trust.js.map +1 -1
  194. package/dist/core/prompt-templates.d.ts.map +1 -1
  195. package/dist/core/prompt-templates.js.map +1 -1
  196. package/dist/core/provider-attribution.d.ts.map +1 -1
  197. package/dist/core/provider-attribution.js.map +1 -1
  198. package/dist/core/provider-composer.d.ts +4 -1
  199. package/dist/core/provider-composer.d.ts.map +1 -1
  200. package/dist/core/provider-composer.js +36 -15
  201. package/dist/core/provider-composer.js.map +1 -1
  202. package/dist/core/radius.d.ts.map +1 -1
  203. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  204. package/dist/core/remote-catalog-provider.js +73 -67
  205. package/dist/core/remote-catalog-provider.js.map +1 -1
  206. package/dist/core/resolve-config-value.d.ts.map +1 -1
  207. package/dist/core/resolve-config-value.js.map +1 -1
  208. package/dist/core/resource-loader.d.ts.map +1 -1
  209. package/dist/core/resource-loader.js +2 -46
  210. package/dist/core/resource-loader.js.map +1 -1
  211. package/dist/core/runtime-credentials.d.ts +5 -5
  212. package/dist/core/runtime-credentials.d.ts.map +1 -1
  213. package/dist/core/runtime-credentials.js +12 -10
  214. package/dist/core/runtime-credentials.js.map +1 -1
  215. package/dist/core/sdk.d.ts.map +1 -1
  216. package/dist/core/sdk.js.map +1 -1
  217. package/dist/core/session-cwd.d.ts.map +1 -1
  218. package/dist/core/session-cwd.js +0 -1
  219. package/dist/core/session-cwd.js.map +1 -1
  220. package/dist/core/session-manager.d.ts.map +1 -1
  221. package/dist/core/session-manager.js +10 -12
  222. package/dist/core/session-manager.js.map +1 -1
  223. package/dist/core/settings-manager.d.ts +12 -0
  224. package/dist/core/settings-manager.d.ts.map +1 -1
  225. package/dist/core/settings-manager.js +47 -33
  226. package/dist/core/settings-manager.js.map +1 -1
  227. package/dist/core/skills.d.ts.map +1 -1
  228. package/dist/core/skills.js.map +1 -1
  229. package/dist/core/slash-commands.d.ts.map +1 -1
  230. package/dist/core/source-info.d.ts.map +1 -1
  231. package/dist/core/source-info.js.map +1 -1
  232. package/dist/core/system-prompt.d.ts.map +1 -1
  233. package/dist/core/system-prompt.js.map +1 -1
  234. package/dist/core/telemetry.d.ts.map +1 -1
  235. package/dist/core/telemetry.js.map +1 -1
  236. package/dist/core/timings.d.ts.map +1 -1
  237. package/dist/core/timings.js.map +1 -1
  238. package/dist/core/tools/bash.d.ts +4 -0
  239. package/dist/core/tools/bash.d.ts.map +1 -1
  240. package/dist/core/tools/bash.js +18 -14
  241. package/dist/core/tools/bash.js.map +1 -1
  242. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  243. package/dist/core/tools/edit-diff.js.map +1 -1
  244. package/dist/core/tools/edit.d.ts +4 -0
  245. package/dist/core/tools/edit.d.ts.map +1 -1
  246. package/dist/core/tools/edit.js +15 -10
  247. package/dist/core/tools/edit.js.map +1 -1
  248. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  249. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  250. package/dist/core/tools/find.d.ts +7 -0
  251. package/dist/core/tools/find.d.ts.map +1 -1
  252. package/dist/core/tools/find.js +18 -17
  253. package/dist/core/tools/find.js.map +1 -1
  254. package/dist/core/tools/grep.d.ts +4 -0
  255. package/dist/core/tools/grep.d.ts.map +1 -1
  256. package/dist/core/tools/grep.js +5 -1
  257. package/dist/core/tools/grep.js.map +1 -1
  258. package/dist/core/tools/index.d.ts.map +1 -1
  259. package/dist/core/tools/index.js.map +1 -1
  260. package/dist/core/tools/ls.d.ts +4 -0
  261. package/dist/core/tools/ls.d.ts.map +1 -1
  262. package/dist/core/tools/ls.js +5 -1
  263. package/dist/core/tools/ls.js.map +1 -1
  264. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  265. package/dist/core/tools/output-accumulator.js +12 -18
  266. package/dist/core/tools/output-accumulator.js.map +1 -1
  267. package/dist/core/tools/path-utils.d.ts.map +1 -1
  268. package/dist/core/tools/path-utils.js.map +1 -1
  269. package/dist/core/tools/read.d.ts +4 -0
  270. package/dist/core/tools/read.d.ts.map +1 -1
  271. package/dist/core/tools/read.js +7 -3
  272. package/dist/core/tools/read.js.map +1 -1
  273. package/dist/core/tools/render-utils.d.ts.map +1 -1
  274. package/dist/core/tools/render-utils.js.map +1 -1
  275. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  276. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  277. package/dist/core/tools/truncate.d.ts.map +1 -1
  278. package/dist/core/tools/truncate.js.map +1 -1
  279. package/dist/core/tools/write.d.ts +4 -0
  280. package/dist/core/tools/write.d.ts.map +1 -1
  281. package/dist/core/tools/write.js +6 -3
  282. package/dist/core/tools/write.js.map +1 -1
  283. package/dist/core/trust-manager.d.ts.map +1 -1
  284. package/dist/core/trust-manager.js +0 -1
  285. package/dist/core/trust-manager.js.map +1 -1
  286. package/dist/core/usage-totals.d.ts.map +1 -1
  287. package/dist/core/usage-totals.js.map +1 -1
  288. package/dist/extensions/biu/index.d.ts +19 -0
  289. package/dist/extensions/biu/index.d.ts.map +1 -0
  290. package/dist/extensions/biu/index.js +350 -0
  291. package/dist/extensions/biu/index.js.map +1 -0
  292. package/dist/extensions/biu/prompts.d.ts +26 -0
  293. package/dist/extensions/biu/prompts.d.ts.map +1 -0
  294. package/dist/extensions/biu/prompts.js +260 -0
  295. package/dist/extensions/biu/prompts.js.map +1 -0
  296. package/dist/extensions/biu/workspace.d.ts +122 -0
  297. package/dist/extensions/biu/workspace.d.ts.map +1 -0
  298. package/dist/extensions/biu/workspace.js +404 -0
  299. package/dist/extensions/biu/workspace.js.map +1 -0
  300. package/dist/extensions/deepwiki/client.d.ts.map +1 -1
  301. package/dist/extensions/deepwiki/client.js.map +1 -1
  302. package/dist/extensions/deepwiki/constants.d.ts.map +1 -1
  303. package/dist/extensions/deepwiki/constants.js.map +1 -1
  304. package/dist/extensions/deepwiki/contents.d.ts.map +1 -1
  305. package/dist/extensions/deepwiki/contents.js.map +1 -1
  306. package/dist/extensions/deepwiki/execute.d.ts.map +1 -1
  307. package/dist/extensions/deepwiki/execute.js.map +1 -1
  308. package/dist/extensions/deepwiki/http.d.ts.map +1 -1
  309. package/dist/extensions/deepwiki/http.js.map +1 -1
  310. package/dist/extensions/deepwiki/index.d.ts.map +1 -1
  311. package/dist/extensions/deepwiki/index.js.map +1 -1
  312. package/dist/extensions/deepwiki/render.d.ts.map +1 -1
  313. package/dist/extensions/deepwiki/render.js.map +1 -1
  314. package/dist/extensions/deepwiki/schema.d.ts +1 -1
  315. package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
  316. package/dist/extensions/deepwiki/schema.js.map +1 -1
  317. package/dist/extensions/index.d.ts.map +1 -1
  318. package/dist/extensions/index.js +2 -0
  319. package/dist/extensions/index.js.map +1 -1
  320. package/dist/extensions/llama/client.d.ts.map +1 -1
  321. package/dist/extensions/llama/client.js +0 -2
  322. package/dist/extensions/llama/client.js.map +1 -1
  323. package/dist/extensions/llama/huggingface.d.ts.map +1 -1
  324. package/dist/extensions/llama/huggingface.js +0 -2
  325. package/dist/extensions/llama/huggingface.js.map +1 -1
  326. package/dist/extensions/llama/index.d.ts.map +1 -1
  327. package/dist/extensions/llama/index.js +11 -2
  328. package/dist/extensions/llama/index.js.map +1 -1
  329. package/dist/extensions/llama/provider.d.ts.map +1 -1
  330. package/dist/extensions/llama/provider.js +21 -7
  331. package/dist/extensions/llama/provider.js.map +1 -1
  332. package/dist/extensions/llama/ui.d.ts.map +1 -1
  333. package/dist/extensions/llama/ui.js +12 -28
  334. package/dist/extensions/llama/ui.js.map +1 -1
  335. package/dist/extensions/question/constants.d.ts.map +1 -1
  336. package/dist/extensions/question/constants.js.map +1 -1
  337. package/dist/extensions/question/dialog-primitives.d.ts.map +1 -1
  338. package/dist/extensions/question/dialog-primitives.js.map +1 -1
  339. package/dist/extensions/question/dialog.d.ts.map +1 -1
  340. package/dist/extensions/question/dialog.js.map +1 -1
  341. package/dist/extensions/question/index.d.ts.map +1 -1
  342. package/dist/extensions/question/index.js.map +1 -1
  343. package/dist/extensions/question/limits.d.ts.map +1 -1
  344. package/dist/extensions/question/render-cache.d.ts.map +1 -1
  345. package/dist/extensions/question/render-cache.js +3 -4
  346. package/dist/extensions/question/render-cache.js.map +1 -1
  347. package/dist/extensions/question/render.d.ts.map +1 -1
  348. package/dist/extensions/question/render.js.map +1 -1
  349. package/dist/extensions/question/results.d.ts.map +1 -1
  350. package/dist/extensions/question/results.js.map +1 -1
  351. package/dist/extensions/question/schema.d.ts.map +1 -1
  352. package/dist/extensions/question/schema.js.map +1 -1
  353. package/dist/extensions/question/state.d.ts.map +1 -1
  354. package/dist/extensions/question/state.js.map +1 -1
  355. package/dist/extensions/question/types.d.ts.map +1 -1
  356. package/dist/extensions/rewind/anchor.d.ts.map +1 -1
  357. package/dist/extensions/rewind/anchor.js.map +1 -1
  358. package/dist/extensions/rewind/config.d.ts.map +1 -1
  359. package/dist/extensions/rewind/config.js.map +1 -1
  360. package/dist/extensions/rewind/engine.d.ts.map +1 -1
  361. package/dist/extensions/rewind/engine.js.map +1 -1
  362. package/dist/extensions/rewind/gc.d.ts.map +1 -1
  363. package/dist/extensions/rewind/gc.js.map +1 -1
  364. package/dist/extensions/rewind/index.d.ts.map +1 -1
  365. package/dist/extensions/rewind/index.js.map +1 -1
  366. package/dist/extensions/rewind/menu.d.ts.map +1 -1
  367. package/dist/extensions/rewind/menu.js.map +1 -1
  368. package/dist/extensions/rewind/paths.d.ts.map +1 -1
  369. package/dist/extensions/rewind/paths.js.map +1 -1
  370. package/dist/extensions/rewind/restore.d.ts.map +1 -1
  371. package/dist/extensions/rewind/restore.js.map +1 -1
  372. package/dist/extensions/rewind/snapshot.d.ts.map +1 -1
  373. package/dist/extensions/rewind/snapshot.js.map +1 -1
  374. package/dist/extensions/rewind/storage.d.ts.map +1 -1
  375. package/dist/extensions/rewind/storage.js.map +1 -1
  376. package/dist/extensions/rewind/text.d.ts.map +1 -1
  377. package/dist/extensions/rewind/text.js.map +1 -1
  378. package/dist/extensions/rewind/tool-path.d.ts.map +1 -1
  379. package/dist/extensions/rewind/tool-path.js.map +1 -1
  380. package/dist/extensions/router/constants.d.ts +3 -0
  381. package/dist/extensions/router/constants.d.ts.map +1 -1
  382. package/dist/extensions/router/constants.js +3 -0
  383. package/dist/extensions/router/constants.js.map +1 -1
  384. package/dist/extensions/router/dialog.d.ts +14 -7
  385. package/dist/extensions/router/dialog.d.ts.map +1 -1
  386. package/dist/extensions/router/dialog.js +70 -132
  387. package/dist/extensions/router/dialog.js.map +1 -1
  388. package/dist/extensions/router/index.d.ts.map +1 -1
  389. package/dist/extensions/router/index.js.map +1 -1
  390. package/dist/extensions/router/presets.d.ts +8 -3
  391. package/dist/extensions/router/presets.d.ts.map +1 -1
  392. package/dist/extensions/router/presets.js +33 -17
  393. package/dist/extensions/router/presets.js.map +1 -1
  394. package/dist/extensions/router/probe.d.ts.map +1 -1
  395. package/dist/extensions/router/probe.js.map +1 -1
  396. package/dist/extensions/router/register.d.ts +3 -3
  397. package/dist/extensions/router/register.d.ts.map +1 -1
  398. package/dist/extensions/router/register.js.map +1 -1
  399. package/dist/extensions/router/store.d.ts.map +1 -1
  400. package/dist/extensions/router/store.js.map +1 -1
  401. package/dist/extensions/router/stream.d.ts.map +1 -1
  402. package/dist/extensions/router/stream.js.map +1 -1
  403. package/dist/extensions/router/types.d.ts.map +1 -1
  404. package/dist/extensions/router/ui.d.ts +11 -2
  405. package/dist/extensions/router/ui.d.ts.map +1 -1
  406. package/dist/extensions/router/ui.js +316 -171
  407. package/dist/extensions/router/ui.js.map +1 -1
  408. package/dist/extensions/statusline/index.d.ts.map +1 -1
  409. package/dist/extensions/statusline/index.js +17 -9
  410. package/dist/extensions/statusline/index.js.map +1 -1
  411. package/dist/extensions/subagent/activity.d.ts.map +1 -1
  412. package/dist/extensions/subagent/activity.js.map +1 -1
  413. package/dist/extensions/subagent/agents.d.ts.map +1 -1
  414. package/dist/extensions/subagent/agents.js.map +1 -1
  415. package/dist/extensions/subagent/constants.d.ts.map +1 -1
  416. package/dist/extensions/subagent/index.d.ts +3 -0
  417. package/dist/extensions/subagent/index.d.ts.map +1 -1
  418. package/dist/extensions/subagent/index.js +83 -12
  419. package/dist/extensions/subagent/index.js.map +1 -1
  420. package/dist/extensions/subagent/picker.d.ts.map +1 -1
  421. package/dist/extensions/subagent/picker.js +2 -9
  422. package/dist/extensions/subagent/picker.js.map +1 -1
  423. package/dist/extensions/subagent/render.d.ts.map +1 -1
  424. package/dist/extensions/subagent/render.js +33 -9
  425. package/dist/extensions/subagent/render.js.map +1 -1
  426. package/dist/extensions/subagent/resolve.d.ts.map +1 -1
  427. package/dist/extensions/subagent/resolve.js.map +1 -1
  428. package/dist/extensions/subagent/retry.d.ts.map +1 -1
  429. package/dist/extensions/subagent/retry.js.map +1 -1
  430. package/dist/extensions/subagent/runner.d.ts +2 -1
  431. package/dist/extensions/subagent/runner.d.ts.map +1 -1
  432. package/dist/extensions/subagent/runner.js +10 -12
  433. package/dist/extensions/subagent/runner.js.map +1 -1
  434. package/dist/extensions/subagent/schema.d.ts.map +1 -1
  435. package/dist/extensions/subagent/schema.js.map +1 -1
  436. package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
  437. package/dist/extensions/subagent/sdk-runner.js +41 -1
  438. package/dist/extensions/subagent/sdk-runner.js.map +1 -1
  439. package/dist/extensions/subagent/settings.d.ts.map +1 -1
  440. package/dist/extensions/subagent/settings.js +46 -36
  441. package/dist/extensions/subagent/settings.js.map +1 -1
  442. package/dist/extensions/subagent/types.d.ts +0 -1
  443. package/dist/extensions/subagent/types.d.ts.map +1 -1
  444. package/dist/extensions/subagent/types.js.map +1 -1
  445. package/dist/extensions/todo/constants.d.ts.map +1 -1
  446. package/dist/extensions/todo/constants.js.map +1 -1
  447. package/dist/extensions/todo/index.d.ts.map +1 -1
  448. package/dist/extensions/todo/index.js.map +1 -1
  449. package/dist/extensions/todo/overlay.d.ts.map +1 -1
  450. package/dist/extensions/todo/overlay.js +6 -10
  451. package/dist/extensions/todo/overlay.js.map +1 -1
  452. package/dist/extensions/todo/schema.d.ts +2 -2
  453. package/dist/extensions/todo/schema.d.ts.map +1 -1
  454. package/dist/extensions/todo/state.d.ts.map +1 -1
  455. package/dist/extensions/todo/state.js.map +1 -1
  456. package/dist/extensions/todo/view.d.ts.map +1 -1
  457. package/dist/extensions/todo/view.js.map +1 -1
  458. package/dist/index.d.ts +4 -4
  459. package/dist/index.d.ts.map +1 -1
  460. package/dist/index.js +1 -1
  461. package/dist/index.js.map +1 -1
  462. package/dist/main.d.ts.map +1 -1
  463. package/dist/main.js +70 -25
  464. package/dist/main.js.map +1 -1
  465. package/dist/migrations.d.ts.map +1 -1
  466. package/dist/migrations.js.map +1 -1
  467. package/dist/modes/index.d.ts +1 -0
  468. package/dist/modes/index.d.ts.map +1 -1
  469. package/dist/modes/index.js.map +1 -1
  470. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  471. package/dist/modes/interactive/components/armin.js +6 -10
  472. package/dist/modes/interactive/components/armin.js.map +1 -1
  473. package/dist/modes/interactive/components/assistant-message.d.ts +5 -2
  474. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  475. package/dist/modes/interactive/components/assistant-message.js +13 -11
  476. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  477. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  478. package/dist/modes/interactive/components/bash-execution.js +4 -10
  479. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  480. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  481. package/dist/modes/interactive/components/bordered-loader.js +0 -3
  482. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  483. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  484. package/dist/modes/interactive/components/branch-summary-message.js +1 -3
  485. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  486. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  487. package/dist/modes/interactive/components/compaction-summary-message.js +1 -3
  488. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  489. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  490. package/dist/modes/interactive/components/config-selector.js +5 -22
  491. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  492. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  493. package/dist/modes/interactive/components/countdown-timer.js +1 -7
  494. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  495. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  496. package/dist/modes/interactive/components/custom-editor.js +8 -8
  497. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  498. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  499. package/dist/modes/interactive/components/custom-entry.js +1 -4
  500. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  501. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  502. package/dist/modes/interactive/components/custom-message.js +1 -7
  503. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  504. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  505. package/dist/modes/interactive/components/daxnuts.js +6 -8
  506. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  507. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  508. package/dist/modes/interactive/components/diff.js.map +1 -1
  509. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  510. package/dist/modes/interactive/components/dynamic-border.js +0 -1
  511. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  512. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
  513. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
  514. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  515. package/dist/modes/interactive/components/extension-editor.js +1 -7
  516. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  517. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  518. package/dist/modes/interactive/components/extension-input.js +2 -8
  519. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  520. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  521. package/dist/modes/interactive/components/extension-selector.js +1 -9
  522. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  523. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  524. package/dist/modes/interactive/components/first-time-setup.js +2 -4
  525. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  526. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  527. package/dist/modes/interactive/components/footer.js +2 -4
  528. package/dist/modes/interactive/components/footer.js.map +1 -1
  529. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  530. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  531. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  532. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  533. package/dist/modes/interactive/components/login-dialog.js +3 -9
  534. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  535. package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
  536. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  537. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  538. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  539. package/dist/modes/interactive/components/mermaid.d.ts +11 -0
  540. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  541. package/dist/modes/interactive/components/mermaid.js +75 -0
  542. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  543. package/dist/modes/interactive/components/model-selector.d.ts +1 -1
  544. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  545. package/dist/modes/interactive/components/model-selector.js +28 -29
  546. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  547. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  548. package/dist/modes/interactive/components/oauth-selector.js +3 -11
  549. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  550. package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
  551. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  552. package/dist/modes/interactive/components/scoped-models-selector.js +34 -13
  553. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  554. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  555. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  556. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  557. package/dist/modes/interactive/components/session-selector.js +35 -60
  558. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  559. package/dist/modes/interactive/components/settings-selector.d.ts +8 -2
  560. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  561. package/dist/modes/interactive/components/settings-selector.js +30 -14
  562. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  563. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  564. package/dist/modes/interactive/components/show-images-selector.js +0 -1
  565. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  566. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  567. package/dist/modes/interactive/components/skill-invocation-message.js +1 -3
  568. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  569. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  570. package/dist/modes/interactive/components/status-indicator.js +0 -2
  571. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  572. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  573. package/dist/modes/interactive/components/theme-selector.js +0 -2
  574. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  575. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  576. package/dist/modes/interactive/components/thinking-selector.js +0 -1
  577. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  578. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  579. package/dist/modes/interactive/components/tool-execution.js +18 -36
  580. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  581. package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
  582. package/dist/modes/interactive/components/tool-group.js +2 -3
  583. package/dist/modes/interactive/components/tool-group.js.map +1 -1
  584. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  585. package/dist/modes/interactive/components/tree-selector.js +19 -39
  586. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  587. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
  588. package/dist/modes/interactive/components/trust-selector.js +0 -6
  589. package/dist/modes/interactive/components/trust-selector.js.map +1 -1
  590. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  591. package/dist/modes/interactive/components/user-message-selector.js +3 -6
  592. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  593. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  594. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  595. package/dist/modes/interactive/components/user-message.js +8 -5
  596. package/dist/modes/interactive/components/user-message.js.map +1 -1
  597. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  598. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  599. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  600. package/dist/modes/interactive/external-editor.js.map +1 -1
  601. package/dist/modes/interactive/interactive-mode.d.ts +46 -5
  602. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  603. package/dist/modes/interactive/interactive-mode.js +538 -282
  604. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  605. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  606. package/dist/modes/interactive/model-search.js.map +1 -1
  607. package/dist/modes/interactive/theme/dark.json +1 -0
  608. package/dist/modes/interactive/theme/light.json +1 -0
  609. package/dist/modes/interactive/theme/theme-controller.d.ts +3 -0
  610. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  611. package/dist/modes/interactive/theme/theme-controller.js +11 -8
  612. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  613. package/dist/modes/interactive/theme/theme-schema.json +5 -1
  614. package/dist/modes/interactive/theme/theme.d.ts +4 -4
  615. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  616. package/dist/modes/interactive/theme/theme.js +24 -12
  617. package/dist/modes/interactive/theme/theme.js.map +1 -1
  618. package/dist/modes/json-event.d.ts +28 -0
  619. package/dist/modes/json-event.d.ts.map +1 -0
  620. package/dist/modes/json-event.js +12 -0
  621. package/dist/modes/json-event.js.map +1 -0
  622. package/dist/modes/print-mode.d.ts.map +1 -1
  623. package/dist/modes/print-mode.js +12 -2
  624. package/dist/modes/print-mode.js.map +1 -1
  625. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  626. package/dist/modes/rpc/jsonl.js.map +1 -1
  627. package/dist/modes/rpc/rpc-client.d.ts +5 -4
  628. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  629. package/dist/modes/rpc/rpc-client.js +7 -8
  630. package/dist/modes/rpc/rpc-client.js.map +1 -1
  631. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  632. package/dist/modes/rpc/rpc-mode.js +4 -3
  633. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  634. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  635. package/dist/package-manager-cli.d.ts.map +1 -1
  636. package/dist/package-manager-cli.js +11 -9
  637. package/dist/package-manager-cli.js.map +1 -1
  638. package/dist/rpc-entry.d.ts.map +1 -1
  639. package/dist/rpc-entry.js +1 -0
  640. package/dist/rpc-entry.js.map +1 -1
  641. package/dist/server/create-harness.d.ts +26 -0
  642. package/dist/server/create-harness.d.ts.map +1 -0
  643. package/dist/server/create-harness.js +104 -0
  644. package/dist/server/create-harness.js.map +1 -0
  645. package/dist/utils/abort.d.ts +5 -0
  646. package/dist/utils/abort.d.ts.map +1 -0
  647. package/dist/utils/abort.js +48 -0
  648. package/dist/utils/abort.js.map +1 -0
  649. package/dist/utils/ansi.d.ts.map +1 -1
  650. package/dist/utils/ansi.js.map +1 -1
  651. package/dist/utils/changelog.d.ts.map +1 -1
  652. package/dist/utils/changelog.js.map +1 -1
  653. package/dist/utils/child-process.d.ts.map +1 -1
  654. package/dist/utils/child-process.js.map +1 -1
  655. package/dist/utils/clipboard-image.d.ts.map +1 -1
  656. package/dist/utils/clipboard-image.js.map +1 -1
  657. package/dist/utils/clipboard-native.d.ts.map +1 -1
  658. package/dist/utils/clipboard-native.js.map +1 -1
  659. package/dist/utils/clipboard.d.ts +1 -1
  660. package/dist/utils/clipboard.d.ts.map +1 -1
  661. package/dist/utils/clipboard.js +22 -2
  662. package/dist/utils/clipboard.js.map +1 -1
  663. package/dist/utils/coalescing-terminal.d.ts +20 -4
  664. package/dist/utils/coalescing-terminal.d.ts.map +1 -1
  665. package/dist/utils/coalescing-terminal.js +48 -12
  666. package/dist/utils/coalescing-terminal.js.map +1 -1
  667. package/dist/utils/deprecation.d.ts.map +1 -1
  668. package/dist/utils/deprecation.js.map +1 -1
  669. package/dist/utils/exif-orientation.d.ts.map +1 -1
  670. package/dist/utils/exif-orientation.js.map +1 -1
  671. package/dist/utils/frontmatter.d.ts.map +1 -1
  672. package/dist/utils/frontmatter.js.map +1 -1
  673. package/dist/utils/fs-watch.d.ts.map +1 -1
  674. package/dist/utils/fs-watch.js.map +1 -1
  675. package/dist/utils/git.d.ts.map +1 -1
  676. package/dist/utils/git.js.map +1 -1
  677. package/dist/utils/html.d.ts.map +1 -1
  678. package/dist/utils/html.js.map +1 -1
  679. package/dist/utils/image-convert.d.ts.map +1 -1
  680. package/dist/utils/image-convert.js.map +1 -1
  681. package/dist/utils/image-process.d.ts.map +1 -1
  682. package/dist/utils/image-process.js.map +1 -1
  683. package/dist/utils/image-resize-core.d.ts.map +1 -1
  684. package/dist/utils/image-resize-core.js.map +1 -1
  685. package/dist/utils/image-resize-worker.d.ts.map +1 -1
  686. package/dist/utils/image-resize-worker.js.map +1 -1
  687. package/dist/utils/image-resize.d.ts.map +1 -1
  688. package/dist/utils/image-resize.js.map +1 -1
  689. package/dist/utils/json.d.ts.map +1 -1
  690. package/dist/utils/json.js.map +1 -1
  691. package/dist/utils/management-http.d.ts +23 -0
  692. package/dist/utils/management-http.d.ts.map +1 -0
  693. package/dist/utils/management-http.js +50 -0
  694. package/dist/utils/management-http.js.map +1 -0
  695. package/dist/utils/mime.d.ts.map +1 -1
  696. package/dist/utils/mime.js.map +1 -1
  697. package/dist/utils/open-browser.d.ts.map +1 -1
  698. package/dist/utils/open-browser.js.map +1 -1
  699. package/dist/utils/paths.d.ts +3 -0
  700. package/dist/utils/paths.d.ts.map +1 -1
  701. package/dist/utils/paths.js +23 -1
  702. package/dist/utils/paths.js.map +1 -1
  703. package/dist/utils/photon.d.ts.map +1 -1
  704. package/dist/utils/photon.js.map +1 -1
  705. package/dist/utils/pi-user-agent.d.ts.map +1 -1
  706. package/dist/utils/pi-user-agent.js.map +1 -1
  707. package/dist/utils/shell.d.ts.map +1 -1
  708. package/dist/utils/shell.js.map +1 -1
  709. package/dist/utils/sleep.d.ts.map +1 -1
  710. package/dist/utils/sleep.js.map +1 -1
  711. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  712. package/dist/utils/syntax-highlight.js.map +1 -1
  713. package/dist/utils/tool-result-images.d.ts +19 -0
  714. package/dist/utils/tool-result-images.d.ts.map +1 -0
  715. package/dist/utils/tool-result-images.js +45 -0
  716. package/dist/utils/tool-result-images.js.map +1 -0
  717. package/dist/utils/tools-manager.d.ts.map +1 -1
  718. package/dist/utils/tools-manager.js +4 -6
  719. package/dist/utils/tools-manager.js.map +1 -1
  720. package/dist/utils/version-check.d.ts +4 -0
  721. package/dist/utils/version-check.d.ts.map +1 -1
  722. package/dist/utils/version-check.js +20 -2
  723. package/dist/utils/version-check.js.map +1 -1
  724. package/dist/utils/windows-self-update.d.ts.map +1 -1
  725. package/dist/utils/windows-self-update.js.map +1 -1
  726. package/docs/bundled/README.md +1 -0
  727. package/docs/bundled/extensions/biu.md +63 -0
  728. package/docs/bundled/extensions/router.md +20 -14
  729. package/docs/bundled/extensions/statusline.md +7 -5
  730. package/docs/custom-provider.md +123 -2
  731. package/docs/development.md +83 -0
  732. package/docs/docs.json +8 -4
  733. package/docs/extensions.md +30 -5
  734. package/docs/json.md +21 -2
  735. package/docs/keybindings.md +46 -14
  736. package/docs/models.md +21 -3
  737. package/docs/providers.md +9 -1
  738. package/docs/quickstart.md +2 -0
  739. package/docs/rpc.md +12 -11
  740. package/docs/sdk.md +46 -0
  741. package/docs/security.md +1 -1
  742. package/docs/settings.md +4 -1
  743. package/docs/themes.md +7 -5
  744. package/docs/usage.md +8 -0
  745. package/examples/extensions/custom-compaction.ts +1 -16
  746. package/examples/extensions/custom-provider-anthropic/index.ts +2 -1
  747. package/examples/extensions/custom-provider-anthropic/package-lock.json +5 -5
  748. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  749. package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -1
  750. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  751. package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
  752. package/examples/extensions/dynamic-resources/dynamic.json +1 -1
  753. package/examples/extensions/gondolin/package-lock.json +2 -2
  754. package/examples/extensions/gondolin/package.json +1 -1
  755. package/examples/extensions/handoff.ts +2 -11
  756. package/examples/extensions/qna.ts +3 -7
  757. package/examples/extensions/sandbox/package-lock.json +3 -3
  758. package/examples/extensions/sandbox/package.json +1 -1
  759. package/examples/extensions/summarize.ts +8 -18
  760. package/examples/extensions/with-deps/package-lock.json +4 -4
  761. package/examples/extensions/with-deps/package.json +1 -1
  762. package/examples/rpc-extension-ui.ts +11 -2
  763. package/examples/sdk/02-custom-model.ts +1 -2
  764. package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
  765. package/examples/sdk/12-full-control.ts +1 -1
  766. package/examples/sdk/README.md +1 -0
  767. package/npm-shrinkwrap.json +193 -264
  768. package/package.json +15 -8
@@ -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,49 @@ 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>;
24
+ }
25
+ export declare class ReadOnlyAuthStorage implements CredentialStore {
26
+ private readonly authPath;
27
+ private data;
28
+ constructor(authPath?: string);
29
+ private load;
30
+ read(providerId: string, options?: AuthOperationOptions): Promise<Credential | undefined>;
31
+ list(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]>;
32
+ modify(_providerId: string, _fn: (current: Credential | undefined) => Promise<Credential | undefined>, _options?: AuthOperationOptions): Promise<Credential | undefined>;
33
+ delete(_providerId: string, _options?: AuthOperationOptions): Promise<void>;
23
34
  }
24
35
  export declare class InMemoryAuthStorageBackend implements AuthStorageBackend {
25
36
  private value;
37
+ private asyncChain;
26
38
  withLock<T>(fn: (current: string | undefined) => LockResult<T>): T;
27
- withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T>;
39
+ withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>, options?: AuthOperationOptions): Promise<T>;
28
40
  }
29
41
  /**
30
42
  * Credential storage backed by a JSON file.
31
43
  */
32
44
  export declare class AuthStorage implements CredentialStore {
33
- private data;
34
45
  private storage;
46
+ private authPath;
47
+ private readState;
35
48
  private constructor();
36
49
  static create(authPath?: string): AuthStorage;
37
50
  static fromStorage(storage: AuthStorageBackend): AuthStorage;
38
51
  static inMemory(data?: AuthStorageData): AuthStorage;
39
52
  private parseStorageData;
53
+ private updateReadState;
40
54
  /**
41
55
  * Reload credentials from storage.
42
56
  */
43
57
  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>;
58
+ private reloadFromStorageAsync;
59
+ private readLatestData;
60
+ read(provider: string, options?: AuthOperationOptions): Promise<Credential | undefined>;
61
+ modify(provider: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>, options?: AuthOperationOptions): Promise<Credential | undefined>;
62
+ delete(provider: string, options?: AuthOperationOptions): Promise<void>;
47
63
  /** List credential metadata without resolving configured key values. */
48
- list(): Promise<readonly CredentialInfo[]>;
64
+ list(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]>;
49
65
  }
50
66
  /**
51
67
  * 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":"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"}
@@ -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 { resolveConfigValue } from "./resolve-config-value.js";
10
+ import { raceWithAbortSignal } from "../utils/abort.js";
11
+ import { getFileRevision, normalizePath } from "../utils/paths.js";
12
+ import { isCommandConfigValue, 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);
@@ -119,8 +154,85 @@ export class FileAuthStorageBackend {
119
154
  }
120
155
  }
121
156
  }
157
+ export class ReadOnlyAuthStorage {
158
+ constructor(authPath = join(getAgentDir(), "auth.json")) {
159
+ this.authPath = normalizePath(authPath);
160
+ }
161
+ load() {
162
+ if (this.data)
163
+ return this.data;
164
+ let parsed;
165
+ try {
166
+ parsed = JSON.parse(readFileSync(this.authPath, "utf-8"));
167
+ }
168
+ catch (error) {
169
+ if (error.code === "ENOENT") {
170
+ this.data = {};
171
+ return this.data;
172
+ }
173
+ throw new Error(`Failed to read auth.json: ${error instanceof Error ? error.message : String(error)}`);
174
+ }
175
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
176
+ throw new Error("Invalid auth.json: expected an object");
177
+ }
178
+ for (const [providerId, credential] of Object.entries(parsed)) {
179
+ if (typeof credential !== "object" || credential === null || Array.isArray(credential)) {
180
+ throw new Error(`Invalid auth.json credential for provider "${providerId}"`);
181
+ }
182
+ const value = credential;
183
+ if (value.type === "api_key") {
184
+ const validKey = value.key === undefined || typeof value.key === "string";
185
+ const validEnv = value.env === undefined ||
186
+ (typeof value.env === "object" &&
187
+ value.env !== null &&
188
+ !Array.isArray(value.env) &&
189
+ Object.values(value.env).every((entry) => typeof entry === "string"));
190
+ if (validKey && validEnv)
191
+ continue;
192
+ }
193
+ else if (value.type === "oauth" &&
194
+ typeof value.access === "string" &&
195
+ typeof value.refresh === "string" &&
196
+ typeof value.expires === "number" &&
197
+ Number.isFinite(value.expires)) {
198
+ continue;
199
+ }
200
+ throw new Error(`Invalid auth.json credential for provider "${providerId}"`);
201
+ }
202
+ this.data = parsed;
203
+ return this.data;
204
+ }
205
+ async read(providerId, options) {
206
+ options?.signal?.throwIfAborted();
207
+ const credential = this.load()[providerId];
208
+ options?.signal?.throwIfAborted();
209
+ if (!credential)
210
+ return undefined;
211
+ if (credential.type !== "api_key" || !credential.key || isCommandConfigValue(credential.key)) {
212
+ return structuredClone(credential);
213
+ }
214
+ return { ...credential, key: resolveConfigValue(credential.key, credential.env) };
215
+ }
216
+ async list(options) {
217
+ options?.signal?.throwIfAborted();
218
+ const credentials = Object.entries(this.load()).map(([providerId, credential]) => ({
219
+ providerId,
220
+ type: credential.type,
221
+ }));
222
+ options?.signal?.throwIfAborted();
223
+ return credentials;
224
+ }
225
+ async modify(_providerId, _fn, _options) {
226
+ throw new Error("Read-only credential storage cannot modify auth.json");
227
+ }
228
+ async delete(_providerId, _options) {
229
+ throw new Error("Read-only credential storage cannot modify auth.json");
230
+ }
231
+ }
122
232
  export class InMemoryAuthStorageBackend {
123
- value;
233
+ constructor() {
234
+ this.asyncChain = Promise.resolve();
235
+ }
124
236
  withLock(fn) {
125
237
  const { result, next } = fn(this.value);
126
238
  if (next !== undefined) {
@@ -128,26 +240,44 @@ export class InMemoryAuthStorageBackend {
128
240
  }
129
241
  return result;
130
242
  }
131
- async withLockAsync(fn) {
132
- const { result, next } = await fn(this.value);
133
- if (next !== undefined) {
134
- this.value = next;
135
- }
136
- return result;
243
+ withLockAsync(fn, options) {
244
+ const previous = this.asyncChain;
245
+ const operation = (async () => {
246
+ await previous.catch(() => { });
247
+ options?.signal?.throwIfAborted();
248
+ const { result, next } = await fn(this.value);
249
+ options?.signal?.throwIfAborted();
250
+ if (next !== undefined) {
251
+ this.value = next;
252
+ }
253
+ return result;
254
+ })();
255
+ this.asyncChain = operation.catch(() => { });
256
+ return raceWithAbortSignal(operation, options?.signal);
137
257
  }
138
258
  }
139
259
  /**
140
260
  * Credential storage backed by a JSON file.
141
261
  */
142
262
  export class AuthStorage {
143
- data = {};
144
- storage;
145
- constructor(storage) {
263
+ constructor(storage, authPath) {
146
264
  this.storage = storage;
265
+ this.authPath = authPath;
266
+ this.readState =
267
+ authPath && sharedAuthFileReadState?.authPath === authPath ? sharedAuthFileReadState.readState : { data: {} };
268
+ if (authPath && !sharedAuthFileReadState) {
269
+ sharedAuthFileReadState = { authPath, readState: this.readState };
270
+ }
271
+ if (authPath) {
272
+ const revision = getFileRevision(authPath);
273
+ if (revision !== undefined && revision === this.readState.revision)
274
+ return;
275
+ }
147
276
  this.reload();
148
277
  }
149
- static create(authPath) {
150
- return new AuthStorage(new FileAuthStorageBackend(authPath ?? join(getAgentDir(), "auth.json")));
278
+ static create(authPath = join(getAgentDir(), "auth.json")) {
279
+ const normalizedAuthPath = normalizePath(authPath);
280
+ return new AuthStorage(new FileAuthStorageBackend(normalizedAuthPath), normalizedAuthPath);
151
281
  }
152
282
  static fromStorage(storage) {
153
283
  return new AuthStorage(storage);
@@ -163,54 +293,117 @@ export class AuthStorage {
163
293
  }
164
294
  return JSON.parse(content);
165
295
  }
296
+ updateReadState(data, revision) {
297
+ this.readState.data = data;
298
+ this.readState.revision = revision;
299
+ }
166
300
  /**
167
301
  * Reload credentials from storage.
168
302
  */
169
303
  reload() {
170
304
  let content;
305
+ let revision;
171
306
  try {
172
307
  this.storage.withLock((current) => {
173
308
  content = current;
309
+ revision = this.authPath ? getFileRevision(this.authPath) : undefined;
174
310
  return { result: undefined };
175
311
  });
176
- this.data = this.parseStorageData(content);
312
+ this.updateReadState(this.parseStorageData(content), revision);
177
313
  }
178
314
  catch {
179
315
  // Preserve the last valid in-memory snapshot.
180
316
  }
181
317
  }
182
- async read(provider) {
183
- const credential = this.data[provider];
318
+ async reloadFromStorageAsync(options) {
319
+ return this.storage.withLockAsync(async (content) => {
320
+ const currentData = this.parseStorageData(content);
321
+ const revision = this.authPath ? getFileRevision(this.authPath) : undefined;
322
+ this.updateReadState(currentData, revision);
323
+ return { result: currentData };
324
+ }, options);
325
+ }
326
+ async readLatestData(options) {
327
+ options?.signal?.throwIfAborted();
328
+ if (!this.authPath) {
329
+ const reload = this.reloadFromStorageAsync(options);
330
+ return options?.signal ? reload : reload.catch(() => this.readState.data);
331
+ }
332
+ const revision = getFileRevision(this.authPath);
333
+ if (revision !== undefined && revision === this.readState.revision)
334
+ return this.readState.data;
335
+ if (!this.readState.reload) {
336
+ const controller = new AbortController();
337
+ const reload = {
338
+ controller,
339
+ promise: this.reloadFromStorageAsync({ signal: controller.signal }),
340
+ readers: 0,
341
+ };
342
+ this.readState.reload = reload;
343
+ void reload.promise.then(() => {
344
+ if (this.readState.reload === reload)
345
+ this.readState.reload = undefined;
346
+ }, () => {
347
+ if (this.readState.reload === reload)
348
+ this.readState.reload = undefined;
349
+ });
350
+ }
351
+ const reload = this.readState.reload;
352
+ reload.readers++;
353
+ try {
354
+ const result = raceWithAbortSignal(reload.promise, options?.signal);
355
+ return options?.signal ? await result : await result.catch(() => this.readState.data);
356
+ }
357
+ finally {
358
+ reload.readers--;
359
+ if (reload.readers === 0 && this.readState.reload === reload) {
360
+ this.readState.reload = undefined;
361
+ reload.controller.abort();
362
+ }
363
+ }
364
+ }
365
+ async read(provider, options) {
366
+ const credential = (await this.readLatestData(options))[provider];
367
+ options?.signal?.throwIfAborted();
184
368
  if (credential?.type !== "api_key")
185
369
  return credential;
186
370
  if (credential.key === undefined)
187
371
  return credential;
188
372
  return { ...credential, key: resolveConfigValue(credential.key, credential.env) };
189
373
  }
190
- async modify(provider, fn) {
191
- return this.storage.withLockAsync(async (content) => {
374
+ async modify(provider, fn, options) {
375
+ let latestData = this.readState.data;
376
+ let revision;
377
+ const result = await this.storage.withLockAsync(async (content) => {
192
378
  const currentData = this.parseStorageData(content);
193
379
  const next = await fn(currentData[provider]);
194
380
  if (next === undefined) {
195
- this.data = currentData;
381
+ latestData = currentData;
382
+ revision = this.authPath ? getFileRevision(this.authPath) : undefined;
196
383
  return { result: currentData[provider] };
197
384
  }
198
385
  const merged = { ...currentData, [provider]: next };
199
- this.data = merged;
386
+ latestData = merged;
200
387
  return { result: next, next: JSON.stringify(merged, null, 2) };
201
- });
388
+ }, options);
389
+ this.updateReadState(latestData, revision);
390
+ return result;
202
391
  }
203
- async delete(provider) {
392
+ async delete(provider, options) {
393
+ let latestData = this.readState.data;
204
394
  await this.storage.withLockAsync(async (content) => {
205
395
  const currentData = this.parseStorageData(content);
206
396
  delete currentData[provider];
207
- this.data = currentData;
397
+ latestData = currentData;
208
398
  return { result: undefined, next: JSON.stringify(currentData, null, 2) };
209
- });
399
+ }, options);
400
+ this.updateReadState(latestData);
210
401
  }
211
402
  /** List credential metadata without resolving configured key values. */
212
- async list() {
213
- return Object.entries(this.data).map(([providerId, credential]) => ({ providerId, type: credential.type }));
403
+ async list(options) {
404
+ const entries = Object.entries(await this.readLatestData(options));
405
+ options?.signal?.throwIfAborted();
406
+ return entries.map(([providerId, credential]) => ({ providerId, type: credential.type }));
214
407
  }
215
408
  }
216
409
  /**
@@ -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 { isCommandConfigValue, 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 ReadOnlyAuthStorage implements CredentialStore {\n\tprivate readonly authPath: string;\n\tprivate data: AuthStorageData | undefined;\n\n\tconstructor(authPath: string = join(getAgentDir(), \"auth.json\")) {\n\t\tthis.authPath = normalizePath(authPath);\n\t}\n\n\tprivate load(): AuthStorageData {\n\t\tif (this.data) return this.data;\n\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(readFileSync(this.authPath, \"utf-8\"));\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\t\tthis.data = {};\n\t\t\t\treturn this.data;\n\t\t\t}\n\t\t\tthrow new Error(`Failed to read auth.json: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n\t\t\tthrow new Error(\"Invalid auth.json: expected an object\");\n\t\t}\n\t\tfor (const [providerId, credential] of Object.entries(parsed)) {\n\t\t\tif (typeof credential !== \"object\" || credential === null || Array.isArray(credential)) {\n\t\t\t\tthrow new Error(`Invalid auth.json credential for provider \"${providerId}\"`);\n\t\t\t}\n\t\t\tconst value = credential as Record<string, unknown>;\n\t\t\tif (value.type === \"api_key\") {\n\t\t\t\tconst validKey = value.key === undefined || typeof value.key === \"string\";\n\t\t\t\tconst validEnv =\n\t\t\t\t\tvalue.env === undefined ||\n\t\t\t\t\t(typeof value.env === \"object\" &&\n\t\t\t\t\t\tvalue.env !== null &&\n\t\t\t\t\t\t!Array.isArray(value.env) &&\n\t\t\t\t\t\tObject.values(value.env).every((entry) => typeof entry === \"string\"));\n\t\t\t\tif (validKey && validEnv) continue;\n\t\t\t} else if (\n\t\t\t\tvalue.type === \"oauth\" &&\n\t\t\t\ttypeof value.access === \"string\" &&\n\t\t\t\ttypeof value.refresh === \"string\" &&\n\t\t\t\ttypeof value.expires === \"number\" &&\n\t\t\t\tNumber.isFinite(value.expires)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new Error(`Invalid auth.json credential for provider \"${providerId}\"`);\n\t\t}\n\n\t\tthis.data = parsed as AuthStorageData;\n\t\treturn this.data;\n\t}\n\n\tasync read(providerId: string, options?: AuthOperationOptions): Promise<Credential | undefined> {\n\t\toptions?.signal?.throwIfAborted();\n\t\tconst credential = this.load()[providerId];\n\t\toptions?.signal?.throwIfAborted();\n\t\tif (!credential) return undefined;\n\t\tif (credential.type !== \"api_key\" || !credential.key || isCommandConfigValue(credential.key)) {\n\t\t\treturn structuredClone(credential);\n\t\t}\n\t\treturn { ...credential, key: resolveConfigValue(credential.key, credential.env) };\n\t}\n\n\tasync list(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]> {\n\t\toptions?.signal?.throwIfAborted();\n\t\tconst credentials = Object.entries(this.load()).map(([providerId, credential]) => ({\n\t\t\tproviderId,\n\t\t\ttype: credential.type,\n\t\t}));\n\t\toptions?.signal?.throwIfAborted();\n\t\treturn credentials;\n\t}\n\n\tasync modify(\n\t\t_providerId: string,\n\t\t_fn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t\t_options?: AuthOperationOptions,\n\t): Promise<Credential | undefined> {\n\t\tthrow new Error(\"Read-only credential storage cannot modify auth.json\");\n\t}\n\n\tasync delete(_providerId: string, _options?: AuthOperationOptions): Promise<void> {\n\t\tthrow new Error(\"Read-only credential storage cannot modify auth.json\");\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"}