pim-agent 0.12.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/package.json +4 -3
  2. package/packages/core/src/attachments/AttachmentStore.ts +8 -13
  3. package/packages/core/src/attachments/Attachments.ts +2 -4
  4. package/packages/core/src/extensions/CoreExtensions.ts +1 -1
  5. package/packages/core/src/extensions/apply-patch/coordinator.ts +1 -1
  6. package/packages/core/src/extensions/apply-patch/executor.ts +21 -25
  7. package/packages/core/src/extensions/apply-patch/matcher.ts +1 -1
  8. package/packages/core/src/extensions/apply-patch/model.ts +2 -6
  9. package/packages/core/src/extensions/apply-patch/parser.ts +60 -162
  10. package/packages/core/src/extensions/apply-patch/schema.ts +0 -1
  11. package/packages/core/src/extensions/bash/MemoryCap.ts +5 -4
  12. package/packages/core/src/extensions/bash/capture.ts +16 -23
  13. package/packages/core/src/extensions/bash/format.ts +2 -2
  14. package/packages/core/src/extensions/bash/image.ts +4 -8
  15. package/packages/core/src/extensions/bash/index.ts +1 -1
  16. package/packages/core/src/extensions/bash/render.ts +1 -1
  17. package/packages/core/src/extensions/bash/run.ts +9 -15
  18. package/packages/core/src/extensions/bash/schema.ts +4 -4
  19. package/packages/core/src/extensions/edit/edit.ts +14 -33
  20. package/packages/core/src/extensions/glob/glob.ts +1 -3
  21. package/packages/core/src/extensions/glob/index.ts +7 -9
  22. package/packages/core/src/extensions/glob/render.ts +2 -4
  23. package/packages/core/src/extensions/glob/schema.ts +1 -1
  24. package/packages/core/src/extensions/grep/grep.ts +7 -7
  25. package/packages/core/src/extensions/grep/render.ts +5 -6
  26. package/packages/core/src/extensions/grep/schema.ts +3 -7
  27. package/packages/core/src/extensions/read/ImageMemory.ts +2 -8
  28. package/packages/core/src/extensions/read/image.ts +3 -3
  29. package/packages/core/src/extensions/read/index.ts +2 -14
  30. package/packages/core/src/extensions/read/read.ts +5 -6
  31. package/packages/core/src/extensions/read/render.ts +1 -1
  32. package/packages/core/src/extensions/read/schema.ts +2 -2
  33. package/packages/core/src/extensions/subagent/render.ts +2 -2
  34. package/packages/core/src/extensions/subagent/subagent.ts +10 -21
  35. package/packages/core/src/extensions/system-prompt/index.ts +3 -2
  36. package/packages/core/src/extensions/system-prompt/prompt.ts +13 -3
  37. package/packages/core/src/extensions/todo/render.ts +1 -4
  38. package/packages/core/src/extensions/todo/todo.ts +16 -23
  39. package/packages/core/src/extensions/web-fetch/JinaReaderClient.ts +3 -11
  40. package/packages/core/src/extensions/web-fetch/WebViewFetchClient.ts +1 -3
  41. package/packages/core/src/extensions/web-fetch/fetch.ts +4 -12
  42. package/packages/core/src/extensions/web-fetch/image.ts +3 -4
  43. package/packages/core/src/extensions/web-fetch/index.ts +2 -13
  44. package/packages/core/src/extensions/web-fetch/render.ts +3 -4
  45. package/packages/core/src/extensions/web-fetch/schema.ts +3 -4
  46. package/packages/core/src/extensions/web-search/ExaMcpClient.ts +23 -31
  47. package/packages/core/src/extensions/web-search/SearchBreaker.ts +1 -1
  48. package/packages/core/src/extensions/web-search/SearchChain.ts +6 -5
  49. package/packages/core/src/extensions/web-search/providers/DuckDuckGoProvider.ts +2 -2
  50. package/packages/core/src/extensions/web-search/providers/FirecrawlProvider.ts +1 -2
  51. package/packages/core/src/extensions/web-search/providers/SearchProvider.ts +3 -3
  52. package/packages/core/src/extensions/write/write.ts +1 -1
  53. package/packages/core/src/picker/InProcessFilePickerSuggestionEngine.ts +1 -3
  54. package/packages/core/src/picker/PickerItem.ts +1 -1
  55. package/packages/core/src/picker/PickerService.ts +3 -7
  56. package/packages/core/src/picker/RemoteFilePickerSuggestionEngine.ts +1 -2
  57. package/packages/core/src/picker/catalog.ts +7 -15
  58. package/packages/core/src/picker/filePickerWorker.ts +1 -3
  59. package/packages/core/src/picker/ranker.ts +1 -1
  60. package/packages/core/src/picker/token.ts +3 -4
  61. package/packages/core/src/session/AgentRuntime.ts +5 -8
  62. package/packages/core/src/session/EventLog.ts +6 -12
  63. package/packages/core/src/session/ReadCursors.ts +3 -4
  64. package/packages/core/src/session/SearchIndex.ts +49 -86
  65. package/packages/core/src/session/SearchTokens.ts +4 -7
  66. package/packages/core/src/session/SessionCache.ts +8 -6
  67. package/packages/core/src/session/SessionDigest.ts +10 -19
  68. package/packages/core/src/session/SessionHost.ts +53 -83
  69. package/packages/core/src/session/SessionLease.ts +12 -15
  70. package/packages/core/src/session/SessionMeta.ts +16 -32
  71. package/packages/core/src/session/SessionName.ts +3 -7
  72. package/packages/core/src/session/SessionRegistry.ts +13 -29
  73. package/packages/core/src/session/SessionUi.ts +12 -16
  74. package/packages/core/src/session/WriteMark.ts +7 -16
  75. package/packages/core/src/shared/Cli.ts +1 -1
  76. package/packages/core/src/shared/DaemonUnit.ts +1 -2
  77. package/packages/core/src/shared/DiffLines.ts +16 -34
  78. package/packages/core/src/shared/DiffRenderer.ts +8 -27
  79. package/packages/core/src/shared/Directories.ts +4 -4
  80. package/packages/core/src/shared/EditMatcher.ts +18 -50
  81. package/packages/core/src/shared/ExtensionToggles.ts +3 -6
  82. package/packages/core/src/shared/FileEnumerator.ts +73 -57
  83. package/packages/core/src/shared/FileScanner.ts +5 -13
  84. package/packages/core/src/shared/FileWatch.ts +13 -17
  85. package/packages/core/src/shared/Format.ts +2 -3
  86. package/packages/core/src/shared/FuzzyMatcher.ts +18 -19
  87. package/packages/core/src/shared/Git.ts +22 -47
  88. package/packages/core/src/shared/GitMonitor.ts +12 -23
  89. package/packages/core/src/shared/GlobExclusions.ts +0 -4
  90. package/packages/core/src/shared/Http.ts +1 -1
  91. package/packages/core/src/shared/ImageMime.ts +3 -5
  92. package/packages/core/src/shared/Images.ts +17 -27
  93. package/packages/core/src/shared/Languages.ts +2 -2
  94. package/packages/core/src/shared/Levenshtein.ts +1 -6
  95. package/packages/core/src/shared/Lines.ts +1 -1
  96. package/packages/core/src/shared/McpClient.ts +2 -2
  97. package/packages/core/src/shared/PatchSummary.ts +1 -1
  98. package/packages/core/src/shared/Paths.ts +4 -1
  99. package/packages/core/src/shared/PiExtensions.ts +5 -12
  100. package/packages/core/src/shared/PimSettings.ts +14 -15
  101. package/packages/core/src/shared/Proc.ts +2 -3
  102. package/packages/core/src/shared/RateLimiter.ts +1 -1
  103. package/packages/core/src/shared/Renderer.ts +1 -3
  104. package/packages/core/src/shared/RepoDiff.ts +24 -46
  105. package/packages/core/src/shared/SearchRender.ts +3 -4
  106. package/packages/core/src/shared/SpillCache.ts +2 -3
  107. package/packages/core/src/shared/SubagentLogs.ts +4 -6
  108. package/packages/core/src/shared/Supervisor.ts +19 -32
  109. package/packages/core/src/shared/Surface.ts +1 -1
  110. package/packages/core/src/shared/Sweeper.ts +1 -1
  111. package/packages/core/src/shared/Tools.ts +17 -30
  112. package/packages/core/src/shared/Updater.ts +15 -15
  113. package/packages/core/src/view/BodyRenderer.ts +1 -1
  114. package/packages/core/src/view/DiffBlocks.ts +0 -1
  115. package/packages/core/src/view/DiffExpand.ts +10 -25
  116. package/packages/core/src/view/DiffLayout.ts +2 -2
  117. package/packages/core/src/view/DiffPairs.ts +2 -2
  118. package/packages/core/src/view/MarkdownPainter.ts +2 -19
  119. package/packages/core/src/view/MovePath.ts +4 -17
  120. package/packages/core/src/view/Painting.ts +4 -4
  121. package/packages/core/src/view/ViewBlock.ts +11 -12
  122. package/packages/daemon/src/Daemon.ts +2 -7
  123. package/packages/daemon/src/DaemonInstall.ts +5 -12
  124. package/packages/daemon/src/Surfaces.ts +3 -12
  125. package/packages/daemon/src/TelegramSurface.ts +0 -1
  126. package/packages/daemon/src/index.ts +0 -1
  127. package/packages/protocol/src/Command.ts +33 -41
  128. package/packages/protocol/src/Diff.ts +0 -5
  129. package/packages/protocol/src/ImageRoute.ts +2 -5
  130. package/packages/protocol/src/ServerEvent.ts +68 -105
  131. package/packages/server/src/AttachmentEndpoint.ts +45 -19
  132. package/packages/server/src/ClientConnection.ts +11 -12
  133. package/packages/server/src/ImageEndpoint.ts +3 -4
  134. package/packages/server/src/ProbeClient.ts +26 -59
  135. package/packages/server/src/Reloader.ts +4 -7
  136. package/packages/server/src/SendFileTool.ts +1 -1
  137. package/packages/server/src/SessionCatalogue.ts +35 -47
  138. package/packages/server/src/SessionProjection.ts +7 -12
  139. package/packages/server/src/SessionStream.ts +33 -80
  140. package/packages/server/src/StaticClient.ts +7 -8
  141. package/packages/server/src/WebOptions.ts +2 -6
  142. package/packages/server/src/WsGateway.ts +35 -96
  143. package/packages/server/src/probe.ts +6 -18
  144. package/packages/telegram/src/Bot.ts +2 -2
  145. package/packages/telegram/src/Commands.ts +108 -65
  146. package/packages/telegram/src/Config.ts +1 -6
  147. package/packages/telegram/src/Markdown.ts +4 -13
  148. package/packages/telegram/src/Renderer.ts +1 -1
  149. package/packages/telegram/src/Session.ts +3 -10
  150. package/packages/telegram/src/TaskScheduler.ts +31 -10
  151. package/packages/telegram/src/TaskStore.ts +11 -1
  152. package/packages/telegram/src/TaskTool.ts +1 -1
  153. package/packages/telegram/src/UpdateConfirm.ts +2 -2
  154. package/packages/tui/src/extensions/_init/index.ts +2 -5
  155. package/packages/tui/src/extensions/file-picker/index.ts +2 -6
  156. package/packages/tui/src/extensions/footer/index.ts +0 -1
  157. package/packages/tui/src/extensions/footer/powerline.ts +16 -28
  158. package/packages/tui/src/extensions/pim/index.ts +1 -1
  159. package/packages/tui/src/extensions/session-lease/index.ts +5 -6
  160. package/packages/tui/src/extensions/working-indicator/index.ts +1 -2
  161. package/packages/tui/src/themes/themeCliArgs.ts +1 -1
  162. package/packages/web/dist/client/assets/abnfDiagram-O67JEVCF-WweOU5DK.js +1 -0
  163. package/packages/web/dist/client/assets/arc-O2PmZXWt.js +1 -0
  164. package/packages/web/dist/client/assets/architecture-7GRP2DOG-COBxVilU.js +1 -0
  165. package/packages/web/dist/client/assets/architectureDiagram-NJMV4G6O-DwYq1YaM.js +36 -0
  166. package/packages/web/dist/client/assets/array-BifhSqXX.js +1 -0
  167. package/packages/web/dist/client/assets/blockDiagram-BEXU5L5S-CVab041n.js +140 -0
  168. package/packages/web/dist/client/assets/c4Diagram-YGBWAQC7-BmotHez3.js +38 -0
  169. package/packages/web/dist/client/assets/channel-BKV-IcTA.js +1 -0
  170. package/packages/web/dist/client/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  171. package/packages/web/dist/client/assets/chunk-3FUC2YCW-CWNS7-n4.js +2 -0
  172. package/packages/web/dist/client/assets/chunk-5DYCD2WN-DflvXohu.js +1 -0
  173. package/packages/web/dist/client/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  174. package/packages/web/dist/client/assets/chunk-742MDFTN-B_0t6_RE.js +1 -0
  175. package/packages/web/dist/client/assets/chunk-7INBJB4K-wKj0Q3Kv.js +62 -0
  176. package/packages/web/dist/client/assets/chunk-7M6MHVWA-BMvUghc8.js +213 -0
  177. package/packages/web/dist/client/assets/chunk-7PRAP22T-BY41wkcT.js +1 -0
  178. package/packages/web/dist/client/assets/chunk-DUW6YSOI-Dgx8z5s3.js +1 -0
  179. package/packages/web/dist/client/assets/chunk-FOHPRMQF-CoA4358r.js +161 -0
  180. package/packages/web/dist/client/assets/chunk-GTNCS2PH-PqY_YoS0.js +88 -0
  181. package/packages/web/dist/client/assets/chunk-GWA4HPMP-fozSU5ty.js +1 -0
  182. package/packages/web/dist/client/assets/chunk-J5ZVWO5B-oDCd-gWO.js +1 -0
  183. package/packages/web/dist/client/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  184. package/packages/web/dist/client/assets/chunk-MBY4JIJT-CrHrC3jw.js +72 -0
  185. package/packages/web/dist/client/assets/chunk-NETBCI7D-DWdAxieG.js +1 -0
  186. package/packages/web/dist/client/assets/chunk-O7XYJQB3-B6uOn9iS.js +128 -0
  187. package/packages/web/dist/client/assets/chunk-UA2S7LBM-BxYSHqyy.js +1 -0
  188. package/packages/web/dist/client/assets/chunk-WEXAMYUT-CtwIaQDa.js +1 -0
  189. package/packages/web/dist/client/assets/chunk-XXDRQBXY-fgBFe-PX.js +1 -0
  190. package/packages/web/dist/client/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  191. package/packages/web/dist/client/assets/chunk-Z7XXMR3K-CPonoV3p.js +10 -0
  192. package/packages/web/dist/client/assets/chunk-ZIGJFQKS-Cdu87cTj.js +2 -0
  193. package/packages/web/dist/client/assets/classDiagram-v2-NBCMYWYE-DSWsPaa7.js +217 -0
  194. package/packages/web/dist/client/assets/core-CBoS7AST.js +3 -0
  195. package/packages/web/dist/client/assets/cose-bilkent-JH36ORCC-CTwlldtJ.js +1 -0
  196. package/packages/web/dist/client/assets/cynefin-OW5HDTMX-CZQ4EPNJ.js +1 -0
  197. package/packages/web/dist/client/assets/cynefinDiagram-VND7K2PF-C2gp6H_Q.js +62 -0
  198. package/packages/web/dist/client/assets/cytoscape.esm-B-1iW2ft.js +321 -0
  199. package/packages/web/dist/client/assets/dagre-6A5THRUB-CDxTP47t.js +4 -0
  200. package/packages/web/dist/client/assets/defaultLocale-BFoDCU3G.js +1 -0
  201. package/packages/web/dist/client/assets/diagram-22UHCM2B-BIohE1lI.js +200 -0
  202. package/packages/web/dist/client/assets/diagram-3UASUU5V-TwAUir-w.js +24 -0
  203. package/packages/web/dist/client/assets/diagram-ATOU4E4O-BM1JQrIu.js +3 -0
  204. package/packages/web/dist/client/assets/diagram-CDSNMT55-BKIqhxSI.js +30 -0
  205. package/packages/web/dist/client/assets/diagram-MLGK6HIB-CVe3QDHr.js +24 -0
  206. package/packages/web/dist/client/assets/diagram-MPIPVDR6-Bj-MQIFI.js +41 -0
  207. package/packages/web/dist/client/assets/dist-DlZpcyc2.js +1 -0
  208. package/packages/web/dist/client/assets/ebnfDiagram-ZINNZB2B-C06mmvmz.js +1 -0
  209. package/packages/web/dist/client/assets/elk-276RUBZZ-CizJSNEj.js +27 -0
  210. package/packages/web/dist/client/assets/erDiagram-OPXOYQCR-M3FQkKI1.js +99 -0
  211. package/packages/web/dist/client/assets/eventmodeling-NTZA5JFV-D_UXLpIu.js +1 -0
  212. package/packages/web/dist/client/assets/flowDiagram-KWPJA3E3-BT4eEEVm.js +1 -0
  213. package/packages/web/dist/client/assets/ganttDiagram-FUAMR5RP-CojF9Q16.js +292 -0
  214. package/packages/web/dist/client/assets/gitGraph-4MIJSDKK-YvKqGEPk.js +1 -0
  215. package/packages/web/dist/client/assets/gitGraphDiagram-X574FWY7-XqNqIFo9.js +106 -0
  216. package/packages/web/dist/client/assets/graphlib-DS17s2tU.js +1 -0
  217. package/packages/web/dist/client/assets/index--2CDtzvY.css +1 -0
  218. package/packages/web/dist/client/assets/index-bT6QPJZs.js +47 -0
  219. package/packages/web/dist/client/assets/info-A6RAGUB7-B_1BCzM2.js +1 -0
  220. package/packages/web/dist/client/assets/infoDiagram-VRGFBTTK-zFX8B-dP.js +2 -0
  221. package/packages/web/dist/client/assets/init-C-OQMol4.js +1 -0
  222. package/packages/web/dist/client/assets/ishikawaDiagram-OU5B5YK6-DLzQ_Uyf.js +70 -0
  223. package/packages/web/dist/client/assets/journeyDiagram-ZHPQQLJL-S3WRMmoa.js +139 -0
  224. package/packages/web/dist/client/assets/kanban-definition-PNTS6WVX-B5Z8I-kM.js +89 -0
  225. package/packages/web/dist/client/assets/katex-ZlcWpGUi.js +257 -0
  226. package/packages/web/dist/client/assets/line-BGMH-i2X.js +1 -0
  227. package/packages/web/dist/client/assets/linear-KsrestXG.js +1 -0
  228. package/packages/web/dist/client/assets/mermaid-parser.core-DNffyJJA.js +7 -0
  229. package/packages/web/dist/client/assets/mermaid.core-Cz3vJeQG.js +44 -0
  230. package/packages/web/dist/client/assets/mindmap-definition-NLK3R4M7-CzA61XUf.js +96 -0
  231. package/packages/web/dist/client/assets/ordinal-BDEzSJ7C.js +1 -0
  232. package/packages/web/dist/client/assets/packet-AYTQ26CC-BO55e7cR.js +1 -0
  233. package/packages/web/dist/client/assets/path-fybaL0A-.js +1 -0
  234. package/packages/web/dist/client/assets/pegDiagram-GJSIUBJH-DeRiXYNd.js +1 -0
  235. package/packages/web/dist/client/assets/pie-WAS4IAKB-D9ibrQRe.js +1 -0
  236. package/packages/web/dist/client/assets/pieDiagram-5QR66LMP-BaBpPP33.js +39 -0
  237. package/packages/web/dist/client/assets/quadrantDiagram-O4NWA36T-DIfn4GjM.js +7 -0
  238. package/packages/web/dist/client/assets/radar-RG4KPBEZ-Dmn5-nJq.js +1 -0
  239. package/packages/web/dist/client/assets/railroad-74A4TZTK-ZCWNEd2Z.js +1 -0
  240. package/packages/web/dist/client/assets/railroad-abnf-HS5TGJTU-_swqhy0y.js +1 -0
  241. package/packages/web/dist/client/assets/railroad-ebnf-LZEXJU2U-CytbazPx.js +1 -0
  242. package/packages/web/dist/client/assets/railroad-peg-WCYAUIDC-Bg8QW17T.js +1 -0
  243. package/packages/web/dist/client/assets/railroadDiagram-XR7U4H2S-CDPZ39sy.js +1 -0
  244. package/packages/web/dist/client/assets/requirementDiagram-PLB6GJNP-CyCI8Yul.js +84 -0
  245. package/packages/web/dist/client/assets/rough.esm-Dy-Kn_BL.js +1 -0
  246. package/packages/web/dist/client/assets/sankeyDiagram-IPEJSGJF-p_XAPv72.js +40 -0
  247. package/packages/web/dist/client/assets/sequenceDiagram-PO4LG4MO-DmR6IP_o.js +169 -0
  248. package/packages/web/dist/client/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  249. package/packages/web/dist/client/assets/src-gnv7pJ1z.js +1 -0
  250. package/packages/web/dist/client/assets/stateDiagram-v2-GCMORJYK-7ZTHl6ih.js +291 -0
  251. package/packages/web/dist/client/assets/swimlanes-2SLR337P-N6bj71pw.js +1 -0
  252. package/packages/web/dist/client/assets/swimlanesDiagram-TC7HE7FX-BJQ2CBsp.js +8 -0
  253. package/packages/web/dist/client/assets/timeline-definition-EJHVYXUP-GNez0kW8.js +120 -0
  254. package/packages/web/dist/client/assets/treeView-Q6P3EWNA-DyQZkboR.js +1 -0
  255. package/packages/web/dist/client/assets/treemap-WGGIJYW6-_J8Pw2TM.js +1 -0
  256. package/packages/web/dist/client/assets/usecaseDiagram-POWQR4AR-Bg-CzKjl.js +328 -0
  257. package/packages/web/dist/client/assets/vennDiagram-UO4OBE2U-DBQKHXhK.js +34 -0
  258. package/packages/web/dist/client/assets/wardley-WFR3VGLG-B5aAsQ3F.js +1 -0
  259. package/packages/web/dist/client/assets/wardleyDiagram-VNRHLVJA-BKUQ1LK6.js +78 -0
  260. package/packages/web/dist/client/assets/xychartDiagram-PMCCYNJV-BI2sVbks.js +7 -0
  261. package/packages/web/dist/client/index.html +2 -2
  262. package/packages/web/dist/client/assets/core-C5fJJN75.js +0 -3
  263. package/packages/web/dist/client/assets/index-C5D7B_8d.js +0 -45
  264. package/packages/web/dist/client/assets/index-OVLzpES-.css +0 -1
@@ -20,7 +20,6 @@ export type FirecrawlProviderOptions = {
20
20
  const defaultEndpoint = "https://api.firecrawl.dev/v2/search";
21
21
  const defaultTimeoutMs = 20_000;
22
22
 
23
- /** Firecrawl search; omitting `Authorization` is the keyless tier, whose exhaustion shows only as a 429. */
24
23
  export class FirecrawlProvider implements SearchProvider {
25
24
  public readonly name = "firecrawl";
26
25
 
@@ -73,7 +72,7 @@ export class FirecrawlProvider implements SearchProvider {
73
72
  quotaStatuses: [429],
74
73
  quotaMessage:
75
74
  "Firecrawl rejected the request: keyless daily limit reached.",
76
- // Firecrawl meters a rolling 24h window and reports the remainder in the body, not Retry-After.
75
+ // Firecrawl reports the wait in the body, not Retry-After.
77
76
  readRetryAfterMs,
78
77
  });
79
78
  }
@@ -18,7 +18,7 @@ export type SearchProvider = {
18
18
  search(input: ProviderSearchInput): Promise<readonly SearchResult[]>;
19
19
  };
20
20
 
21
- /** Quota or rate limit exhausted; only this error opens the breaker and sidelines a provider. */
21
+ /** The only error that trips the breaker. */
22
22
  export class ProviderQuotaError extends Error {
23
23
  public readonly provider: string;
24
24
  public readonly retryAfterMs: number | undefined;
@@ -43,7 +43,7 @@ export class ProviderSearchError extends Error {
43
43
 
44
44
  const MAX_SNIPPET_LENGTH = 500;
45
45
 
46
- /** Caps a provider snippet; Firecrawl returns whole scraped pages where others return two lines. */
46
+ /** Collapses whitespace and caps length; Firecrawl can return whole pages. */
47
47
  export function normalizeSnippet(value: string | undefined): string {
48
48
  const collapsed = (value ?? "").replaceAll(/\s+/gu, " ").trim();
49
49
 
@@ -52,7 +52,7 @@ export function normalizeSnippet(value: string | undefined): string {
52
52
  : collapsed;
53
53
  }
54
54
 
55
- export function parseRetryAfterMs(value: string | null): number | undefined {
55
+ function parseRetryAfterMs(value: string | null): number | undefined {
56
56
  if (value === null) {
57
57
  return undefined;
58
58
  }
@@ -4,7 +4,7 @@ import { FsErrors } from "../../shared/FsErrors";
4
4
 
5
5
  const CONTEXT_LINES = 3;
6
6
 
7
- // Diff.diffLines is O(n*d): above this only the diff is skipped, never the write.
7
+ // Diffing is O(n*d); above this the diff is skipped, not the write.
8
8
  const MAX_DIFF_BYTES = 2 * 1024 * 1024;
9
9
 
10
10
  export type WriteOutcome = {
@@ -25,9 +25,7 @@ export class InProcessFilePickerSuggestionEngine implements FilePickerSuggestion
25
25
  this.cachedRelative = catalog;
26
26
  })
27
27
  .catch(() => {
28
- if (this.cachedRelative === undefined) {
29
- this.cachedRelative = [];
30
- }
28
+ this.cachedRelative ??= [];
31
29
  })
32
30
  .finally(() => {
33
31
  this.refresh = undefined;
@@ -1,4 +1,4 @@
1
- /** One completion row, structurally identical to pi-tui's `AutocompleteItem`. */
1
+ /** Structurally identical to pi-tui's `AutocompleteItem`. */
2
2
  export type PickerItem = {
3
3
  readonly value: string;
4
4
  readonly label: string;
@@ -9,19 +9,16 @@ import { InProcessFilePickerSuggestionEngine } from "./InProcessFilePickerSugges
9
9
  import type { PickerItem } from "./PickerItem";
10
10
 
11
11
  export type PickerServiceDeps = {
12
- /** Read per query: a session's cwd can move between turns. */
12
+ /** Read per query; the cwd can change between turns. */
13
13
  readonly cwd: () => string;
14
14
  readonly agentDir: string;
15
- /** Extension-registered commands, available only while an agent is built. */
15
+ /** Source of extension commands; undefined until an agent is built. */
16
16
  readonly agent?: () => AgentSession | undefined;
17
17
  };
18
18
 
19
19
  const DEFAULT_LIMIT = 50;
20
20
 
21
- /**
22
- * The `.agents/skills` roots pi reads and `loadSkills` does not: every one from
23
- * the cwd up to the repository root, plus the user's own.
24
- */
21
+ /** `.agents/skills` dirs from cwd up to the repo root, plus `~/.agents/skills`; `loadSkills` skips these. */
25
22
  function agentsSkillDirs(cwd: string): string[] {
26
23
  const dirs: string[] = [];
27
24
  let dir = resolve(cwd);
@@ -37,7 +34,6 @@ function agentsSkillDirs(cwd: string): string[] {
37
34
  return dirs;
38
35
  }
39
36
 
40
- /** Answers one session's picker queries against the machine the agent runs on. */
41
37
  export class PickerService {
42
38
  private readonly deps: PickerServiceDeps;
43
39
  private fileCache:
@@ -13,7 +13,7 @@ const DEBOUNCE_MS = 30;
13
13
 
14
14
  const CACHE_LIMIT = 100;
15
15
 
16
- /** The client half of the `@` picker: the TUI's engine contract, answered by the server. Browser-safe APIs only. */
16
+ /** Browser-safe: asks the server for `@` picker rows. */
17
17
  export class RemoteFilePickerSuggestionEngine implements FilePickerSuggestionEngine {
18
18
  private readonly cache = new Map<string, readonly PickerItem[]>();
19
19
  private generation = 0;
@@ -23,7 +23,6 @@ export class RemoteFilePickerSuggestionEngine implements FilePickerSuggestionEng
23
23
  private readonly debounceMs: number = DEBOUNCE_MS
24
24
  ) {}
25
25
 
26
- /** The invalidation hook: `picker_invalidate` from the server lands here. */
27
26
  public refreshRelative(): Promise<void> {
28
27
  this.cache.clear();
29
28
  return Promise.resolve();
@@ -122,14 +122,13 @@ async function runLoadRelative(
122
122
  options: LoadRelativeOptions
123
123
  ): Promise<readonly FileCandidate[]> {
124
124
  const spawner = options.gitSpawner ?? defaultGitSpawner;
125
-
126
- const fastPath = await tryGitListFiles(root, spawner);
127
- if (fastPath !== undefined) {
128
- return finalizeRelative(fastPath);
129
- }
130
-
131
- const fallback = await scanWithGlob(root);
132
- return finalizeRelative(fallback);
125
+ const paths =
126
+ (await tryGitListFiles(root, spawner)) ??
127
+ (await FileEnumerator.enumerate(root, {
128
+ includeDotfiles: false,
129
+ includeIgnored: false,
130
+ }));
131
+ return finalizeRelative(paths);
133
132
  }
134
133
 
135
134
  async function tryGitListFiles(
@@ -148,13 +147,6 @@ async function tryGitListFiles(
148
147
  return result.stdout.split("\n").filter((line) => line.length > 0);
149
148
  }
150
149
 
151
- async function scanWithGlob(root: string): Promise<readonly string[]> {
152
- return FileEnumerator.enumerate(root, {
153
- includeDotfiles: false,
154
- includeIgnored: false,
155
- });
156
- }
157
-
158
150
  function finalizeRelative(paths: readonly string[]): readonly FileCandidate[] {
159
151
  const normalized = paths.map(Paths.toForwardSlashes);
160
152
 
@@ -18,9 +18,7 @@ const refreshRelative = async (id: number, root: string): Promise<void> => {
18
18
  ok: true,
19
19
  } satisfies FilePickerWorkerResponse);
20
20
  } catch (error) {
21
- if (cachedRelative === undefined) {
22
- cachedRelative = [];
23
- }
21
+ cachedRelative ??= [];
24
22
  self.postMessage({
25
23
  id,
26
24
  type: "refreshRelative",
@@ -164,7 +164,7 @@ class RelativeRankingIndex {
164
164
  substringHits.push(candidate);
165
165
  }
166
166
 
167
- // Only prefix hits may end the scan early: a late prefix must not lose to an earlier substring.
167
+ // Only prefix hits end the scan, so a late prefix hit still beats substrings.
168
168
  if (prefixHits.length >= limitSize) {
169
169
  break;
170
170
  }
@@ -1,15 +1,14 @@
1
- /** Which picker the caret is sitting in, if any. */
2
1
  export type PickerToken = {
3
2
  readonly kind: "file" | "command";
4
3
  readonly query: string;
5
- /** Offset of the sigil itself, so a completion replaces it too. */
4
+ /** Offset of the sigil. */
6
5
  readonly start: number;
7
6
  };
8
7
 
9
8
  export const AT_PREFIX = /(?:^|\s)@(\S*)$/;
10
9
  export const SLASH_PREFIX = /(?:^|\s)\/(\S*)$/;
11
10
 
12
- /** Offset of the sigil in a match that also swallows the whitespace before it. */
11
+ /** Skips the leading whitespace the prefix regexes may match. */
13
12
  export function sigilOffset(match: RegExpMatchArray): number {
14
13
  const matched = match[0] ?? "";
15
14
  return (match.index ?? 0) + (/^\s/.test(matched) ? 1 : 0);
@@ -53,7 +52,7 @@ export function tokenKey(token: PickerToken | undefined): string {
53
52
  export type Completion = {
54
53
  readonly text: string;
55
54
  readonly caret: number;
56
- /** A directory keeps the picker open so the next segment can be drilled into. */
55
+ /** True for a directory, so the next segment can be picked. */
57
56
  readonly keepOpen: boolean;
58
57
  };
59
58
 
@@ -7,19 +7,16 @@ import {
7
7
  } from "@earendil-works/pi-coding-agent";
8
8
  import { join } from "node:path";
9
9
 
10
- /** One model a session can be switched to, named the way `setModel` takes it. */
11
10
  export type ModelChoice = {
11
+ /** `provider/id`, as `setModel` takes it. */
12
12
  readonly id: string;
13
13
  readonly label: string;
14
- /** Who serves it, for a client that groups or tags the catalogue. */
15
14
  readonly provider: string;
16
15
  };
17
16
 
18
17
  /**
19
- * Pi's installation as one process sees it: a single `ModelRuntime` over a
20
- * single `auth.json`, and one `SettingsManager` per cwd. Every surface in a
21
- * process shares one of these — two runtimes over one auth file race each
22
- * other's token refresh.
18
+ * One `ModelRuntime` per process, shared by every surface: two runtimes over
19
+ * one `auth.json` race each other's token refresh.
23
20
  */
24
21
  export class AgentRuntime {
25
22
  public readonly agentDir: string;
@@ -32,7 +29,7 @@ export class AgentRuntime {
32
29
  this.agentDir = agentDir ?? getAgentDir();
33
30
  }
34
31
 
35
- /** Idempotent, and shared by every caller: the second surface to ask waits on the first. */
32
+ /** Idempotent; concurrent callers share one boot. A failed boot can be retried. */
36
33
  public init(): Promise<void> {
37
34
  this.booting ??= this.bootstrap().catch((err: unknown) => {
38
35
  this.booting = undefined;
@@ -49,7 +46,7 @@ export class AgentRuntime {
49
46
  return this.required(this.registry);
50
47
  }
51
48
 
52
- /** Every model this machine has credentials for, qualified as `setModel` takes them. */
49
+ /** Models with credentials available. */
53
50
  public models(): readonly ModelChoice[] {
54
51
  return this.modelRegistry.getAvailable().map((model: Model<ModelApi>) => ({
55
52
  id: `${model.provider}/${model.id}`,
@@ -18,7 +18,7 @@ async function ifPresent<T>(read: () => Promise<T>, absent: T): Promise<T> {
18
18
  }
19
19
  }
20
20
 
21
- /** One durable line of a session file; the header is line 1, so entries start at `seq` 2. */
21
+ /** `seq` is the 1-based line number; the header is line 1. */
22
22
  export type LoggedEntry = {
23
23
  readonly seq: number;
24
24
  readonly entry: FileEntry;
@@ -40,7 +40,7 @@ function isHeader(entry: FileEntry): entry is SessionHeader {
40
40
  return entry.type === "session";
41
41
  }
42
42
 
43
- /** A reader over one pi session file: append-only JSONL, so a line's `seq` never changes. */
43
+ /** Reader over one append-only pi session file. */
44
44
  export class EventLog {
45
45
  public readonly path: string;
46
46
  private cursor: Cursor = { offset: 0, seq: 0 };
@@ -56,7 +56,7 @@ export class EventLog {
56
56
  const file = Bun.file(this.path);
57
57
  const text = await ifPresent(() => file.slice(start.offset).text(), "");
58
58
 
59
- // A trailing fragment is a write in progress: stop short of it or reads lose entries.
59
+ // Skip a trailing partial line; it is still being written.
60
60
  const lastBreak = text.lastIndexOf("\n");
61
61
  if (lastBreak === -1) {
62
62
  return [];
@@ -92,24 +92,18 @@ export class EventLog {
92
92
  return undefined;
93
93
  }
94
94
 
95
- /** The `seq` of the last complete line, without parsing any of them. */
95
+ /** The `seq` of the last complete line. */
96
96
  public async head(): Promise<number> {
97
97
  await this.read(Number.MAX_SAFE_INTEGER);
98
98
  return this.cursor.seq;
99
99
  }
100
100
 
101
- /**
102
- * The name pi's own `/name` writes: the last `session_info` entry wins, and an
103
- * empty one clears it. Appended rather than replaced, so it is found by reading
104
- * the whole file — the one unbounded read the catalogue makes, and the only
105
- * reason `SessionDigest` takes a whole file rather than a bounded head and tail.
106
- */
101
+ /** The last `session_info` name; an empty one clears it. Reads the whole file. */
107
102
  public async name(): Promise<string | undefined> {
108
103
  const body = await durableBytes(Bun.file(this.path));
109
104
  return body === undefined ? undefined : SessionDigest.nameOf(body);
110
105
  }
111
106
 
112
- /** Title and settle time for the catalogue, without opening a session. */
113
107
  public async digest(): Promise<SessionDigest> {
114
108
  const body = await durableBytes(Bun.file(this.path));
115
109
  return body === undefined
@@ -122,7 +116,7 @@ async function* headLines(
122
116
  file: BunFile,
123
117
  count: number
124
118
  ): AsyncGenerator<string> {
125
- // Decode with `stream: true`: a chunk boundary can split a character.
119
+ // `stream: true`: a chunk boundary can split a character.
126
120
  const decoder = new TextDecoder();
127
121
  let pending = "";
128
122
  let yielded = 0;
@@ -22,7 +22,6 @@ export class ReadCursors {
22
22
  this.ready = this.load();
23
23
  }
24
24
 
25
- /** Whether a session has been answered since anything last read it. */
26
25
  public async isUnread(
27
26
  sessionId: string,
28
27
  answeredAt: number | undefined
@@ -34,7 +33,7 @@ export class ReadCursors {
34
33
  );
35
34
  }
36
35
 
37
- /** Moves a session's cursor forward; the write behind it is not waited on. */
36
+ /** Only moves forward. Does not wait for the write. */
38
37
  public async mark(sessionId: string, at: number = Date.now()): Promise<void> {
39
38
  await this.ready;
40
39
  if ((this.cursors.get(sessionId) ?? this.baseline) >= at) {
@@ -58,7 +57,7 @@ export class ReadCursors {
58
57
  }
59
58
  }
60
59
 
61
- /** Settles the writes behind the marks taken so far, for a clean stop. */
60
+ /** Waits for pending writes. */
62
61
  public async flush(): Promise<void> {
63
62
  await this.ready;
64
63
  await this.writes.run(async () => undefined);
@@ -69,7 +68,7 @@ export class ReadCursors {
69
68
  .json()
70
69
  .catch(() => undefined)) as Partial<Stored> | undefined;
71
70
  if (typeof stored?.baseline !== "number") {
72
- // Persist the baseline now: recomputing it on each start clears every unread session.
71
+ // Persist it, or every restart would mark everything read.
73
72
  this.baseline = Date.now();
74
73
  this.persist();
75
74
  return;