@astralyn/pi 1.4.11 → 1.5.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 (546) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/bundle/chunks/anthropic-messages-G5ZGBHOH.js +6 -0
  3. package/dist/bundle/chunks/azure-openai-responses-EMPTMYNF.js +2 -0
  4. package/dist/bundle/chunks/bedrock-converse-stream.js +22 -15
  5. package/dist/bundle/chunks/chunk-AXX7FFFD.js +2 -0
  6. package/dist/bundle/chunks/chunk-FNGB3ASD.js +2 -0
  7. package/dist/bundle/chunks/chunk-FPALVF3F.js +4 -0
  8. package/dist/bundle/chunks/chunk-H3UF54OB.js +9 -0
  9. package/dist/bundle/chunks/chunk-IC6JXX2J.js +10 -0
  10. package/dist/bundle/chunks/{chunk-TH3QDDPD.js → chunk-IRUUTK4W.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-MZJC45TM.js → chunk-J7L6O5XA.js} +3 -3
  12. package/dist/bundle/chunks/{chunk-DLVLAQEG.js → chunk-KBFO53OG.js} +3 -3
  13. package/dist/bundle/chunks/{chunk-TPVFPFJP.js → chunk-P7VXFB2M.js} +1 -1
  14. package/dist/bundle/chunks/chunk-PSYLMRL6.js +9 -0
  15. package/dist/bundle/chunks/chunk-QNZARXLE.js +82 -0
  16. package/dist/bundle/chunks/chunk-R3YHAMWH.js +1503 -0
  17. package/dist/bundle/chunks/chunk-RAIYJ5FC.js +4 -0
  18. package/dist/bundle/chunks/{chunk-OV2VMHBX.js → chunk-SR6EWNPW.js} +1 -1
  19. package/dist/bundle/chunks/chunk-TA3YH2ZI.js +16 -0
  20. package/dist/bundle/chunks/{chunk-NUQMVNKQ.js → chunk-THAJ4BZF.js} +58 -62
  21. package/dist/bundle/chunks/{chunk-24FY4C5S.js → chunk-TRSJS3FM.js} +1 -1
  22. package/dist/bundle/chunks/chunk-ZRI3ICDE.js +2 -0
  23. package/dist/bundle/chunks/{cli-MBFCFGI2.js → cli-LAZQG54B.js} +11 -9
  24. package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-7BKATOEJ.js → cloudflare-workers-ai-system-one-4L2ABUJE.js} +1 -1
  25. package/dist/bundle/chunks/{execute-VLAIP26K.js → execute-ACWDKC3C.js} +1 -1
  26. package/dist/bundle/chunks/github-copilot.js +1 -1
  27. package/dist/bundle/chunks/{google-generative-ai-HTUSU45F.js → google-generative-ai-OOVDGS5W.js} +1 -1
  28. package/dist/bundle/chunks/{google-vertex-AVQV4P76.js → google-vertex-IK5RNG7J.js} +1 -1
  29. package/dist/bundle/chunks/image-resize-worker.js +1 -1
  30. package/dist/bundle/chunks/kimi-coding.js +1 -1
  31. package/dist/bundle/chunks/{llama-cpp-classify-27QYLJZY.js → llama-cpp-classify-XHAVT37C.js} +1 -1
  32. package/dist/bundle/chunks/meta.js +1 -1
  33. package/dist/bundle/chunks/mistral-conversations-Z56KY4OJ.js +5 -0
  34. package/dist/bundle/chunks/{openai-codex-responses-Q25MHDFX.js → openai-codex-responses-5NAH3SK6.js} +1 -1
  35. package/dist/bundle/chunks/openai-completions-S7S6PO3J.js +7 -0
  36. package/dist/bundle/chunks/{openai-decisions-3WYFPGSK.js → openai-decisions-7A36EAHE.js} +1 -1
  37. package/dist/bundle/chunks/{openai-responses-E4BNZIQK.js → openai-responses-ZQRZJKH4.js} +1 -1
  38. package/dist/bundle/chunks/{openrouter-images-CBP3OPOD.js → openrouter-images-X7PX72ON.js} +1 -1
  39. package/dist/bundle/chunks/pi-messages-TXNWPLI4.js +8 -0
  40. package/dist/bundle/chunks/radius.js +1 -1
  41. package/dist/bundle/chunks/{runtime-3RPOJS5T.js → runtime-X3XOMNXQ.js} +1 -1
  42. package/dist/bundle/chunks/{typesafe-system-one-BNICP2LS.js → typesafe-system-one-XJGMSHWL.js} +1 -1
  43. package/dist/bundle/chunks/virtual-modules-T2KLVAFL.js +2 -0
  44. package/dist/bundle/cli.js +1 -1
  45. package/dist/bundle/index.js +1 -1
  46. package/dist/bundle/rpc-entry.js +1 -1
  47. package/dist/cli/args.d.ts.map +1 -1
  48. package/dist/cli/args.js +8 -7
  49. package/dist/cli/args.js.map +1 -1
  50. package/dist/config.d.ts +10 -0
  51. package/dist/config.d.ts.map +1 -1
  52. package/dist/config.js +24 -5
  53. package/dist/config.js.map +1 -1
  54. package/dist/core/agent-session-runtime.d.ts +0 -5
  55. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  56. package/dist/core/agent-session-runtime.js +12 -28
  57. package/dist/core/agent-session-runtime.js.map +1 -1
  58. package/dist/core/agent-session.d.ts +21 -14
  59. package/dist/core/agent-session.d.ts.map +1 -1
  60. package/dist/core/agent-session.js +67 -93
  61. package/dist/core/agent-session.js.map +1 -1
  62. package/dist/core/compaction/branch-summarization.d.ts +4 -2
  63. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  64. package/dist/core/compaction/branch-summarization.js +16 -4
  65. package/dist/core/compaction/branch-summarization.js.map +1 -1
  66. package/dist/core/exec.d.ts +9 -1
  67. package/dist/core/exec.d.ts.map +1 -1
  68. package/dist/core/exec.js +104 -60
  69. package/dist/core/exec.js.map +1 -1
  70. package/dist/core/export-html/template.css +9 -0
  71. package/dist/core/export-html/template.js +165 -45
  72. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  73. package/dist/core/export-html/tool-renderer.js +5 -0
  74. package/dist/core/export-html/tool-renderer.js.map +1 -1
  75. package/dist/core/extensions/index.d.ts +1 -1
  76. package/dist/core/extensions/index.d.ts.map +1 -1
  77. package/dist/core/extensions/index.js.map +1 -1
  78. package/dist/core/extensions/loader.d.ts.map +1 -1
  79. package/dist/core/extensions/loader.js +7 -6
  80. package/dist/core/extensions/loader.js.map +1 -1
  81. package/dist/core/extensions/pi-ai-extension-view.d.ts +19 -0
  82. package/dist/core/extensions/pi-ai-extension-view.d.ts.map +1 -0
  83. package/dist/core/extensions/pi-ai-extension-view.js +22 -0
  84. package/dist/core/extensions/pi-ai-extension-view.js.map +1 -0
  85. package/dist/core/extensions/runner.d.ts +0 -1
  86. package/dist/core/extensions/runner.d.ts.map +1 -1
  87. package/dist/core/extensions/runner.js +7 -12
  88. package/dist/core/extensions/runner.js.map +1 -1
  89. package/dist/core/extensions/types.d.ts +41 -23
  90. package/dist/core/extensions/types.d.ts.map +1 -1
  91. package/dist/core/extensions/types.js.map +1 -1
  92. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  93. package/dist/core/extensions/virtual-modules.js +8 -7
  94. package/dist/core/extensions/virtual-modules.js.map +1 -1
  95. package/dist/core/mcp-servers.d.ts +11 -4
  96. package/dist/core/mcp-servers.d.ts.map +1 -1
  97. package/dist/core/mcp-servers.js +15 -5
  98. package/dist/core/mcp-servers.js.map +1 -1
  99. package/dist/core/model-config.d.ts +1678 -2029
  100. package/dist/core/model-config.d.ts.map +1 -1
  101. package/dist/core/model-config.js +2 -3
  102. package/dist/core/model-config.js.map +1 -1
  103. package/dist/core/model-resolver.d.ts.map +1 -1
  104. package/dist/core/model-resolver.js +16 -10
  105. package/dist/core/model-resolver.js.map +1 -1
  106. package/dist/core/package-manager.d.ts +14 -0
  107. package/dist/core/package-manager.d.ts.map +1 -1
  108. package/dist/core/package-manager.js +160 -46
  109. package/dist/core/package-manager.js.map +1 -1
  110. package/dist/core/pi-ai-schemas.d.ts +163 -0
  111. package/dist/core/pi-ai-schemas.d.ts.map +1 -0
  112. package/dist/core/pi-ai-schemas.js +21 -0
  113. package/dist/core/pi-ai-schemas.js.map +1 -0
  114. package/dist/core/pi-manifest.d.ts +1 -0
  115. package/dist/core/pi-manifest.d.ts.map +1 -1
  116. package/dist/core/pi-manifest.js +4 -0
  117. package/dist/core/pi-manifest.js.map +1 -1
  118. package/dist/core/project-trust.js +1 -1
  119. package/dist/core/project-trust.js.map +1 -1
  120. package/dist/core/quiescence.d.ts +24 -0
  121. package/dist/core/quiescence.d.ts.map +1 -0
  122. package/dist/core/quiescence.js +81 -0
  123. package/dist/core/quiescence.js.map +1 -0
  124. package/dist/core/resource-loader.d.ts +4 -1
  125. package/dist/core/resource-loader.d.ts.map +1 -1
  126. package/dist/core/resource-loader.js +41 -28
  127. package/dist/core/resource-loader.js.map +1 -1
  128. package/dist/core/sdk.d.ts.map +1 -1
  129. package/dist/core/sdk.js +3 -1
  130. package/dist/core/sdk.js.map +1 -1
  131. package/dist/core/session-manager.d.ts +7 -0
  132. package/dist/core/session-manager.d.ts.map +1 -1
  133. package/dist/core/session-manager.js +32 -13
  134. package/dist/core/session-manager.js.map +1 -1
  135. package/dist/core/settings-manager.d.ts +2 -0
  136. package/dist/core/settings-manager.d.ts.map +1 -1
  137. package/dist/core/settings-manager.js +11 -0
  138. package/dist/core/settings-manager.js.map +1 -1
  139. package/dist/core/settings-schema.d.ts +4 -2
  140. package/dist/core/settings-schema.d.ts.map +1 -1
  141. package/dist/core/settings-schema.js +8 -1
  142. package/dist/core/settings-schema.js.map +1 -1
  143. package/dist/core/skills.d.ts.map +1 -1
  144. package/dist/core/skills.js +6 -14
  145. package/dist/core/skills.js.map +1 -1
  146. package/dist/core/slash-command-name.d.ts +6 -0
  147. package/dist/core/slash-command-name.d.ts.map +1 -0
  148. package/dist/core/slash-command-name.js +11 -0
  149. package/dist/core/slash-command-name.js.map +1 -0
  150. package/dist/core/slash-commands.js +2 -2
  151. package/dist/core/slash-commands.js.map +1 -1
  152. package/dist/core/source-info.d.ts +9 -0
  153. package/dist/core/source-info.d.ts.map +1 -1
  154. package/dist/core/source-info.js +13 -0
  155. package/dist/core/source-info.js.map +1 -1
  156. package/dist/core/system-prompt.d.ts.map +1 -1
  157. package/dist/core/system-prompt.js +5 -6
  158. package/dist/core/system-prompt.js.map +1 -1
  159. package/dist/core/tasks/codec.d.ts +14 -0
  160. package/dist/core/tasks/codec.d.ts.map +1 -1
  161. package/dist/core/tasks/codec.js +57 -4
  162. package/dist/core/tasks/codec.js.map +1 -1
  163. package/dist/core/tasks/record.d.ts +1 -7
  164. package/dist/core/tasks/record.d.ts.map +1 -1
  165. package/dist/core/tasks/record.js +0 -18
  166. package/dist/core/tasks/record.js.map +1 -1
  167. package/dist/core/tasks/reminder.d.ts +3 -2
  168. package/dist/core/tasks/reminder.d.ts.map +1 -1
  169. package/dist/core/tasks/reminder.js +4 -3
  170. package/dist/core/tasks/reminder.js.map +1 -1
  171. package/dist/core/tasks/runtime.d.ts +0 -2
  172. package/dist/core/tasks/runtime.d.ts.map +1 -1
  173. package/dist/core/tasks/runtime.js +2 -15
  174. package/dist/core/tasks/runtime.js.map +1 -1
  175. package/dist/core/tasks/session.d.ts +9 -2
  176. package/dist/core/tasks/session.d.ts.map +1 -1
  177. package/dist/core/tasks/session.js +23 -9
  178. package/dist/core/tasks/session.js.map +1 -1
  179. package/dist/core/tasks/types.d.ts +1 -18
  180. package/dist/core/tasks/types.d.ts.map +1 -1
  181. package/dist/core/tasks/types.js +1 -1
  182. package/dist/core/tasks/types.js.map +1 -1
  183. package/dist/core/tools/bash.d.ts +8 -7
  184. package/dist/core/tools/bash.d.ts.map +1 -1
  185. package/dist/core/tools/bash.js +6 -5
  186. package/dist/core/tools/bash.js.map +1 -1
  187. package/dist/core/tools/edit.d.ts +3 -3
  188. package/dist/core/tools/edit.d.ts.map +1 -1
  189. package/dist/core/tools/edit.js +2 -4
  190. package/dist/core/tools/edit.js.map +1 -1
  191. package/dist/core/tools/find.d.ts +2 -2
  192. package/dist/core/tools/find.d.ts.map +1 -1
  193. package/dist/core/tools/find.js.map +1 -1
  194. package/dist/core/tools/grep.d.ts +2 -2
  195. package/dist/core/tools/grep.d.ts.map +1 -1
  196. package/dist/core/tools/grep.js +1 -1
  197. package/dist/core/tools/grep.js.map +1 -1
  198. package/dist/core/tools/ls.d.ts +2 -2
  199. package/dist/core/tools/ls.d.ts.map +1 -1
  200. package/dist/core/tools/ls.js.map +1 -1
  201. package/dist/core/tools/powershell.d.ts +1 -5
  202. package/dist/core/tools/powershell.d.ts.map +1 -1
  203. package/dist/core/tools/read.d.ts +2 -2
  204. package/dist/core/tools/read.d.ts.map +1 -1
  205. package/dist/core/tools/read.js.map +1 -1
  206. package/dist/core/tools/render-utils.d.ts +4 -6
  207. package/dist/core/tools/render-utils.d.ts.map +1 -1
  208. package/dist/core/tools/render-utils.js +19 -41
  209. package/dist/core/tools/render-utils.js.map +1 -1
  210. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  211. package/dist/core/tools/renderers/bash.js +3 -25
  212. package/dist/core/tools/renderers/bash.js.map +1 -1
  213. package/dist/core/tools/renderers/write.d.ts.map +1 -1
  214. package/dist/core/tools/renderers/write.js +18 -19
  215. package/dist/core/tools/renderers/write.js.map +1 -1
  216. package/dist/core/tools/shell-execution.d.ts +20 -13
  217. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  218. package/dist/core/tools/shell-execution.js +165 -183
  219. package/dist/core/tools/shell-execution.js.map +1 -1
  220. package/dist/core/tools/shell-tool.d.ts +9 -14
  221. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  222. package/dist/core/tools/shell-tool.js +38 -66
  223. package/dist/core/tools/shell-tool.js.map +1 -1
  224. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -4
  225. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  226. package/dist/core/tools/tool-definition-wrapper.js +2 -3
  227. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  228. package/dist/core/tools/write.d.ts +2 -2
  229. package/dist/core/tools/write.d.ts.map +1 -1
  230. package/dist/core/tools/write.js.map +1 -1
  231. package/dist/core/trust-manager.d.ts.map +1 -1
  232. package/dist/core/trust-manager.js +30 -13
  233. package/dist/core/trust-manager.js.map +1 -1
  234. package/dist/core/usage-totals.d.ts +0 -9
  235. package/dist/core/usage-totals.d.ts.map +1 -1
  236. package/dist/core/usage-totals.js +24 -91
  237. package/dist/core/usage-totals.js.map +1 -1
  238. package/dist/extensions/agent/activity-lines.d.ts +2 -3
  239. package/dist/extensions/agent/activity-lines.d.ts.map +1 -1
  240. package/dist/extensions/agent/activity-lines.js +5 -9
  241. package/dist/extensions/agent/activity-lines.js.map +1 -1
  242. package/dist/extensions/agent/activity.d.ts +0 -2
  243. package/dist/extensions/agent/activity.d.ts.map +1 -1
  244. package/dist/extensions/agent/activity.js +1 -1
  245. package/dist/extensions/agent/activity.js.map +1 -1
  246. package/dist/extensions/agent/progress.d.ts +0 -3
  247. package/dist/extensions/agent/progress.d.ts.map +1 -1
  248. package/dist/extensions/agent/progress.js +2 -8
  249. package/dist/extensions/agent/progress.js.map +1 -1
  250. package/dist/extensions/agent/render.js +1 -1
  251. package/dist/extensions/agent/render.js.map +1 -1
  252. package/dist/extensions/agent/tool.d.ts.map +1 -1
  253. package/dist/extensions/agent/tool.js +0 -6
  254. package/dist/extensions/agent/tool.js.map +1 -1
  255. package/dist/{core/isolated-session.d.ts → extensions/agent/worker-session.d.ts} +6 -6
  256. package/dist/extensions/agent/worker-session.d.ts.map +1 -0
  257. package/dist/{core/isolated-session.js → extensions/agent/worker-session.js} +9 -9
  258. package/dist/extensions/agent/worker-session.js.map +1 -0
  259. package/dist/extensions/agent/worker.d.ts +0 -3
  260. package/dist/extensions/agent/worker.d.ts.map +1 -1
  261. package/dist/extensions/agent/worker.js +2 -3
  262. package/dist/extensions/agent/worker.js.map +1 -1
  263. package/dist/extensions/btw/agent.d.ts.map +1 -1
  264. package/dist/extensions/btw/agent.js +2 -1
  265. package/dist/extensions/btw/agent.js.map +1 -1
  266. package/dist/extensions/cached-compaction/render.d.ts.map +1 -1
  267. package/dist/extensions/cached-compaction/render.js +3 -3
  268. package/dist/extensions/cached-compaction/render.js.map +1 -1
  269. package/dist/extensions/codemode/renderer.d.ts.map +1 -1
  270. package/dist/extensions/codemode/renderer.js +6 -2
  271. package/dist/extensions/codemode/renderer.js.map +1 -1
  272. package/dist/extensions/codemode/tool.d.ts +2 -1
  273. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  274. package/dist/extensions/codemode/tool.js +33 -8
  275. package/dist/extensions/codemode/tool.js.map +1 -1
  276. package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
  277. package/dist/extensions/deepwiki/schema.js +1 -1
  278. package/dist/extensions/deepwiki/schema.js.map +1 -1
  279. package/dist/extensions/llama/ui.d.ts.map +1 -1
  280. package/dist/extensions/llama/ui.js +16 -4
  281. package/dist/extensions/llama/ui.js.map +1 -1
  282. package/dist/extensions/mcp/cli.d.ts.map +1 -1
  283. package/dist/extensions/mcp/cli.js +34 -8
  284. package/dist/extensions/mcp/cli.js.map +1 -1
  285. package/dist/extensions/mcp/oauth.d.ts +1 -1
  286. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  287. package/dist/extensions/mcp/oauth.js +36 -13
  288. package/dist/extensions/mcp/oauth.js.map +1 -1
  289. package/dist/extensions/mcp/ui.d.ts +1 -0
  290. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  291. package/dist/extensions/mcp/ui.js +33 -24
  292. package/dist/extensions/mcp/ui.js.map +1 -1
  293. package/dist/extensions/run-summary/index.d.ts +1 -1
  294. package/dist/extensions/run-summary/index.d.ts.map +1 -1
  295. package/dist/extensions/run-summary/index.js +11 -23
  296. package/dist/extensions/run-summary/index.js.map +1 -1
  297. package/dist/extensions/statusline/usage.d.ts.map +1 -1
  298. package/dist/extensions/statusline/usage.js +2 -1
  299. package/dist/extensions/statusline/usage.js.map +1 -1
  300. package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
  301. package/dist/extensions/tasks/tool/schema.js +1 -1
  302. package/dist/extensions/tasks/tool/schema.js.map +1 -1
  303. package/dist/extensions/tasks/ui/completion-render.d.ts +5 -1
  304. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
  305. package/dist/extensions/tasks/ui/completion-render.js +25 -70
  306. package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
  307. package/dist/extensions/tasks/ui/inspector.d.ts +1 -1
  308. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  309. package/dist/extensions/tasks/ui/inspector.js +0 -6
  310. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  311. package/dist/extensions/tasks/ui/manager.d.ts +1 -1
  312. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
  313. package/dist/extensions/tasks/ui/manager.js.map +1 -1
  314. package/dist/extensions/tasks/ui/views.d.ts +2 -4
  315. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  316. package/dist/extensions/tasks/ui/views.js +3 -7
  317. package/dist/extensions/tasks/ui/views.js.map +1 -1
  318. package/dist/extensions/tool-presentation/fallback.d.ts.map +1 -0
  319. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/fallback.js +5 -5
  320. package/dist/extensions/tool-presentation/fallback.js.map +1 -0
  321. package/dist/extensions/tool-presentation/index.js +1 -1
  322. package/dist/extensions/tool-presentation/index.js.map +1 -1
  323. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/shell.d.ts +1 -1
  324. package/dist/extensions/tool-presentation/shell.d.ts.map +1 -0
  325. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/shell.js +3 -3
  326. package/dist/extensions/tool-presentation/shell.js.map +1 -0
  327. package/dist/extensions/tool-search/tool.d.ts +21 -6
  328. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  329. package/dist/extensions/tool-search/tool.js +104 -36
  330. package/dist/extensions/tool-search/tool.js.map +1 -1
  331. package/dist/index.d.ts +2 -2
  332. package/dist/index.d.ts.map +1 -1
  333. package/dist/index.js.map +1 -1
  334. package/dist/main.d.ts.map +1 -1
  335. package/dist/main.js +15 -8
  336. package/dist/main.js.map +1 -1
  337. package/dist/modes/interactive/components/assistant-message.d.ts +5 -3
  338. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  339. package/dist/modes/interactive/components/assistant-message.js +61 -45
  340. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  341. package/dist/modes/interactive/components/config-selector-skills.d.ts +54 -0
  342. package/dist/modes/interactive/components/config-selector-skills.d.ts.map +1 -0
  343. package/dist/modes/interactive/components/config-selector-skills.js +178 -0
  344. package/dist/modes/interactive/components/config-selector-skills.js.map +1 -0
  345. package/dist/modes/interactive/components/config-selector.d.ts +2 -11
  346. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  347. package/dist/modes/interactive/components/config-selector.js +31 -181
  348. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  349. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/custom-editor.js +7 -0
  351. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  352. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  353. package/dist/modes/interactive/components/custom-entry.js +2 -1
  354. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  355. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  356. package/dist/modes/interactive/components/custom-message.js +2 -1
  357. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  358. package/dist/modes/interactive/components/extension-editor.d.ts +2 -0
  359. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  360. package/dist/modes/interactive/components/extension-editor.js +4 -0
  361. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  362. package/dist/modes/interactive/components/login-dialog.d.ts +5 -0
  363. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/login-dialog.js +103 -10
  365. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  366. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -1
  367. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
  368. package/dist/modes/interactive/components/markdown-transform.js +3 -2
  369. package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
  370. package/dist/modes/interactive/components/model-selector.d.ts +1 -0
  371. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  372. package/dist/modes/interactive/components/model-selector.js +17 -6
  373. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  374. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -0
  375. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  376. package/dist/modes/interactive/components/oauth-selector.js +13 -4
  377. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  378. package/dist/modes/interactive/components/scoped-models-selector.d.ts +1 -0
  379. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  380. package/dist/modes/interactive/components/scoped-models-selector.js +14 -3
  381. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  382. package/dist/modes/interactive/components/session-selector-search.d.ts +4 -0
  383. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  384. package/dist/modes/interactive/components/session-selector-search.js +86 -22
  385. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  386. package/dist/modes/interactive/components/session-selector.d.ts +2 -1
  387. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  388. package/dist/modes/interactive/components/session-selector.js +15 -23
  389. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  390. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  391. package/dist/modes/interactive/components/settings-submenu.js +2 -0
  392. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  393. package/dist/modes/interactive/components/tool-execution.d.ts +7 -0
  394. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  395. package/dist/modes/interactive/components/tool-execution.js +48 -9
  396. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  397. package/dist/modes/interactive/components/tree-selector.d.ts +1 -0
  398. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  399. package/dist/modes/interactive/components/tree-selector.js +5 -6
  400. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  401. package/dist/modes/interactive/components/user-message-selector.d.ts +1 -0
  402. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  403. package/dist/modes/interactive/components/user-message-selector.js +9 -1
  404. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  405. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  406. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  407. package/dist/modes/interactive/components/user-message.js +4 -2
  408. package/dist/modes/interactive/components/user-message.js.map +1 -1
  409. package/dist/modes/interactive/editor-host.d.ts.map +1 -1
  410. package/dist/modes/interactive/editor-host.js +3 -2
  411. package/dist/modes/interactive/editor-host.js.map +1 -1
  412. package/dist/modes/interactive/external-editor.d.ts +1 -0
  413. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  414. package/dist/modes/interactive/external-editor.js +17 -5
  415. package/dist/modes/interactive/external-editor.js.map +1 -1
  416. package/dist/modes/interactive/interactive-mode.d.ts +8 -12
  417. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  418. package/dist/modes/interactive/interactive-mode.js +169 -112
  419. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  420. package/dist/modes/interactive/model-search.d.ts +10 -0
  421. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  422. package/dist/modes/interactive/model-search.js +21 -0
  423. package/dist/modes/interactive/model-search.js.map +1 -1
  424. package/dist/modes/interactive/theme/theme.d.ts +10 -0
  425. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  426. package/dist/modes/interactive/theme/theme.js +30 -23
  427. package/dist/modes/interactive/theme/theme.js.map +1 -1
  428. package/dist/modes/interactive/tool-view/chat.d.ts +2 -2
  429. package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -1
  430. package/dist/modes/interactive/tool-view/chat.js +22 -19
  431. package/dist/modes/interactive/tool-view/chat.js.map +1 -1
  432. package/dist/modes/interactive/transcript-layout.d.ts +2 -0
  433. package/dist/modes/interactive/transcript-layout.d.ts.map +1 -1
  434. package/dist/modes/interactive/transcript-layout.js +5 -2
  435. package/dist/modes/interactive/transcript-layout.js.map +1 -1
  436. package/dist/modes/rpc/rpc-client.d.ts +9 -1
  437. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  438. package/dist/modes/rpc/rpc-client.js +23 -23
  439. package/dist/modes/rpc/rpc-client.js.map +1 -1
  440. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  441. package/dist/modes/rpc/rpc-mode.js +0 -3
  442. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  443. package/dist/package-manager-cli.d.ts.map +1 -1
  444. package/dist/package-manager-cli.js +55 -4
  445. package/dist/package-manager-cli.js.map +1 -1
  446. package/dist/utils/ansi.d.ts.map +1 -1
  447. package/dist/utils/ansi.js +5 -2
  448. package/dist/utils/ansi.js.map +1 -1
  449. package/dist/utils/clipboard-command.d.ts.map +1 -1
  450. package/dist/utils/clipboard-command.js +4 -0
  451. package/dist/utils/clipboard-command.js.map +1 -1
  452. package/dist/utils/git.d.ts +1 -1
  453. package/dist/utils/git.d.ts.map +1 -1
  454. package/dist/utils/git.js.map +1 -1
  455. package/dist/utils/image-resize-core.d.ts.map +1 -1
  456. package/dist/utils/image-resize-core.js +5 -3
  457. package/dist/utils/image-resize-core.js.map +1 -1
  458. package/dist/utils/open-browser.d.ts.map +1 -1
  459. package/dist/utils/open-browser.js +4 -1
  460. package/dist/utils/open-browser.js.map +1 -1
  461. package/dist/utils/paths.d.ts +17 -0
  462. package/dist/utils/paths.d.ts.map +1 -1
  463. package/dist/utils/paths.js +42 -1
  464. package/dist/utils/paths.js.map +1 -1
  465. package/dist/utils/shell.d.ts.map +1 -1
  466. package/dist/utils/shell.js +14 -0
  467. package/dist/utils/shell.js.map +1 -1
  468. package/dist/utils/syntax-highlight.d.ts +5 -0
  469. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  470. package/dist/utils/syntax-highlight.js +7 -0
  471. package/dist/utils/syntax-highlight.js.map +1 -1
  472. package/dist/utils/tools-manager.d.ts.map +1 -1
  473. package/dist/utils/tools-manager.js +30 -35
  474. package/dist/utils/tools-manager.js.map +1 -1
  475. package/dist/utils/usage.d.ts +5 -0
  476. package/dist/utils/usage.d.ts.map +1 -0
  477. package/dist/utils/usage.js +16 -0
  478. package/dist/utils/usage.js.map +1 -0
  479. package/docs/bundled/README.md +1 -1
  480. package/docs/bundled/extensions/agent.md +5 -5
  481. package/docs/bundled/extensions/run-summary.md +4 -4
  482. package/docs/bundled/tasks.md +2 -4
  483. package/docs/bundled/tool-presentation.md +2 -2
  484. package/docs/custom-provider.md +1 -1
  485. package/docs/environment-variables.md +2 -0
  486. package/docs/extensions.md +36 -21
  487. package/docs/keybindings.md +1 -1
  488. package/docs/llama-cpp.md +17 -12
  489. package/docs/mcp.md +6 -4
  490. package/docs/packages.md +26 -1
  491. package/docs/rpc.md +1 -1
  492. package/docs/sdk.md +7 -5
  493. package/docs/session-format.md +2 -2
  494. package/docs/sessions.md +10 -0
  495. package/docs/settings.md +5 -4
  496. package/docs/terminal-setup.md +2 -2
  497. package/docs/tmux.md +6 -0
  498. package/docs/tui.md +12 -7
  499. package/docs/usage.md +19 -9
  500. package/docs/windows.md +29 -0
  501. package/examples/extensions/README.md +2 -1
  502. package/examples/extensions/custom-provider-anthropic/index.ts +27 -31
  503. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  504. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  505. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  506. package/examples/extensions/debug-provider.ts +2 -2
  507. package/examples/extensions/gondolin/package-lock.json +19 -29
  508. package/examples/extensions/gondolin/package.json +2 -2
  509. package/examples/extensions/preset.ts +2 -0
  510. package/examples/extensions/reload-runtime.ts +17 -5
  511. package/examples/extensions/tools.ts +2 -0
  512. package/examples/extensions/with-deps/package-lock.json +2 -2
  513. package/examples/extensions/with-deps/package.json +1 -1
  514. package/package.json +9 -9
  515. package/schemas/models.schema.json +36 -36
  516. package/schemas/settings.schema.json +17 -0
  517. package/dist/bundle/chunks/anthropic-messages-HWL6AS7T.js +0 -6
  518. package/dist/bundle/chunks/azure-openai-responses-4YYPDYV5.js +0 -2
  519. package/dist/bundle/chunks/chunk-6JS2SOFO.js +0 -11
  520. package/dist/bundle/chunks/chunk-ANCZPKX7.js +0 -2
  521. package/dist/bundle/chunks/chunk-FEZ5RM2B.js +0 -2
  522. package/dist/bundle/chunks/chunk-LPF7HQ3S.js +0 -4
  523. package/dist/bundle/chunks/chunk-MMNIHCU7.js +0 -2
  524. package/dist/bundle/chunks/chunk-PUU43PDV.js +0 -1484
  525. package/dist/bundle/chunks/chunk-R267VV5T.js +0 -82
  526. package/dist/bundle/chunks/chunk-RVKT7OUB.js +0 -9
  527. package/dist/bundle/chunks/chunk-SA2AQYEI.js +0 -7
  528. package/dist/bundle/chunks/chunk-ZAIGBRV5.js +0 -16
  529. package/dist/bundle/chunks/mistral-conversations-V2JJTMJ5.js +0 -5
  530. package/dist/bundle/chunks/openai-completions-TXZXILJR.js +0 -7
  531. package/dist/bundle/chunks/pi-messages-LBJQ4NGP.js +0 -8
  532. package/dist/bundle/chunks/virtual-modules-63XNTSVN.js +0 -2
  533. package/dist/core/isolated-session.d.ts.map +0 -1
  534. package/dist/core/isolated-session.js.map +0 -1
  535. package/dist/modes/interactive/tool-view/fallback.d.ts.map +0 -1
  536. package/dist/modes/interactive/tool-view/fallback.js.map +0 -1
  537. package/dist/modes/interactive/tool-view/shell.d.ts.map +0 -1
  538. package/dist/modes/interactive/tool-view/shell.js.map +0 -1
  539. package/dist/utils/path-identity.d.ts +0 -12
  540. package/dist/utils/path-identity.d.ts.map +0 -1
  541. package/dist/utils/path-identity.js +0 -63
  542. package/dist/utils/path-identity.js.map +0 -1
  543. package/examples/extensions/sandbox/index.ts +0 -321
  544. package/examples/extensions/sandbox/package-lock.json +0 -92
  545. package/examples/extensions/sandbox/package.json +0 -19
  546. /package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/fallback.d.ts +0 -0
@@ -1,9 +1,9 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir, userInfo } from "node:os";
2
3
  import { dirname, join } from "node:path";
3
4
  import lockfile from "proper-lockfile";
4
5
  import { CONFIG_DIR_NAME } from "../config.js";
5
- import { findPathKeys, userAgentsSkillsDirMatcher } from "../utils/path-identity.js";
6
- import { canonicalizePath, resolvePath } from "../utils/paths.js";
6
+ import { canonicalizePath, pathsEqual, resolvePath } from "../utils/paths.js";
7
7
  import { stripBom } from "../utils/text.js";
8
8
  const TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES = [
9
9
  "settings.json",
@@ -18,12 +18,28 @@ const TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES = [
18
18
  function normalizeCwd(cwd) {
19
19
  return canonicalizePath(resolvePath(cwd));
20
20
  }
21
+ /** Trust file keys naming `path`. Usually one; several on Windows when saved with different casing. */
22
+ function findTrustFileKeys(data, path) {
23
+ return Object.keys(data).filter((key) => pathsEqual(key, path));
24
+ }
25
+ /** The account's home from the operating system; HOME can point elsewhere, for example under MSYS. */
26
+ function getAccountHomeDir() {
27
+ try {
28
+ return userInfo().homedir;
29
+ }
30
+ catch {
31
+ // Some restricted runtimes cannot query the operating-system account database.
32
+ return homedir();
33
+ }
34
+ }
21
35
  function findNearestTrustEntry(data, cwd) {
22
36
  let currentDir = normalizeCwd(cwd);
23
37
  while (true) {
24
- const value = data[findPathKeys(data, currentDir)[0] ?? currentDir];
25
- if (value === true || value === false) {
26
- return { path: currentDir, decision: value };
38
+ for (const key of findTrustFileKeys(data, currentDir)) {
39
+ const value = data[key];
40
+ if (value === true || value === false) {
41
+ return { path: key, decision: value };
42
+ }
27
43
  }
28
44
  const parentDir = dirname(currentDir);
29
45
  if (parentDir === currentDir) {
@@ -149,7 +165,9 @@ function withTrustFileLock(path, fn) {
149
165
  * trusted user resource and is ignored here, even when cwd is $HOME.
150
166
  */
151
167
  export function hasTrustRequiringProjectResources(cwd) {
152
- const isUserAgentsSkillsDir = userAgentsSkillsDirMatcher();
168
+ const homeDir = canonicalizePath(resolvePath(process.env.HOME || homedir()));
169
+ const userAgentsSkillsDir = join(homeDir, ".agents", "skills");
170
+ const accountAgentsSkillsDir = join(canonicalizePath(getAccountHomeDir()), ".agents", "skills");
153
171
  let currentDir = canonicalizePath(resolvePath(cwd));
154
172
  const configDir = join(currentDir, CONFIG_DIR_NAME);
155
173
  if (TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES.some((entry) => existsSync(join(configDir, entry)))) {
@@ -157,7 +175,9 @@ export function hasTrustRequiringProjectResources(cwd) {
157
175
  }
158
176
  while (true) {
159
177
  const agentsSkillsDir = join(currentDir, ".agents", "skills");
160
- if (!isUserAgentsSkillsDir(agentsSkillsDir) && existsSync(agentsSkillsDir)) {
178
+ if (!pathsEqual(agentsSkillsDir, userAgentsSkillsDir) &&
179
+ !pathsEqual(agentsSkillsDir, accountAgentsSkillsDir) &&
180
+ existsSync(agentsSkillsDir)) {
161
181
  return true;
162
182
  }
163
183
  const parentDir = dirname(currentDir);
@@ -188,13 +208,10 @@ export class ProjectTrustStore {
188
208
  const data = readTrustFile(this.trustPath);
189
209
  for (const { path, decision } of decisions) {
190
210
  const key = normalizeCwd(path);
191
- for (const alias of findPathKeys(data, key))
192
- if (alias !== key)
193
- delete data[alias];
194
- if (decision === null) {
195
- delete data[key];
211
+ for (const existingKey of findTrustFileKeys(data, key)) {
212
+ delete data[existingKey];
196
213
  }
197
- else {
214
+ if (decision !== null) {
198
215
  data[key] = decision;
199
216
  }
200
217
  }
@@ -1 +1 @@
1
- {"version":3,"file":"trust-manager.js","sourceRoot":"","sources":["../../src/core/trust-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAuB5C,MAAM,wCAAwC,GAAG;IAChD,eAAe;IACf,UAAU;IACV,YAAY;IACZ,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,WAAW;IACX,kBAAkB;CACT,CAAC;AAEX,SAAS,YAAY,CAAC,GAAW;IAChC,OAAO,gBAAgB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAe,EAAE,GAAW;IAC1D,IAAI,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC;QACpE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;YACvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC9C,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACtC,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC;QACb,CAAC;QACD,UAAU,GAAG,SAAS,CAAC;IACxB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,GAAW;IACpD,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAAW,EAAE,OAA0C;IAC7F,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,YAAY,GAAyB;QAC1C,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE;KACvG,CAAC;IACF,MAAM,UAAU,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC;IAClD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC9B,YAAY,CAAC,IAAI,CAAC;YACjB,KAAK,EAAE,wBAAwB,UAAU,GAAG;YAC5C,OAAO,EAAE,IAAI;YACb,OAAO,EAAE;gBACR,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE;gBACpC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;aACnC;YACD,SAAS,EAAE,UAAU;SACrB,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,EAAE,kBAAkB,EAAE,CAAC;QACjC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2BAA2B,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,YAAY,CAAC,IAAI,CAAC;QACjB,KAAK,EAAE,cAAc;QACrB,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC/C,SAAS,EAAE,SAAS;KACpB,CAAC,CAAC;IACH,IAAI,OAAO,EAAE,kBAAkB,EAAE,CAAC;QACjC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,YAAY,CAAC;AACrB,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,sBAAsB,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,eAAe,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC/G,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,IAAe;IACpD,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACzD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrB,CAAC;IACF,CAAC;IACD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY;IACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,EAAE,CAAC;IACnB,IAAI,SAAkB,CAAC;IAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACzD,IAAI,CAAC;YACJ,OAAO,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC,CAAC;QACvF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,GACT,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK;gBAC7D,CAAC,CAAC,MAAM,CAAE,KAA4B,CAAC,IAAI,CAAC;gBAC5C,CAAC,CAAC,SAAS,CAAC;YACd,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;gBACnD,MAAM,KAAK,CAAC;YACb,CAAC;YACD,SAAS,GAAG,KAAK,CAAC;YAClB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,OAAO,EAAE,CAAC;gBACrC,sEAAsE;YACvE,CAAC;QACF,CAAC;IACF,CAAC;IAED,IAAI,SAAS,YAAY,KAAK,EAAE,CAAC;QAChC,MAAM,SAAS,CAAC;IACjB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,iBAAiB,CAAI,IAAY,EAAE,EAAW;IACtD,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC;QACJ,OAAO,EAAE,EAAE,CAAC;IACb,CAAC;YAAS,CAAC;QACV,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iCAAiC,CAAC,GAAW;IAC5D,MAAM,qBAAqB,GAAG,0BAA0B,EAAE,CAAC;IAC3D,IAAI,UAAU,GAAG,gBAAgB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAEpD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IACpD,IAAI,wCAAwC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAClG,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,eAAe,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC9D,IAAI,CAAC,qBAAqB,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YAC5E,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACtC,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACd,CAAC;QACD,UAAU,GAAG,SAAS,CAAC;IACxB,CAAC;AACF,CAAC;AAED,MAAM,OAAO,iBAAiB;IAG7B,YAAY,QAAgB;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAC;IAC5D,CAAC;IAED,GAAG,CAAC,GAAW;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,IAAI,IAAI,CAAC;IAC7C,CAAC;IAED,QAAQ,CAAC,GAAW;QACnB,OAAO,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;YAC7C,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3C,OAAO,qBAAqB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,QAA8B;QAC9C,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,CAAC,SAA+B;QACtC,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;YACtC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3C,KAAK,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,SAAS,EAAE,CAAC;gBAC5C,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;gBAC/B,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC;oBAAE,IAAI,KAAK,KAAK,GAAG;wBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;gBACnF,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;oBACvB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;gBAClB,CAAC;qBAAM,CAAC;oBACP,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;gBACtB,CAAC;YACF,CAAC;YACD,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACJ,CAAC;CACD","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { CONFIG_DIR_NAME } from \"../config.ts\";\nimport { findPathKeys, userAgentsSkillsDirMatcher } from \"../utils/path-identity.ts\";\nimport { canonicalizePath, resolvePath } from \"../utils/paths.ts\";\nimport { stripBom } from \"../utils/text.ts\";\n\nexport type ProjectTrustDecision = boolean | null;\n\nexport interface ProjectTrustStoreEntry {\n\tpath: string;\n\tdecision: boolean;\n}\n\nexport interface ProjectTrustUpdate {\n\tpath: string;\n\tdecision: ProjectTrustDecision;\n}\n\nexport interface ProjectTrustOption {\n\tlabel: string;\n\ttrusted: boolean;\n\tupdates: ProjectTrustUpdate[];\n\tsavedPath?: string;\n}\n\ntype TrustFile = Record<string, boolean | null | undefined>;\n\nconst TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES = [\n\t\"settings.json\",\n\t\"mcp.json\",\n\t\"extensions\",\n\t\"skills\",\n\t\"prompts\",\n\t\"themes\",\n\t\"SYSTEM.md\",\n\t\"APPEND_SYSTEM.md\",\n] as const;\n\nfunction normalizeCwd(cwd: string): string {\n\treturn canonicalizePath(resolvePath(cwd));\n}\n\nfunction findNearestTrustEntry(data: TrustFile, cwd: string): ProjectTrustStoreEntry | null {\n\tlet currentDir = normalizeCwd(cwd);\n\twhile (true) {\n\t\tconst value = data[findPathKeys(data, currentDir)[0] ?? currentDir];\n\t\tif (value === true || value === false) {\n\t\t\treturn { path: currentDir, decision: value };\n\t\t}\n\n\t\tconst parentDir = dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\treturn null;\n\t\t}\n\t\tcurrentDir = parentDir;\n\t}\n}\n\nexport function getProjectTrustParentPath(cwd: string): string | undefined {\n\tconst trustPath = normalizeCwd(cwd);\n\tconst parentDir = dirname(trustPath);\n\treturn parentDir === trustPath ? undefined : parentDir;\n}\n\nexport function getProjectTrustOptions(cwd: string, options?: { includeSessionOnly?: boolean }): ProjectTrustOption[] {\n\tconst trustPath = normalizeCwd(cwd);\n\tconst trustOptions: ProjectTrustOption[] = [\n\t\t{ label: \"Trust\", trusted: true, updates: [{ path: trustPath, decision: true }], savedPath: trustPath },\n\t];\n\tconst parentPath = getProjectTrustParentPath(cwd);\n\tif (parentPath !== undefined) {\n\t\ttrustOptions.push({\n\t\t\tlabel: `Trust parent folder (${parentPath})`,\n\t\t\ttrusted: true,\n\t\t\tupdates: [\n\t\t\t\t{ path: parentPath, decision: true },\n\t\t\t\t{ path: trustPath, decision: null },\n\t\t\t],\n\t\t\tsavedPath: parentPath,\n\t\t});\n\t}\n\tif (options?.includeSessionOnly) {\n\t\ttrustOptions.push({ label: \"Trust (this session only)\", trusted: true, updates: [] });\n\t}\n\ttrustOptions.push({\n\t\tlabel: \"Do not trust\",\n\t\ttrusted: false,\n\t\tupdates: [{ path: trustPath, decision: false }],\n\t\tsavedPath: trustPath,\n\t});\n\tif (options?.includeSessionOnly) {\n\t\ttrustOptions.push({ label: \"Do not trust (this session only)\", trusted: false, updates: [] });\n\t}\n\treturn trustOptions;\n}\n\nfunction readTrustFile(path: string): TrustFile {\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(stripBom(readFileSync(path, \"utf-8\")));\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to read trust store ${path}: ${message}`);\n\t}\n\n\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid trust store ${path}: expected an object`);\n\t}\n\n\tconst data: TrustFile = {};\n\tfor (const [key, value] of Object.entries(parsed)) {\n\t\tif (value !== true && value !== false && value !== null) {\n\t\t\tthrow new Error(`Invalid trust store ${path}: value for ${JSON.stringify(key)} must be true, false, or null`);\n\t\t}\n\t\tdata[key] = value;\n\t}\n\treturn data;\n}\n\nfunction writeTrustFile(path: string, data: TrustFile): void {\n\tconst sorted: TrustFile = {};\n\tfor (const key of Object.keys(data).sort()) {\n\t\tconst value = data[key];\n\t\tif (value === true || value === false || value === null) {\n\t\t\tsorted[key] = value;\n\t\t}\n\t}\n\tmkdirSync(dirname(path), { recursive: true });\n\twriteFileSync(path, `${JSON.stringify(sorted, null, 2)}\\n`, \"utf-8\");\n}\n\nfunction acquireTrustLockSync(path: string): () => void {\n\tconst trustDir = dirname(path);\n\tmkdirSync(trustDir, { recursive: true });\n\tconst maxAttempts = 10;\n\tconst delayMs = 20;\n\tlet lastError: unknown;\n\n\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\ttry {\n\t\t\treturn lockfile.lockSync(trustDir, { realpath: false, lockfilePath: `${path}.lock` });\n\t\t} catch (error) {\n\t\t\tconst code =\n\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t: undefined;\n\t\t\tif (code !== \"ELOCKED\" || attempt === maxAttempts) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tlastError = error;\n\t\t\tconst start = Date.now();\n\t\t\twhile (Date.now() - start < delayMs) {\n\t\t\t\t// Sleep synchronously to avoid changing trust store callers to async.\n\t\t\t}\n\t\t}\n\t}\n\n\tif (lastError instanceof Error) {\n\t\tthrow lastError;\n\t}\n\tthrow new Error(\"Failed to acquire trust store lock\");\n}\n\nfunction withTrustFileLock<T>(path: string, fn: () => T): T {\n\tconst release = acquireTrustLockSync(path);\n\ttry {\n\t\treturn fn();\n\t} finally {\n\t\trelease();\n\t}\n}\n\n/**\n * Returns true when cwd has project-local resources that must be gated by\n * project trust: trust-requiring entries under cwd/.pi, or .agents/skills in\n * cwd or one of its ancestors. Returns false when no such project resources\n * exist. The user/global ~/.agents/skills directory is always treated as a\n * trusted user resource and is ignored here, even when cwd is $HOME.\n */\nexport function hasTrustRequiringProjectResources(cwd: string): boolean {\n\tconst isUserAgentsSkillsDir = userAgentsSkillsDirMatcher();\n\tlet currentDir = canonicalizePath(resolvePath(cwd));\n\n\tconst configDir = join(currentDir, CONFIG_DIR_NAME);\n\tif (TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES.some((entry) => existsSync(join(configDir, entry)))) {\n\t\treturn true;\n\t}\n\n\twhile (true) {\n\t\tconst agentsSkillsDir = join(currentDir, \".agents\", \"skills\");\n\t\tif (!isUserAgentsSkillsDir(agentsSkillsDir) && existsSync(agentsSkillsDir)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst parentDir = dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\treturn false;\n\t\t}\n\t\tcurrentDir = parentDir;\n\t}\n}\n\nexport class ProjectTrustStore {\n\tprivate trustPath: string;\n\n\tconstructor(agentDir: string) {\n\t\tthis.trustPath = join(resolvePath(agentDir), \"trust.json\");\n\t}\n\n\tget(cwd: string): ProjectTrustDecision {\n\t\treturn this.getEntry(cwd)?.decision ?? null;\n\t}\n\n\tgetEntry(cwd: string): ProjectTrustStoreEntry | null {\n\t\treturn withTrustFileLock(this.trustPath, () => {\n\t\t\tconst data = readTrustFile(this.trustPath);\n\t\t\treturn findNearestTrustEntry(data, cwd);\n\t\t});\n\t}\n\n\tset(cwd: string, decision: ProjectTrustDecision): void {\n\t\tthis.setMany([{ path: cwd, decision }]);\n\t}\n\n\tsetMany(decisions: ProjectTrustUpdate[]): void {\n\t\twithTrustFileLock(this.trustPath, () => {\n\t\t\tconst data = readTrustFile(this.trustPath);\n\t\t\tfor (const { path, decision } of decisions) {\n\t\t\t\tconst key = normalizeCwd(path);\n\t\t\t\tfor (const alias of findPathKeys(data, key)) if (alias !== key) delete data[alias];\n\t\t\t\tif (decision === null) {\n\t\t\t\t\tdelete data[key];\n\t\t\t\t} else {\n\t\t\t\t\tdata[key] = decision;\n\t\t\t\t}\n\t\t\t}\n\t\t\twriteTrustFile(this.trustPath, data);\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"trust-manager.js","sourceRoot":"","sources":["../../src/core/trust-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir, userInfo } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { CONFIG_DIR_NAME } from \"../config.ts\";\nimport { canonicalizePath, pathsEqual, resolvePath } from \"../utils/paths.ts\";\nimport { stripBom } from \"../utils/text.ts\";\n\nexport type ProjectTrustDecision = boolean | null;\n\nexport interface ProjectTrustStoreEntry {\n\tpath: string;\n\tdecision: boolean;\n}\n\nexport interface ProjectTrustUpdate {\n\tpath: string;\n\tdecision: ProjectTrustDecision;\n}\n\nexport interface ProjectTrustOption {\n\tlabel: string;\n\ttrusted: boolean;\n\tupdates: ProjectTrustUpdate[];\n\tsavedPath?: string;\n}\n\ntype TrustFile = Record<string, boolean | null | undefined>;\n\nconst TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES = [\n\t\"settings.json\",\n\t\"mcp.json\",\n\t\"extensions\",\n\t\"skills\",\n\t\"prompts\",\n\t\"themes\",\n\t\"SYSTEM.md\",\n\t\"APPEND_SYSTEM.md\",\n] as const;\n\nfunction normalizeCwd(cwd: string): string {\n\treturn canonicalizePath(resolvePath(cwd));\n}\n\n/** Trust file keys naming `path`. Usually one; several on Windows when saved with different casing. */\nfunction findTrustFileKeys(data: TrustFile, path: string): string[] {\n\treturn Object.keys(data).filter((key) => pathsEqual(key, path));\n}\n\n/** The account's home from the operating system; HOME can point elsewhere, for example under MSYS. */\nfunction getAccountHomeDir(): string {\n\ttry {\n\t\treturn userInfo().homedir;\n\t} catch {\n\t\t// Some restricted runtimes cannot query the operating-system account database.\n\t\treturn homedir();\n\t}\n}\n\nfunction findNearestTrustEntry(data: TrustFile, cwd: string): ProjectTrustStoreEntry | null {\n\tlet currentDir = normalizeCwd(cwd);\n\twhile (true) {\n\t\tfor (const key of findTrustFileKeys(data, currentDir)) {\n\t\t\tconst value = data[key];\n\t\t\tif (value === true || value === false) {\n\t\t\t\treturn { path: key, decision: value };\n\t\t\t}\n\t\t}\n\n\t\tconst parentDir = dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\treturn null;\n\t\t}\n\t\tcurrentDir = parentDir;\n\t}\n}\n\nexport function getProjectTrustParentPath(cwd: string): string | undefined {\n\tconst trustPath = normalizeCwd(cwd);\n\tconst parentDir = dirname(trustPath);\n\treturn parentDir === trustPath ? undefined : parentDir;\n}\n\nexport function getProjectTrustOptions(cwd: string, options?: { includeSessionOnly?: boolean }): ProjectTrustOption[] {\n\tconst trustPath = normalizeCwd(cwd);\n\tconst trustOptions: ProjectTrustOption[] = [\n\t\t{ label: \"Trust\", trusted: true, updates: [{ path: trustPath, decision: true }], savedPath: trustPath },\n\t];\n\tconst parentPath = getProjectTrustParentPath(cwd);\n\tif (parentPath !== undefined) {\n\t\ttrustOptions.push({\n\t\t\tlabel: `Trust parent folder (${parentPath})`,\n\t\t\ttrusted: true,\n\t\t\tupdates: [\n\t\t\t\t{ path: parentPath, decision: true },\n\t\t\t\t{ path: trustPath, decision: null },\n\t\t\t],\n\t\t\tsavedPath: parentPath,\n\t\t});\n\t}\n\tif (options?.includeSessionOnly) {\n\t\ttrustOptions.push({ label: \"Trust (this session only)\", trusted: true, updates: [] });\n\t}\n\ttrustOptions.push({\n\t\tlabel: \"Do not trust\",\n\t\ttrusted: false,\n\t\tupdates: [{ path: trustPath, decision: false }],\n\t\tsavedPath: trustPath,\n\t});\n\tif (options?.includeSessionOnly) {\n\t\ttrustOptions.push({ label: \"Do not trust (this session only)\", trusted: false, updates: [] });\n\t}\n\treturn trustOptions;\n}\n\nfunction readTrustFile(path: string): TrustFile {\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(stripBom(readFileSync(path, \"utf-8\")));\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to read trust store ${path}: ${message}`);\n\t}\n\n\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid trust store ${path}: expected an object`);\n\t}\n\n\tconst data: TrustFile = {};\n\tfor (const [key, value] of Object.entries(parsed)) {\n\t\tif (value !== true && value !== false && value !== null) {\n\t\t\tthrow new Error(`Invalid trust store ${path}: value for ${JSON.stringify(key)} must be true, false, or null`);\n\t\t}\n\t\tdata[key] = value;\n\t}\n\treturn data;\n}\n\nfunction writeTrustFile(path: string, data: TrustFile): void {\n\tconst sorted: TrustFile = {};\n\tfor (const key of Object.keys(data).sort()) {\n\t\tconst value = data[key];\n\t\tif (value === true || value === false || value === null) {\n\t\t\tsorted[key] = value;\n\t\t}\n\t}\n\tmkdirSync(dirname(path), { recursive: true });\n\twriteFileSync(path, `${JSON.stringify(sorted, null, 2)}\\n`, \"utf-8\");\n}\n\nfunction acquireTrustLockSync(path: string): () => void {\n\tconst trustDir = dirname(path);\n\tmkdirSync(trustDir, { recursive: true });\n\tconst maxAttempts = 10;\n\tconst delayMs = 20;\n\tlet lastError: unknown;\n\n\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\ttry {\n\t\t\treturn lockfile.lockSync(trustDir, { realpath: false, lockfilePath: `${path}.lock` });\n\t\t} catch (error) {\n\t\t\tconst code =\n\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t: undefined;\n\t\t\tif (code !== \"ELOCKED\" || attempt === maxAttempts) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tlastError = error;\n\t\t\tconst start = Date.now();\n\t\t\twhile (Date.now() - start < delayMs) {\n\t\t\t\t// Sleep synchronously to avoid changing trust store callers to async.\n\t\t\t}\n\t\t}\n\t}\n\n\tif (lastError instanceof Error) {\n\t\tthrow lastError;\n\t}\n\tthrow new Error(\"Failed to acquire trust store lock\");\n}\n\nfunction withTrustFileLock<T>(path: string, fn: () => T): T {\n\tconst release = acquireTrustLockSync(path);\n\ttry {\n\t\treturn fn();\n\t} finally {\n\t\trelease();\n\t}\n}\n\n/**\n * Returns true when cwd has project-local resources that must be gated by\n * project trust: trust-requiring entries under cwd/.pi, or .agents/skills in\n * cwd or one of its ancestors. Returns false when no such project resources\n * exist. The user/global ~/.agents/skills directory is always treated as a\n * trusted user resource and is ignored here, even when cwd is $HOME.\n */\nexport function hasTrustRequiringProjectResources(cwd: string): boolean {\n\tconst homeDir = canonicalizePath(resolvePath(process.env.HOME || homedir()));\n\tconst userAgentsSkillsDir = join(homeDir, \".agents\", \"skills\");\n\tconst accountAgentsSkillsDir = join(canonicalizePath(getAccountHomeDir()), \".agents\", \"skills\");\n\tlet currentDir = canonicalizePath(resolvePath(cwd));\n\n\tconst configDir = join(currentDir, CONFIG_DIR_NAME);\n\tif (TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES.some((entry) => existsSync(join(configDir, entry)))) {\n\t\treturn true;\n\t}\n\n\twhile (true) {\n\t\tconst agentsSkillsDir = join(currentDir, \".agents\", \"skills\");\n\t\tif (\n\t\t\t!pathsEqual(agentsSkillsDir, userAgentsSkillsDir) &&\n\t\t\t!pathsEqual(agentsSkillsDir, accountAgentsSkillsDir) &&\n\t\t\texistsSync(agentsSkillsDir)\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst parentDir = dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\treturn false;\n\t\t}\n\t\tcurrentDir = parentDir;\n\t}\n}\n\nexport class ProjectTrustStore {\n\tprivate trustPath: string;\n\n\tconstructor(agentDir: string) {\n\t\tthis.trustPath = join(resolvePath(agentDir), \"trust.json\");\n\t}\n\n\tget(cwd: string): ProjectTrustDecision {\n\t\treturn this.getEntry(cwd)?.decision ?? null;\n\t}\n\n\tgetEntry(cwd: string): ProjectTrustStoreEntry | null {\n\t\treturn withTrustFileLock(this.trustPath, () => {\n\t\t\tconst data = readTrustFile(this.trustPath);\n\t\t\treturn findNearestTrustEntry(data, cwd);\n\t\t});\n\t}\n\n\tset(cwd: string, decision: ProjectTrustDecision): void {\n\t\tthis.setMany([{ path: cwd, decision }]);\n\t}\n\n\tsetMany(decisions: ProjectTrustUpdate[]): void {\n\t\twithTrustFileLock(this.trustPath, () => {\n\t\t\tconst data = readTrustFile(this.trustPath);\n\t\t\tfor (const { path, decision } of decisions) {\n\t\t\t\tconst key = normalizeCwd(path);\n\t\t\t\tfor (const existingKey of findTrustFileKeys(data, key)) {\n\t\t\t\t\tdelete data[existingKey];\n\t\t\t\t}\n\t\t\t\tif (decision !== null) {\n\t\t\t\t\tdata[key] = decision;\n\t\t\t\t}\n\t\t\t}\n\t\t\twriteTrustFile(this.trustPath, data);\n\t\t});\n\t}\n}\n"]}
@@ -11,20 +11,11 @@ export declare function createUsageTotals(): UsageTotals;
11
11
  export declare function addUsageToTotals(totals: UsageTotals, usage: Usage): void;
12
12
  /** Sum of two usages, keeping the optional token splits when either side reports them. */
13
13
  export declare function combineUsage(first: Usage, second: Usage): Usage;
14
- export declare function emptyUsage(): Usage;
15
- /** Share of one request's prompt served from cache, or undefined when it reported no cache activity. */
16
- export declare function cacheHitPercent({ input, cacheRead, cacheWrite, }: Pick<Usage, "input" | "cacheRead" | "cacheWrite">): number | undefined;
17
14
  export interface UsageCostBreakdownEntry {
18
15
  key: string;
19
16
  cost: number;
20
17
  tokens: number;
21
18
  }
22
- export interface TaskUsageRecord {
23
- taskId: string;
24
- usage: Usage;
25
- }
26
- /** Validate a task record's usage settlement and return only its serializable accounting fields. */
27
- export declare function getTaskUsageRecord(entry: SessionEntry): TaskUsageRecord | undefined;
28
19
  /** Legacy usage plus the first valid ledger record per task. Managed results omit usage. */
29
20
  export declare function getAccountedUsages(entries: readonly SessionEntry[]): Usage[];
30
21
  /** Group model-attributed usage by model and all other usage into a separate bucket. */
@@ -1 +1 @@
1
- {"version":3,"file":"usage-totals.d.ts","sourceRoot":"","sources":["../../src/core/usage-totals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,iBAAiB,IAAI,WAAW,CAQ/C;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAMxE;AAED,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAG,KAAK,CAqB/D;AAED,wBAAgB,UAAU,IAAI,KAAK,CASlC;AAED,wGAAwG;AACxG,wBAAgB,eAAe,CAAC,EAC/B,KAAK,EACL,SAAS,EACT,UAAU,GACV,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,YAAY,CAAC,GAAG,MAAM,GAAG,SAAS,CAGxE;AAED,MAAM,WAAW,uBAAuB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;CACb;AAsBD,oGAAoG;AACpG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,eAAe,GAAG,SAAS,CA0CnF;AAyBD,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,KAAK,EAAE,CAE5E;AAED,wFAAwF;AACxF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,uBAAuB,EAAE,CAmBjG"}
1
+ {"version":3,"file":"usage-totals.d.ts","sourceRoot":"","sources":["../../src/core/usage-totals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,iBAAiB,IAAI,WAAW,CAQ/C;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAMxE;AAED,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAG,KAAK,CAuB/D;AAED,MAAM,WAAW,uBAAuB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CACf;AAiCD,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,KAAK,EAAE,CAE5E;AAED,wFAAwF;AACxF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,uBAAuB,EAAE,CAmBjG"}
@@ -1,4 +1,4 @@
1
- import { TASK_RECORD_TYPE, TASK_SNAPSHOT_VERSION } from "./tasks/codec.js";
1
+ import { readTaskUsage } from "./tasks/codec.js";
2
2
  export function createUsageTotals() {
3
3
  return {
4
4
  input: 0,
@@ -35,111 +35,44 @@ export function combineUsage(first, second) {
35
35
  cacheRead: first.cost.cacheRead + second.cost.cacheRead,
36
36
  cacheWrite: first.cost.cacheWrite + second.cost.cacheWrite,
37
37
  total: first.cost.total + second.cost.total,
38
+ // A sum is provider-reported only when every part is.
39
+ totalFromProvider: first.cost.totalFromProvider === true && second.cost.totalFromProvider === true,
38
40
  },
39
41
  };
40
42
  }
41
- export function emptyUsage() {
42
- return {
43
- input: 0,
44
- output: 0,
45
- cacheRead: 0,
46
- cacheWrite: 0,
47
- totalTokens: 0,
48
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
49
- };
50
- }
51
- /** Share of one request's prompt served from cache, or undefined when it reported no cache activity. */
52
- export function cacheHitPercent({ input, cacheRead, cacheWrite, }) {
53
- const promptTokens = input + cacheRead + cacheWrite;
54
- return (cacheRead > 0 || cacheWrite > 0) && promptTokens > 0 ? (cacheRead / promptTokens) * 100 : undefined;
55
- }
56
- function isRecord(value) {
57
- return typeof value === "object" && value !== null && !Array.isArray(value);
58
- }
59
- function isUsageValue(value) {
60
- return typeof value === "number" && Number.isFinite(value) && value >= 0;
61
- }
62
- /** Released sessions settled usage in separate entries; their billing still counts. */
63
- const LEGACY_TASK_USAGE_TYPE = "task-usage";
64
- function settledTaskId(entry) {
65
- if (entry.type !== "custom" || !isRecord(entry.data))
66
- return undefined;
67
- const data = entry.data;
68
- if (entry.customType === TASK_RECORD_TYPE)
69
- return data.version === TASK_SNAPSHOT_VERSION && isRecord(data.task) ? data.task.id : undefined;
70
- if (entry.customType === LEGACY_TASK_USAGE_TYPE)
71
- return data.version === 1 ? data.taskId : undefined;
72
- return undefined;
73
- }
74
- /** Validate a task record's usage settlement and return only its serializable accounting fields. */
75
- export function getTaskUsageRecord(entry) {
76
- const taskId = settledTaskId(entry);
77
- if (typeof taskId !== "string" || !taskId.trim() || entry.type !== "custom")
78
- return undefined;
79
- const data = entry.data;
80
- const usage = data.usage;
81
- if (!isRecord(usage) || !isRecord(usage.cost))
82
- return undefined;
83
- const { input, output, cacheRead, cacheWrite, totalTokens, reasoning, cacheWrite1h } = usage;
84
- const cost = usage.cost;
85
- if (!isUsageValue(input) ||
86
- !isUsageValue(output) ||
87
- !isUsageValue(cacheRead) ||
88
- !isUsageValue(cacheWrite) ||
89
- !isUsageValue(totalTokens) ||
90
- !isUsageValue(cost.input) ||
91
- !isUsageValue(cost.output) ||
92
- !isUsageValue(cost.cacheRead) ||
93
- !isUsageValue(cost.cacheWrite) ||
94
- !isUsageValue(cost.total) ||
95
- (reasoning !== undefined && !isUsageValue(reasoning)) ||
96
- (cacheWrite1h !== undefined && !isUsageValue(cacheWrite1h)))
97
- return undefined;
98
- return {
99
- taskId,
100
- usage: {
101
- input,
102
- output,
103
- cacheRead,
104
- cacheWrite,
105
- totalTokens,
106
- ...(reasoning === undefined ? {} : { reasoning }),
107
- ...(cacheWrite1h === undefined ? {} : { cacheWrite1h }),
108
- cost: {
109
- input: cost.input,
110
- output: cost.output,
111
- cacheRead: cost.cacheRead,
112
- cacheWrite: cost.cacheWrite,
113
- total: cost.total,
114
- },
115
- },
116
- };
117
- }
43
+ /** Usage that counts toward totals: legacy entries plus the first valid settlement per task. */
118
44
  function* accountedUsageEntries(entries) {
119
- const backgroundTasks = new Set();
45
+ const settledTasks = new Set();
120
46
  for (const entry of entries) {
47
+ let key;
48
+ let usage;
121
49
  if (entry.type === "message" && entry.message.role === "assistant") {
122
- yield {
123
- key: `${entry.message.provider}/${entry.message.responseModel ?? entry.message.model}`,
124
- usage: entry.message.usage,
125
- };
50
+ key = `${entry.message.provider}/${entry.message.responseModel ?? entry.message.model}`;
51
+ usage = entry.message.usage;
126
52
  }
127
53
  else if (entry.type === "usage") {
128
- yield { key: `${entry.provider}/${entry.model}`, usage: entry.usage };
54
+ key = `${entry.provider}/${entry.model}`;
55
+ usage = entry.usage;
129
56
  }
130
57
  else if (entry.type === "message" && entry.message.role === "toolResult" && entry.message.usage) {
131
- yield { key: "Tools/summaries", usage: entry.message.usage };
58
+ key = "Tools/summaries";
59
+ usage = entry.message.usage;
132
60
  }
133
61
  else if ((entry.type === "branch_summary" || entry.type === "compaction") && entry.usage) {
134
- yield { key: "Tools/summaries", usage: entry.usage };
62
+ key = "Tools/summaries";
63
+ usage = entry.usage;
135
64
  }
136
65
  else {
137
- const record = getTaskUsageRecord(entry);
138
- if (!record || backgroundTasks.has(record.taskId))
139
- continue;
140
- backgroundTasks.add(record.taskId);
141
- yield { key: "Tools/summaries", usage: record.usage };
66
+ const settlement = readTaskUsage(entry);
67
+ if (settlement && !settledTasks.has(settlement.taskId)) {
68
+ settledTasks.add(settlement.taskId);
69
+ key = "Tools/summaries";
70
+ usage = settlement.usage;
71
+ }
142
72
  }
73
+ if (!key || !usage)
74
+ continue;
75
+ yield { key, usage };
143
76
  }
144
77
  }
145
78
  /** Legacy usage plus the first valid ledger record per task. Managed results omit usage. */
@@ -1 +1 @@
1
- {"version":3,"file":"usage-totals.js","sourceRoot":"","sources":["../../src/core/usage-totals.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport type { SessionEntry } from \"./session-manager.ts\";\nimport { TASK_RECORD_TYPE, TASK_SNAPSHOT_VERSION } from \"./tasks/codec.ts\";\n\nexport interface UsageTotals {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: number;\n}\n\nexport function createUsageTotals(): UsageTotals {\n\treturn {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\tcost: 0,\n\t};\n}\n\nexport function addUsageToTotals(totals: UsageTotals, usage: Usage): void {\n\ttotals.input += usage.input;\n\ttotals.output += usage.output;\n\ttotals.cacheRead += usage.cacheRead;\n\ttotals.cacheWrite += usage.cacheWrite;\n\ttotals.cost += usage.cost.total;\n}\n\n/** Sum of two usages, keeping the optional token splits when either side reports them. */\nexport function combineUsage(first: Usage, second: Usage): Usage {\n\treturn {\n\t\tinput: first.input + second.input,\n\t\toutput: first.output + second.output,\n\t\tcacheRead: first.cacheRead + second.cacheRead,\n\t\tcacheWrite: first.cacheWrite + second.cacheWrite,\n\t\t...(first.cacheWrite1h !== undefined || second.cacheWrite1h !== undefined\n\t\t\t? { cacheWrite1h: (first.cacheWrite1h ?? 0) + (second.cacheWrite1h ?? 0) }\n\t\t\t: {}),\n\t\t...(first.reasoning !== undefined || second.reasoning !== undefined\n\t\t\t? { reasoning: (first.reasoning ?? 0) + (second.reasoning ?? 0) }\n\t\t\t: {}),\n\t\ttotalTokens: first.totalTokens + second.totalTokens,\n\t\tcost: {\n\t\t\tinput: first.cost.input + second.cost.input,\n\t\t\toutput: first.cost.output + second.cost.output,\n\t\t\tcacheRead: first.cost.cacheRead + second.cost.cacheRead,\n\t\t\tcacheWrite: first.cost.cacheWrite + second.cost.cacheWrite,\n\t\t\ttotal: first.cost.total + second.cost.total,\n\t\t},\n\t};\n}\n\nexport function emptyUsage(): Usage {\n\treturn {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\ttotalTokens: 0,\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t};\n}\n\n/** Share of one request's prompt served from cache, or undefined when it reported no cache activity. */\nexport function cacheHitPercent({\n\tinput,\n\tcacheRead,\n\tcacheWrite,\n}: Pick<Usage, \"input\" | \"cacheRead\" | \"cacheWrite\">): number | undefined {\n\tconst promptTokens = input + cacheRead + cacheWrite;\n\treturn (cacheRead > 0 || cacheWrite > 0) && promptTokens > 0 ? (cacheRead / promptTokens) * 100 : undefined;\n}\n\nexport interface UsageCostBreakdownEntry {\n\tkey: string;\n\tcost: number;\n\ttokens: number;\n}\n\nexport interface TaskUsageRecord {\n\ttaskId: string;\n\tusage: Usage;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isUsageValue(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\n/** Released sessions settled usage in separate entries; their billing still counts. */\nconst LEGACY_TASK_USAGE_TYPE = \"task-usage\";\n\nfunction settledTaskId(entry: SessionEntry): unknown {\n\tif (entry.type !== \"custom\" || !isRecord(entry.data)) return undefined;\n\tconst data = entry.data;\n\tif (entry.customType === TASK_RECORD_TYPE)\n\t\treturn data.version === TASK_SNAPSHOT_VERSION && isRecord(data.task) ? data.task.id : undefined;\n\tif (entry.customType === LEGACY_TASK_USAGE_TYPE) return data.version === 1 ? data.taskId : undefined;\n\treturn undefined;\n}\n\n/** Validate a task record's usage settlement and return only its serializable accounting fields. */\nexport function getTaskUsageRecord(entry: SessionEntry): TaskUsageRecord | undefined {\n\tconst taskId = settledTaskId(entry);\n\tif (typeof taskId !== \"string\" || !taskId.trim() || entry.type !== \"custom\") return undefined;\n\tconst data = entry.data as Record<string, unknown>;\n\tconst usage = data.usage;\n\tif (!isRecord(usage) || !isRecord(usage.cost)) return undefined;\n\tconst { input, output, cacheRead, cacheWrite, totalTokens, reasoning, cacheWrite1h } = usage;\n\tconst cost = usage.cost;\n\tif (\n\t\t!isUsageValue(input) ||\n\t\t!isUsageValue(output) ||\n\t\t!isUsageValue(cacheRead) ||\n\t\t!isUsageValue(cacheWrite) ||\n\t\t!isUsageValue(totalTokens) ||\n\t\t!isUsageValue(cost.input) ||\n\t\t!isUsageValue(cost.output) ||\n\t\t!isUsageValue(cost.cacheRead) ||\n\t\t!isUsageValue(cost.cacheWrite) ||\n\t\t!isUsageValue(cost.total) ||\n\t\t(reasoning !== undefined && !isUsageValue(reasoning)) ||\n\t\t(cacheWrite1h !== undefined && !isUsageValue(cacheWrite1h))\n\t)\n\t\treturn undefined;\n\treturn {\n\t\ttaskId,\n\t\tusage: {\n\t\t\tinput,\n\t\t\toutput,\n\t\t\tcacheRead,\n\t\t\tcacheWrite,\n\t\t\ttotalTokens,\n\t\t\t...(reasoning === undefined ? {} : { reasoning }),\n\t\t\t...(cacheWrite1h === undefined ? {} : { cacheWrite1h }),\n\t\t\tcost: {\n\t\t\t\tinput: cost.input,\n\t\t\t\toutput: cost.output,\n\t\t\t\tcacheRead: cost.cacheRead,\n\t\t\t\tcacheWrite: cost.cacheWrite,\n\t\t\t\ttotal: cost.total,\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction* accountedUsageEntries(entries: readonly SessionEntry[]): Generator<{ key: string; usage: Usage }> {\n\tconst backgroundTasks = new Set<string>();\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tyield {\n\t\t\t\tkey: `${entry.message.provider}/${entry.message.responseModel ?? entry.message.model}`,\n\t\t\t\tusage: entry.message.usage,\n\t\t\t};\n\t\t} else if (entry.type === \"usage\") {\n\t\t\tyield { key: `${entry.provider}/${entry.model}`, usage: entry.usage };\n\t\t} else if (entry.type === \"message\" && entry.message.role === \"toolResult\" && entry.message.usage) {\n\t\t\tyield { key: \"Tools/summaries\", usage: entry.message.usage };\n\t\t} else if ((entry.type === \"branch_summary\" || entry.type === \"compaction\") && entry.usage) {\n\t\t\tyield { key: \"Tools/summaries\", usage: entry.usage };\n\t\t} else {\n\t\t\tconst record = getTaskUsageRecord(entry);\n\t\t\tif (!record || backgroundTasks.has(record.taskId)) continue;\n\t\t\tbackgroundTasks.add(record.taskId);\n\t\t\tyield { key: \"Tools/summaries\", usage: record.usage };\n\t\t}\n\t}\n}\n\n/** Legacy usage plus the first valid ledger record per task. Managed results omit usage. */\nexport function getAccountedUsages(entries: readonly SessionEntry[]): Usage[] {\n\treturn Array.from(accountedUsageEntries(entries), ({ usage }) => usage);\n}\n\n/** Group model-attributed usage by model and all other usage into a separate bucket. */\nexport function getUsageCostBreakdown(entries: readonly SessionEntry[]): UsageCostBreakdownEntry[] {\n\tconst totalsByKey = new Map<string, UsageTotals>();\n\n\tfor (const { key, usage } of accountedUsageEntries(entries)) {\n\t\tlet totals = totalsByKey.get(key);\n\t\tif (!totals) {\n\t\t\ttotals = createUsageTotals();\n\t\t\ttotalsByKey.set(key, totals);\n\t\t}\n\t\taddUsageToTotals(totals, usage);\n\t}\n\n\treturn Array.from(totalsByKey, ([key, totals]) => ({\n\t\tkey,\n\t\tcost: totals.cost,\n\t\ttokens: totals.input + totals.output + totals.cacheRead + totals.cacheWrite,\n\t}))\n\t\t.filter((entry) => entry.cost > 0 || entry.tokens > 0)\n\t\t.sort((a, b) => b.cost - a.cost);\n}\n"]}
1
+ {"version":3,"file":"usage-totals.js","sourceRoot":"","sources":["../../src/core/usage-totals.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport type { SessionEntry } from \"./session-manager.ts\";\nimport { readTaskUsage } from \"./tasks/codec.ts\";\n\nexport interface UsageTotals {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: number;\n}\n\nexport function createUsageTotals(): UsageTotals {\n\treturn {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\tcost: 0,\n\t};\n}\n\nexport function addUsageToTotals(totals: UsageTotals, usage: Usage): void {\n\ttotals.input += usage.input;\n\ttotals.output += usage.output;\n\ttotals.cacheRead += usage.cacheRead;\n\ttotals.cacheWrite += usage.cacheWrite;\n\ttotals.cost += usage.cost.total;\n}\n\n/** Sum of two usages, keeping the optional token splits when either side reports them. */\nexport function combineUsage(first: Usage, second: Usage): Usage {\n\treturn {\n\t\tinput: first.input + second.input,\n\t\toutput: first.output + second.output,\n\t\tcacheRead: first.cacheRead + second.cacheRead,\n\t\tcacheWrite: first.cacheWrite + second.cacheWrite,\n\t\t...(first.cacheWrite1h !== undefined || second.cacheWrite1h !== undefined\n\t\t\t? { cacheWrite1h: (first.cacheWrite1h ?? 0) + (second.cacheWrite1h ?? 0) }\n\t\t\t: {}),\n\t\t...(first.reasoning !== undefined || second.reasoning !== undefined\n\t\t\t? { reasoning: (first.reasoning ?? 0) + (second.reasoning ?? 0) }\n\t\t\t: {}),\n\t\ttotalTokens: first.totalTokens + second.totalTokens,\n\t\tcost: {\n\t\t\tinput: first.cost.input + second.cost.input,\n\t\t\toutput: first.cost.output + second.cost.output,\n\t\t\tcacheRead: first.cost.cacheRead + second.cost.cacheRead,\n\t\t\tcacheWrite: first.cost.cacheWrite + second.cost.cacheWrite,\n\t\t\ttotal: first.cost.total + second.cost.total,\n\t\t\t// A sum is provider-reported only when every part is.\n\t\t\ttotalFromProvider: first.cost.totalFromProvider === true && second.cost.totalFromProvider === true,\n\t\t},\n\t};\n}\n\nexport interface UsageCostBreakdownEntry {\n\tkey: string;\n\tcost: number;\n\ttokens: number;\n}\n\n/** Usage that counts toward totals: legacy entries plus the first valid settlement per task. */\nfunction* accountedUsageEntries(entries: readonly SessionEntry[]): Generator<{ key: string; usage: Usage }> {\n\tconst settledTasks = new Set<string>();\n\tfor (const entry of entries) {\n\t\tlet key: string | undefined;\n\t\tlet usage: Usage | undefined;\n\t\tif (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tkey = `${entry.message.provider}/${entry.message.responseModel ?? entry.message.model}`;\n\t\t\tusage = entry.message.usage;\n\t\t} else if (entry.type === \"usage\") {\n\t\t\tkey = `${entry.provider}/${entry.model}`;\n\t\t\tusage = entry.usage;\n\t\t} else if (entry.type === \"message\" && entry.message.role === \"toolResult\" && entry.message.usage) {\n\t\t\tkey = \"Tools/summaries\";\n\t\t\tusage = entry.message.usage;\n\t\t} else if ((entry.type === \"branch_summary\" || entry.type === \"compaction\") && entry.usage) {\n\t\t\tkey = \"Tools/summaries\";\n\t\t\tusage = entry.usage;\n\t\t} else {\n\t\t\tconst settlement = readTaskUsage(entry);\n\t\t\tif (settlement && !settledTasks.has(settlement.taskId)) {\n\t\t\t\tsettledTasks.add(settlement.taskId);\n\t\t\t\tkey = \"Tools/summaries\";\n\t\t\t\tusage = settlement.usage;\n\t\t\t}\n\t\t}\n\t\tif (!key || !usage) continue;\n\t\tyield { key, usage };\n\t}\n}\n\n/** Legacy usage plus the first valid ledger record per task. Managed results omit usage. */\nexport function getAccountedUsages(entries: readonly SessionEntry[]): Usage[] {\n\treturn Array.from(accountedUsageEntries(entries), ({ usage }) => usage);\n}\n\n/** Group model-attributed usage by model and all other usage into a separate bucket. */\nexport function getUsageCostBreakdown(entries: readonly SessionEntry[]): UsageCostBreakdownEntry[] {\n\tconst totalsByKey = new Map<string, UsageTotals>();\n\n\tfor (const { key, usage } of accountedUsageEntries(entries)) {\n\t\tlet totals = totalsByKey.get(key);\n\t\tif (!totals) {\n\t\t\ttotals = createUsageTotals();\n\t\t\ttotalsByKey.set(key, totals);\n\t\t}\n\t\taddUsageToTotals(totals, usage);\n\t}\n\n\treturn Array.from(totalsByKey, ([key, totals]) => ({\n\t\tkey,\n\t\tcost: totals.cost,\n\t\ttokens: totals.input + totals.output + totals.cacheRead + totals.cacheWrite,\n\t}))\n\t\t.filter((entry) => entry.cost > 0 || entry.tokens > 0)\n\t\t.sort((a, b) => b.cost - a.cost);\n}\n"]}
@@ -1,10 +1,9 @@
1
1
  import type { Theme } from "../../modes/interactive/theme/theme.ts";
2
2
  import type { AgentActivity } from "./types.ts";
3
3
  /**
4
- * Themed rows for `activities`: an optional `… N earlier tool calls` line, then one row per call
5
- * with an aligned tool-name column, durations right-aligned in one column, and a failed call's first
4
+ * Themed rows for `activities`: one row per call with an aligned tool-name column, durations right-aligned in one column, and a failed call's first
6
5
  * error line beneath it. The table is as wide as its longest row, at most `width`. Measured at
7
6
  * `now`, a running call shows a spinner frame and the time since it started.
8
7
  */
9
- export declare function activityLines(activities: readonly AgentActivity[], earlier: number, width: number, theme: Theme, now?: number): string[];
8
+ export declare function activityLines(activities: readonly AgentActivity[], width: number, theme: Theme, now?: number): string[];
10
9
  //# sourceMappingURL=activity-lines.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"activity-lines.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/activity-lines.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AAUpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAyDhD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK,EACZ,GAAG,SAAa,GACd,MAAM,EAAE,CAwBV"}
1
+ {"version":3,"file":"activity-lines.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/activity-lines.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AAGpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAyDhD;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK,EACZ,GAAG,SAAa,GACd,MAAM,EAAE,CAwBV"}
@@ -1,10 +1,7 @@
1
- /**
2
- * The themed tool-call list of a running Agent. The Transcript's expanded row and the /tasks
3
- * Output both render through `activityLines`, so the two cannot drift apart.
4
- */
1
+ /** The themed tool-call list of a running Agent's expanded Transcript row. */
5
2
  import { stripTerminalSequences, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
6
3
  import { sanitizeBinaryOutput } from "../../utils/shell.js";
7
- import { activityMarker, earlierLabel, errorLine, formatActivityDuration, nameColumnWidth, targetOf, } from "./activity.js";
4
+ import { activityMarker, errorLine, formatActivityDuration, nameColumnWidth, targetOf } from "./activity.js";
8
5
  /** ` · ` before the duration column. */
9
6
  const SEPARATOR_WIDTH = 3;
10
7
  /** One line of tool-call text with no terminal sequences or control characters; the Agent's arguments are untrusted. */
@@ -44,12 +41,11 @@ function activityRow(row, nameWidth, durationWidth, tableWidth, theme) {
44
41
  return `${head} ${theme.fg("muted", clipped)}${" ".repeat(room - visibleWidth(clipped))}${tail}`;
45
42
  }
46
43
  /**
47
- * Themed rows for `activities`: an optional `… N earlier tool calls` line, then one row per call
48
- * with an aligned tool-name column, durations right-aligned in one column, and a failed call's first
44
+ * Themed rows for `activities`: one row per call with an aligned tool-name column, durations right-aligned in one column, and a failed call's first
49
45
  * error line beneath it. The table is as wide as its longest row, at most `width`. Measured at
50
46
  * `now`, a running call shows a spinner frame and the time since it started.
51
47
  */
52
- export function activityLines(activities, earlier, width, theme, now = Date.now()) {
48
+ export function activityLines(activities, width, theme, now = Date.now()) {
53
49
  if (width <= 0)
54
50
  return [];
55
51
  const nameWidth = nameColumnWidth(activities);
@@ -64,7 +60,7 @@ export function activityLines(activities, earlier, width, theme, now = Date.now(
64
60
  const tailWidth = durationWidth ? SEPARATOR_WIDTH + durationWidth : 0;
65
61
  const naturalWidth = Math.max(0, ...rows.map((row) => headWidth(row, nameWidth) + visibleWidth(row.target) + tailWidth));
66
62
  const tableWidth = Math.min(width, naturalWidth);
67
- const lines = earlier > 0 ? [truncateToWidth(theme.fg("dim", earlierLabel(earlier)), width, "…")] : [];
63
+ const lines = [];
68
64
  for (const row of rows) {
69
65
  lines.push(activityRow(row, nameWidth, durationWidth, tableWidth, theme));
70
66
  const error = row.activity.error ? oneLine(errorLine(row.activity.error)) : "";
@@ -1 +1 @@
1
- {"version":3,"file":"activity-lines.js","sourceRoot":"","sources":["../../../src/extensions/agent/activity-lines.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The themed tool-call list of a running Agent. The Transcript's expanded row and the /tasks\n * Output both render through `activityLines`, so the two cannot drift apart.\n */\nimport { stripTerminalSequences, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { StatusMarker } from \"../../modes/interactive/components/status-marker.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { sanitizeBinaryOutput } from \"../../utils/shell.ts\";\nimport {\n\tactivityMarker,\n\tearlierLabel,\n\terrorLine,\n\tformatActivityDuration,\n\tnameColumnWidth,\n\ttargetOf,\n} from \"./activity.ts\";\nimport type { AgentActivity } from \"./types.ts\";\n\n/** ` · ` before the duration column. */\nconst SEPARATOR_WIDTH = 3;\n\n/** One row's text and marker before styling; widths are measured on these. */\ninterface RowParts {\n\tactivity: AgentActivity;\n\tmarker: StatusMarker;\n\tname: string;\n\ttarget: string;\n\tduration: string;\n}\n\n/** One line of tool-call text with no terminal sequences or control characters; the Agent's arguments are untrusted. */\nfunction oneLine(text: string): string {\n\treturn sanitizeBinaryOutput(stripTerminalSequences(text)).replace(/\\s+/gu, \" \").trim();\n}\n\n/** A finished call's own duration; a running call's time since it started. */\nfunction shownDuration(activity: AgentActivity, now: number): string {\n\tif (activity.status === \"running\")\n\t\treturn activity.startedAt === undefined ? \"\" : formatActivityDuration(Math.max(0, now - activity.startedAt));\n\treturn formatActivityDuration(activity.durationMs);\n}\n\n/** `glyph name` with the padding that lines targets up, plus the space before the target. */\nfunction headWidth(row: RowParts, nameWidth: number): number {\n\treturn visibleWidth(row.marker.glyph) + 1 + Math.max(nameWidth, visibleWidth(row.name)) + 1;\n}\n\n/**\n * `glyph name target · duration`, with the durations right-aligned in one column ending at\n * `tableWidth`. A long target gives way before the duration does.\n */\nfunction activityRow(\n\trow: RowParts,\n\tnameWidth: number,\n\tdurationWidth: number,\n\ttableWidth: number,\n\ttheme: Theme,\n): string {\n\tconst { marker, name, target, duration } = row;\n\tconst padding = \" \".repeat(Math.max(0, nameWidth - visibleWidth(name)));\n\tconst head = `${theme.fg(marker.color, marker.glyph)} ${theme.fg(\"toolTitle\", name)}${padding}`;\n\tconst durationPad = \" \".repeat(Math.max(0, durationWidth - visibleWidth(duration)));\n\tconst tail = duration ? `${theme.fg(\"dim\", \" · \")}${durationPad}${theme.fg(\"dim\", duration)}` : \"\";\n\tif (!target && !tail) return truncateToWidth(head.trimEnd(), tableWidth, \"…\");\n\tconst room = tableWidth - headWidth(row, nameWidth) - (tail ? SEPARATOR_WIDTH + durationWidth : 0);\n\t// Without room for even a clipped target, the whole row is clipped instead.\n\tif (room < 2) return truncateToWidth(`${head} ${theme.fg(\"muted\", target)}${tail}`, tableWidth, \"…\");\n\tconst clipped = truncateToWidth(target, room, \"…\");\n\t// A row without a duration ends at its target instead of trailing blanks.\n\tif (!tail) return `${head} ${theme.fg(\"muted\", clipped)}`;\n\treturn `${head} ${theme.fg(\"muted\", clipped)}${\" \".repeat(room - visibleWidth(clipped))}${tail}`;\n}\n\n/**\n * Themed rows for `activities`: an optional `… N earlier tool calls` line, then one row per call\n * with an aligned tool-name column, durations right-aligned in one column, and a failed call's first\n * error line beneath it. The table is as wide as its longest row, at most `width`. Measured at\n * `now`, a running call shows a spinner frame and the time since it started.\n */\nexport function activityLines(\n\tactivities: readonly AgentActivity[],\n\tearlier: number,\n\twidth: number,\n\ttheme: Theme,\n\tnow = Date.now(),\n): string[] {\n\tif (width <= 0) return [];\n\tconst nameWidth = nameColumnWidth(activities);\n\tconst rows: RowParts[] = activities.map((activity) => ({\n\t\tactivity,\n\t\tmarker: activityMarker(activity.status, now),\n\t\tname: oneLine(activity.name),\n\t\ttarget: oneLine(targetOf(activity)),\n\t\tduration: shownDuration(activity, now),\n\t}));\n\tconst durationWidth = Math.max(0, ...rows.map((row) => visibleWidth(row.duration)));\n\tconst tailWidth = durationWidth ? SEPARATOR_WIDTH + durationWidth : 0;\n\tconst naturalWidth = Math.max(\n\t\t0,\n\t\t...rows.map((row) => headWidth(row, nameWidth) + visibleWidth(row.target) + tailWidth),\n\t);\n\tconst tableWidth = Math.min(width, naturalWidth);\n\tconst lines = earlier > 0 ? [truncateToWidth(theme.fg(\"dim\", earlierLabel(earlier)), width, \"…\")] : [];\n\tfor (const row of rows) {\n\t\tlines.push(activityRow(row, nameWidth, durationWidth, tableWidth, theme));\n\t\tconst error = row.activity.error ? oneLine(errorLine(row.activity.error)) : \"\";\n\t\tif (error) lines.push(truncateToWidth(`${\" \".repeat(3 + nameWidth)}${theme.fg(\"error\", error)}`, width, \"…\"));\n\t}\n\treturn lines;\n}\n"]}
1
+ {"version":3,"file":"activity-lines.js","sourceRoot":"","sources":["../../../src/extensions/agent/activity-lines.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAG/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,sBAAsB,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG7G,wCAAwC;AACxC,MAAM,eAAe,GAAG,CAAC,CAAC;AAW1B,wHAAwH;AACxH,SAAS,OAAO,CAAC,IAAY;IAC5B,OAAO,oBAAoB,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACxF,CAAC;AAED,8EAA8E;AAC9E,SAAS,aAAa,CAAC,QAAuB,EAAE,GAAW;IAC1D,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS;QAChC,OAAO,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9G,OAAO,sBAAsB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AACpD,CAAC;AAED,6FAA6F;AAC7F,SAAS,SAAS,CAAC,GAAa,EAAE,SAAiB;IAClD,OAAO,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;AAC7F,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CACnB,GAAa,EACb,SAAiB,EACjB,aAAqB,EACrB,UAAkB,EAClB,KAAY;IAEZ,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;IAC/C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,OAAO,EAAE,CAAC;IAChG,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,WAAW,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnG,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI;QAAE,OAAO,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAC9E,MAAM,IAAI,GAAG,UAAU,GAAG,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnG,4EAA4E;IAC5E,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,eAAe,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IACrG,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACnD,0EAA0E;IAC1E,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;IAC1D,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;AAClG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC5B,UAAoC,EACpC,KAAa,EACb,KAAY,EACZ,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAEhB,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1B,MAAM,SAAS,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAe,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACtD,QAAQ;QACR,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;QAC5C,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC5B,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnC,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC;KACtC,CAAC,CAAC,CAAC;IACJ,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,eAAe,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAC5B,CAAC,EACD,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,CACtF,CAAC;IACF,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACjD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;QAC1E,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,IAAI,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/G,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC","sourcesContent":["/** The themed tool-call list of a running Agent's expanded Transcript row. */\nimport { stripTerminalSequences, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { StatusMarker } from \"../../modes/interactive/components/status-marker.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { sanitizeBinaryOutput } from \"../../utils/shell.ts\";\nimport { activityMarker, errorLine, formatActivityDuration, nameColumnWidth, targetOf } from \"./activity.ts\";\nimport type { AgentActivity } from \"./types.ts\";\n\n/** ` · ` before the duration column. */\nconst SEPARATOR_WIDTH = 3;\n\n/** One row's text and marker before styling; widths are measured on these. */\ninterface RowParts {\n\tactivity: AgentActivity;\n\tmarker: StatusMarker;\n\tname: string;\n\ttarget: string;\n\tduration: string;\n}\n\n/** One line of tool-call text with no terminal sequences or control characters; the Agent's arguments are untrusted. */\nfunction oneLine(text: string): string {\n\treturn sanitizeBinaryOutput(stripTerminalSequences(text)).replace(/\\s+/gu, \" \").trim();\n}\n\n/** A finished call's own duration; a running call's time since it started. */\nfunction shownDuration(activity: AgentActivity, now: number): string {\n\tif (activity.status === \"running\")\n\t\treturn activity.startedAt === undefined ? \"\" : formatActivityDuration(Math.max(0, now - activity.startedAt));\n\treturn formatActivityDuration(activity.durationMs);\n}\n\n/** `glyph name` with the padding that lines targets up, plus the space before the target. */\nfunction headWidth(row: RowParts, nameWidth: number): number {\n\treturn visibleWidth(row.marker.glyph) + 1 + Math.max(nameWidth, visibleWidth(row.name)) + 1;\n}\n\n/**\n * `glyph name target · duration`, with the durations right-aligned in one column ending at\n * `tableWidth`. A long target gives way before the duration does.\n */\nfunction activityRow(\n\trow: RowParts,\n\tnameWidth: number,\n\tdurationWidth: number,\n\ttableWidth: number,\n\ttheme: Theme,\n): string {\n\tconst { marker, name, target, duration } = row;\n\tconst padding = \" \".repeat(Math.max(0, nameWidth - visibleWidth(name)));\n\tconst head = `${theme.fg(marker.color, marker.glyph)} ${theme.fg(\"toolTitle\", name)}${padding}`;\n\tconst durationPad = \" \".repeat(Math.max(0, durationWidth - visibleWidth(duration)));\n\tconst tail = duration ? `${theme.fg(\"dim\", \" · \")}${durationPad}${theme.fg(\"dim\", duration)}` : \"\";\n\tif (!target && !tail) return truncateToWidth(head.trimEnd(), tableWidth, \"…\");\n\tconst room = tableWidth - headWidth(row, nameWidth) - (tail ? SEPARATOR_WIDTH + durationWidth : 0);\n\t// Without room for even a clipped target, the whole row is clipped instead.\n\tif (room < 2) return truncateToWidth(`${head} ${theme.fg(\"muted\", target)}${tail}`, tableWidth, \"…\");\n\tconst clipped = truncateToWidth(target, room, \"…\");\n\t// A row without a duration ends at its target instead of trailing blanks.\n\tif (!tail) return `${head} ${theme.fg(\"muted\", clipped)}`;\n\treturn `${head} ${theme.fg(\"muted\", clipped)}${\" \".repeat(room - visibleWidth(clipped))}${tail}`;\n}\n\n/**\n * Themed rows for `activities`: one row per call with an aligned tool-name column, durations right-aligned in one column, and a failed call's first\n * error line beneath it. The table is as wide as its longest row, at most `width`. Measured at\n * `now`, a running call shows a spinner frame and the time since it started.\n */\nexport function activityLines(\n\tactivities: readonly AgentActivity[],\n\twidth: number,\n\ttheme: Theme,\n\tnow = Date.now(),\n): string[] {\n\tif (width <= 0) return [];\n\tconst nameWidth = nameColumnWidth(activities);\n\tconst rows: RowParts[] = activities.map((activity) => ({\n\t\tactivity,\n\t\tmarker: activityMarker(activity.status, now),\n\t\tname: oneLine(activity.name),\n\t\ttarget: oneLine(targetOf(activity)),\n\t\tduration: shownDuration(activity, now),\n\t}));\n\tconst durationWidth = Math.max(0, ...rows.map((row) => visibleWidth(row.duration)));\n\tconst tailWidth = durationWidth ? SEPARATOR_WIDTH + durationWidth : 0;\n\tconst naturalWidth = Math.max(\n\t\t0,\n\t\t...rows.map((row) => headWidth(row, nameWidth) + visibleWidth(row.target) + tailWidth),\n\t);\n\tconst tableWidth = Math.min(width, naturalWidth);\n\tconst lines: string[] = [];\n\tfor (const row of rows) {\n\t\tlines.push(activityRow(row, nameWidth, durationWidth, tableWidth, theme));\n\t\tconst error = row.activity.error ? oneLine(errorLine(row.activity.error)) : \"\";\n\t\tif (error) lines.push(truncateToWidth(`${\" \".repeat(3 + nameWidth)}${theme.fg(\"error\", error)}`, width, \"…\"));\n\t}\n\treturn lines;\n}\n"]}
@@ -27,8 +27,6 @@ export declare function paddedName(activity: AgentActivity, width: number): stri
27
27
  export declare function errorLine(error: string): string;
28
28
  /** `glyph name target · duration`, plus a failure line under the target column. */
29
29
  export declare function activityText(activity: AgentActivity, nameWidth?: number): string;
30
- /** The line standing for calls no longer retained. */
31
- export declare function earlierLabel(earlier: number): string;
32
30
  /** The plain /tasks display: a count of calls no longer retained, then one aligned row per call. */
33
31
  export declare function activitiesText(activities: readonly AgentActivity[], earlier?: number): string;
34
32
  //# sourceMappingURL=activity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/activity.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAgB,MAAM,qDAAqD,CAAC;AAEtG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAMtD;AAOD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAO3E;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBhF;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAOxD;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMrE;AASD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,YAAY,CAE1F;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,MAAM,CAErE;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CAE5E;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,SAA8B,GAAG,MAAM,CAMrG;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,oGAAoG;AACpG,wBAAgB,cAAc,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,EAAE,OAAO,SAAI,GAAG,MAAM,CAIxF"}
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/activity.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAgB,MAAM,qDAAqD,CAAC;AAEtG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAMtD;AAOD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAO3E;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBhF;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAOxD;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMrE;AASD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,YAAY,CAE1F;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,MAAM,CAErE;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CAE5E;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,SAA8B,GAAG,MAAM,CAMrG;AAOD,oGAAoG;AACpG,wBAAgB,cAAc,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,EAAE,OAAO,SAAI,GAAG,MAAM,CAIxF"}
@@ -118,7 +118,7 @@ export function activityText(activity, nameWidth = nameColumnWidth([activity]))
118
118
  return error ? `${line}\n${" ".repeat(3 + nameWidth)}${error}` : line;
119
119
  }
120
120
  /** The line standing for calls no longer retained. */
121
- export function earlierLabel(earlier) {
121
+ function earlierLabel(earlier) {
122
122
  return `… ${earlier} earlier tool ${earlier === 1 ? "call" : "calls"}`;
123
123
  }
124
124
  /** The plain /tasks display: a count of calls no longer retained, then one aligned row per call. */
@@ -1 +1 @@
1
- {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../../src/extensions/agent/activity.ts"],"names":[],"mappings":"AAAA,yGAAyG;AACzG,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,OAAO,EAAqB,YAAY,EAAE,MAAM,qDAAqD,CAAC;AACtG,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGzD,kGAAkG;AAClG,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAa;IACnD,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK;QAAE,OAAO,IAAI,CAAC;IAClD,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAa;IAC7C,IAAI,CAAC;QACJ,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED,8GAA8G;AAC9G,SAAS,mBAAmB,CAAC,IAAY;IACxC,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACrG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,GAAuB;IAClE,IAAI,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACjF,0EAA0E;IAC1E,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,GAAG,CAAC;IAC3B,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxG,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,IAAa,EAAE,GAAY;IACvE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC5F,MAAM,MAAM,GAAG,IAA+B,CAAC;IAC/C,MAAM,IAAI,GACT,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,YAAY;QACvC,CAAC,CAAC,CAAC,SAAS,CAAC;QACb,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM;YACnC,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC;YACrB,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACpC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;YAAE,SAAS;QACzD,MAAM,KAAK,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC3F,MAAM,IAAI,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAC9D,OAAO,QAAQ,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,QAAQ,CAAC,QAAuB;IAC/C,IAAI,QAAQ,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC,MAAM,CAAC;IAC5C,IAAI,CAAC;QACJ,OAAO,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,QAAQ,CAAC,IAAI,CAAC;IACtB,CAAC;AACF,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,sBAAsB,CAAC,EAAsB;IAC5D,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9B,IAAI,MAAM,GAAG,IAAI;QAAE,OAAO,GAAG,MAAM,IAAI,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IACzC,OAAO,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,WAAW,GAAgD;IAChE,OAAO,EAAE,SAAS;IAClB,EAAE,EAAE,WAAW;IACf,KAAK,EAAE,QAAQ;IACf,SAAS,EAAE,WAAW;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAA+B,EAAE,GAAY;IAC3E,OAAO,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAA+B;IAC5D,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;AACrC,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,eAAe,CAAC,UAAoC;IACnE,OAAO,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtG,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,UAAU,CAAC,QAAuB,EAAE,KAAa;IAChE,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AACzE,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,SAAS,CAAC,KAAa;IACtC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACpG,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACrG,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,YAAY,CAAC,QAAuB,EAAE,SAAS,GAAG,eAAe,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC5F,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpJ,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,YAAY,CAAC,OAAe;IAC3C,OAAO,KAAK,OAAO,iBAAiB,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;AACxE,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,cAAc,CAAC,UAAoC,EAAE,OAAO,GAAG,CAAC;IAC/E,MAAM,KAAK,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IACzE,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3E,CAAC","sourcesContent":["/** Compact, bounded formatting of an Agent's tool-call activity, shared by the Transcript and /tasks. */\nimport { isAbsolute, relative, sep, win32 } from \"node:path\";\nimport { boundText } from \"../../core/tasks/output.ts\";\nimport type { TaskStatus } from \"../../core/tasks/types.ts\";\nimport { type StatusMarker, statusMarker } from \"../../modes/interactive/components/status-marker.ts\";\nimport { formatDuration } from \"../../utils/duration.ts\";\nimport type { AgentActivity } from \"./types.ts\";\n\n/** The tool-name column never grows past this, so one long name cannot push every target away. */\nconst NAME_COLUMN_MAX = 8;\nconst ERROR_LINE_CHARS = 160;\n\nexport function clipText(text: string, bytes: number): string {\n\tif (Buffer.byteLength(text) <= bytes) return text;\n\treturn `${boundText(text, Math.max(1, bytes - 1))}…`;\n}\n\nexport function compactArguments(args: unknown): string {\n\ttry {\n\t\treturn clipText(JSON.stringify(args) ?? String(args), 512).replace(/\\s+/gu, \" \");\n\t} catch {\n\t\treturn \"{…}\";\n\t}\n}\n\n/** A fully qualified absolute path; a rooted path without a drive would resolve against the process drive. */\nfunction isQualifiedAbsolute(path: string): boolean {\n\treturn process.platform === \"win32\" ? /^(?:[A-Za-z]:[\\\\/]|[\\\\/]{2})/u.test(path) : isAbsolute(path);\n}\n\n/**\n * An absolute path inside `cwd` as a forward-slash relative path. Relative paths and paths outside\n * `cwd` are returned unchanged; nothing is ever resolved against the process working directory.\n */\nexport function relativeToCwd(path: string, cwd: string | undefined): string {\n\tif (!cwd || !isQualifiedAbsolute(path) || !isQualifiedAbsolute(cwd)) return path;\n\t// node:path compares case-insensitively on Windows and exactly elsewhere.\n\tconst rel = relative(cwd, path);\n\tif (rel === \"\") return \".\";\n\tif (rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel) || win32.isAbsolute(rel)) return path;\n\treturn rel.split(sep).join(\"/\");\n}\n\n/** A short display target; full arguments remain available in Tasks Output. */\nexport function activityTarget(name: string, args: unknown, cwd?: string): string {\n\tif (!args || typeof args !== \"object\" || Array.isArray(args)) return compactArguments(args);\n\tconst record = args as Record<string, unknown>;\n\tconst keys =\n\t\tname === \"bash\" || name === \"powershell\"\n\t\t\t? [\"command\"]\n\t\t\t: name === \"grep\" || name === \"find\"\n\t\t\t\t? [\"pattern\", \"path\"]\n\t\t\t\t: [\"path\", \"pattern\", \"command\"];\n\tfor (const key of keys) {\n\t\tconst value = record[key];\n\t\tif (typeof value !== \"string\" || !value.trim()) continue;\n\t\tconst first = key === \"command\" ? value.split(/\\r?\\n/).find((line) => line.trim()) : value;\n\t\tconst text = (first ?? value).trim().replace(/[ \\t]+/gu, \" \");\n\t\treturn clipText(key === \"path\" ? relativeToCwd(text, cwd) : text, 160);\n\t}\n\treturn compactArguments(args);\n}\n\n/** The stored display target, or one derived from the bounded arguments. */\nexport function targetOf(activity: AgentActivity): string {\n\tif (activity.target) return activity.target;\n\ttry {\n\t\treturn activityTarget(activity.name, JSON.parse(activity.args));\n\t} catch {\n\t\treturn activity.args;\n\t}\n}\n\n/** `Nms` under a second, `N.Ns` under a minute, then the shared `1m 5s` form. */\nexport function formatActivityDuration(ms: number | undefined): string {\n\tif (ms === undefined) return \"\";\n\tconst millis = Math.round(ms);\n\tif (millis < 1000) return `${millis}ms`;\n\tconst tenths = Math.round(ms / 100) / 10;\n\treturn tenths < 60 ? `${tenths.toFixed(1)}s` : formatDuration(ms);\n}\n\nconst TASK_STATUS: Record<AgentActivity[\"status\"], TaskStatus> = {\n\trunning: \"running\",\n\tok: \"completed\",\n\terror: \"failed\",\n\tcancelled: \"cancelled\",\n};\n\n/**\n * A call's glyph and color in the shared task status vocabulary, so a call reads like the task\n * rows around it in /tasks. Pass `now` to animate a running call as a spinner frame.\n */\nexport function activityMarker(status: AgentActivity[\"status\"], now?: number): StatusMarker {\n\treturn statusMarker(TASK_STATUS[status], now === undefined ? undefined : { now });\n}\n\nexport function activityGlyph(status: AgentActivity[\"status\"]): string {\n\treturn activityMarker(status).glyph;\n}\n\n/** Width of the tool-name column for the calls being shown. */\nexport function nameColumnWidth(activities: readonly AgentActivity[]): number {\n\treturn Math.min(NAME_COLUMN_MAX, Math.max(0, ...activities.map((activity) => activity.name.length)));\n}\n\n/** Pads a name only when a target follows it, so a bare name leaves no trailing blanks. */\nexport function paddedName(activity: AgentActivity, width: number): string {\n\treturn targetOf(activity) ? activity.name.padEnd(width) : activity.name;\n}\n\n/** The first non-empty line of a failure, clipped to one display line. */\nexport function errorLine(error: string): string {\n\tconst line = (error.split(/\\r?\\n/u).find((part) => part.trim()) ?? \"\").replace(/\\s+/gu, \" \").trim();\n\tconst chars = Array.from(line);\n\treturn chars.length > ERROR_LINE_CHARS ? `${chars.slice(0, ERROR_LINE_CHARS - 1).join(\"\")}…` : line;\n}\n\n/** `glyph name target · duration`, plus a failure line under the target column. */\nexport function activityText(activity: AgentActivity, nameWidth = nameColumnWidth([activity])): string {\n\tconst target = targetOf(activity);\n\tconst duration = formatActivityDuration(activity.durationMs);\n\tconst line = `${activityGlyph(activity.status)} ${paddedName(activity, nameWidth)}${target ? ` ${target}` : \"\"}${duration ? ` · ${duration}` : \"\"}`;\n\tconst error = activity.error ? errorLine(activity.error) : \"\";\n\treturn error ? `${line}\\n${\" \".repeat(3 + nameWidth)}${error}` : line;\n}\n\n/** The line standing for calls no longer retained. */\nexport function earlierLabel(earlier: number): string {\n\treturn `… ${earlier} earlier tool ${earlier === 1 ? \"call\" : \"calls\"}`;\n}\n\n/** The plain /tasks display: a count of calls no longer retained, then one aligned row per call. */\nexport function activitiesText(activities: readonly AgentActivity[], earlier = 0): string {\n\tconst width = nameColumnWidth(activities);\n\tconst rows = activities.map((activity) => activityText(activity, width));\n\treturn (earlier > 0 ? [earlierLabel(earlier), ...rows] : rows).join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../../src/extensions/agent/activity.ts"],"names":[],"mappings":"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","sourcesContent":["/** Compact, bounded formatting of an Agent's tool-call activity, shared by the Transcript and /tasks. */\nimport { isAbsolute, relative, sep, win32 } from \"node:path\";\nimport { boundText } from \"../../core/tasks/output.ts\";\nimport type { TaskStatus } from \"../../core/tasks/types.ts\";\nimport { type StatusMarker, statusMarker } from \"../../modes/interactive/components/status-marker.ts\";\nimport { formatDuration } from \"../../utils/duration.ts\";\nimport type { AgentActivity } from \"./types.ts\";\n\n/** The tool-name column never grows past this, so one long name cannot push every target away. */\nconst NAME_COLUMN_MAX = 8;\nconst ERROR_LINE_CHARS = 160;\n\nexport function clipText(text: string, bytes: number): string {\n\tif (Buffer.byteLength(text) <= bytes) return text;\n\treturn `${boundText(text, Math.max(1, bytes - 1))}…`;\n}\n\nexport function compactArguments(args: unknown): string {\n\ttry {\n\t\treturn clipText(JSON.stringify(args) ?? String(args), 512).replace(/\\s+/gu, \" \");\n\t} catch {\n\t\treturn \"{…}\";\n\t}\n}\n\n/** A fully qualified absolute path; a rooted path without a drive would resolve against the process drive. */\nfunction isQualifiedAbsolute(path: string): boolean {\n\treturn process.platform === \"win32\" ? /^(?:[A-Za-z]:[\\\\/]|[\\\\/]{2})/u.test(path) : isAbsolute(path);\n}\n\n/**\n * An absolute path inside `cwd` as a forward-slash relative path. Relative paths and paths outside\n * `cwd` are returned unchanged; nothing is ever resolved against the process working directory.\n */\nexport function relativeToCwd(path: string, cwd: string | undefined): string {\n\tif (!cwd || !isQualifiedAbsolute(path) || !isQualifiedAbsolute(cwd)) return path;\n\t// node:path compares case-insensitively on Windows and exactly elsewhere.\n\tconst rel = relative(cwd, path);\n\tif (rel === \"\") return \".\";\n\tif (rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel) || win32.isAbsolute(rel)) return path;\n\treturn rel.split(sep).join(\"/\");\n}\n\n/** A short display target; full arguments remain available in Tasks Output. */\nexport function activityTarget(name: string, args: unknown, cwd?: string): string {\n\tif (!args || typeof args !== \"object\" || Array.isArray(args)) return compactArguments(args);\n\tconst record = args as Record<string, unknown>;\n\tconst keys =\n\t\tname === \"bash\" || name === \"powershell\"\n\t\t\t? [\"command\"]\n\t\t\t: name === \"grep\" || name === \"find\"\n\t\t\t\t? [\"pattern\", \"path\"]\n\t\t\t\t: [\"path\", \"pattern\", \"command\"];\n\tfor (const key of keys) {\n\t\tconst value = record[key];\n\t\tif (typeof value !== \"string\" || !value.trim()) continue;\n\t\tconst first = key === \"command\" ? value.split(/\\r?\\n/).find((line) => line.trim()) : value;\n\t\tconst text = (first ?? value).trim().replace(/[ \\t]+/gu, \" \");\n\t\treturn clipText(key === \"path\" ? relativeToCwd(text, cwd) : text, 160);\n\t}\n\treturn compactArguments(args);\n}\n\n/** The stored display target, or one derived from the bounded arguments. */\nexport function targetOf(activity: AgentActivity): string {\n\tif (activity.target) return activity.target;\n\ttry {\n\t\treturn activityTarget(activity.name, JSON.parse(activity.args));\n\t} catch {\n\t\treturn activity.args;\n\t}\n}\n\n/** `Nms` under a second, `N.Ns` under a minute, then the shared `1m 5s` form. */\nexport function formatActivityDuration(ms: number | undefined): string {\n\tif (ms === undefined) return \"\";\n\tconst millis = Math.round(ms);\n\tif (millis < 1000) return `${millis}ms`;\n\tconst tenths = Math.round(ms / 100) / 10;\n\treturn tenths < 60 ? `${tenths.toFixed(1)}s` : formatDuration(ms);\n}\n\nconst TASK_STATUS: Record<AgentActivity[\"status\"], TaskStatus> = {\n\trunning: \"running\",\n\tok: \"completed\",\n\terror: \"failed\",\n\tcancelled: \"cancelled\",\n};\n\n/**\n * A call's glyph and color in the shared task status vocabulary, so a call reads like the task\n * rows around it in /tasks. Pass `now` to animate a running call as a spinner frame.\n */\nexport function activityMarker(status: AgentActivity[\"status\"], now?: number): StatusMarker {\n\treturn statusMarker(TASK_STATUS[status], now === undefined ? undefined : { now });\n}\n\nexport function activityGlyph(status: AgentActivity[\"status\"]): string {\n\treturn activityMarker(status).glyph;\n}\n\n/** Width of the tool-name column for the calls being shown. */\nexport function nameColumnWidth(activities: readonly AgentActivity[]): number {\n\treturn Math.min(NAME_COLUMN_MAX, Math.max(0, ...activities.map((activity) => activity.name.length)));\n}\n\n/** Pads a name only when a target follows it, so a bare name leaves no trailing blanks. */\nexport function paddedName(activity: AgentActivity, width: number): string {\n\treturn targetOf(activity) ? activity.name.padEnd(width) : activity.name;\n}\n\n/** The first non-empty line of a failure, clipped to one display line. */\nexport function errorLine(error: string): string {\n\tconst line = (error.split(/\\r?\\n/u).find((part) => part.trim()) ?? \"\").replace(/\\s+/gu, \" \").trim();\n\tconst chars = Array.from(line);\n\treturn chars.length > ERROR_LINE_CHARS ? `${chars.slice(0, ERROR_LINE_CHARS - 1).join(\"\")}…` : line;\n}\n\n/** `glyph name target · duration`, plus a failure line under the target column. */\nexport function activityText(activity: AgentActivity, nameWidth = nameColumnWidth([activity])): string {\n\tconst target = targetOf(activity);\n\tconst duration = formatActivityDuration(activity.durationMs);\n\tconst line = `${activityGlyph(activity.status)} ${paddedName(activity, nameWidth)}${target ? ` ${target}` : \"\"}${duration ? ` · ${duration}` : \"\"}`;\n\tconst error = activity.error ? errorLine(activity.error) : \"\";\n\treturn error ? `${line}\\n${\" \".repeat(3 + nameWidth)}${error}` : line;\n}\n\n/** The line standing for calls no longer retained. */\nfunction earlierLabel(earlier: number): string {\n\treturn `… ${earlier} earlier tool ${earlier === 1 ? \"call\" : \"calls\"}`;\n}\n\n/** The plain /tasks display: a count of calls no longer retained, then one aligned row per call. */\nexport function activitiesText(activities: readonly AgentActivity[], earlier = 0): string {\n\tconst width = nameColumnWidth(activities);\n\tconst rows = activities.map((activity) => activityText(activity, width));\n\treturn (earlier > 0 ? [earlierLabel(earlier), ...rows] : rows).join(\"\\n\");\n}\n"]}
@@ -1,7 +1,6 @@
1
1
  import type { AgentMessage } from "@earendil-works/pi-agent-core";
2
2
  import type { AgentSessionEvent } from "../../core/agent-session.ts";
3
3
  import type { TaskCompletion, TaskControl, TaskFact, TaskTerminalStatus } from "../../core/tasks/types.ts";
4
- import type { Theme } from "../../modes/interactive/theme/theme.ts";
5
4
  import { type AgentArtifacts } from "./artifacts.ts";
6
5
  import type { FinalReport } from "./report.ts";
7
6
  import { type AgentToolDetails } from "./types.ts";
@@ -32,8 +31,6 @@ export declare class AgentProgress {
32
31
  constructor(control: TaskControl<AgentToolDetails>, cwd?: string);
33
32
  handle(event: AgentSessionEvent): void;
34
33
  publish(): void;
35
- /** The themed live tool-call list for /tasks Output; `undefined` before the first call, so the default view shows. */
36
- present(width: number, theme: Theme): string[] | undefined;
37
34
  /** Classify a finished run from its last assistant message. */
38
35
  outcome(): {
39
36
  status: TaskTerminalStatus;