@phnx-labs/agents-cli 0.1.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 (486) hide show
  1. package/CHANGELOG.md +316 -0
  2. package/LICENSE +21 -0
  3. package/README.md +537 -0
  4. package/dist/commands/__tests__/sessions.test.d.ts +2 -0
  5. package/dist/commands/__tests__/sessions.test.d.ts.map +1 -0
  6. package/dist/commands/__tests__/sessions.test.js +636 -0
  7. package/dist/commands/__tests__/sessions.test.js.map +1 -0
  8. package/dist/commands/cloud.d.ts +3 -0
  9. package/dist/commands/cloud.d.ts.map +1 -0
  10. package/dist/commands/cloud.js +322 -0
  11. package/dist/commands/cloud.js.map +1 -0
  12. package/dist/commands/commands.d.ts +3 -0
  13. package/dist/commands/commands.d.ts.map +1 -0
  14. package/dist/commands/commands.js +628 -0
  15. package/dist/commands/commands.js.map +1 -0
  16. package/dist/commands/daemon.d.ts +3 -0
  17. package/dist/commands/daemon.d.ts.map +1 -0
  18. package/dist/commands/daemon.js +110 -0
  19. package/dist/commands/daemon.js.map +1 -0
  20. package/dist/commands/drive.d.ts +3 -0
  21. package/dist/commands/drive.d.ts.map +1 -0
  22. package/dist/commands/drive.js +166 -0
  23. package/dist/commands/drive.js.map +1 -0
  24. package/dist/commands/exec.d.ts +3 -0
  25. package/dist/commands/exec.d.ts.map +1 -0
  26. package/dist/commands/exec.js +241 -0
  27. package/dist/commands/exec.js.map +1 -0
  28. package/dist/commands/fork.d.ts +3 -0
  29. package/dist/commands/fork.d.ts.map +1 -0
  30. package/dist/commands/fork.js +139 -0
  31. package/dist/commands/fork.js.map +1 -0
  32. package/dist/commands/hooks.d.ts +3 -0
  33. package/dist/commands/hooks.d.ts.map +1 -0
  34. package/dist/commands/hooks.js +689 -0
  35. package/dist/commands/hooks.js.map +1 -0
  36. package/dist/commands/init.d.ts +6 -0
  37. package/dist/commands/init.d.ts.map +1 -0
  38. package/dist/commands/init.js +127 -0
  39. package/dist/commands/init.js.map +1 -0
  40. package/dist/commands/mcp.d.ts +3 -0
  41. package/dist/commands/mcp.d.ts.map +1 -0
  42. package/dist/commands/mcp.js +581 -0
  43. package/dist/commands/mcp.js.map +1 -0
  44. package/dist/commands/models.d.ts +3 -0
  45. package/dist/commands/models.d.ts.map +1 -0
  46. package/dist/commands/models.js +158 -0
  47. package/dist/commands/models.js.map +1 -0
  48. package/dist/commands/packages.d.ts +3 -0
  49. package/dist/commands/packages.d.ts.map +1 -0
  50. package/dist/commands/packages.js +541 -0
  51. package/dist/commands/packages.js.map +1 -0
  52. package/dist/commands/permissions.d.ts +3 -0
  53. package/dist/commands/permissions.d.ts.map +1 -0
  54. package/dist/commands/permissions.js +723 -0
  55. package/dist/commands/permissions.js.map +1 -0
  56. package/dist/commands/plugins.d.ts +3 -0
  57. package/dist/commands/plugins.d.ts.map +1 -0
  58. package/dist/commands/plugins.js +382 -0
  59. package/dist/commands/plugins.js.map +1 -0
  60. package/dist/commands/profiles.d.ts +3 -0
  61. package/dist/commands/profiles.d.ts.map +1 -0
  62. package/dist/commands/profiles.js +242 -0
  63. package/dist/commands/profiles.js.map +1 -0
  64. package/dist/commands/pty.d.ts +20 -0
  65. package/dist/commands/pty.d.ts.map +1 -0
  66. package/dist/commands/pty.js +389 -0
  67. package/dist/commands/pty.js.map +1 -0
  68. package/dist/commands/pull.d.ts +3 -0
  69. package/dist/commands/pull.d.ts.map +1 -0
  70. package/dist/commands/pull.js +448 -0
  71. package/dist/commands/pull.js.map +1 -0
  72. package/dist/commands/push.d.ts +3 -0
  73. package/dist/commands/push.d.ts.map +1 -0
  74. package/dist/commands/push.js +180 -0
  75. package/dist/commands/push.js.map +1 -0
  76. package/dist/commands/refresh-memory.d.ts +9 -0
  77. package/dist/commands/refresh-memory.d.ts.map +1 -0
  78. package/dist/commands/refresh-memory.js +45 -0
  79. package/dist/commands/refresh-memory.js.map +1 -0
  80. package/dist/commands/resource-view.d.ts +31 -0
  81. package/dist/commands/resource-view.d.ts.map +1 -0
  82. package/dist/commands/resource-view.js +183 -0
  83. package/dist/commands/resource-view.js.map +1 -0
  84. package/dist/commands/routines.d.ts +3 -0
  85. package/dist/commands/routines.d.ts.map +1 -0
  86. package/dist/commands/routines.js +579 -0
  87. package/dist/commands/routines.js.map +1 -0
  88. package/dist/commands/rules.d.ts +3 -0
  89. package/dist/commands/rules.d.ts.map +1 -0
  90. package/dist/commands/rules.js +488 -0
  91. package/dist/commands/rules.js.map +1 -0
  92. package/dist/commands/secrets.d.ts +3 -0
  93. package/dist/commands/secrets.d.ts.map +1 -0
  94. package/dist/commands/secrets.js +339 -0
  95. package/dist/commands/secrets.js.map +1 -0
  96. package/dist/commands/sessions-picker.d.ts +16 -0
  97. package/dist/commands/sessions-picker.d.ts.map +1 -0
  98. package/dist/commands/sessions-picker.js +256 -0
  99. package/dist/commands/sessions-picker.js.map +1 -0
  100. package/dist/commands/sessions.d.ts +16 -0
  101. package/dist/commands/sessions.d.ts.map +1 -0
  102. package/dist/commands/sessions.js +1077 -0
  103. package/dist/commands/sessions.js.map +1 -0
  104. package/dist/commands/skills.d.ts +3 -0
  105. package/dist/commands/skills.d.ts.map +1 -0
  106. package/dist/commands/skills.js +716 -0
  107. package/dist/commands/skills.js.map +1 -0
  108. package/dist/commands/status.d.ts +3 -0
  109. package/dist/commands/status.d.ts.map +1 -0
  110. package/dist/commands/status.js +19 -0
  111. package/dist/commands/status.js.map +1 -0
  112. package/dist/commands/subagents.d.ts +3 -0
  113. package/dist/commands/subagents.d.ts.map +1 -0
  114. package/dist/commands/subagents.js +350 -0
  115. package/dist/commands/subagents.js.map +1 -0
  116. package/dist/commands/sync.d.ts +3 -0
  117. package/dist/commands/sync.d.ts.map +1 -0
  118. package/dist/commands/sync.js +62 -0
  119. package/dist/commands/sync.js.map +1 -0
  120. package/dist/commands/teams-picker.d.ts +14 -0
  121. package/dist/commands/teams-picker.d.ts.map +1 -0
  122. package/dist/commands/teams-picker.js +278 -0
  123. package/dist/commands/teams-picker.js.map +1 -0
  124. package/dist/commands/teams.d.ts +3 -0
  125. package/dist/commands/teams.d.ts.map +1 -0
  126. package/dist/commands/teams.js +917 -0
  127. package/dist/commands/teams.js.map +1 -0
  128. package/dist/commands/utils.d.ts +39 -0
  129. package/dist/commands/utils.d.ts.map +1 -0
  130. package/dist/commands/utils.js +100 -0
  131. package/dist/commands/utils.js.map +1 -0
  132. package/dist/commands/versions.d.ts +3 -0
  133. package/dist/commands/versions.d.ts.map +1 -0
  134. package/dist/commands/versions.js +700 -0
  135. package/dist/commands/versions.js.map +1 -0
  136. package/dist/commands/view.d.ts +8 -0
  137. package/dist/commands/view.d.ts.map +1 -0
  138. package/dist/commands/view.js +626 -0
  139. package/dist/commands/view.js.map +1 -0
  140. package/dist/index.d.ts +3 -0
  141. package/dist/index.d.ts.map +1 -0
  142. package/dist/index.js +484 -0
  143. package/dist/index.js.map +1 -0
  144. package/dist/lib/__tests__/bugfixes.test.d.ts +2 -0
  145. package/dist/lib/__tests__/bugfixes.test.d.ts.map +1 -0
  146. package/dist/lib/__tests__/bugfixes.test.js +192 -0
  147. package/dist/lib/__tests__/bugfixes.test.js.map +1 -0
  148. package/dist/lib/__tests__/exec.test.d.ts +2 -0
  149. package/dist/lib/__tests__/exec.test.d.ts.map +1 -0
  150. package/dist/lib/__tests__/exec.test.js +446 -0
  151. package/dist/lib/__tests__/exec.test.js.map +1 -0
  152. package/dist/lib/__tests__/git-sync.test.d.ts +2 -0
  153. package/dist/lib/__tests__/git-sync.test.d.ts.map +1 -0
  154. package/dist/lib/__tests__/git-sync.test.js +138 -0
  155. package/dist/lib/__tests__/git-sync.test.js.map +1 -0
  156. package/dist/lib/__tests__/hooks.test.d.ts +2 -0
  157. package/dist/lib/__tests__/hooks.test.d.ts.map +1 -0
  158. package/dist/lib/__tests__/hooks.test.js +203 -0
  159. package/dist/lib/__tests__/hooks.test.js.map +1 -0
  160. package/dist/lib/__tests__/memory-compile.test.d.ts +2 -0
  161. package/dist/lib/__tests__/memory-compile.test.d.ts.map +1 -0
  162. package/dist/lib/__tests__/memory-compile.test.js +95 -0
  163. package/dist/lib/__tests__/memory-compile.test.js.map +1 -0
  164. package/dist/lib/__tests__/models.test.d.ts +2 -0
  165. package/dist/lib/__tests__/models.test.d.ts.map +1 -0
  166. package/dist/lib/__tests__/models.test.js +239 -0
  167. package/dist/lib/__tests__/models.test.js.map +1 -0
  168. package/dist/lib/__tests__/rotate.test.d.ts +2 -0
  169. package/dist/lib/__tests__/rotate.test.d.ts.map +1 -0
  170. package/dist/lib/__tests__/rotate.test.js +80 -0
  171. package/dist/lib/__tests__/rotate.test.js.map +1 -0
  172. package/dist/lib/__tests__/secrets-bundles.test.d.ts +2 -0
  173. package/dist/lib/__tests__/secrets-bundles.test.d.ts.map +1 -0
  174. package/dist/lib/__tests__/secrets-bundles.test.js +104 -0
  175. package/dist/lib/__tests__/secrets-bundles.test.js.map +1 -0
  176. package/dist/lib/__tests__/secrets.test.d.ts +2 -0
  177. package/dist/lib/__tests__/secrets.test.d.ts.map +1 -0
  178. package/dist/lib/__tests__/secrets.test.js +90 -0
  179. package/dist/lib/__tests__/secrets.test.js.map +1 -0
  180. package/dist/lib/__tests__/shims.test.d.ts +2 -0
  181. package/dist/lib/__tests__/shims.test.d.ts.map +1 -0
  182. package/dist/lib/__tests__/shims.test.js +39 -0
  183. package/dist/lib/__tests__/shims.test.js.map +1 -0
  184. package/dist/lib/__tests__/usage.test.d.ts +2 -0
  185. package/dist/lib/__tests__/usage.test.d.ts.map +1 -0
  186. package/dist/lib/__tests__/usage.test.js +220 -0
  187. package/dist/lib/__tests__/usage.test.js.map +1 -0
  188. package/dist/lib/__tests__/versions.test.d.ts +2 -0
  189. package/dist/lib/__tests__/versions.test.d.ts.map +1 -0
  190. package/dist/lib/__tests__/versions.test.js +63 -0
  191. package/dist/lib/__tests__/versions.test.js.map +1 -0
  192. package/dist/lib/agents.d.ts +107 -0
  193. package/dist/lib/agents.d.ts.map +1 -0
  194. package/dist/lib/agents.js +1096 -0
  195. package/dist/lib/agents.js.map +1 -0
  196. package/dist/lib/artifact-actions.d.ts +22 -0
  197. package/dist/lib/artifact-actions.d.ts.map +1 -0
  198. package/dist/lib/artifact-actions.js +55 -0
  199. package/dist/lib/artifact-actions.js.map +1 -0
  200. package/dist/lib/cloud/codex.d.ts +19 -0
  201. package/dist/lib/cloud/codex.d.ts.map +1 -0
  202. package/dist/lib/cloud/codex.js +210 -0
  203. package/dist/lib/cloud/codex.js.map +1 -0
  204. package/dist/lib/cloud/factory.d.ts +26 -0
  205. package/dist/lib/cloud/factory.d.ts.map +1 -0
  206. package/dist/lib/cloud/factory.js +37 -0
  207. package/dist/lib/cloud/factory.js.map +1 -0
  208. package/dist/lib/cloud/registry.d.ts +6 -0
  209. package/dist/lib/cloud/registry.d.ts.map +1 -0
  210. package/dist/lib/cloud/registry.js +56 -0
  211. package/dist/lib/cloud/registry.js.map +1 -0
  212. package/dist/lib/cloud/rush.d.ts +15 -0
  213. package/dist/lib/cloud/rush.d.ts.map +1 -0
  214. package/dist/lib/cloud/rush.js +185 -0
  215. package/dist/lib/cloud/rush.js.map +1 -0
  216. package/dist/lib/cloud/store.d.ts +10 -0
  217. package/dist/lib/cloud/store.d.ts.map +1 -0
  218. package/dist/lib/cloud/store.js +96 -0
  219. package/dist/lib/cloud/store.js.map +1 -0
  220. package/dist/lib/cloud/stream.d.ts +18 -0
  221. package/dist/lib/cloud/stream.d.ts.map +1 -0
  222. package/dist/lib/cloud/stream.js +138 -0
  223. package/dist/lib/cloud/stream.js.map +1 -0
  224. package/dist/lib/cloud/types.d.ts +60 -0
  225. package/dist/lib/cloud/types.d.ts.map +1 -0
  226. package/dist/lib/cloud/types.js +2 -0
  227. package/dist/lib/cloud/types.js.map +1 -0
  228. package/dist/lib/commands.d.ts +121 -0
  229. package/dist/lib/commands.d.ts.map +1 -0
  230. package/dist/lib/commands.js +499 -0
  231. package/dist/lib/commands.js.map +1 -0
  232. package/dist/lib/convert.d.ts +11 -0
  233. package/dist/lib/convert.d.ts.map +1 -0
  234. package/dist/lib/convert.js +45 -0
  235. package/dist/lib/convert.js.map +1 -0
  236. package/dist/lib/daemon.d.ts +22 -0
  237. package/dist/lib/daemon.d.ts.map +1 -0
  238. package/dist/lib/daemon.js +311 -0
  239. package/dist/lib/daemon.js.map +1 -0
  240. package/dist/lib/drive-sync.d.ts +28 -0
  241. package/dist/lib/drive-sync.d.ts.map +1 -0
  242. package/dist/lib/drive-sync.js +193 -0
  243. package/dist/lib/drive-sync.js.map +1 -0
  244. package/dist/lib/exec.d.ts +85 -0
  245. package/dist/lib/exec.d.ts.map +1 -0
  246. package/dist/lib/exec.js +423 -0
  247. package/dist/lib/exec.js.map +1 -0
  248. package/dist/lib/factory.d.ts +57 -0
  249. package/dist/lib/factory.d.ts.map +1 -0
  250. package/dist/lib/factory.js +110 -0
  251. package/dist/lib/factory.js.map +1 -0
  252. package/dist/lib/git.d.ts +146 -0
  253. package/dist/lib/git.d.ts.map +1 -0
  254. package/dist/lib/git.js +635 -0
  255. package/dist/lib/git.js.map +1 -0
  256. package/dist/lib/help.d.ts +3 -0
  257. package/dist/lib/help.d.ts.map +1 -0
  258. package/dist/lib/help.js +63 -0
  259. package/dist/lib/help.js.map +1 -0
  260. package/dist/lib/hooks.d.ts +116 -0
  261. package/dist/lib/hooks.d.ts.map +1 -0
  262. package/dist/lib/hooks.js +837 -0
  263. package/dist/lib/hooks.js.map +1 -0
  264. package/dist/lib/manifest.d.ts +8 -0
  265. package/dist/lib/manifest.d.ts.map +1 -0
  266. package/dist/lib/manifest.js +36 -0
  267. package/dist/lib/manifest.js.map +1 -0
  268. package/dist/lib/markdown.d.ts +5 -0
  269. package/dist/lib/markdown.d.ts.map +1 -0
  270. package/dist/lib/markdown.js +11 -0
  271. package/dist/lib/markdown.js.map +1 -0
  272. package/dist/lib/mcp.d.ts +64 -0
  273. package/dist/lib/mcp.d.ts.map +1 -0
  274. package/dist/lib/mcp.js +327 -0
  275. package/dist/lib/mcp.js.map +1 -0
  276. package/dist/lib/memory-compile.d.ts +56 -0
  277. package/dist/lib/memory-compile.d.ts.map +1 -0
  278. package/dist/lib/memory-compile.js +167 -0
  279. package/dist/lib/memory-compile.js.map +1 -0
  280. package/dist/lib/memory.d.ts +56 -0
  281. package/dist/lib/memory.d.ts.map +1 -0
  282. package/dist/lib/memory.js +267 -0
  283. package/dist/lib/memory.js.map +1 -0
  284. package/dist/lib/models.d.ts +91 -0
  285. package/dist/lib/models.d.ts.map +1 -0
  286. package/dist/lib/models.js +706 -0
  287. package/dist/lib/models.js.map +1 -0
  288. package/dist/lib/permissions.d.ts +204 -0
  289. package/dist/lib/permissions.d.ts.map +1 -0
  290. package/dist/lib/permissions.js +1022 -0
  291. package/dist/lib/permissions.js.map +1 -0
  292. package/dist/lib/picker.d.ts +17 -0
  293. package/dist/lib/picker.d.ts.map +1 -0
  294. package/dist/lib/picker.js +95 -0
  295. package/dist/lib/picker.js.map +1 -0
  296. package/dist/lib/plugins.d.ts +73 -0
  297. package/dist/lib/plugins.d.ts.map +1 -0
  298. package/dist/lib/plugins.js +549 -0
  299. package/dist/lib/plugins.js.map +1 -0
  300. package/dist/lib/profiles-keychain.d.ts +3 -0
  301. package/dist/lib/profiles-keychain.d.ts.map +1 -0
  302. package/dist/lib/profiles-keychain.js +10 -0
  303. package/dist/lib/profiles-keychain.js.map +1 -0
  304. package/dist/lib/profiles-presets.d.ts +15 -0
  305. package/dist/lib/profiles-presets.d.ts.map +1 -0
  306. package/dist/lib/profiles-presets.js +95 -0
  307. package/dist/lib/profiles-presets.js.map +1 -0
  308. package/dist/lib/profiles.d.ts +35 -0
  309. package/dist/lib/profiles.d.ts.map +1 -0
  310. package/dist/lib/profiles.js +123 -0
  311. package/dist/lib/profiles.js.map +1 -0
  312. package/dist/lib/pty-client.d.ts +22 -0
  313. package/dist/lib/pty-client.d.ts.map +1 -0
  314. package/dist/lib/pty-client.js +181 -0
  315. package/dist/lib/pty-client.js.map +1 -0
  316. package/dist/lib/pty-server.d.ts +16 -0
  317. package/dist/lib/pty-server.d.ts.map +1 -0
  318. package/dist/lib/pty-server.js +422 -0
  319. package/dist/lib/pty-server.js.map +1 -0
  320. package/dist/lib/registry.d.ts +28 -0
  321. package/dist/lib/registry.d.ts.map +1 -0
  322. package/dist/lib/registry.js +203 -0
  323. package/dist/lib/registry.js.map +1 -0
  324. package/dist/lib/resources.d.ts +50 -0
  325. package/dist/lib/resources.d.ts.map +1 -0
  326. package/dist/lib/resources.js +103 -0
  327. package/dist/lib/resources.js.map +1 -0
  328. package/dist/lib/rotate.d.ts +52 -0
  329. package/dist/lib/rotate.d.ts.map +1 -0
  330. package/dist/lib/rotate.js +87 -0
  331. package/dist/lib/rotate.js.map +1 -0
  332. package/dist/lib/routines.d.ts +70 -0
  333. package/dist/lib/routines.d.ts.map +1 -0
  334. package/dist/lib/routines.js +325 -0
  335. package/dist/lib/routines.js.map +1 -0
  336. package/dist/lib/runner.d.ts +12 -0
  337. package/dist/lib/runner.d.ts.map +1 -0
  338. package/dist/lib/runner.js +311 -0
  339. package/dist/lib/runner.js.map +1 -0
  340. package/dist/lib/sandbox.d.ts +10 -0
  341. package/dist/lib/sandbox.d.ts.map +1 -0
  342. package/dist/lib/sandbox.js +201 -0
  343. package/dist/lib/sandbox.js.map +1 -0
  344. package/dist/lib/scheduler.d.ts +18 -0
  345. package/dist/lib/scheduler.d.ts.map +1 -0
  346. package/dist/lib/scheduler.js +69 -0
  347. package/dist/lib/scheduler.js.map +1 -0
  348. package/dist/lib/secrets-bundles.d.ts +29 -0
  349. package/dist/lib/secrets-bundles.d.ts.map +1 -0
  350. package/dist/lib/secrets-bundles.js +168 -0
  351. package/dist/lib/secrets-bundles.js.map +1 -0
  352. package/dist/lib/secrets.d.ts +27 -0
  353. package/dist/lib/secrets.d.ts.map +1 -0
  354. package/dist/lib/secrets.js +127 -0
  355. package/dist/lib/secrets.js.map +1 -0
  356. package/dist/lib/session/__tests__/db.test.d.ts +2 -0
  357. package/dist/lib/session/__tests__/db.test.d.ts.map +1 -0
  358. package/dist/lib/session/__tests__/db.test.js +54 -0
  359. package/dist/lib/session/__tests__/db.test.js.map +1 -0
  360. package/dist/lib/session/__tests__/discover.test.d.ts +2 -0
  361. package/dist/lib/session/__tests__/discover.test.d.ts.map +1 -0
  362. package/dist/lib/session/__tests__/discover.test.js +63 -0
  363. package/dist/lib/session/__tests__/discover.test.js.map +1 -0
  364. package/dist/lib/session/__tests__/prompt.test.d.ts +2 -0
  365. package/dist/lib/session/__tests__/prompt.test.d.ts.map +1 -0
  366. package/dist/lib/session/__tests__/prompt.test.js +44 -0
  367. package/dist/lib/session/__tests__/prompt.test.js.map +1 -0
  368. package/dist/lib/session/__tests__/render.test.d.ts +2 -0
  369. package/dist/lib/session/__tests__/render.test.d.ts.map +1 -0
  370. package/dist/lib/session/__tests__/render.test.js +602 -0
  371. package/dist/lib/session/__tests__/render.test.js.map +1 -0
  372. package/dist/lib/session/artifacts.d.ts +5 -0
  373. package/dist/lib/session/artifacts.d.ts.map +1 -0
  374. package/dist/lib/session/artifacts.js +75 -0
  375. package/dist/lib/session/artifacts.js.map +1 -0
  376. package/dist/lib/session/db.d.ts +118 -0
  377. package/dist/lib/session/db.d.ts.map +1 -0
  378. package/dist/lib/session/db.js +576 -0
  379. package/dist/lib/session/db.js.map +1 -0
  380. package/dist/lib/session/discover.d.ts +60 -0
  381. package/dist/lib/session/discover.d.ts.map +1 -0
  382. package/dist/lib/session/discover.js +1272 -0
  383. package/dist/lib/session/discover.js.map +1 -0
  384. package/dist/lib/session/parse.d.ts +23 -0
  385. package/dist/lib/session/parse.d.ts.map +1 -0
  386. package/dist/lib/session/parse.js +650 -0
  387. package/dist/lib/session/parse.js.map +1 -0
  388. package/dist/lib/session/prompt.d.ts +4 -0
  389. package/dist/lib/session/prompt.d.ts.map +1 -0
  390. package/dist/lib/session/prompt.js +64 -0
  391. package/dist/lib/session/prompt.js.map +1 -0
  392. package/dist/lib/session/prompt.test.d.ts +2 -0
  393. package/dist/lib/session/prompt.test.d.ts.map +1 -0
  394. package/dist/lib/session/prompt.test.js +57 -0
  395. package/dist/lib/session/prompt.test.js.map +1 -0
  396. package/dist/lib/session/render.d.ts +90 -0
  397. package/dist/lib/session/render.d.ts.map +1 -0
  398. package/dist/lib/session/render.js +778 -0
  399. package/dist/lib/session/render.js.map +1 -0
  400. package/dist/lib/session/team-filter.d.ts +26 -0
  401. package/dist/lib/session/team-filter.d.ts.map +1 -0
  402. package/dist/lib/session/team-filter.js +66 -0
  403. package/dist/lib/session/team-filter.js.map +1 -0
  404. package/dist/lib/session/team-filter.test.d.ts +2 -0
  405. package/dist/lib/session/team-filter.test.d.ts.map +1 -0
  406. package/dist/lib/session/team-filter.test.js +157 -0
  407. package/dist/lib/session/team-filter.test.js.map +1 -0
  408. package/dist/lib/session/types.d.ts +69 -0
  409. package/dist/lib/session/types.d.ts.map +1 -0
  410. package/dist/lib/session/types.js +2 -0
  411. package/dist/lib/session/types.js.map +1 -0
  412. package/dist/lib/shims.d.ts +228 -0
  413. package/dist/lib/shims.d.ts.map +1 -0
  414. package/dist/lib/shims.js +1170 -0
  415. package/dist/lib/shims.js.map +1 -0
  416. package/dist/lib/skills.d.ts +134 -0
  417. package/dist/lib/skills.d.ts.map +1 -0
  418. package/dist/lib/skills.js +783 -0
  419. package/dist/lib/skills.js.map +1 -0
  420. package/dist/lib/state.d.ts +53 -0
  421. package/dist/lib/state.d.ts.map +1 -0
  422. package/dist/lib/state.js +299 -0
  423. package/dist/lib/state.js.map +1 -0
  424. package/dist/lib/subagents.d.ts +75 -0
  425. package/dist/lib/subagents.d.ts.map +1 -0
  426. package/dist/lib/subagents.js +402 -0
  427. package/dist/lib/subagents.js.map +1 -0
  428. package/dist/lib/teams/agents.d.ts +146 -0
  429. package/dist/lib/teams/agents.d.ts.map +1 -0
  430. package/dist/lib/teams/agents.js +1072 -0
  431. package/dist/lib/teams/agents.js.map +1 -0
  432. package/dist/lib/teams/api.d.ts +77 -0
  433. package/dist/lib/teams/api.d.ts.map +1 -0
  434. package/dist/lib/teams/api.js +229 -0
  435. package/dist/lib/teams/api.js.map +1 -0
  436. package/dist/lib/teams/cloud.d.ts +11 -0
  437. package/dist/lib/teams/cloud.d.ts.map +1 -0
  438. package/dist/lib/teams/cloud.js +169 -0
  439. package/dist/lib/teams/cloud.js.map +1 -0
  440. package/dist/lib/teams/debug.d.ts +2 -0
  441. package/dist/lib/teams/debug.d.ts.map +1 -0
  442. package/dist/lib/teams/debug.js +6 -0
  443. package/dist/lib/teams/debug.js.map +1 -0
  444. package/dist/lib/teams/file_ops.d.ts +6 -0
  445. package/dist/lib/teams/file_ops.d.ts.map +1 -0
  446. package/dist/lib/teams/file_ops.js +59 -0
  447. package/dist/lib/teams/file_ops.js.map +1 -0
  448. package/dist/lib/teams/parsers.d.ts +5 -0
  449. package/dist/lib/teams/parsers.d.ts.map +1 -0
  450. package/dist/lib/teams/parsers.js +826 -0
  451. package/dist/lib/teams/parsers.js.map +1 -0
  452. package/dist/lib/teams/persistence.d.ts +28 -0
  453. package/dist/lib/teams/persistence.d.ts.map +1 -0
  454. package/dist/lib/teams/persistence.js +289 -0
  455. package/dist/lib/teams/persistence.js.map +1 -0
  456. package/dist/lib/teams/ralph.d.ts +8 -0
  457. package/dist/lib/teams/ralph.d.ts.map +1 -0
  458. package/dist/lib/teams/ralph.js +59 -0
  459. package/dist/lib/teams/ralph.js.map +1 -0
  460. package/dist/lib/teams/registry.d.ts +11 -0
  461. package/dist/lib/teams/registry.d.ts.map +1 -0
  462. package/dist/lib/teams/registry.js +56 -0
  463. package/dist/lib/teams/registry.js.map +1 -0
  464. package/dist/lib/teams/summarizer.d.ts +58 -0
  465. package/dist/lib/teams/summarizer.d.ts.map +1 -0
  466. package/dist/lib/teams/summarizer.js +766 -0
  467. package/dist/lib/teams/summarizer.js.map +1 -0
  468. package/dist/lib/template.d.ts +24 -0
  469. package/dist/lib/template.d.ts.map +1 -0
  470. package/dist/lib/template.js +57 -0
  471. package/dist/lib/template.js.map +1 -0
  472. package/dist/lib/types.d.ts +282 -0
  473. package/dist/lib/types.d.ts.map +1 -0
  474. package/dist/lib/types.js +18 -0
  475. package/dist/lib/types.js.map +1 -0
  476. package/dist/lib/usage.d.ts +73 -0
  477. package/dist/lib/usage.d.ts.map +1 -0
  478. package/dist/lib/usage.js +623 -0
  479. package/dist/lib/usage.js.map +1 -0
  480. package/dist/lib/versions.d.ts +248 -0
  481. package/dist/lib/versions.d.ts.map +1 -0
  482. package/dist/lib/versions.js +1737 -0
  483. package/dist/lib/versions.js.map +1 -0
  484. package/package.json +82 -0
  485. package/scripts/postinstall.js +72 -0
  486. package/scripts/rebuild-sqlite.sh +46 -0
@@ -0,0 +1,778 @@
1
+ import chalk from 'chalk';
2
+ import { summarizeToolUse } from './parse.js';
3
+ import { cleanSessionPrompt, extractSessionTopic } from './prompt.js';
4
+ import { renderMarkdown } from '../markdown.js';
5
+ // ── Path helpers ──────────────────────────────────────────────────────────────
6
+ /**
7
+ * Return absPath relative to cwd; fall back to ~/… then absolute.
8
+ */
9
+ export function relativeToCwd(absPath, cwd) {
10
+ if (cwd && (absPath === cwd || absPath.startsWith(cwd + '/'))) {
11
+ const rel = absPath.slice(cwd.length + 1);
12
+ return rel || '.';
13
+ }
14
+ const home = process.env.HOME || '';
15
+ if (home && (absPath === home || absPath.startsWith(home + '/'))) {
16
+ return '~' + absPath.slice(home.length);
17
+ }
18
+ return absPath;
19
+ }
20
+ /**
21
+ * Wrap label in an OSC 8 hyperlink when the terminal supports it.
22
+ * Degrades to plain label otherwise.
23
+ */
24
+ export function linkPath(absPath, label) {
25
+ if (process.stdout.isTTY &&
26
+ (process.env.TERM_PROGRAM ||
27
+ process.env.WT_SESSION ||
28
+ process.env.KITTY_WINDOW_ID ||
29
+ process.env.WEZTERM_PANE)) {
30
+ return `\x1b]8;;file://${absPath}\x1b\\${label}\x1b]8;;\x1b\\`;
31
+ }
32
+ return label;
33
+ }
34
+ // ── Command grouping ──────────────────────────────────────────────────────────
35
+ /**
36
+ * Unwrap wrapper prefixes to find the actual executable.
37
+ */
38
+ export function unwrapCommand(cmd) {
39
+ const ssh = cmd.match(/^ssh\s+\S+\s+"(.+)"\s*(?:\|.*)?$/);
40
+ if (ssh)
41
+ return unwrapCommand(ssh[1]);
42
+ const lead = cmd.match(/^(?:sudo|env\s+\S+=\S+|time)\s+(.+)/);
43
+ if (lead)
44
+ return unwrapCommand(lead[1]);
45
+ // Strip shell-style leading env assignments: `PATH=/x CMD ...`, `FOO=bar BAR=baz CMD ...`
46
+ const shellEnv = cmd.match(/^(?:[A-Z_][A-Z0-9_]*=\S+\s+)+(\S.*)$/);
47
+ if (shellEnv)
48
+ return unwrapCommand(shellEnv[1]);
49
+ const cd = cmd.match(/^cd\s+\S+\s*&&\s*(.+)/);
50
+ if (cd)
51
+ return unwrapCommand(cd[1]);
52
+ const npx = cmd.match(/^npx\s+(.+)/);
53
+ if (npx)
54
+ return unwrapCommand(npx[1]);
55
+ return cmd;
56
+ }
57
+ /**
58
+ * Normalize a command so trivial flag/pipe variations collapse to the same key.
59
+ */
60
+ export function normalizeForDedup(cmd) {
61
+ let s = cmd.trim();
62
+ s = s.replace(/\s+-[a-zA-Z]+/g, '');
63
+ s = s.replace(/\s+--[a-zA-Z][-a-zA-Z0-9]*(?:=\S+)?/g, '');
64
+ s = s.replace(/\s*\|\s*(head|tail|wc|less|more|cat)(\s+\S+)?.*$/, '');
65
+ s = s.replace(/\s*2>&1\s*$/, '');
66
+ s = s.replace(/\s*;\s*echo\b.*$/, '');
67
+ const home = process.env.HOME ?? '';
68
+ if (home) {
69
+ s = s.replace(new RegExp('^' + home.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')), '~');
70
+ }
71
+ return s.trim();
72
+ }
73
+ const CATEGORIES = [
74
+ { name: 'Probes', match: t => ['ls', 'cat', 'head', 'tail', 'wc', 'stat', 'file', 'which', 'tree', 'pwd'].includes(t), signal: 'low' },
75
+ { name: 'Search', match: t => ['grep', 'rg', 'ag', 'fd', 'find'].includes(t), signal: 'low' },
76
+ { name: 'Build/test', match: t => ['make', 'cargo', 'pytest', 'go', 'bun', 'npm', 'pnpm', 'yarn', 'tsc', 'vitest', 'tsx', 'node', 'python', 'python3', 'jest'].includes(t), signal: 'high' },
77
+ { name: 'Install', match: t => ['brew', 'pip', 'apt', 'apk'].includes(t), signal: 'high' },
78
+ { name: 'VCS', match: t => ['git', 'gh'].includes(t), signal: 'mid' },
79
+ { name: 'HTTP', match: t => ['curl', 'wget', 'rush', 'http'].includes(t), signal: 'mid' },
80
+ { name: 'Remote', match: t => ['ssh', 'scp', 'rsync'].includes(t), signal: 'mid' },
81
+ { name: 'Shell', match: t => ['rm', 'mv', 'cp', 'mkdir', 'touch', 'echo', 'printf', 'chmod', 'ln', 'awk', 'sed', 'tee', 'xargs', 'for'].includes(t), signal: 'low' },
82
+ { name: 'Wait', match: t => ['sleep', 'wait'].includes(t), signal: 'low' },
83
+ ];
84
+ const TWO_LEVEL_TOKENS = new Set([
85
+ 'git', 'gh', 'bun', 'npm', 'cargo', 'docker', 'kubectl', 'rush', 'openclaw', 'pnpm', 'yarn',
86
+ ]);
87
+ /**
88
+ * Return the bucket key for a command (used for grouping within a category).
89
+ */
90
+ export function bucketKey(cmd) {
91
+ const unwrapped = unwrapCommand(cmd);
92
+ const tokens = unwrapped.trim().split(/\s+/);
93
+ const first = tokens[0] ?? 'other';
94
+ const isRemote = cmd.trim().startsWith('ssh ') || cmd.trim().startsWith('scp ');
95
+ if (TWO_LEVEL_TOKENS.has(first) && tokens[1]) {
96
+ const key = `${first} ${tokens[1]}`;
97
+ return isRemote ? `ssh\u2192${key}` : key;
98
+ }
99
+ return isRemote ? `ssh\u2192${first}` : first;
100
+ }
101
+ function categoryOf(cmd) {
102
+ const rawFirst = cmd.trim().split(/\s+/)[0]?.toLowerCase() ?? '';
103
+ // Remote wrappers: classify as Remote regardless of inner command.
104
+ if (['ssh', 'scp', 'rsync'].includes(rawFirst)) {
105
+ return CATEGORIES.find(c => c.name === 'Remote') ?? null;
106
+ }
107
+ const unwrapped = unwrapCommand(cmd);
108
+ const first = unwrapped.trim().split(/\s+/)[0]?.toLowerCase() ?? '';
109
+ return CATEGORIES.find(c => c.match(first)) ?? null;
110
+ }
111
+ /**
112
+ * Collapse consecutive same-normalized commands within a 60-second window
113
+ * when they appear 3+ times. Fewer than 3 stay as separate entries.
114
+ */
115
+ export function collapseRetries(commands) {
116
+ const groups = [];
117
+ for (const { cmd, ts } of commands) {
118
+ const normalized = normalizeForDedup(unwrapCommand(cmd));
119
+ const last = groups[groups.length - 1];
120
+ if (last && last.normalized === normalized && ts - last.lastTs <= 60_000) {
121
+ last.count++;
122
+ last.lastTs = ts;
123
+ }
124
+ else {
125
+ groups.push({ normalized, raw: cmd, firstTs: ts, lastTs: ts, count: 1 });
126
+ }
127
+ }
128
+ // Expand groups with count < 3 back to individual entries
129
+ const result = [];
130
+ for (const g of groups) {
131
+ if (g.count >= 3) {
132
+ result.push(g);
133
+ }
134
+ else {
135
+ for (let i = 0; i < g.count; i++) {
136
+ result.push({ normalized: g.normalized, raw: g.raw, firstTs: g.firstTs, lastTs: g.lastTs, count: 1 });
137
+ }
138
+ }
139
+ }
140
+ return result;
141
+ }
142
+ export function computeSummaryStats(events) {
143
+ const modelSet = new Set();
144
+ let userTurns = 0;
145
+ let assistantTurns = 0;
146
+ let toolCount = 0;
147
+ let errorCount = 0;
148
+ let outputTokens = 0;
149
+ let cacheReadTokens = 0;
150
+ let firstTs = Infinity;
151
+ let lastTs = -Infinity;
152
+ for (const e of events) {
153
+ const ts = new Date(e.timestamp).getTime();
154
+ if (!isNaN(ts)) {
155
+ if (ts < firstTs)
156
+ firstTs = ts;
157
+ if (ts > lastTs)
158
+ lastTs = ts;
159
+ }
160
+ if (e.type === 'message') {
161
+ if (e.role === 'user')
162
+ userTurns++;
163
+ else if (e.role === 'assistant')
164
+ assistantTurns++;
165
+ }
166
+ else if (e.type === 'tool_use' && !e._local) {
167
+ toolCount++;
168
+ }
169
+ else if (e.type === 'error') {
170
+ errorCount++;
171
+ }
172
+ else if (e.type === 'usage') {
173
+ if (e.model)
174
+ modelSet.add(shortenModel(e.model));
175
+ outputTokens += e.outputTokens ?? 0;
176
+ cacheReadTokens += e.cacheReadTokens ?? 0;
177
+ }
178
+ }
179
+ return {
180
+ models: Array.from(modelSet),
181
+ userTurns,
182
+ assistantTurns,
183
+ toolCount,
184
+ errorCount,
185
+ outputTokens,
186
+ cacheReadTokens,
187
+ firstTs: firstTs === Infinity ? 0 : firstTs,
188
+ lastTs: lastTs === -Infinity ? 0 : lastTs,
189
+ };
190
+ }
191
+ function shortenModel(model) {
192
+ return model.replace(/^claude-/, '').replace(/-\d{8}$/, '');
193
+ }
194
+ function formatTokenCount(n) {
195
+ if (n === 0)
196
+ return '0';
197
+ if (n < 1000)
198
+ return String(n);
199
+ if (n < 1_000_000) {
200
+ const k = n / 1000;
201
+ return (k >= 100 ? Math.round(k) : parseFloat(k.toFixed(1))) + 'K';
202
+ }
203
+ const m = n / 1_000_000;
204
+ return (m >= 100 ? Math.round(m) : parseFloat(m.toFixed(1))) + 'M';
205
+ }
206
+ function formatDuration(ms) {
207
+ const totalMin = Math.round(ms / 60_000);
208
+ if (totalMin < 1)
209
+ return 'under 1 min';
210
+ if (totalMin < 60)
211
+ return `${totalMin} min`;
212
+ const hrs = Math.floor(totalMin / 60);
213
+ const mins = totalMin % 60;
214
+ return mins > 0 ? `${hrs}h ${mins}min` : `${hrs}h`;
215
+ }
216
+ /**
217
+ * Return the stats line for a session summary header.
218
+ * e.g. "221 turns · 198 tools (10 errors) · 67.5M cached / 361K out · 12 min"
219
+ */
220
+ export function renderSummaryHeader(stats) {
221
+ const turns = stats.userTurns + stats.assistantTurns;
222
+ const parts = [];
223
+ parts.push(`${turns} turn${turns !== 1 ? 's' : ''}`);
224
+ if (stats.toolCount > 0) {
225
+ const toolPart = stats.errorCount > 0
226
+ ? `${stats.toolCount} tools (${stats.errorCount} error${stats.errorCount !== 1 ? 's' : ''})`
227
+ : `${stats.toolCount} tools`;
228
+ parts.push(toolPart);
229
+ }
230
+ if (stats.cacheReadTokens > 0 || stats.outputTokens > 0) {
231
+ const tokenPart = stats.cacheReadTokens > 0
232
+ ? `${formatTokenCount(stats.cacheReadTokens)} cached / ${formatTokenCount(stats.outputTokens)} out`
233
+ : `${formatTokenCount(stats.outputTokens)} out`;
234
+ parts.push(tokenPart);
235
+ }
236
+ if (stats.lastTs > stats.firstTs) {
237
+ parts.push(formatDuration(stats.lastTs - stats.firstTs));
238
+ }
239
+ return parts.join(' · ');
240
+ }
241
+ // ── Prompt reference extraction ───────────────────────────────────────────────
242
+ function extractReferences(text) {
243
+ const refs = new Set();
244
+ for (const m of text.matchAll(/@[\w/.-]+/g))
245
+ refs.add(m[0]);
246
+ for (const m of text.matchAll(/(?:^|\s)(\/[\w/.-]{3,})/gm))
247
+ refs.add(m[1]);
248
+ for (const m of text.matchAll(/~\/[\w/.-]+/g))
249
+ refs.add(m[0]);
250
+ return Array.from(refs);
251
+ }
252
+ function renderCommandsSection(cmds, lines) {
253
+ if (cmds.length === 0)
254
+ return;
255
+ const runs = collapseRetries(cmds);
256
+ // Group runs by category → key → {count, samples}
257
+ const catMap = new Map();
258
+ let otherCount = 0;
259
+ const otherKeys = new Map();
260
+ for (const run of runs) {
261
+ const cat = categoryOf(run.raw);
262
+ const key = bucketKey(run.raw);
263
+ if (cat) {
264
+ let catEntry = catMap.get(cat.name);
265
+ if (!catEntry) {
266
+ catEntry = { signal: cat.signal, keys: new Map() };
267
+ catMap.set(cat.name, catEntry);
268
+ }
269
+ const existing = catEntry.keys.get(key) ?? { count: 0, samples: [] };
270
+ existing.count += run.count;
271
+ if (existing.samples.length < 5 && !existing.samples.some(s => sharesPrefix(s, run.raw, 30))) {
272
+ existing.samples.push(run.raw);
273
+ }
274
+ catEntry.keys.set(key, existing);
275
+ }
276
+ else {
277
+ otherCount += run.count;
278
+ const existing = otherKeys.get(key) ?? { count: 0, samples: [] };
279
+ existing.count += run.count;
280
+ if (existing.samples.length < 3)
281
+ existing.samples.push(run.raw);
282
+ otherKeys.set(key, existing);
283
+ }
284
+ }
285
+ // Total command count (sum of all run counts)
286
+ const total = runs.reduce((sum, r) => sum + r.count, 0);
287
+ lines.push(chalk.bold('Commands') + chalk.gray(` (${total})`));
288
+ // Sort categories: high-signal first, then mid, then low, by total count desc. Other last.
289
+ const SIGNAL_ORDER = { high: 0, mid: 1, low: 2 };
290
+ const sortedCats = Array.from(catMap.entries()).sort((a, b) => {
291
+ const sigA = SIGNAL_ORDER[a[1].signal] ?? 3;
292
+ const sigB = SIGNAL_ORDER[b[1].signal] ?? 3;
293
+ if (sigA !== sigB)
294
+ return sigA - sigB;
295
+ const countA = Array.from(a[1].keys.values()).reduce((s, v) => s + v.count, 0);
296
+ const countB = Array.from(b[1].keys.values()).reduce((s, v) => s + v.count, 0);
297
+ return countB - countA;
298
+ });
299
+ for (const [catName, catEntry] of sortedCats) {
300
+ const catTotal = Array.from(catEntry.keys.values()).reduce((s, v) => s + v.count, 0);
301
+ if (catEntry.signal === 'low') {
302
+ // Single inline line: category name + top 5 first tokens
303
+ const topTokens = Array.from(catEntry.keys.keys()).slice(0, 5).join(', ');
304
+ lines.push(` ${chalk.dim(catName)} ${chalk.gray(`(${catTotal})`)} ${chalk.gray('— ' + topTokens)}`);
305
+ }
306
+ else {
307
+ lines.push(` ${chalk.dim(catName)} ${chalk.gray(`(${catTotal})`)}`);
308
+ const keysSorted = Array.from(catEntry.keys.entries()).sort((a, b) => b[1].count - a[1].count);
309
+ const limit = catEntry.signal === 'high' ? Infinity : 3;
310
+ let shown = 0;
311
+ for (const [key, v] of keysSorted) {
312
+ if (shown >= limit)
313
+ break;
314
+ if (catEntry.signal === 'mid') {
315
+ // Mid signal: display the bucket key (e.g. ssh→openclaw browser) with aggregate count
316
+ const countSuffix = v.count > 1 ? chalk.gray(` × ${v.count}`) : '';
317
+ lines.push(` ${chalk.cyan(truncateCmd(key, 80))}${countSuffix}`);
318
+ }
319
+ else {
320
+ // High signal: display distinct raw sample commands
321
+ const distinctSamples = pickDistinct(v.samples, 3);
322
+ for (const sample of distinctSamples) {
323
+ const countSuffix = v.count > 1 ? chalk.gray(` × ${v.count}`) : '';
324
+ lines.push(` ${chalk.cyan(truncateCmd(sample, 80))}${countSuffix}`);
325
+ }
326
+ }
327
+ shown++;
328
+ }
329
+ }
330
+ }
331
+ if (otherCount > 0) {
332
+ lines.push(` ${chalk.dim('Other')} ${chalk.gray(`(${otherCount})`)}`);
333
+ for (const [, v] of Array.from(otherKeys.entries()).slice(0, 5)) {
334
+ const countSuffix = v.count > 1 ? chalk.gray(` × ${v.count}`) : '';
335
+ lines.push(` ${chalk.cyan(truncateCmd(v.samples[0] ?? '', 80))}${countSuffix}`);
336
+ }
337
+ }
338
+ lines.push('');
339
+ }
340
+ function sharesPrefix(a, b, len) {
341
+ return a.slice(0, len) === b.slice(0, len);
342
+ }
343
+ function pickDistinct(samples, max) {
344
+ const result = [];
345
+ for (const s of samples) {
346
+ if (result.length >= max)
347
+ break;
348
+ if (!result.some(r => sharesPrefix(r, s, 30)))
349
+ result.push(s);
350
+ }
351
+ return result.length > 0 ? result : samples.slice(0, max);
352
+ }
353
+ function truncateCmd(cmd, max) {
354
+ return cmd.length <= max ? cmd : cmd.slice(0, max - 1) + '…';
355
+ }
356
+ // ── File grouping ─────────────────────────────────────────────────────────────
357
+ function groupByParentDir(paths, cwd) {
358
+ const groups = new Map();
359
+ for (const p of paths) {
360
+ const rel = relativeToCwd(p, cwd);
361
+ const slashIdx = rel.lastIndexOf('/');
362
+ const dir = slashIdx >= 0 ? rel.slice(0, slashIdx) : '.';
363
+ const base = slashIdx >= 0 ? rel.slice(slashIdx + 1) : rel;
364
+ const arr = groups.get(dir) ?? [];
365
+ arr.push(base);
366
+ groups.set(dir, arr);
367
+ }
368
+ return new Map(Array.from(groups.entries()).sort((a, b) => b[1].length - a[1].length));
369
+ }
370
+ function renderFileGroup(lines, groups, absPathMap) {
371
+ if (groups.size === 1) {
372
+ const [dir, files] = Array.from(groups.entries())[0];
373
+ for (const f of files) {
374
+ const abs = absPathMap.get(dir === '.' ? f : `${dir}/${f}`) ?? '';
375
+ const label = dir === '.' ? f : `${dir}/${f}`;
376
+ lines.push(' ' + chalk.cyan(abs ? linkPath(abs, label) : label));
377
+ }
378
+ }
379
+ else {
380
+ for (const [dir, files] of groups) {
381
+ lines.push(` ${chalk.dim(dir + '/')}`);
382
+ for (const f of files) {
383
+ const abs = absPathMap.get(dir === '.' ? f : `${dir}/${f}`) ?? '';
384
+ const label = f;
385
+ lines.push(' ' + chalk.cyan(abs ? linkPath(abs, label) : label));
386
+ }
387
+ }
388
+ }
389
+ }
390
+ // ── Main summary renderer ─────────────────────────────────────────────────────
391
+ /**
392
+ * Render session as an activity summary.
393
+ * Returns a chalk-formatted string (not markdown) for direct terminal output.
394
+ */
395
+ export function renderSummary(events, cwd) {
396
+ // ── Collect data in a single chronological pass ───────────────────────────
397
+ let firstUserMessage = '';
398
+ const attachments = [];
399
+ let lastAssistantMessage = '';
400
+ // File paths (absolute) for grouping — split by whether they're inside cwd
401
+ const filesModifiedAbs = new Set();
402
+ const filesReadAbs = new Set();
403
+ const filesModifiedExternal = new Set();
404
+ // Commands with timestamps
405
+ const cmdList = [];
406
+ // Plan items
407
+ const todoItems = [];
408
+ let exitPlanContent = null;
409
+ // Subagent spawns
410
+ const subagents = [];
411
+ // Errors
412
+ const errors = [];
413
+ // Assistant message count (used to decide whether the session produced any narration)
414
+ let assistantCount = 0;
415
+ const isInsideCwd = (p) => !!(cwd && p.startsWith(cwd + '/'));
416
+ for (const event of events) {
417
+ const ts = new Date(event.timestamp).getTime() || 0;
418
+ if (event.type === 'tool_use') {
419
+ if (event._local)
420
+ continue;
421
+ const tool = event.tool || '';
422
+ const args = event.args || {};
423
+ const p = event.path || args.file_path || args.path || '';
424
+ if (['Read', 'read_file', 'view_file', 'cat_file', 'get_file'].includes(tool)) {
425
+ if (p)
426
+ filesReadAbs.add(p);
427
+ }
428
+ else if (['Write', 'Edit', 'write_file', 'edit_file', 'create_file', 'replace', 'patch'].includes(tool)) {
429
+ if (p)
430
+ (isInsideCwd(p) || !cwd ? filesModifiedAbs : filesModifiedExternal).add(p);
431
+ }
432
+ if (event.command) {
433
+ const cmd = event.command.replace(/\n/g, ' ').trim();
434
+ if (cmd)
435
+ cmdList.push({ cmd, ts });
436
+ }
437
+ // Plan items: TodoWrite items + TaskCreate descriptions (project's task tracker)
438
+ if (tool === 'TodoWrite' && Array.isArray(args.todos)) {
439
+ for (const item of args.todos) {
440
+ const text = item.content || item.text || String(item);
441
+ if (text && !todoItems.includes(text))
442
+ todoItems.push(text);
443
+ }
444
+ }
445
+ if (tool === 'TaskCreate' && (args.description || args.prompt)) {
446
+ const text = String(args.description || args.prompt || '').slice(0, 140);
447
+ if (text && !todoItems.includes(text))
448
+ todoItems.push(text);
449
+ }
450
+ if (tool === 'ExitPlanMode') {
451
+ exitPlanContent = args.result || args.plan || args.content || null;
452
+ }
453
+ // Subagent spawns
454
+ if ((tool === 'Agent' || tool === 'Task') && (args.description || args.prompt)) {
455
+ subagents.push({
456
+ description: String(args.description || args.prompt || '').slice(0, 120),
457
+ subagentType: String(args.subagent_type || ''),
458
+ });
459
+ }
460
+ }
461
+ else if (event.type === 'error') {
462
+ errors.push({
463
+ tool: event.tool || 'unknown',
464
+ cmd: event.args?.command ? String(event.args.command).slice(0, 80) : undefined,
465
+ content: event.content?.slice(0, 120),
466
+ });
467
+ }
468
+ else if (event.type === 'message') {
469
+ if (event.role === 'user') {
470
+ if (!firstUserMessage) {
471
+ const content = event.content || '';
472
+ if (!/^\s*<local-command-caveat>/i.test(content)) {
473
+ const topic = extractSessionTopic(content);
474
+ if (topic)
475
+ firstUserMessage = content;
476
+ }
477
+ }
478
+ }
479
+ else if (event.role === 'assistant' && event.content) {
480
+ lastAssistantMessage = event.content;
481
+ assistantCount++;
482
+ }
483
+ }
484
+ else if (event.type === 'attachment') {
485
+ attachments.push({ mediaType: event.mediaType || 'image/png' });
486
+ }
487
+ }
488
+ // Dedupe: files in Modified should not appear in Read
489
+ for (const p of filesModifiedAbs)
490
+ filesReadAbs.delete(p);
491
+ for (const p of filesModifiedExternal)
492
+ filesReadAbs.delete(p);
493
+ // Build abs→rel mapping for linkPath
494
+ const buildAbsMap = (absSet) => {
495
+ const m = new Map();
496
+ for (const abs of absSet) {
497
+ const rel = relativeToCwd(abs, cwd);
498
+ m.set(rel, abs);
499
+ }
500
+ return m;
501
+ };
502
+ const modifiedAbsMap = buildAbsMap(filesModifiedAbs);
503
+ const readAbsMap = buildAbsMap(filesReadAbs);
504
+ // ── Render sections ───────────────────────────────────────────────────────
505
+ const lines = [''];
506
+ // 1. Prompt
507
+ if (firstUserMessage) {
508
+ const cleaned = cleanSessionPrompt(firstUserMessage);
509
+ if (cleaned) {
510
+ lines.push(chalk.bold('Prompt:') + ' ' + cleaned.split('\n')[0]);
511
+ const secondLine = cleaned.split('\n')[1]?.trim();
512
+ if (secondLine)
513
+ lines.push(' ' + secondLine);
514
+ const refs = extractReferences(cleaned);
515
+ if (refs.length > 0) {
516
+ lines.push(chalk.gray(' Referenced: ' + refs.join(', ')));
517
+ }
518
+ }
519
+ }
520
+ // Attachments (images/documents in the first user turn)
521
+ if (attachments.length > 0) {
522
+ const mediaTypes = [...new Set(attachments.map(a => a.mediaType))].join(', ');
523
+ lines.push(chalk.gray(` + ${attachments.length} screenshot${attachments.length !== 1 ? 's' : ''} (${mediaTypes})`));
524
+ }
525
+ if (firstUserMessage || attachments.length > 0)
526
+ lines.push('');
527
+ // 2. Plan
528
+ if (todoItems.length > 0 || exitPlanContent) {
529
+ lines.push(chalk.bold('Plan'));
530
+ if (exitPlanContent) {
531
+ const planLines = exitPlanContent.split('\n').slice(0, 10);
532
+ for (const l of planLines)
533
+ lines.push(' ' + l);
534
+ }
535
+ else {
536
+ for (const item of todoItems.slice(0, 20)) {
537
+ lines.push(' · ' + item);
538
+ }
539
+ }
540
+ lines.push('');
541
+ }
542
+ // 3. Subagents
543
+ if (subagents.length > 0) {
544
+ lines.push(chalk.bold('Subagents') + chalk.gray(` (${subagents.length})`));
545
+ for (const s of subagents) {
546
+ const typeSuffix = s.subagentType ? chalk.gray(` (${s.subagentType})`) : '';
547
+ lines.push(' Task: ' + s.description + typeSuffix);
548
+ }
549
+ lines.push('');
550
+ }
551
+ // 4. Modified files
552
+ if (filesModifiedAbs.size > 0) {
553
+ lines.push(chalk.bold('Modified') + chalk.gray(` (${filesModifiedAbs.size})`));
554
+ const groups = groupByParentDir(filesModifiedAbs, cwd);
555
+ renderFileGroup(lines, groups, modifiedAbsMap);
556
+ lines.push('');
557
+ }
558
+ // 4b. External edits (files edited outside the project root — typically /tmp)
559
+ if (filesModifiedExternal.size > 0) {
560
+ const externalList = [...filesModifiedExternal].sort();
561
+ const home = process.env.HOME ?? '';
562
+ const display = externalList.slice(0, 3).map(p => home && p.startsWith(home) ? p.replace(home, '~') : p);
563
+ const more = externalList.length > 3 ? chalk.gray(` +${externalList.length - 3} more`) : '';
564
+ lines.push(chalk.gray(`External edits (${filesModifiedExternal.size}): ${display.join(', ')}${more}`));
565
+ lines.push('');
566
+ }
567
+ // 5. Read files
568
+ if (filesReadAbs.size > 0) {
569
+ if (filesReadAbs.size <= 5) {
570
+ lines.push(chalk.bold('Read') + chalk.gray(` (${filesReadAbs.size})`));
571
+ const groups = groupByParentDir(filesReadAbs, cwd);
572
+ renderFileGroup(lines, groups, readAbsMap);
573
+ }
574
+ else {
575
+ lines.push(chalk.bold('Read') + chalk.gray(` ${filesReadAbs.size} other files`));
576
+ }
577
+ lines.push('');
578
+ }
579
+ // 6. Commands
580
+ renderCommandsSection(cmdList, lines);
581
+ // 7. Errors
582
+ if (errors.length > 0) {
583
+ const first = errors[0];
584
+ const firstDesc = first.cmd
585
+ ? `${first.tool} "${first.cmd.slice(0, 60)}"`
586
+ : first.content
587
+ ? `${first.tool}: ${first.content.slice(0, 60)}`
588
+ : first.tool;
589
+ lines.push(chalk.red(chalk.bold('Errors')) +
590
+ chalk.gray(`: ${errors.length} failure${errors.length !== 1 ? 's' : ''} — first: ${firstDesc}`));
591
+ lines.push('');
592
+ }
593
+ // 9. Final message
594
+ if (lastAssistantMessage) {
595
+ const hasActivity = filesModifiedAbs.size > 0 || filesReadAbs.size > 0 || cmdList.length > 0;
596
+ if (hasActivity || errors.length > 0)
597
+ lines.push(chalk.gray('─'.repeat(60)));
598
+ lines.push('');
599
+ const truncated = lastAssistantMessage.length > 3000
600
+ ? lastAssistantMessage.slice(0, 2997) + '...'
601
+ : lastAssistantMessage;
602
+ lines.push(renderMarkdown(truncated).trimEnd());
603
+ lines.push('');
604
+ }
605
+ else if (filesModifiedAbs.size === 0 &&
606
+ filesReadAbs.size === 0 &&
607
+ cmdList.length === 0 &&
608
+ assistantCount === 0) {
609
+ lines.push(chalk.gray('No activity recorded in this session.'));
610
+ lines.push('');
611
+ }
612
+ return lines.join('\n');
613
+ }
614
+ // ── Event filters ─────────────────────────────────────────────────────────────
615
+ export const VALID_ROLE_VALUES = ['user', 'assistant', 'thinking', 'tools'];
616
+ /**
617
+ * Parse a comma-separated role list (e.g. "user,assistant") into typed values.
618
+ * Throws with a clear message listing valid values on any unknown entry.
619
+ */
620
+ export function parseRoleList(raw, flag) {
621
+ const parts = raw.split(',').map(s => s.trim()).filter(Boolean);
622
+ if (parts.length === 0) {
623
+ throw new Error(`${flag} requires at least one role. Valid values: ${VALID_ROLE_VALUES.join(', ')}`);
624
+ }
625
+ for (const p of parts) {
626
+ if (!VALID_ROLE_VALUES.includes(p)) {
627
+ throw new Error(`Invalid value "${p}" for ${flag}. Valid values: ${VALID_ROLE_VALUES.join(', ')}`);
628
+ }
629
+ }
630
+ return parts;
631
+ }
632
+ function roleOfEvent(e) {
633
+ if (e.type === 'message' && e.role === 'user')
634
+ return 'user';
635
+ if (e.type === 'message' && e.role === 'assistant')
636
+ return 'assistant';
637
+ if (e.type === 'thinking')
638
+ return 'thinking';
639
+ if (e.type === 'tool_use' || e.type === 'tool_result')
640
+ return 'tools';
641
+ return null;
642
+ }
643
+ /**
644
+ * Keep events whose role is in `include` (whitelist) or whose role is not in
645
+ * `exclude` (blacklist). Non-role events (errors, usage, attachments, init,
646
+ * result) are preserved unless explicitly constrained by `include` — that
647
+ * matches the user model: "include user" means "only user".
648
+ */
649
+ function applyRoleFilter(events, opts) {
650
+ if (opts.include && opts.include.length > 0) {
651
+ const set = new Set(opts.include);
652
+ return events.filter(e => {
653
+ const role = roleOfEvent(e);
654
+ return role !== null && set.has(role);
655
+ });
656
+ }
657
+ if (opts.exclude && opts.exclude.length > 0) {
658
+ const set = new Set(opts.exclude);
659
+ return events.filter(e => {
660
+ const role = roleOfEvent(e);
661
+ return role === null || !set.has(role);
662
+ });
663
+ }
664
+ return events;
665
+ }
666
+ /**
667
+ * A "turn" starts at each user message. `--first N` keeps events through the
668
+ * end of the Nth user turn; `--last N` keeps events from the start of the
669
+ * (M-N+1)th user turn to the end. If the session has no user messages, every
670
+ * assistant message counts as a turn instead.
671
+ */
672
+ function applyTurnSlice(events, opts) {
673
+ if (opts.first === undefined && opts.last === undefined)
674
+ return events;
675
+ if (opts.first !== undefined && opts.last !== undefined) {
676
+ throw new Error('--first and --last are mutually exclusive');
677
+ }
678
+ const n = (opts.first ?? opts.last);
679
+ if (!Number.isFinite(n) || n <= 0) {
680
+ throw new Error(`Turn count must be a positive integer, got ${n}`);
681
+ }
682
+ const isTurnStart = (e) => e.type === 'message' && e.role === 'user';
683
+ const turnStartIdx = [];
684
+ for (let i = 0; i < events.length; i++)
685
+ if (isTurnStart(events[i]))
686
+ turnStartIdx.push(i);
687
+ // Fallback: no user messages — treat assistant messages as turn boundaries.
688
+ if (turnStartIdx.length === 0) {
689
+ for (let i = 0; i < events.length; i++) {
690
+ if (events[i].type === 'message' && events[i].role === 'assistant')
691
+ turnStartIdx.push(i);
692
+ }
693
+ }
694
+ if (turnStartIdx.length === 0)
695
+ return events;
696
+ if (opts.first !== undefined) {
697
+ if (n >= turnStartIdx.length)
698
+ return events;
699
+ const endIdx = turnStartIdx[n]; // exclusive
700
+ return events.slice(0, endIdx);
701
+ }
702
+ // --last
703
+ if (n >= turnStartIdx.length)
704
+ return events;
705
+ const startIdx = turnStartIdx[turnStartIdx.length - n];
706
+ return events.slice(startIdx);
707
+ }
708
+ /**
709
+ * Apply include/exclude/first/last. Turn slicing runs first so role filters
710
+ * operate on the sliced window (natural semantics: "last 3 turns, user only").
711
+ */
712
+ export function filterEvents(events, opts) {
713
+ if (opts.include && opts.include.length > 0 && opts.exclude && opts.exclude.length > 0) {
714
+ throw new Error('--include and --exclude are mutually exclusive');
715
+ }
716
+ const sliced = applyTurnSlice(events, opts);
717
+ return applyRoleFilter(sliced, opts);
718
+ }
719
+ // ── Conversation renderers ────────────────────────────────────────────────────
720
+ /**
721
+ * Build the conversation as a single markdown string: user / assistant
722
+ * messages, inline thinking blocks, tool calls, and errors. Emitted in event
723
+ * order so reasoning sits where it actually occurred relative to the assistant
724
+ * reply.
725
+ */
726
+ export function renderConversationMarkdown(events) {
727
+ const parts = [];
728
+ for (const event of events) {
729
+ if (event.type === 'message') {
730
+ if (event.role === 'user') {
731
+ parts.push(`## User\n\n${event.content ?? ''}`);
732
+ }
733
+ else if (event.role === 'assistant') {
734
+ parts.push(`## Assistant\n\n${event.content ?? ''}`);
735
+ }
736
+ }
737
+ else if (event.type === 'thinking') {
738
+ if (event.content)
739
+ parts.push(`### Thinking\n\n${event.content}`);
740
+ }
741
+ else if (event.type === 'tool_use') {
742
+ const tool = event.tool || 'unknown';
743
+ if (event.command) {
744
+ parts.push(`### Tool: ${tool}\n\n\`\`\`bash\n${event.command}\n\`\`\``);
745
+ }
746
+ else if (event.path) {
747
+ parts.push(`### Tool: ${tool}\n\n\`${shortenPathTrace(event.path)}\``);
748
+ }
749
+ else {
750
+ const summary = summarizeToolUse(tool, event.args);
751
+ parts.push(`### Tool: ${tool}\n\n${summary}`);
752
+ }
753
+ }
754
+ else if (event.type === 'tool_result') {
755
+ if (event.content) {
756
+ const body = event.content.length > 2000 ? event.content.slice(0, 2000) + '\n…' : event.content;
757
+ parts.push(`### Tool Result\n\n\`\`\`\n${body}\n\`\`\``);
758
+ }
759
+ }
760
+ else if (event.type === 'error') {
761
+ parts.push(`### Error\n\n${event.content || event.tool || 'Unknown error'}`);
762
+ }
763
+ }
764
+ return parts.join('\n\n');
765
+ }
766
+ /**
767
+ * Render session as JSON (normalized events).
768
+ */
769
+ export function renderJson(events) {
770
+ return JSON.stringify(events, null, 2);
771
+ }
772
+ function shortenPathTrace(p) {
773
+ const home = process.env.HOME || '';
774
+ if (home && p.startsWith(home))
775
+ return '~' + p.slice(home.length);
776
+ return p;
777
+ }
778
+ //# sourceMappingURL=render.js.map