@oh-my-pi/pi-coding-agent 17.0.9 → 17.1.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 (349) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +1 -1
  3. package/dist/cli.js +4685 -4614
  4. package/dist/types/async/job-manager.d.ts +37 -1
  5. package/dist/types/cli/args.d.ts +2 -0
  6. package/dist/types/cli/bench-cli.d.ts +41 -0
  7. package/dist/types/commands/bench.d.ts +15 -3
  8. package/dist/types/commands/launch.d.ts +4 -0
  9. package/dist/types/config/model-registry.d.ts +3 -1
  10. package/dist/types/config/models-config-schema.d.ts +18 -6
  11. package/dist/types/config/models-config.d.ts +14 -5
  12. package/dist/types/config/provider-globals.d.ts +2 -2
  13. package/dist/types/config/service-tier.d.ts +5 -1
  14. package/dist/types/config/settings-schema.d.ts +374 -47
  15. package/dist/types/config/settings.d.ts +7 -0
  16. package/dist/types/dap/client.d.ts +20 -0
  17. package/dist/types/exec/bash-executor.d.ts +38 -0
  18. package/dist/types/exec/direnv.d.ts +33 -0
  19. package/dist/types/export/html/args.d.ts +15 -0
  20. package/dist/types/export/html/index.d.ts +11 -26
  21. package/dist/types/export/html/web-palette.d.ts +55 -116
  22. package/dist/types/extensibility/extensions/loader.d.ts +3 -0
  23. package/dist/types/extensibility/extensions/types.d.ts +17 -2
  24. package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +3 -0
  25. package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +13 -0
  26. package/dist/types/live/attestation.d.ts +2 -0
  27. package/dist/types/live/controller.d.ts +48 -0
  28. package/dist/types/live/protocol.d.ts +85 -0
  29. package/dist/types/live/protocol.test.d.ts +1 -0
  30. package/dist/types/live/transport.d.ts +35 -0
  31. package/dist/types/live/visualizer.d.ts +30 -0
  32. package/dist/types/lsp/client.d.ts +16 -1
  33. package/dist/types/mcp/config-writer.test.d.ts +1 -0
  34. package/dist/types/mcp/oauth-discovery.d.ts +2 -0
  35. package/dist/types/mcp/smithery-auth.d.ts +1 -1
  36. package/dist/types/mcp/smithery-auth.test.d.ts +1 -0
  37. package/dist/types/memory-backend/tool-names.d.ts +2 -0
  38. package/dist/types/modes/components/assistant-message.d.ts +1 -0
  39. package/dist/types/modes/components/custom-message.d.ts +1 -1
  40. package/dist/types/modes/components/login-dialog.d.ts +2 -2
  41. package/dist/types/modes/components/message-frame.d.ts +8 -4
  42. package/dist/types/modes/components/plan-review-overlay.d.ts +26 -0
  43. package/dist/types/modes/components/session-account-selector.d.ts +11 -0
  44. package/dist/types/modes/components/settings-defs.d.ts +7 -1
  45. package/dist/types/modes/components/status-line/component.jj-cache.test.d.ts +1 -0
  46. package/dist/types/modes/components/tool-execution.d.ts +9 -1
  47. package/dist/types/modes/controllers/command-controller.d.ts +1 -1
  48. package/dist/types/modes/controllers/event-controller.d.ts +6 -1
  49. package/dist/types/modes/controllers/live-command-controller.d.ts +14 -0
  50. package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
  51. package/dist/types/modes/interactive-mode.d.ts +6 -0
  52. package/dist/types/modes/theme/theme.d.ts +1 -1
  53. package/dist/types/modes/types.d.ts +4 -1
  54. package/dist/types/modes/utils/context-usage.d.ts +12 -2
  55. package/dist/types/plan-mode/plan-files.d.ts +10 -0
  56. package/dist/types/registry/agent-lifecycle.d.ts +21 -9
  57. package/dist/types/registry/agent-registry.d.ts +11 -4
  58. package/dist/types/sdk.d.ts +15 -1
  59. package/dist/types/secrets/index.d.ts +15 -2
  60. package/dist/types/secrets/obfuscator.d.ts +113 -15
  61. package/dist/types/session/acp-permission-gate.d.ts +19 -0
  62. package/dist/types/session/agent-session-events.d.ts +84 -0
  63. package/dist/types/session/agent-session-types.d.ts +321 -0
  64. package/dist/types/session/agent-session.d.ts +135 -753
  65. package/dist/types/session/async-job-delivery.d.ts +28 -0
  66. package/dist/types/session/auth-storage.d.ts +1 -1
  67. package/dist/types/session/bash-runner.d.ts +75 -0
  68. package/dist/types/session/blob-store.d.ts +11 -1
  69. package/dist/types/session/blob-store.test.d.ts +1 -0
  70. package/dist/types/session/checkpoint-entries.d.ts +28 -0
  71. package/dist/types/session/eval-runner.d.ts +51 -0
  72. package/dist/types/session/irc-bridge.d.ts +46 -0
  73. package/dist/types/session/messages.d.ts +24 -0
  74. package/dist/types/session/model-controls.d.ts +180 -0
  75. package/dist/types/session/prewalk.d.ts +46 -0
  76. package/dist/types/session/queued-messages.d.ts +22 -0
  77. package/dist/types/session/redis-session-storage.d.ts +1 -0
  78. package/dist/types/session/retry-fallback-chains.d.ts +74 -0
  79. package/dist/types/session/role-models.d.ts +15 -0
  80. package/dist/types/session/session-advisors.d.ts +228 -0
  81. package/dist/types/session/session-entries.d.ts +8 -0
  82. package/dist/types/session/session-handoff.d.ts +70 -0
  83. package/dist/types/session/session-history-format.d.ts +6 -1
  84. package/dist/types/session/session-maintenance.d.ts +246 -0
  85. package/dist/types/session/session-manager.d.ts +41 -0
  86. package/dist/types/session/session-memory.d.ts +56 -0
  87. package/dist/types/session/session-provider-boundary.d.ts +62 -0
  88. package/dist/types/session/session-stats.d.ts +48 -0
  89. package/dist/types/session/session-tools.d.ts +158 -0
  90. package/dist/types/session/session-workspace.d.ts +32 -0
  91. package/dist/types/session/stream-guards.d.ts +44 -0
  92. package/dist/types/session/streaming-output.d.ts +8 -0
  93. package/dist/types/session/todo-tracker.d.ts +56 -0
  94. package/dist/types/session/ttsr-coordinator.d.ts +51 -0
  95. package/dist/types/session/turn-recovery.d.ts +225 -0
  96. package/dist/types/slash-commands/helpers/session-pin.d.ts +9 -0
  97. package/dist/types/stt/index.d.ts +0 -2
  98. package/dist/types/stt/stt-controller.d.ts +7 -0
  99. package/dist/types/system-prompt.d.ts +2 -0
  100. package/dist/types/task/executor.d.ts +4 -1
  101. package/dist/types/task/output-manager.d.ts +3 -1
  102. package/dist/types/tiny/title-client.d.ts +10 -0
  103. package/dist/types/tools/approval.d.ts +1 -0
  104. package/dist/types/tools/browser/launch.d.ts +5 -0
  105. package/dist/types/tools/builtin-names.d.ts +1 -1
  106. package/dist/types/tools/computer/protocol.d.ts +43 -0
  107. package/dist/types/tools/computer/supervisor.d.ts +32 -0
  108. package/dist/types/tools/computer/worker-entry.d.ts +1 -0
  109. package/dist/types/tools/computer/worker.d.ts +15 -0
  110. package/dist/types/tools/computer-renderer.d.ts +22 -0
  111. package/dist/types/tools/computer.d.ts +71 -0
  112. package/dist/types/tools/context.d.ts +2 -0
  113. package/dist/types/tools/default-renderer.d.ts +21 -0
  114. package/dist/types/tools/image-gen.d.ts +4 -4
  115. package/dist/types/tools/image-providers.d.ts +38 -0
  116. package/dist/types/tools/index.d.ts +7 -0
  117. package/dist/types/tools/path-utils.d.ts +8 -0
  118. package/dist/types/tools/todo.d.ts +10 -4
  119. package/dist/types/tools/xdev.d.ts +5 -1
  120. package/dist/types/tts/streaming-player.d.ts +10 -29
  121. package/dist/types/tts/vocalizer.d.ts +5 -0
  122. package/dist/types/utils/jj.d.ts +29 -0
  123. package/dist/types/utils/lang-from-path.d.ts +1 -0
  124. package/dist/types/utils/title-generator.d.ts +30 -0
  125. package/dist/types/utils/tools-manager.d.ts +1 -2
  126. package/dist/types/vibe/runtime.d.ts +36 -8
  127. package/dist/types/web/search/index.d.ts +1 -1
  128. package/dist/types/web/search/provider.d.ts +15 -5
  129. package/dist/types/web/search/types.d.ts +94 -0
  130. package/package.json +12 -12
  131. package/scripts/generate-share-viewer.ts +4 -6
  132. package/src/advisor/__tests__/advisor.test.ts +643 -0
  133. package/src/advisor/runtime.ts +144 -43
  134. package/src/async/job-manager.ts +90 -2
  135. package/src/cli/args.ts +3 -0
  136. package/src/cli/auth-gateway-cli.ts +18 -3
  137. package/src/cli/bench-cli.ts +395 -29
  138. package/src/cli/flag-tables.ts +3 -0
  139. package/src/cli/gc-cli.ts +2 -2
  140. package/src/cli/setup-cli.ts +2 -14
  141. package/src/cli/usage-cli.ts +10 -1
  142. package/src/cli.ts +8 -0
  143. package/src/collab/host.ts +3 -2
  144. package/src/commands/bench.ts +18 -4
  145. package/src/commands/launch.ts +4 -0
  146. package/src/config/model-registry.ts +16 -2
  147. package/src/config/models-config-schema.ts +15 -4
  148. package/src/config/provider-globals.ts +9 -9
  149. package/src/config/service-tier.ts +26 -1
  150. package/src/config/settings-schema.ts +270 -51
  151. package/src/config/settings.ts +81 -2
  152. package/src/dap/client.ts +37 -4
  153. package/src/edit/index.ts +49 -12
  154. package/src/eval/executor-base.ts +1 -0
  155. package/src/eval/js/executor.ts +2 -0
  156. package/src/eval/py/executor.ts +103 -33
  157. package/src/exec/bash-executor.ts +90 -6
  158. package/src/exec/direnv.ts +145 -0
  159. package/src/export/html/args.ts +20 -0
  160. package/src/export/html/index.ts +45 -47
  161. package/src/export/html/template.css +19 -1
  162. package/src/export/html/template.html +6 -0
  163. package/src/export/html/template.js +21 -0
  164. package/src/export/html/tool-views.generated.js +31 -31
  165. package/src/export/html/web-palette.ts +116 -132
  166. package/src/export/share.ts +249 -49
  167. package/src/extensibility/extensions/loader.ts +29 -1
  168. package/src/extensibility/extensions/runner.ts +6 -0
  169. package/src/extensibility/extensions/types.ts +33 -2
  170. package/src/extensibility/extensions/wrapper.ts +68 -12
  171. package/src/extensibility/legacy-pi-coding-agent-shim.ts +7 -1
  172. package/src/extensibility/plugins/legacy-pi-compat.ts +19 -1
  173. package/src/hindsight/state.ts +64 -6
  174. package/src/internal-urls/local-protocol.ts +2 -1
  175. package/src/internal-urls/memory-protocol.ts +2 -2
  176. package/src/internal-urls/skill-protocol.ts +2 -2
  177. package/src/internal-urls/ssh-protocol.ts +2 -1
  178. package/src/internal-urls/vault-protocol.ts +2 -1
  179. package/src/live/attestation.ts +91 -0
  180. package/src/live/controller.ts +517 -0
  181. package/src/live/prompts/agent-final-message.md +3 -0
  182. package/src/live/prompts/live-instructions.md +23 -0
  183. package/src/live/protocol.test.ts +140 -0
  184. package/src/live/protocol.ts +233 -0
  185. package/src/live/transport.ts +422 -0
  186. package/src/live/visualizer.ts +214 -0
  187. package/src/lsp/client.ts +29 -9
  188. package/src/lsp/index.ts +19 -4
  189. package/src/main.ts +8 -1
  190. package/src/mcp/config-writer.test.ts +43 -0
  191. package/src/mcp/config-writer.ts +109 -82
  192. package/src/mcp/oauth-discovery.ts +10 -2
  193. package/src/mcp/smithery-auth.test.ts +29 -0
  194. package/src/mcp/smithery-auth.ts +3 -2
  195. package/src/memories/index.ts +40 -20
  196. package/src/memory-backend/tool-names.ts +2 -0
  197. package/src/mnemopi/backend.ts +24 -7
  198. package/src/modes/acp/acp-agent.ts +56 -10
  199. package/src/modes/acp/acp-event-mapper.ts +8 -1
  200. package/src/modes/components/agent-hub.ts +1 -1
  201. package/src/modes/components/assistant-message.ts +7 -2
  202. package/src/modes/components/custom-message.ts +4 -1
  203. package/src/modes/components/login-dialog.ts +14 -4
  204. package/src/modes/components/message-frame.ts +14 -8
  205. package/src/modes/components/plan-review-overlay.ts +350 -35
  206. package/src/modes/components/session-account-selector.ts +62 -0
  207. package/src/modes/components/settings-defs.ts +23 -1
  208. package/src/modes/components/settings-selector.ts +169 -1
  209. package/src/modes/components/status-line/component.jj-cache.test.ts +229 -0
  210. package/src/modes/components/status-line/component.ts +123 -2
  211. package/src/modes/components/tool-execution.ts +28 -112
  212. package/src/modes/controllers/command-controller.ts +56 -15
  213. package/src/modes/controllers/event-controller.ts +111 -16
  214. package/src/modes/controllers/extension-ui-controller.test.ts +1 -0
  215. package/src/modes/controllers/extension-ui-controller.ts +20 -4
  216. package/src/modes/controllers/input-controller.ts +47 -39
  217. package/src/modes/controllers/live-command-controller.ts +255 -0
  218. package/src/modes/controllers/mcp-command-controller.ts +10 -1
  219. package/src/modes/controllers/omfg-controller.ts +44 -40
  220. package/src/modes/controllers/selector-controller.ts +80 -10
  221. package/src/modes/controllers/session-focus-controller.ts +6 -1
  222. package/src/modes/interactive-mode.ts +176 -38
  223. package/src/modes/runtime-init.ts +2 -0
  224. package/src/modes/setup-wizard/scenes/web-search.ts +17 -9
  225. package/src/modes/theme/theme.ts +1 -1
  226. package/src/modes/types.ts +4 -1
  227. package/src/modes/utils/context-usage.ts +23 -7
  228. package/src/modes/utils/ui-helpers.ts +10 -5
  229. package/src/plan-mode/plan-files.ts +40 -0
  230. package/src/prompts/bench/cache-prefix-chunk.md +1 -0
  231. package/src/prompts/bench/cache-prefix.md +3 -0
  232. package/src/prompts/bench/cache-suffix.md +1 -0
  233. package/src/prompts/system/computer-safety.md +14 -0
  234. package/src/prompts/system/custom-system-prompt.md +1 -1
  235. package/src/prompts/system/project-prompt.md +8 -1
  236. package/src/prompts/system/subagent-async-pending.md +6 -0
  237. package/src/prompts/system/system-prompt.md +1 -1
  238. package/src/prompts/system/workflow-notice.md +48 -40
  239. package/src/prompts/system/xdev-mount-notice.md +4 -0
  240. package/src/prompts/tools/computer.md +26 -0
  241. package/src/prompts/tools/todo.md +3 -1
  242. package/src/registry/agent-lifecycle.ts +116 -46
  243. package/src/registry/agent-registry.ts +35 -8
  244. package/src/registry/persisted-agents.ts +26 -2
  245. package/src/sdk.ts +215 -136
  246. package/src/secrets/index.ts +127 -4
  247. package/src/secrets/obfuscator.ts +2328 -105
  248. package/src/session/acp-permission-gate.ts +165 -0
  249. package/src/session/agent-session-error-log.test.ts +1 -1
  250. package/src/session/agent-session-events.ts +66 -0
  251. package/src/session/agent-session-types.ts +343 -0
  252. package/src/session/agent-session.ts +1940 -12218
  253. package/src/session/artifacts.ts +6 -5
  254. package/src/session/async-job-delivery.ts +74 -0
  255. package/src/session/auth-storage.ts +1 -0
  256. package/src/session/bash-runner.ts +326 -0
  257. package/src/session/blob-store.test.ts +56 -0
  258. package/src/session/blob-store.ts +18 -2
  259. package/src/session/checkpoint-entries.ts +81 -0
  260. package/src/session/eval-runner.ts +217 -0
  261. package/src/session/indexed-session-storage.ts +9 -2
  262. package/src/session/irc-bridge.ts +203 -0
  263. package/src/session/messages.ts +266 -1
  264. package/src/session/model-controls.ts +714 -0
  265. package/src/session/prewalk.ts +252 -0
  266. package/src/session/queued-messages.ts +93 -0
  267. package/src/session/redis-session-storage.ts +51 -11
  268. package/src/session/retry-fallback-chains.ts +455 -0
  269. package/src/session/role-models.ts +85 -0
  270. package/src/session/session-advisors.ts +1679 -0
  271. package/src/session/session-context.ts +6 -3
  272. package/src/session/session-entries.ts +8 -0
  273. package/src/session/session-handoff.ts +308 -0
  274. package/src/session/session-history-format.ts +20 -9
  275. package/src/session/session-loader.ts +0 -46
  276. package/src/session/session-maintenance.ts +2983 -0
  277. package/src/session/session-manager.ts +390 -30
  278. package/src/session/session-memory.ts +222 -0
  279. package/src/session/session-provider-boundary.ts +307 -0
  280. package/src/session/session-stats.ts +293 -0
  281. package/src/session/session-tools.ts +980 -0
  282. package/src/session/session-workspace.ts +53 -0
  283. package/src/session/stream-guards.ts +417 -0
  284. package/src/session/streaming-output.ts +52 -5
  285. package/src/session/todo-tracker.ts +380 -0
  286. package/src/session/ttsr-coordinator.ts +496 -0
  287. package/src/session/turn-recovery.ts +1629 -0
  288. package/src/slash-commands/builtin-registry.ts +257 -20
  289. package/src/slash-commands/helpers/session-pin.ts +44 -0
  290. package/src/slash-commands/helpers/usage-report.ts +22 -3
  291. package/src/stt/downloader.ts +0 -2
  292. package/src/stt/index.ts +0 -2
  293. package/src/stt/stt-controller.ts +57 -146
  294. package/src/system-prompt.ts +45 -17
  295. package/src/task/executor.ts +285 -70
  296. package/src/task/index.ts +98 -105
  297. package/src/task/output-manager.ts +25 -3
  298. package/src/task/persisted-revive.ts +4 -3
  299. package/src/task/structured-subagent.ts +1 -0
  300. package/src/tiny/title-client.ts +22 -0
  301. package/src/tools/approval.ts +55 -10
  302. package/src/tools/bash-interactive.ts +116 -86
  303. package/src/tools/bash-skill-urls.ts +28 -2
  304. package/src/tools/bash.ts +339 -123
  305. package/src/tools/browser/launch.ts +9 -1
  306. package/src/tools/browser/tab-supervisor.ts +8 -5
  307. package/src/tools/browser.ts +94 -47
  308. package/src/tools/builtin-names.ts +1 -0
  309. package/src/tools/computer/protocol.ts +28 -0
  310. package/src/tools/computer/supervisor.ts +258 -0
  311. package/src/tools/computer/worker-entry.ts +25 -0
  312. package/src/tools/computer/worker.ts +135 -0
  313. package/src/tools/computer-renderer.ts +108 -0
  314. package/src/tools/computer.ts +433 -0
  315. package/src/tools/context.ts +2 -0
  316. package/src/tools/default-renderer.ts +139 -0
  317. package/src/tools/essential-tools.ts +1 -0
  318. package/src/tools/image-gen.ts +20 -28
  319. package/src/tools/image-providers.ts +50 -0
  320. package/src/tools/index.ts +14 -0
  321. package/src/tools/path-utils.ts +49 -2
  322. package/src/tools/read.ts +156 -88
  323. package/src/tools/renderers.ts +9 -1
  324. package/src/tools/todo.ts +101 -11
  325. package/src/tools/vibe.ts +1 -2
  326. package/src/tools/write.ts +51 -1
  327. package/src/tools/xdev.ts +121 -29
  328. package/src/tts/streaming-player.ts +82 -283
  329. package/src/tts/vocalizer.ts +18 -1
  330. package/src/utils/clipboard.ts +1 -30
  331. package/src/utils/jj.ts +125 -4
  332. package/src/utils/lang-from-path.ts +7 -0
  333. package/src/utils/mac-file-urls.applescript +37 -0
  334. package/src/utils/title-generator.ts +137 -1
  335. package/src/utils/tool-choice.ts +14 -0
  336. package/src/utils/tools-manager.ts +1 -19
  337. package/src/vibe/runtime.ts +852 -72
  338. package/src/web/search/index.ts +3 -6
  339. package/src/web/search/provider.ts +31 -16
  340. package/src/web/search/providers/xai.ts +7 -1
  341. package/src/web/search/types.ts +3 -0
  342. package/dist/types/stt/recorder.d.ts +0 -30
  343. package/dist/types/stt/transcriber.d.ts +0 -14
  344. package/dist/types/stt/wav.d.ts +0 -29
  345. package/dist/types/tts/player.d.ts +0 -32
  346. package/src/stt/recorder.ts +0 -551
  347. package/src/stt/transcriber.ts +0 -60
  348. package/src/stt/wav.ts +0 -173
  349. package/src/tts/player.ts +0 -137
@@ -5,7 +5,12 @@ import * as AIError from "@oh-my-pi/pi-ai/error";
5
5
  import { type CursorExecResolvedCarrier, kCursorExecResolved } from "@oh-my-pi/pi-ai/utils/block-symbols";
6
6
  import { logger } from "@oh-my-pi/pi-utils";
7
7
  import { obfuscateToolArguments, type SecretObfuscator } from "../secrets/obfuscator";
8
- import { formatSessionHistoryMarkdown, PRIMARY_CONTEXT_CUSTOM_TYPES } from "../session/session-history-format";
8
+ import {
9
+ formatExecutionSourcePreview,
10
+ formatSessionHistoryMarkdown,
11
+ formatToolResultErrorPreview,
12
+ PRIMARY_CONTEXT_CUSTOM_TYPES,
13
+ } from "../session/session-history-format";
9
14
 
10
15
  /**
11
16
  * Minimal slice of `Agent` the runtime drives — satisfied by pi-agent-core
@@ -267,6 +272,8 @@ export class AdvisorRuntime {
267
272
  #seenContext = new Map<string, string>();
268
273
  /** Incremented whenever the advisor loses context so queued raw deltas are re-rendered against fresh dedupe state. */
269
274
  #renderRevision = 0;
275
+ /** Regex secret values observed in primary deltas and retained until advisor context resets. */
276
+ #advisorRegexSecretValues = new Set<string>();
270
277
  #pending: PendingDelta[] = [];
271
278
  #busy = false;
272
279
  #backlog = 0;
@@ -428,6 +435,7 @@ export class AdvisorRuntime {
428
435
  this.#backlog = 0;
429
436
  this.#consecutiveFailures = 0;
430
437
  this.#failureNotified = false;
438
+ this.#advisorRegexSecretValues.clear();
431
439
  this.#wakeAllWaiters();
432
440
  try {
433
441
  this.agent.abort("advisor disposed");
@@ -436,6 +444,7 @@ export class AdvisorRuntime {
436
444
 
437
445
  #clearSeenContext(): void {
438
446
  this.#seenContext.clear();
447
+ this.#advisorRegexSecretValues.clear();
439
448
  this.#renderRevision++;
440
449
  }
441
450
 
@@ -527,9 +536,44 @@ export class AdvisorRuntime {
527
536
  .map(message => this.#dedupContextMessage(message));
528
537
  if (delta.length === 0) return null;
529
538
  const obfuscator = this.host.obfuscator;
530
- const formattedDelta = obfuscator?.hasSecrets() ? obfuscateAdvisorDelta(obfuscator, delta) : delta;
531
- const md = formatSessionHistoryMarkdown(formattedDelta, ADVISOR_RENDER_OPTIONS);
539
+ let md = formatSessionHistoryMarkdown(delta, ADVISOR_RENDER_OPTIONS);
532
540
  if (!md.trim()) return null;
541
+ if (obfuscator?.hasSecrets()) {
542
+ let discoveredNewRegexSecretValue = false;
543
+ const addRegexValues = (text: string): void => {
544
+ for (const secretValue of obfuscator.collectRegexSecretValuesForObfuscation(text)) {
545
+ if (this.#advisorRegexSecretValues.has(secretValue)) continue;
546
+ this.#advisorRegexSecretValues.add(secretValue);
547
+ discoveredNewRegexSecretValue = true;
548
+ }
549
+ };
550
+ for (const message of delta) {
551
+ if (
552
+ message.role === "custom" &&
553
+ PRIMARY_CONTEXT_CUSTOM_TYPES.has(message.customType) &&
554
+ typeof message.content === "string"
555
+ ) {
556
+ addRegexValues(message.content);
557
+ }
558
+ }
559
+ addRegexValues(md);
560
+ scrubAdvisorHistory(obfuscator, this.agent.state.messages, this.#advisorRegexSecretValues);
561
+ if (discoveredNewRegexSecretValue) {
562
+ this.#pending = this.#pending.map(delta => ({
563
+ ...delta,
564
+ text: obfuscator.stripUnsafeFriendlyPlaceholderPrefixes(delta.text, this.#advisorRegexSecretValues),
565
+ }));
566
+ }
567
+ md = formatSessionHistoryMarkdown(
568
+ delta.map(message =>
569
+ message.role === "custom" && PRIMARY_CONTEXT_CUSTOM_TYPES.has(message.customType)
570
+ ? obfuscateAdvisorMessage(obfuscator, message, this.#advisorRegexSecretValues)
571
+ : message,
572
+ ),
573
+ ADVISOR_RENDER_OPTIONS,
574
+ );
575
+ md = obfuscator.obfuscate(md, this.#advisorRegexSecretValues);
576
+ }
533
577
  const heading = wip ? "### Session update [in progress — more steps follow]" : "### Session update";
534
578
  return `${heading}\n\n${md}`;
535
579
  }
@@ -731,6 +775,10 @@ export class AdvisorRuntime {
731
775
  wip = late.at(-1)!.wip;
732
776
  }
733
777
 
778
+ const batchObfuscator = this.host.obfuscator;
779
+ if (batchObfuscator?.hasSecrets()) {
780
+ batchText = batchObfuscator.stripUnsafeFriendlyPlaceholderPrefixes(batchText, this.#advisorRegexSecretValues);
781
+ }
734
782
  return { batch: batchText || null, rawMessages, finalTurns: turns, wip, resetContext: false };
735
783
  }
736
784
 
@@ -987,12 +1035,16 @@ function getAdvisorTurnError(messages: readonly AgentMessage[]): Error | undefin
987
1035
 
988
1036
  type TextualContent = string | readonly (TextContent | ImageContent)[];
989
1037
 
990
- function obfuscateTextualContent(obfuscator: SecretObfuscator, content: TextualContent): TextualContent {
991
- if (typeof content === "string") return obfuscator.obfuscate(content);
1038
+ function obfuscateTextualContent(
1039
+ obfuscator: SecretObfuscator,
1040
+ content: TextualContent,
1041
+ sharedRegexSecretValues: ReadonlySet<string>,
1042
+ ): TextualContent {
1043
+ if (typeof content === "string") return obfuscator.obfuscate(content, sharedRegexSecretValues);
992
1044
  let changed = false;
993
1045
  const result = content.map((block): TextContent | ImageContent => {
994
1046
  if (block.type !== "text") return block;
995
- const text = obfuscator.obfuscate(block.text);
1047
+ const text = obfuscator.obfuscate(block.text, sharedRegexSecretValues);
996
1048
  if (text === block.text) return block;
997
1049
  changed = true;
998
1050
  return { ...block, text };
@@ -1000,17 +1052,50 @@ function obfuscateTextualContent(obfuscator: SecretObfuscator, content: TextualC
1000
1052
  return changed ? result : content;
1001
1053
  }
1002
1054
 
1003
- function obfuscateAssistantMessage(obfuscator: SecretObfuscator, message: AssistantMessage): AssistantMessage {
1055
+ function firstAdvisorToolResultErrorLine(content: TextualContent): string | undefined {
1056
+ if (typeof content === "string") return content.split("\n", 1)[0];
1057
+ const first = content[0];
1058
+ if (first?.type !== "text") return undefined;
1059
+ return first.text.split("\n", 1)[0];
1060
+ }
1061
+
1062
+ function obfuscateAdvisorToolResultErrorContent(
1063
+ obfuscator: SecretObfuscator,
1064
+ content: TextualContent,
1065
+ sharedRegexSecretValues: ReadonlySet<string>,
1066
+ ): TextualContent {
1067
+ const firstLine = firstAdvisorToolResultErrorLine(content);
1068
+ if (firstLine === undefined) return content;
1069
+ const preview = formatToolResultErrorPreview(content);
1070
+ const obfuscatedPreview = obfuscator.obfuscate(preview, sharedRegexSecretValues);
1071
+ if (obfuscatedPreview === firstLine) return content;
1072
+ if (typeof content === "string") return obfuscatedPreview + content.slice(firstLine.length);
1073
+ const first = content[0]!;
1074
+ if (first.type !== "text") return content;
1075
+ return [{ ...first, text: obfuscatedPreview + first.text.slice(firstLine.length) }, ...content.slice(1)];
1076
+ }
1077
+
1078
+ function obfuscateAssistantMessage(
1079
+ obfuscator: SecretObfuscator,
1080
+ message: AssistantMessage,
1081
+ sharedRegexSecretValues: ReadonlySet<string>,
1082
+ ): AssistantMessage {
1004
1083
  let changed = false;
1005
1084
  const content = message.content.map((block): AssistantMessage["content"][number] => {
1006
1085
  if (block.type === "text") {
1007
- const text = obfuscator.obfuscate(block.text);
1086
+ const text = obfuscator.obfuscate(block.text, sharedRegexSecretValues);
1008
1087
  if (text === block.text) return block;
1009
1088
  changed = true;
1010
1089
  return { ...block, text };
1011
1090
  }
1091
+ if (block.type === "thinking") {
1092
+ const thinking = obfuscator.obfuscate(block.thinking, sharedRegexSecretValues);
1093
+ if (thinking === block.thinking) return block;
1094
+ changed = true;
1095
+ return { ...block, thinking, thinkingSignature: undefined };
1096
+ }
1012
1097
  if (block.type === "toolCall") {
1013
- const args = obfuscateToolArguments(obfuscator, block.arguments);
1098
+ const args = obfuscateToolArguments(obfuscator, block.arguments, sharedRegexSecretValues);
1014
1099
  if (args === block.arguments) return block;
1015
1100
  changed = true;
1016
1101
  return { ...block, arguments: args };
@@ -1023,68 +1108,83 @@ function obfuscateAssistantMessage(obfuscator: SecretObfuscator, message: Assist
1023
1108
  function obfuscateDetails(
1024
1109
  obfuscator: SecretObfuscator,
1025
1110
  details: Record<string, unknown> | undefined,
1111
+ sharedRegexSecretValues: ReadonlySet<string>,
1026
1112
  ): Record<string, unknown> | undefined {
1027
1113
  if (!details) return details;
1028
1114
  // Walk strings at every depth: `customOneLiner` renders nested fields
1029
1115
  // (e.g. `async-result` reads `details.jobs[].label`/`jobId`), so a shallow
1030
1116
  // pass leaks any secret a background job's label happens to contain.
1031
- return obfuscateToolArguments(obfuscator, details);
1117
+ return obfuscateToolArguments(obfuscator, details, sharedRegexSecretValues);
1032
1118
  }
1033
1119
 
1034
- function obfuscateAdvisorMessage(obfuscator: SecretObfuscator, message: AgentMessage): AgentMessage {
1120
+ function obfuscateAdvisorMessage(
1121
+ obfuscator: SecretObfuscator,
1122
+ message: AgentMessage,
1123
+ sharedRegexSecretValues: ReadonlySet<string>,
1124
+ ): AgentMessage {
1035
1125
  switch (message.role) {
1036
1126
  case "user":
1037
1127
  case "developer": {
1038
- const content = obfuscateTextualContent(obfuscator, message.content as TextualContent);
1128
+ const content = obfuscateTextualContent(
1129
+ obfuscator,
1130
+ message.content as TextualContent,
1131
+ sharedRegexSecretValues,
1132
+ );
1039
1133
  return content === message.content ? message : ({ ...(message as object), content } as AgentMessage);
1040
1134
  }
1041
1135
  case "toolResult": {
1042
1136
  const msg = message as AgentMessage & {
1043
1137
  content: TextualContent;
1044
1138
  details?: Record<string, unknown>;
1139
+ isError?: boolean;
1045
1140
  };
1046
- const content = obfuscateTextualContent(obfuscator, msg.content);
1047
- const details = obfuscateDetails(obfuscator, msg.details);
1141
+ const content = msg.isError
1142
+ ? obfuscateAdvisorToolResultErrorContent(obfuscator, msg.content, sharedRegexSecretValues)
1143
+ : msg.content;
1144
+ let details = msg.details;
1145
+ if (typeof details?.diff === "string") {
1146
+ const diff = obfuscator.obfuscate(details.diff, sharedRegexSecretValues);
1147
+ if (diff !== details.diff) details = { ...details, diff };
1148
+ }
1048
1149
  if (content === msg.content && details === msg.details) return message;
1049
1150
  return { ...(message as object), content, details } as AgentMessage;
1050
1151
  }
1051
1152
  case "assistant":
1052
- return obfuscateAssistantMessage(obfuscator, message as AssistantMessage) as AgentMessage;
1153
+ return obfuscateAssistantMessage(
1154
+ obfuscator,
1155
+ message as AssistantMessage,
1156
+ sharedRegexSecretValues,
1157
+ ) as AgentMessage;
1053
1158
  case "custom":
1054
1159
  case "hookMessage": {
1160
+ if (!formatSessionHistoryMarkdown([message], { expandPrimaryContext: true }).trim()) return message;
1055
1161
  const msg = message as AgentMessage & {
1056
1162
  content: TextualContent;
1057
1163
  details?: Record<string, unknown>;
1058
1164
  };
1059
- const content = obfuscateTextualContent(obfuscator, msg.content);
1060
- const details = obfuscateDetails(obfuscator, msg.details);
1165
+ const content = obfuscateTextualContent(obfuscator, msg.content, sharedRegexSecretValues);
1166
+ const details = obfuscateDetails(obfuscator, msg.details, sharedRegexSecretValues);
1061
1167
  if (content === msg.content && details === msg.details) return message;
1062
1168
  return { ...(message as object), content, details } as AgentMessage;
1063
1169
  }
1064
1170
  case "bashExecution": {
1065
- const msg = message as AgentMessage & { command: string; output: string };
1066
- const command = obfuscator.obfuscate(msg.command);
1067
- const output = obfuscator.obfuscate(msg.output);
1068
- return command === msg.command && output === msg.output
1069
- ? message
1070
- : ({ ...(message as object), command, output } as AgentMessage);
1171
+ const msg = message as AgentMessage & { command: string };
1172
+ const command = obfuscator.obfuscate(formatExecutionSourcePreview(msg.command), sharedRegexSecretValues);
1173
+ return command === msg.command ? message : ({ ...(message as object), command } as AgentMessage);
1071
1174
  }
1072
1175
  case "pythonExecution": {
1073
- const msg = message as AgentMessage & { code: string; output: string };
1074
- const code = obfuscator.obfuscate(msg.code);
1075
- const output = obfuscator.obfuscate(msg.output);
1076
- return code === msg.code && output === msg.output
1077
- ? message
1078
- : ({ ...(message as object), code, output } as AgentMessage);
1176
+ const msg = message as AgentMessage & { code: string };
1177
+ const code = obfuscator.obfuscate(formatExecutionSourcePreview(msg.code), sharedRegexSecretValues);
1178
+ return code === msg.code ? message : ({ ...(message as object), code } as AgentMessage);
1079
1179
  }
1080
1180
  case "branchSummary": {
1081
1181
  const msg = message as AgentMessage & { summary: string };
1082
- const summary = obfuscator.obfuscate(msg.summary);
1182
+ const summary = obfuscator.obfuscate(msg.summary, sharedRegexSecretValues);
1083
1183
  return summary === msg.summary ? message : ({ ...(message as object), summary } as AgentMessage);
1084
1184
  }
1085
1185
  case "compactionSummary": {
1086
1186
  const msg = message as AgentMessage & { summary: string };
1087
- const summary = obfuscator.obfuscate(msg.summary);
1187
+ const summary = obfuscator.obfuscate(msg.summary, sharedRegexSecretValues);
1088
1188
  return summary === msg.summary ? message : ({ ...(message as object), summary } as AgentMessage);
1089
1189
  }
1090
1190
  case "fileMention": {
@@ -1093,11 +1193,10 @@ function obfuscateAdvisorMessage(obfuscator: SecretObfuscator, message: AgentMes
1093
1193
  };
1094
1194
  let changed = false;
1095
1195
  const files = msg.files.map(file => {
1096
- const path = obfuscator.obfuscate(file.path);
1097
- const content = obfuscator.obfuscate(file.content);
1098
- if (path === file.path && content === file.content) return file;
1196
+ const path = obfuscator.obfuscate(file.path, sharedRegexSecretValues);
1197
+ if (path === file.path) return file;
1099
1198
  changed = true;
1100
- return { ...file, path, content };
1199
+ return { ...file, path };
1101
1200
  });
1102
1201
  return changed ? ({ ...(message as object), files } as AgentMessage) : message;
1103
1202
  }
@@ -1106,12 +1205,14 @@ function obfuscateAdvisorMessage(obfuscator: SecretObfuscator, message: AgentMes
1106
1205
  }
1107
1206
  }
1108
1207
 
1109
- function obfuscateAdvisorDelta(obfuscator: SecretObfuscator, messages: AgentMessage[]): AgentMessage[] {
1110
- let changed = false;
1111
- const result = messages.map(message => {
1112
- const next = obfuscateAdvisorMessage(obfuscator, message);
1113
- if (next !== message) changed = true;
1114
- return next;
1115
- });
1116
- return changed ? result : messages;
1208
+ function scrubAdvisorHistory(
1209
+ obfuscator: SecretObfuscator,
1210
+ messages: AgentMessage[],
1211
+ sharedRegexSecretValues: ReadonlySet<string>,
1212
+ ): void {
1213
+ for (let index = 0; index < messages.length; index++) {
1214
+ const message = messages[index]!;
1215
+ const next = obfuscateAdvisorMessage(obfuscator, message, sharedRegexSecretValues);
1216
+ if (next !== message) messages[index] = next;
1217
+ }
1117
1218
  }
@@ -60,8 +60,19 @@ export interface AsyncJob {
60
60
  queued?: boolean;
61
61
  }
62
62
 
63
+ /** Delivery callback for a settled job's result text. */
64
+ export type AsyncJobDeliverySink = (jobId: string, text: string, job?: AsyncJob) => void | Promise<void>;
65
+
63
66
  export interface AsyncJobManagerOptions {
64
- onJobComplete: (jobId: string, text: string, job?: AsyncJob) => void | Promise<void>;
67
+ /**
68
+ * Delivery sink for UNOWNED completions (jobs registered without an
69
+ * `ownerId`). Owned deliveries route exclusively through
70
+ * {@link AsyncJobManager.registerDeliverySink}; when the owner has no live
71
+ * sink they are dead-lettered (dropped with a warning; the job row keeps
72
+ * the result text until retention eviction) — never routed here, which
73
+ * would leak one agent's result into another session.
74
+ */
75
+ onJobComplete?: AsyncJobDeliverySink;
65
76
  maxRunningJobs?: number;
66
77
  retentionMs?: number;
67
78
  }
@@ -128,6 +139,7 @@ export class AsyncJobManager {
128
139
  readonly #watchedJobs = new Set<string>();
129
140
  readonly #evictionTimers = new Map<string, NodeJS.Timeout>();
130
141
  readonly #pollEscalation = new Map<string | undefined, PollEscalationState>();
142
+ readonly #deliverySinks = new Map<string, AsyncJobDeliverySink>();
131
143
  readonly #onJobComplete: AsyncJobManagerOptions["onJobComplete"];
132
144
  readonly #maxRunningJobs: number;
133
145
  readonly #retentionMs: number;
@@ -409,6 +421,55 @@ export class AsyncJobManager {
409
421
  await Promise.all(Array.from(this.#jobs.values()).map(job => job.promise));
410
422
  }
411
423
 
424
+ /**
425
+ * Route completions for jobs owned by `ownerId` to `sink`. Sessions register
426
+ * their own sink at construction and unregister on dispose. Owned deliveries
427
+ * with no live sink are dead-lettered — `onJobComplete` serves only unowned
428
+ * deliveries.
429
+ *
430
+ * Last registration wins for an owner id; the returned unregister clears the
431
+ * mapping only while it still points at `sink`, so a revived session's fresh
432
+ * registration survives its parked predecessor's late cleanup.
433
+ */
434
+ registerDeliverySink(ownerId: string, sink: AsyncJobDeliverySink): () => void {
435
+ this.#deliverySinks.set(ownerId, sink);
436
+ return () => {
437
+ if (this.#deliverySinks.get(ownerId) === sink) this.#deliverySinks.delete(ownerId);
438
+ };
439
+ }
440
+
441
+ /**
442
+ * Wait until every job owned by `ownerId` has settled — its run promise
443
+ * resolved, which for cancelled jobs means the underlying process actually
444
+ * exited. Jobs registered while waiting (e.g. by a follow-up turn) are
445
+ * awaited too. Returns false when `timeoutMs` elapses first.
446
+ *
447
+ * `excludeSuppressed` skips jobs whose delivery is suppressed (acknowledged
448
+ * or `hub`-watched): those can never re-wake a run, so quiescence barriers
449
+ * pass it to share one contract with the pending-async-wake predicate.
450
+ * Teardown reaps omit it — worktree safety concerns every owner process.
451
+ */
452
+ async waitForOwnerJobs(
453
+ ownerId: string,
454
+ options?: { timeoutMs?: number; excludeSuppressed?: boolean },
455
+ ): Promise<boolean> {
456
+ const deadline =
457
+ options?.timeoutMs === undefined ? Number.POSITIVE_INFINITY : Date.now() + Math.max(0, options.timeoutMs);
458
+ const awaited = new Set<string>();
459
+ for (;;) {
460
+ const pending = this.#filterJobs(this.#jobs.values(), { ownerId }).filter(
461
+ job => !awaited.has(job.id) && (options?.excludeSuppressed !== true || !this.isDeliverySuppressed(job.id)),
462
+ );
463
+ if (pending.length === 0) return true;
464
+ for (const job of pending) awaited.add(job.id);
465
+ const settled = await this.#waitForDeliveryPromise(
466
+ Promise.all(pending.map(job => job.promise)).then(() => {}),
467
+ deadline,
468
+ );
469
+ if (!settled) return false;
470
+ }
471
+ }
472
+
412
473
  async #waitForAllUntil(deadline: number): Promise<boolean> {
413
474
  const promises = Array.from(this.#jobs.values()).map(job => job.promise);
414
475
  if (promises.length === 0) return true;
@@ -489,6 +550,7 @@ export class AsyncJobManager {
489
550
  this.#suppressedDeliveries.clear();
490
551
  this.#watchedJobs.clear();
491
552
  this.#pollEscalation.clear();
553
+ this.#deliverySinks.clear();
492
554
  return jobsSettled && drained;
493
555
  }
494
556
 
@@ -655,11 +717,37 @@ export class AsyncJobManager {
655
717
  }
656
718
  }
657
719
 
720
+ /**
721
+ * Resolve the sink for one delivery attempt: owned deliveries route ONLY to
722
+ * their owner's registered sink (a missing sink dead-letters — never the
723
+ * default, which would misroute a dead owner's result into another
724
+ * session); unowned deliveries use the constructor default. Resolved per
725
+ * attempt so a sink registered between retries (e.g. a revived session)
726
+ * picks up the retry.
727
+ */
728
+ #resolveDeliverySink(ownerId: string | undefined): AsyncJobDeliverySink | undefined {
729
+ if (ownerId !== undefined) return this.#deliverySinks.get(ownerId);
730
+ return this.#onJobComplete;
731
+ }
732
+
658
733
  #deliverDelivery(delivery: AsyncJobDelivery): Promise<void> {
734
+ const sink = this.#resolveDeliverySink(delivery.ownerId);
735
+ if (!sink) {
736
+ // Dead-letter: owned delivery with no live sink (session disposed or
737
+ // parked), or unowned delivery with no default sink. Drop it — the
738
+ // job row keeps its result/error text until retention eviction, so
739
+ // the outcome stays inspectable via job queries and agent:// reads.
740
+ logger.warn("Async job delivery dead-lettered: no delivery sink", {
741
+ jobId: delivery.jobId,
742
+ ownerId: delivery.ownerId,
743
+ });
744
+ delivery.promise = Promise.resolve();
745
+ return delivery.promise;
746
+ }
659
747
  const promise = (async () => {
660
748
  this.#inFlightDeliveries.push(delivery);
661
749
  try {
662
- await this.#onJobComplete(delivery.jobId, delivery.text, this.#jobs.get(delivery.jobId));
750
+ await sink(delivery.jobId, delivery.text, this.#jobs.get(delivery.jobId));
663
751
  } catch (error) {
664
752
  delivery.attempt += 1;
665
753
  delivery.lastError = error instanceof Error ? error.message : String(error);
package/src/cli/args.ts CHANGED
@@ -19,6 +19,8 @@ export type Mode = "text" | "json" | "rpc" | "acp" | "rpc-ui";
19
19
 
20
20
  export interface Args {
21
21
  cwd?: string;
22
+ /** Workspace directories beyond cwd for this session (repeatable `--add-dir`). */
23
+ addDir?: string[];
22
24
  profile?: string;
23
25
  alias?: string;
24
26
  allowHome?: boolean;
@@ -394,6 +396,7 @@ ${chalk.bold("Available Tools (default-enabled unless noted):")}
394
396
  notebook - Edit Jupyter notebooks
395
397
  inspect_image - Analyze images with a vision model
396
398
  browser - Browser automation (Puppeteer)
399
+ computer - Native host desktop capture and input (disabled by default)
397
400
  task - Launch sub-agents for parallel tasks
398
401
  todo - Manage todo/task lists
399
402
  web_search - Search the web
@@ -24,7 +24,12 @@ import {
24
24
  completeSimple,
25
25
  type Model,
26
26
  } from "@oh-my-pi/pi-ai";
27
- import { AuthBrokerClient, RemoteAuthCredentialStore, type SnapshotResponse } from "@oh-my-pi/pi-ai/auth-broker";
27
+ import {
28
+ AuthBrokerClient,
29
+ loadAuthBrokerAccountPool,
30
+ RemoteAuthCredentialStore,
31
+ type SnapshotResponse,
32
+ } from "@oh-my-pi/pi-ai/auth-broker";
28
33
  import { DEFAULT_AUTH_GATEWAY_BIND, startAuthGateway } from "@oh-my-pi/pi-ai/auth-gateway";
29
34
  import { type GeneratedProvider, getBundledModels, getBundledProviders } from "@oh-my-pi/pi-catalog/models";
30
35
  import { getConfigRootDir, isEnoent, VERSION } from "@oh-my-pi/pi-utils";
@@ -147,9 +152,14 @@ async function runServe(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
147
152
 
148
153
  // Build a broker-backed AuthStorage — same pattern as discoverAuthStorage()
149
154
  // in sdk.ts. The gateway never touches local SQLite.
155
+ const accountPool = await loadAuthBrokerAccountPool();
150
156
  const client = createBrokerClient(brokerConfig);
151
157
  const initialSnapshot = await fetchBrokerSnapshot(client);
152
- const store = new RemoteAuthCredentialStore({ client, initialSnapshot });
158
+ const store = new RemoteAuthCredentialStore({
159
+ client,
160
+ initialSnapshot,
161
+ accountPool,
162
+ });
153
163
  // Refresh + usage both flow through the store's broker hooks automatically —
154
164
  // `RemoteAuthCredentialStore.refreshOAuthCredential` and `.fetchUsageReports`.
155
165
  // AuthStorage discovers them when no explicit option overrides them, so the
@@ -538,9 +548,14 @@ async function runCheck(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
538
548
  );
539
549
  }
540
550
 
551
+ const accountPool = await loadAuthBrokerAccountPool();
541
552
  const client = createBrokerClient(brokerConfig);
542
553
  const initialSnapshot = await fetchBrokerSnapshot(client);
543
- const store = new RemoteAuthCredentialStore({ client, initialSnapshot });
554
+ const store = new RemoteAuthCredentialStore({
555
+ client,
556
+ initialSnapshot,
557
+ accountPool,
558
+ });
544
559
  const storage = new AuthStorage(store, { sourceLabel: `broker ${brokerConfig.url}` });
545
560
  try {
546
561
  await storage.reload();