@swarmify/agents-cli 1.13.4 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (567) hide show
  1. package/README.md +2 -319
  2. package/bin/agents.js +2 -0
  3. package/package.json +13 -79
  4. package/scripts/postinstall.js +4 -71
  5. package/CHANGELOG.md +0 -316
  6. package/LICENSE +0 -21
  7. package/dist/commands/__tests__/sessions-tail.test.d.ts +0 -2
  8. package/dist/commands/__tests__/sessions-tail.test.d.ts.map +0 -1
  9. package/dist/commands/__tests__/sessions-tail.test.js +0 -108
  10. package/dist/commands/__tests__/sessions-tail.test.js.map +0 -1
  11. package/dist/commands/__tests__/sessions.test.d.ts +0 -2
  12. package/dist/commands/__tests__/sessions.test.d.ts.map +0 -1
  13. package/dist/commands/__tests__/sessions.test.js +0 -636
  14. package/dist/commands/__tests__/sessions.test.js.map +0 -1
  15. package/dist/commands/cloud.d.ts +0 -11
  16. package/dist/commands/cloud.d.ts.map +0 -1
  17. package/dist/commands/cloud.js +0 -363
  18. package/dist/commands/cloud.js.map +0 -1
  19. package/dist/commands/commands.d.ts +0 -12
  20. package/dist/commands/commands.d.ts.map +0 -1
  21. package/dist/commands/commands.js +0 -629
  22. package/dist/commands/commands.js.map +0 -1
  23. package/dist/commands/daemon.d.ts +0 -11
  24. package/dist/commands/daemon.d.ts.map +0 -1
  25. package/dist/commands/daemon.js +0 -119
  26. package/dist/commands/daemon.js.map +0 -1
  27. package/dist/commands/drive.d.ts +0 -11
  28. package/dist/commands/drive.d.ts.map +0 -1
  29. package/dist/commands/drive.js +0 -175
  30. package/dist/commands/drive.js.map +0 -1
  31. package/dist/commands/exec.d.ts +0 -11
  32. package/dist/commands/exec.d.ts.map +0 -1
  33. package/dist/commands/exec.js +0 -251
  34. package/dist/commands/exec.js.map +0 -1
  35. package/dist/commands/factory.d.ts +0 -11
  36. package/dist/commands/factory.d.ts.map +0 -1
  37. package/dist/commands/factory.js +0 -445
  38. package/dist/commands/factory.js.map +0 -1
  39. package/dist/commands/fork.d.ts +0 -11
  40. package/dist/commands/fork.d.ts.map +0 -1
  41. package/dist/commands/fork.js +0 -147
  42. package/dist/commands/fork.js.map +0 -1
  43. package/dist/commands/hooks.d.ts +0 -12
  44. package/dist/commands/hooks.d.ts.map +0 -1
  45. package/dist/commands/hooks.js +0 -690
  46. package/dist/commands/hooks.js.map +0 -1
  47. package/dist/commands/init.d.ts +0 -15
  48. package/dist/commands/init.d.ts.map +0 -1
  49. package/dist/commands/init.js +0 -137
  50. package/dist/commands/init.js.map +0 -1
  51. package/dist/commands/mcp.d.ts +0 -12
  52. package/dist/commands/mcp.d.ts.map +0 -1
  53. package/dist/commands/mcp.js +0 -583
  54. package/dist/commands/mcp.js.map +0 -1
  55. package/dist/commands/models.d.ts +0 -11
  56. package/dist/commands/models.d.ts.map +0 -1
  57. package/dist/commands/models.js +0 -170
  58. package/dist/commands/models.js.map +0 -1
  59. package/dist/commands/packages.d.ts +0 -11
  60. package/dist/commands/packages.d.ts.map +0 -1
  61. package/dist/commands/packages.js +0 -551
  62. package/dist/commands/packages.js.map +0 -1
  63. package/dist/commands/permissions.d.ts +0 -12
  64. package/dist/commands/permissions.d.ts.map +0 -1
  65. package/dist/commands/permissions.js +0 -724
  66. package/dist/commands/permissions.js.map +0 -1
  67. package/dist/commands/plugins.d.ts +0 -11
  68. package/dist/commands/plugins.d.ts.map +0 -1
  69. package/dist/commands/plugins.js +0 -393
  70. package/dist/commands/plugins.js.map +0 -1
  71. package/dist/commands/profiles.d.ts +0 -12
  72. package/dist/commands/profiles.d.ts.map +0 -1
  73. package/dist/commands/profiles.js +0 -255
  74. package/dist/commands/profiles.js.map +0 -1
  75. package/dist/commands/pty.d.ts +0 -21
  76. package/dist/commands/pty.d.ts.map +0 -1
  77. package/dist/commands/pty.js +0 -391
  78. package/dist/commands/pty.js.map +0 -1
  79. package/dist/commands/pull.d.ts +0 -11
  80. package/dist/commands/pull.d.ts.map +0 -1
  81. package/dist/commands/pull.js +0 -456
  82. package/dist/commands/pull.js.map +0 -1
  83. package/dist/commands/push.d.ts +0 -11
  84. package/dist/commands/push.d.ts.map +0 -1
  85. package/dist/commands/push.js +0 -188
  86. package/dist/commands/push.js.map +0 -1
  87. package/dist/commands/refresh-memory.d.ts +0 -16
  88. package/dist/commands/refresh-memory.d.ts.map +0 -1
  89. package/dist/commands/refresh-memory.js +0 -52
  90. package/dist/commands/refresh-memory.js.map +0 -1
  91. package/dist/commands/resource-view.d.ts +0 -39
  92. package/dist/commands/resource-view.d.ts.map +0 -1
  93. package/dist/commands/resource-view.js +0 -197
  94. package/dist/commands/resource-view.js.map +0 -1
  95. package/dist/commands/routines.d.ts +0 -11
  96. package/dist/commands/routines.d.ts.map +0 -1
  97. package/dist/commands/routines.js +0 -590
  98. package/dist/commands/routines.js.map +0 -1
  99. package/dist/commands/rules.d.ts +0 -12
  100. package/dist/commands/rules.d.ts.map +0 -1
  101. package/dist/commands/rules.js +0 -489
  102. package/dist/commands/rules.js.map +0 -1
  103. package/dist/commands/secrets.d.ts +0 -11
  104. package/dist/commands/secrets.d.ts.map +0 -1
  105. package/dist/commands/secrets.js +0 -352
  106. package/dist/commands/secrets.js.map +0 -1
  107. package/dist/commands/sessions-picker.d.ts +0 -18
  108. package/dist/commands/sessions-picker.d.ts.map +0 -1
  109. package/dist/commands/sessions-picker.js +0 -265
  110. package/dist/commands/sessions-picker.js.map +0 -1
  111. package/dist/commands/sessions-tail.d.ts +0 -20
  112. package/dist/commands/sessions-tail.d.ts.map +0 -1
  113. package/dist/commands/sessions-tail.js +0 -236
  114. package/dist/commands/sessions-tail.js.map +0 -1
  115. package/dist/commands/sessions.d.ts +0 -18
  116. package/dist/commands/sessions.d.ts.map +0 -1
  117. package/dist/commands/sessions.js +0 -1173
  118. package/dist/commands/sessions.js.map +0 -1
  119. package/dist/commands/skills.d.ts +0 -12
  120. package/dist/commands/skills.d.ts.map +0 -1
  121. package/dist/commands/skills.js +0 -717
  122. package/dist/commands/skills.js.map +0 -1
  123. package/dist/commands/status.d.ts +0 -10
  124. package/dist/commands/status.d.ts.map +0 -1
  125. package/dist/commands/status.js +0 -26
  126. package/dist/commands/status.js.map +0 -1
  127. package/dist/commands/subagents.d.ts +0 -11
  128. package/dist/commands/subagents.d.ts.map +0 -1
  129. package/dist/commands/subagents.js +0 -361
  130. package/dist/commands/subagents.js.map +0 -1
  131. package/dist/commands/sync.d.ts +0 -11
  132. package/dist/commands/sync.d.ts.map +0 -1
  133. package/dist/commands/sync.js +0 -70
  134. package/dist/commands/sync.js.map +0 -1
  135. package/dist/commands/teams-picker.d.ts +0 -18
  136. package/dist/commands/teams-picker.d.ts.map +0 -1
  137. package/dist/commands/teams-picker.js +0 -290
  138. package/dist/commands/teams-picker.js.map +0 -1
  139. package/dist/commands/teams.d.ts +0 -18
  140. package/dist/commands/teams.d.ts.map +0 -1
  141. package/dist/commands/teams.js +0 -1144
  142. package/dist/commands/teams.js.map +0 -1
  143. package/dist/commands/utils.d.ts +0 -45
  144. package/dist/commands/utils.d.ts.map +0 -1
  145. package/dist/commands/utils.js +0 -106
  146. package/dist/commands/utils.js.map +0 -1
  147. package/dist/commands/versions.d.ts +0 -11
  148. package/dist/commands/versions.d.ts.map +0 -1
  149. package/dist/commands/versions.js +0 -701
  150. package/dist/commands/versions.js.map +0 -1
  151. package/dist/commands/view.d.ts +0 -43
  152. package/dist/commands/view.d.ts.map +0 -1
  153. package/dist/commands/view.js +0 -894
  154. package/dist/commands/view.js.map +0 -1
  155. package/dist/index.d.ts +0 -9
  156. package/dist/index.d.ts.map +0 -1
  157. package/dist/index.js +0 -496
  158. package/dist/index.js.map +0 -1
  159. package/dist/lib/__tests__/bugfixes.test.d.ts +0 -2
  160. package/dist/lib/__tests__/bugfixes.test.d.ts.map +0 -1
  161. package/dist/lib/__tests__/bugfixes.test.js +0 -192
  162. package/dist/lib/__tests__/bugfixes.test.js.map +0 -1
  163. package/dist/lib/__tests__/exec.test.d.ts +0 -2
  164. package/dist/lib/__tests__/exec.test.d.ts.map +0 -1
  165. package/dist/lib/__tests__/exec.test.js +0 -446
  166. package/dist/lib/__tests__/exec.test.js.map +0 -1
  167. package/dist/lib/__tests__/git-sync.test.d.ts +0 -2
  168. package/dist/lib/__tests__/git-sync.test.d.ts.map +0 -1
  169. package/dist/lib/__tests__/git-sync.test.js +0 -138
  170. package/dist/lib/__tests__/git-sync.test.js.map +0 -1
  171. package/dist/lib/__tests__/hooks.test.d.ts +0 -2
  172. package/dist/lib/__tests__/hooks.test.d.ts.map +0 -1
  173. package/dist/lib/__tests__/hooks.test.js +0 -203
  174. package/dist/lib/__tests__/hooks.test.js.map +0 -1
  175. package/dist/lib/__tests__/memory-compile.test.d.ts +0 -2
  176. package/dist/lib/__tests__/memory-compile.test.d.ts.map +0 -1
  177. package/dist/lib/__tests__/memory-compile.test.js +0 -95
  178. package/dist/lib/__tests__/memory-compile.test.js.map +0 -1
  179. package/dist/lib/__tests__/models.test.d.ts +0 -2
  180. package/dist/lib/__tests__/models.test.d.ts.map +0 -1
  181. package/dist/lib/__tests__/models.test.js +0 -239
  182. package/dist/lib/__tests__/models.test.js.map +0 -1
  183. package/dist/lib/__tests__/rotate.test.d.ts +0 -2
  184. package/dist/lib/__tests__/rotate.test.d.ts.map +0 -1
  185. package/dist/lib/__tests__/rotate.test.js +0 -80
  186. package/dist/lib/__tests__/rotate.test.js.map +0 -1
  187. package/dist/lib/__tests__/secrets-bundles.test.d.ts +0 -2
  188. package/dist/lib/__tests__/secrets-bundles.test.d.ts.map +0 -1
  189. package/dist/lib/__tests__/secrets-bundles.test.js +0 -104
  190. package/dist/lib/__tests__/secrets-bundles.test.js.map +0 -1
  191. package/dist/lib/__tests__/secrets.test.d.ts +0 -2
  192. package/dist/lib/__tests__/secrets.test.d.ts.map +0 -1
  193. package/dist/lib/__tests__/secrets.test.js +0 -90
  194. package/dist/lib/__tests__/secrets.test.js.map +0 -1
  195. package/dist/lib/__tests__/shims.test.d.ts +0 -2
  196. package/dist/lib/__tests__/shims.test.d.ts.map +0 -1
  197. package/dist/lib/__tests__/shims.test.js +0 -57
  198. package/dist/lib/__tests__/shims.test.js.map +0 -1
  199. package/dist/lib/__tests__/usage.test.d.ts +0 -2
  200. package/dist/lib/__tests__/usage.test.d.ts.map +0 -1
  201. package/dist/lib/__tests__/usage.test.js +0 -220
  202. package/dist/lib/__tests__/usage.test.js.map +0 -1
  203. package/dist/lib/__tests__/versions.test.d.ts +0 -2
  204. package/dist/lib/__tests__/versions.test.d.ts.map +0 -1
  205. package/dist/lib/__tests__/versions.test.js +0 -63
  206. package/dist/lib/__tests__/versions.test.js.map +0 -1
  207. package/dist/lib/agents.d.ts +0 -158
  208. package/dist/lib/agents.d.ts.map +0 -1
  209. package/dist/lib/agents.js +0 -1159
  210. package/dist/lib/agents.js.map +0 -1
  211. package/dist/lib/artifact-actions.d.ts +0 -27
  212. package/dist/lib/artifact-actions.d.ts.map +0 -1
  213. package/dist/lib/artifact-actions.js +0 -58
  214. package/dist/lib/artifact-actions.js.map +0 -1
  215. package/dist/lib/cloud/codex.d.ts +0 -26
  216. package/dist/lib/cloud/codex.d.ts.map +0 -1
  217. package/dist/lib/cloud/codex.js +0 -237
  218. package/dist/lib/cloud/codex.js.map +0 -1
  219. package/dist/lib/cloud/factory.d.ts +0 -32
  220. package/dist/lib/cloud/factory.d.ts.map +0 -1
  221. package/dist/lib/cloud/factory.js +0 -43
  222. package/dist/lib/cloud/factory.js.map +0 -1
  223. package/dist/lib/cloud/registry.d.ts +0 -16
  224. package/dist/lib/cloud/registry.d.ts.map +0 -1
  225. package/dist/lib/cloud/registry.js +0 -68
  226. package/dist/lib/cloud/registry.js.map +0 -1
  227. package/dist/lib/cloud/rush.d.ts +0 -37
  228. package/dist/lib/cloud/rush.d.ts.map +0 -1
  229. package/dist/lib/cloud/rush.js +0 -230
  230. package/dist/lib/cloud/rush.js.map +0 -1
  231. package/dist/lib/cloud/rush.test.d.ts +0 -2
  232. package/dist/lib/cloud/rush.test.d.ts.map +0 -1
  233. package/dist/lib/cloud/rush.test.js +0 -63
  234. package/dist/lib/cloud/rush.test.js.map +0 -1
  235. package/dist/lib/cloud/store.d.ts +0 -23
  236. package/dist/lib/cloud/store.d.ts.map +0 -1
  237. package/dist/lib/cloud/store.js +0 -116
  238. package/dist/lib/cloud/store.js.map +0 -1
  239. package/dist/lib/cloud/stream.d.ts +0 -24
  240. package/dist/lib/cloud/stream.d.ts.map +0 -1
  241. package/dist/lib/cloud/stream.js +0 -145
  242. package/dist/lib/cloud/stream.js.map +0 -1
  243. package/dist/lib/cloud/types.d.ts +0 -109
  244. package/dist/lib/cloud/types.d.ts.map +0 -1
  245. package/dist/lib/cloud/types.js +0 -33
  246. package/dist/lib/cloud/types.js.map +0 -1
  247. package/dist/lib/cloud/types.test.d.ts +0 -2
  248. package/dist/lib/cloud/types.test.d.ts.map +0 -1
  249. package/dist/lib/cloud/types.test.js +0 -41
  250. package/dist/lib/cloud/types.test.js.map +0 -1
  251. package/dist/lib/commands.d.ts +0 -141
  252. package/dist/lib/commands.d.ts.map +0 -1
  253. package/dist/lib/commands.js +0 -514
  254. package/dist/lib/commands.js.map +0 -1
  255. package/dist/lib/convert.d.ts +0 -21
  256. package/dist/lib/convert.d.ts.map +0 -1
  257. package/dist/lib/convert.js +0 -54
  258. package/dist/lib/convert.js.map +0 -1
  259. package/dist/lib/daemon.d.ts +0 -43
  260. package/dist/lib/daemon.d.ts.map +0 -1
  261. package/dist/lib/daemon.js +0 -332
  262. package/dist/lib/daemon.js.map +0 -1
  263. package/dist/lib/drive-sync.d.ts +0 -46
  264. package/dist/lib/drive-sync.d.ts.map +0 -1
  265. package/dist/lib/drive-sync.js +0 -209
  266. package/dist/lib/drive-sync.js.map +0 -1
  267. package/dist/lib/exec.d.ts +0 -101
  268. package/dist/lib/exec.d.ts.map +0 -1
  269. package/dist/lib/exec.js +0 -450
  270. package/dist/lib/exec.js.map +0 -1
  271. package/dist/lib/factory/__tests__/config.test.d.ts +0 -2
  272. package/dist/lib/factory/__tests__/config.test.d.ts.map +0 -1
  273. package/dist/lib/factory/__tests__/config.test.js +0 -128
  274. package/dist/lib/factory/__tests__/config.test.js.map +0 -1
  275. package/dist/lib/factory/config.d.ts +0 -49
  276. package/dist/lib/factory/config.d.ts.map +0 -1
  277. package/dist/lib/factory/config.js +0 -127
  278. package/dist/lib/factory/config.js.map +0 -1
  279. package/dist/lib/factory.d.ts +0 -57
  280. package/dist/lib/factory.d.ts.map +0 -1
  281. package/dist/lib/factory.js +0 -107
  282. package/dist/lib/factory.js.map +0 -1
  283. package/dist/lib/git.d.ts +0 -157
  284. package/dist/lib/git.d.ts.map +0 -1
  285. package/dist/lib/git.js +0 -647
  286. package/dist/lib/git.js.map +0 -1
  287. package/dist/lib/help.d.ts +0 -10
  288. package/dist/lib/help.d.ts.map +0 -1
  289. package/dist/lib/help.js +0 -66
  290. package/dist/lib/help.js.map +0 -1
  291. package/dist/lib/hooks.d.ts +0 -125
  292. package/dist/lib/hooks.d.ts.map +0 -1
  293. package/dist/lib/hooks.js +0 -846
  294. package/dist/lib/hooks.js.map +0 -1
  295. package/dist/lib/ledger/__tests__/local.test.d.ts +0 -2
  296. package/dist/lib/ledger/__tests__/local.test.d.ts.map +0 -1
  297. package/dist/lib/ledger/__tests__/local.test.js +0 -177
  298. package/dist/lib/ledger/__tests__/local.test.js.map +0 -1
  299. package/dist/lib/ledger/__tests__/sync.test.d.ts +0 -2
  300. package/dist/lib/ledger/__tests__/sync.test.d.ts.map +0 -1
  301. package/dist/lib/ledger/__tests__/sync.test.js +0 -117
  302. package/dist/lib/ledger/__tests__/sync.test.js.map +0 -1
  303. package/dist/lib/ledger/index.d.ts +0 -18
  304. package/dist/lib/ledger/index.d.ts.map +0 -1
  305. package/dist/lib/ledger/index.js +0 -32
  306. package/dist/lib/ledger/index.js.map +0 -1
  307. package/dist/lib/ledger/local.d.ts +0 -22
  308. package/dist/lib/ledger/local.d.ts.map +0 -1
  309. package/dist/lib/ledger/local.js +0 -333
  310. package/dist/lib/ledger/local.js.map +0 -1
  311. package/dist/lib/ledger/r2.d.ts +0 -41
  312. package/dist/lib/ledger/r2.d.ts.map +0 -1
  313. package/dist/lib/ledger/r2.js +0 -335
  314. package/dist/lib/ledger/r2.js.map +0 -1
  315. package/dist/lib/ledger/sync.d.ts +0 -33
  316. package/dist/lib/ledger/sync.d.ts.map +0 -1
  317. package/dist/lib/ledger/sync.js +0 -106
  318. package/dist/lib/ledger/sync.js.map +0 -1
  319. package/dist/lib/ledger/types.d.ts +0 -100
  320. package/dist/lib/ledger/types.d.ts.map +0 -1
  321. package/dist/lib/ledger/types.js +0 -21
  322. package/dist/lib/ledger/types.js.map +0 -1
  323. package/dist/lib/manifest.d.ts +0 -14
  324. package/dist/lib/manifest.d.ts.map +0 -1
  325. package/dist/lib/manifest.js +0 -48
  326. package/dist/lib/manifest.js.map +0 -1
  327. package/dist/lib/markdown.d.ts +0 -5
  328. package/dist/lib/markdown.d.ts.map +0 -1
  329. package/dist/lib/markdown.js +0 -17
  330. package/dist/lib/markdown.js.map +0 -1
  331. package/dist/lib/mcp.d.ts +0 -64
  332. package/dist/lib/mcp.d.ts.map +0 -1
  333. package/dist/lib/mcp.js +0 -327
  334. package/dist/lib/mcp.js.map +0 -1
  335. package/dist/lib/memory-compile.d.ts +0 -65
  336. package/dist/lib/memory-compile.d.ts.map +0 -1
  337. package/dist/lib/memory-compile.js +0 -174
  338. package/dist/lib/memory-compile.js.map +0 -1
  339. package/dist/lib/memory.d.ts +0 -64
  340. package/dist/lib/memory.d.ts.map +0 -1
  341. package/dist/lib/memory.js +0 -275
  342. package/dist/lib/memory.js.map +0 -1
  343. package/dist/lib/models.d.ts +0 -98
  344. package/dist/lib/models.d.ts.map +0 -1
  345. package/dist/lib/models.js +0 -728
  346. package/dist/lib/models.js.map +0 -1
  347. package/dist/lib/permissions.d.ts +0 -227
  348. package/dist/lib/permissions.d.ts.map +0 -1
  349. package/dist/lib/permissions.js +0 -1085
  350. package/dist/lib/permissions.js.map +0 -1
  351. package/dist/lib/picker.d.ts +0 -27
  352. package/dist/lib/picker.d.ts.map +0 -1
  353. package/dist/lib/picker.js +0 -110
  354. package/dist/lib/picker.js.map +0 -1
  355. package/dist/lib/plugins.d.ts +0 -80
  356. package/dist/lib/plugins.d.ts.map +0 -1
  357. package/dist/lib/plugins.js +0 -556
  358. package/dist/lib/plugins.js.map +0 -1
  359. package/dist/lib/profiles-keychain.d.ts +0 -11
  360. package/dist/lib/profiles-keychain.d.ts.map +0 -1
  361. package/dist/lib/profiles-keychain.js +0 -14
  362. package/dist/lib/profiles-keychain.js.map +0 -1
  363. package/dist/lib/profiles-presets.d.ts +0 -25
  364. package/dist/lib/profiles-presets.d.ts.map +0 -1
  365. package/dist/lib/profiles-presets.js +0 -104
  366. package/dist/lib/profiles-presets.js.map +0 -1
  367. package/dist/lib/profiles.d.ts +0 -70
  368. package/dist/lib/profiles.d.ts.map +0 -1
  369. package/dist/lib/profiles.js +0 -145
  370. package/dist/lib/profiles.js.map +0 -1
  371. package/dist/lib/pty-client.d.ts +0 -23
  372. package/dist/lib/pty-client.d.ts.map +0 -1
  373. package/dist/lib/pty-client.js +0 -181
  374. package/dist/lib/pty-client.js.map +0 -1
  375. package/dist/lib/pty-server.d.ts +0 -21
  376. package/dist/lib/pty-server.d.ts.map +0 -1
  377. package/dist/lib/pty-server.js +0 -427
  378. package/dist/lib/pty-server.js.map +0 -1
  379. package/dist/lib/registry.d.ts +0 -45
  380. package/dist/lib/registry.d.ts.map +0 -1
  381. package/dist/lib/registry.js +0 -220
  382. package/dist/lib/registry.js.map +0 -1
  383. package/dist/lib/resources.d.ts +0 -55
  384. package/dist/lib/resources.d.ts.map +0 -1
  385. package/dist/lib/resources.js +0 -103
  386. package/dist/lib/resources.js.map +0 -1
  387. package/dist/lib/rotate.d.ts +0 -58
  388. package/dist/lib/rotate.d.ts.map +0 -1
  389. package/dist/lib/rotate.js +0 -93
  390. package/dist/lib/rotate.js.map +0 -1
  391. package/dist/lib/routines.d.ts +0 -99
  392. package/dist/lib/routines.d.ts.map +0 -1
  393. package/dist/lib/routines.js +0 -352
  394. package/dist/lib/routines.js.map +0 -1
  395. package/dist/lib/runner.d.ts +0 -26
  396. package/dist/lib/runner.d.ts.map +0 -1
  397. package/dist/lib/runner.js +0 -325
  398. package/dist/lib/runner.js.map +0 -1
  399. package/dist/lib/sandbox.d.ts +0 -26
  400. package/dist/lib/sandbox.d.ts.map +0 -1
  401. package/dist/lib/sandbox.js +0 -218
  402. package/dist/lib/sandbox.js.map +0 -1
  403. package/dist/lib/scheduler.d.ts +0 -26
  404. package/dist/lib/scheduler.d.ts.map +0 -1
  405. package/dist/lib/scheduler.js +0 -77
  406. package/dist/lib/scheduler.js.map +0 -1
  407. package/dist/lib/secrets-bundles.d.ts +0 -38
  408. package/dist/lib/secrets-bundles.d.ts.map +0 -1
  409. package/dist/lib/secrets-bundles.js +0 -176
  410. package/dist/lib/secrets-bundles.js.map +0 -1
  411. package/dist/lib/secrets.d.ts +0 -53
  412. package/dist/lib/secrets.d.ts.map +0 -1
  413. package/dist/lib/secrets.js +0 -140
  414. package/dist/lib/secrets.js.map +0 -1
  415. package/dist/lib/session/__tests__/db.test.d.ts +0 -2
  416. package/dist/lib/session/__tests__/db.test.d.ts.map +0 -1
  417. package/dist/lib/session/__tests__/db.test.js +0 -54
  418. package/dist/lib/session/__tests__/db.test.js.map +0 -1
  419. package/dist/lib/session/__tests__/discover.test.d.ts +0 -2
  420. package/dist/lib/session/__tests__/discover.test.d.ts.map +0 -1
  421. package/dist/lib/session/__tests__/discover.test.js +0 -63
  422. package/dist/lib/session/__tests__/discover.test.js.map +0 -1
  423. package/dist/lib/session/__tests__/prompt.test.d.ts +0 -2
  424. package/dist/lib/session/__tests__/prompt.test.d.ts.map +0 -1
  425. package/dist/lib/session/__tests__/prompt.test.js +0 -44
  426. package/dist/lib/session/__tests__/prompt.test.js.map +0 -1
  427. package/dist/lib/session/__tests__/render.test.d.ts +0 -2
  428. package/dist/lib/session/__tests__/render.test.d.ts.map +0 -1
  429. package/dist/lib/session/__tests__/render.test.js +0 -602
  430. package/dist/lib/session/__tests__/render.test.js.map +0 -1
  431. package/dist/lib/session/active.d.ts +0 -44
  432. package/dist/lib/session/active.d.ts.map +0 -1
  433. package/dist/lib/session/active.js +0 -379
  434. package/dist/lib/session/active.js.map +0 -1
  435. package/dist/lib/session/artifacts.d.ts +0 -15
  436. package/dist/lib/session/artifacts.d.ts.map +0 -1
  437. package/dist/lib/session/artifacts.js +0 -86
  438. package/dist/lib/session/artifacts.js.map +0 -1
  439. package/dist/lib/session/db.d.ts +0 -140
  440. package/dist/lib/session/db.d.ts.map +0 -1
  441. package/dist/lib/session/db.js +0 -599
  442. package/dist/lib/session/db.js.map +0 -1
  443. package/dist/lib/session/discover.d.ts +0 -72
  444. package/dist/lib/session/discover.d.ts.map +0 -1
  445. package/dist/lib/session/discover.js +0 -1315
  446. package/dist/lib/session/discover.js.map +0 -1
  447. package/dist/lib/session/parse.d.ts +0 -34
  448. package/dist/lib/session/parse.d.ts.map +0 -1
  449. package/dist/lib/session/parse.js +0 -663
  450. package/dist/lib/session/parse.js.map +0 -1
  451. package/dist/lib/session/prompt.d.ts +0 -13
  452. package/dist/lib/session/prompt.d.ts.map +0 -1
  453. package/dist/lib/session/prompt.js +0 -79
  454. package/dist/lib/session/prompt.js.map +0 -1
  455. package/dist/lib/session/prompt.test.d.ts +0 -2
  456. package/dist/lib/session/prompt.test.d.ts.map +0 -1
  457. package/dist/lib/session/prompt.test.js +0 -57
  458. package/dist/lib/session/prompt.test.js.map +0 -1
  459. package/dist/lib/session/render.d.ts +0 -103
  460. package/dist/lib/session/render.d.ts.map +0 -1
  461. package/dist/lib/session/render.js +0 -798
  462. package/dist/lib/session/render.js.map +0 -1
  463. package/dist/lib/session/team-filter.d.ts +0 -35
  464. package/dist/lib/session/team-filter.d.ts.map +0 -1
  465. package/dist/lib/session/team-filter.js +0 -75
  466. package/dist/lib/session/team-filter.js.map +0 -1
  467. package/dist/lib/session/team-filter.test.d.ts +0 -2
  468. package/dist/lib/session/team-filter.test.d.ts.map +0 -1
  469. package/dist/lib/session/team-filter.test.js +0 -157
  470. package/dist/lib/session/team-filter.test.js.map +0 -1
  471. package/dist/lib/session/types.d.ts +0 -84
  472. package/dist/lib/session/types.d.ts.map +0 -1
  473. package/dist/lib/session/types.js +0 -11
  474. package/dist/lib/session/types.js.map +0 -1
  475. package/dist/lib/shims.d.ts +0 -272
  476. package/dist/lib/shims.d.ts.map +0 -1
  477. package/dist/lib/shims.js +0 -1322
  478. package/dist/lib/shims.js.map +0 -1
  479. package/dist/lib/skills.d.ts +0 -142
  480. package/dist/lib/skills.d.ts.map +0 -1
  481. package/dist/lib/skills.js +0 -791
  482. package/dist/lib/skills.js.map +0 -1
  483. package/dist/lib/state.d.ts +0 -87
  484. package/dist/lib/state.d.ts.map +0 -1
  485. package/dist/lib/state.js +0 -333
  486. package/dist/lib/state.js.map +0 -1
  487. package/dist/lib/subagents.d.ts +0 -84
  488. package/dist/lib/subagents.d.ts.map +0 -1
  489. package/dist/lib/subagents.js +0 -410
  490. package/dist/lib/subagents.js.map +0 -1
  491. package/dist/lib/teams/__tests__/oracle.test.d.ts +0 -2
  492. package/dist/lib/teams/__tests__/oracle.test.d.ts.map +0 -1
  493. package/dist/lib/teams/__tests__/oracle.test.js +0 -89
  494. package/dist/lib/teams/__tests__/oracle.test.js.map +0 -1
  495. package/dist/lib/teams/__tests__/supervisor.test.d.ts +0 -2
  496. package/dist/lib/teams/__tests__/supervisor.test.d.ts.map +0 -1
  497. package/dist/lib/teams/__tests__/supervisor.test.js +0 -179
  498. package/dist/lib/teams/__tests__/supervisor.test.js.map +0 -1
  499. package/dist/lib/teams/agents.d.ts +0 -247
  500. package/dist/lib/teams/agents.d.ts.map +0 -1
  501. package/dist/lib/teams/agents.js +0 -1244
  502. package/dist/lib/teams/agents.js.map +0 -1
  503. package/dist/lib/teams/api.d.ts +0 -91
  504. package/dist/lib/teams/api.d.ts.map +0 -1
  505. package/dist/lib/teams/api.js +0 -239
  506. package/dist/lib/teams/api.js.map +0 -1
  507. package/dist/lib/teams/cloud.d.ts +0 -11
  508. package/dist/lib/teams/cloud.d.ts.map +0 -1
  509. package/dist/lib/teams/cloud.js +0 -169
  510. package/dist/lib/teams/cloud.js.map +0 -1
  511. package/dist/lib/teams/debug.d.ts +0 -8
  512. package/dist/lib/teams/debug.d.ts.map +0 -1
  513. package/dist/lib/teams/debug.js +0 -12
  514. package/dist/lib/teams/debug.js.map +0 -1
  515. package/dist/lib/teams/file_ops.d.ts +0 -13
  516. package/dist/lib/teams/file_ops.d.ts.map +0 -1
  517. package/dist/lib/teams/file_ops.js +0 -66
  518. package/dist/lib/teams/file_ops.js.map +0 -1
  519. package/dist/lib/teams/index.d.ts +0 -16
  520. package/dist/lib/teams/index.d.ts.map +0 -1
  521. package/dist/lib/teams/index.js +0 -15
  522. package/dist/lib/teams/index.js.map +0 -1
  523. package/dist/lib/teams/oracle.d.ts +0 -20
  524. package/dist/lib/teams/oracle.d.ts.map +0 -1
  525. package/dist/lib/teams/oracle.js +0 -59
  526. package/dist/lib/teams/oracle.js.map +0 -1
  527. package/dist/lib/teams/parsers.d.ts +0 -9
  528. package/dist/lib/teams/parsers.d.ts.map +0 -1
  529. package/dist/lib/teams/parsers.js +0 -837
  530. package/dist/lib/teams/parsers.js.map +0 -1
  531. package/dist/lib/teams/persistence.d.ts +0 -43
  532. package/dist/lib/teams/persistence.d.ts.map +0 -1
  533. package/dist/lib/teams/persistence.js +0 -299
  534. package/dist/lib/teams/persistence.js.map +0 -1
  535. package/dist/lib/teams/ralph.d.ts +0 -8
  536. package/dist/lib/teams/ralph.d.ts.map +0 -1
  537. package/dist/lib/teams/ralph.js +0 -59
  538. package/dist/lib/teams/ralph.js.map +0 -1
  539. package/dist/lib/teams/registry.d.ts +0 -18
  540. package/dist/lib/teams/registry.d.ts.map +0 -1
  541. package/dist/lib/teams/registry.js +0 -68
  542. package/dist/lib/teams/registry.js.map +0 -1
  543. package/dist/lib/teams/summarizer.d.ts +0 -73
  544. package/dist/lib/teams/summarizer.d.ts.map +0 -1
  545. package/dist/lib/teams/summarizer.js +0 -780
  546. package/dist/lib/teams/summarizer.js.map +0 -1
  547. package/dist/lib/teams/supervisor.d.ts +0 -49
  548. package/dist/lib/teams/supervisor.d.ts.map +0 -1
  549. package/dist/lib/teams/supervisor.js +0 -74
  550. package/dist/lib/teams/supervisor.js.map +0 -1
  551. package/dist/lib/template.d.ts +0 -27
  552. package/dist/lib/template.d.ts.map +0 -1
  553. package/dist/lib/template.js +0 -60
  554. package/dist/lib/template.js.map +0 -1
  555. package/dist/lib/types.d.ts +0 -331
  556. package/dist/lib/types.d.ts.map +0 -1
  557. package/dist/lib/types.js +0 -29
  558. package/dist/lib/types.js.map +0 -1
  559. package/dist/lib/usage.d.ts +0 -105
  560. package/dist/lib/usage.d.ts.map +0 -1
  561. package/dist/lib/usage.js +0 -686
  562. package/dist/lib/usage.js.map +0 -1
  563. package/dist/lib/versions.d.ts +0 -253
  564. package/dist/lib/versions.d.ts.map +0 -1
  565. package/dist/lib/versions.js +0 -1796
  566. package/dist/lib/versions.js.map +0 -1
  567. package/scripts/rebuild-sqlite.sh +0 -46
@@ -1,1315 +0,0 @@
1
- /**
2
- * Session discovery across Claude, Codex, Gemini, OpenCode, and OpenClaw.
3
- *
4
- * Performs incremental scans: each agent's session files are stat'd and compared
5
- * to a scan-stamp ledger in SQLite. Only files whose mtime or size changed since
6
- * the last run are re-parsed. All metadata is upserted into the sessions DB so
7
- * subsequent queries are served entirely from the cache.
8
- */
9
- import * as fs from 'fs';
10
- import * as path from 'path';
11
- import * as os from 'os';
12
- import * as crypto from 'crypto';
13
- import * as readline from 'readline';
14
- import { execSync } from 'child_process';
15
- import { AGENTS, getCliVersion } from '../agents.js';
16
- import { getConfigSymlinkVersion } from '../shims.js';
17
- import { SESSION_AGENTS } from './types.js';
18
- import { extractSessionTopic } from './prompt.js';
19
- import { getDB, getScanStampByPath, getScanStampsForPaths, recordScans, syncLabels, upsertSessionsBatch, querySessions, countSessions, ftsSearch, } from './db.js';
20
- const HOME = os.homedir();
21
- const AGENTS_DIR = path.join(HOME, '.agents');
22
- /** How long OpenClaw channel/cron snapshots stay valid before we re-shell-out. */
23
- const OPENCLAW_TTL_MS = 60_000;
24
- let cachedOpenClawWorkspaces = null;
25
- const cachedAgentVersions = new Map();
26
- /**
27
- * Discover sessions. Scans only files whose (mtime, size) have changed since
28
- * the last run; everything else is served from the SQLite cache.
29
- */
30
- export async function discoverSessions(options) {
31
- // Touch the DB so the schema is ready and connection is cached for this run.
32
- getDB();
33
- const agents = options?.agent ? [options.agent] : SESSION_AGENTS;
34
- const onProgress = options?.onProgress;
35
- // Incrementally re-scan changed files across all selected agents in parallel.
36
- await Promise.all(agents.map(agent => {
37
- switch (agent) {
38
- case 'claude': return scanClaudeIncremental(onProgress);
39
- case 'codex': return scanCodexIncremental(onProgress);
40
- case 'gemini': return scanGeminiIncremental(onProgress);
41
- case 'opencode': return scanOpenCodeIncremental();
42
- case 'openclaw': return scanOpenClawIncremental();
43
- }
44
- }));
45
- const sessions = querySessions(buildQueryOptions(options, agents, { includeLimit: true }));
46
- return sessions;
47
- }
48
- /**
49
- * Count sessions in scope without running an incremental scan. Assumes the DB
50
- * is already fresh (typically true because `discoverSessions` ran first this
51
- * turn). Uses the exact same filter shape as the discover query.
52
- */
53
- export function countSessionsInScope(options) {
54
- const agents = options.agent ? [options.agent] : SESSION_AGENTS;
55
- return countSessions(buildQueryOptions(options, agents, { includeLimit: false }));
56
- }
57
- /** Translate DiscoverOptions into the QueryOptions shape expected by the DB layer. */
58
- function buildQueryOptions(options, agents, opts) {
59
- const projectQuery = options?.project?.trim();
60
- const sinceMs = options?.since ? parseTimeFilter(options.since) : undefined;
61
- const untilMs = options?.until ? new Date(options.until).getTime() : undefined;
62
- let cwdFilter;
63
- let cwdPrefixFilter;
64
- if (options?.cwdPrefix) {
65
- cwdPrefixFilter = normalizeCwd(options.cwdPrefix);
66
- }
67
- else if (!options?.all && !projectQuery) {
68
- cwdFilter = normalizeCwd(options?.cwd || process.cwd());
69
- }
70
- return {
71
- agent: options?.agent,
72
- agents: options?.agent ? undefined : agents,
73
- version: options?.version,
74
- cwd: cwdFilter,
75
- cwdPrefix: cwdPrefixFilter,
76
- project: projectQuery,
77
- sinceMs,
78
- untilMs: Number.isFinite(untilMs) ? untilMs : undefined,
79
- limit: opts.includeLimit ? (options?.limit ?? 50) : undefined,
80
- excludeTeamOrigin: options?.excludeTeamOrigin,
81
- onlyTeamOrigin: options?.onlyTeamOrigin,
82
- };
83
- }
84
- /** Resolve and canonicalize a working directory path (follows symlinks). */
85
- function normalizeCwd(cwd) {
86
- if (!cwd)
87
- return '';
88
- const resolved = path.resolve(cwd);
89
- return safeRealpathSync(resolved) || resolved;
90
- }
91
- /**
92
- * Resolve a session by full or short ID. Accepts a pre-loaded session list
93
- * (fast path from discoverSessions) and falls back to a DB lookup for the
94
- * "I only know the id" case.
95
- */
96
- export function resolveSessionById(sessions, idQuery) {
97
- const query = idQuery.toLowerCase();
98
- const exact = sessions.filter(s => s.id.toLowerCase() === query || s.shortId.toLowerCase() === query);
99
- if (exact.length > 0)
100
- return exact;
101
- return sessions.filter(s => s.id.toLowerCase().startsWith(query) || s.shortId.toLowerCase().startsWith(query));
102
- }
103
- // ---------------------------------------------------------------------------
104
- // Content-index search (FTS5-backed)
105
- // ---------------------------------------------------------------------------
106
- /**
107
- * Run an FTS5 search over the DB and intersect with the given session list,
108
- * preserving the existing SessionMeta[] contract so sessions.ts is unchanged.
109
- */
110
- export function searchContentIndex(sessions, query) {
111
- if (!query.trim())
112
- return new Map();
113
- const hits = ftsSearch(query);
114
- if (hits.length === 0)
115
- return new Map();
116
- const byId = new Map(sessions.map(s => [s.id, s]));
117
- const result = new Map();
118
- for (const hit of hits) {
119
- const session = byId.get(hit.sessionId);
120
- if (!session)
121
- continue;
122
- result.set(hit.sessionId, {
123
- ...session,
124
- _matchedTerms: hit.matchedTerms,
125
- _bm25Score: hit.score,
126
- });
127
- }
128
- return result;
129
- }
130
- // ---------------------------------------------------------------------------
131
- // Incremental scan orchestration
132
- // ---------------------------------------------------------------------------
133
- /**
134
- * For a list of files, stat each, compare to the DB ledger, and return only
135
- * the ones that need rescanning. One bulk DB query for the whole list.
136
- */
137
- function filterChangedFiles(filePaths) {
138
- const ledger = getScanStampsForPaths(filePaths);
139
- const out = [];
140
- for (const filePath of filePaths) {
141
- const stat = safeStatSync(filePath);
142
- if (!stat)
143
- continue;
144
- const scan = {
145
- fileMtimeMs: Math.floor(stat.mtimeMs),
146
- fileSize: stat.size,
147
- };
148
- const prev = ledger.get(filePath);
149
- if (prev && prev.fileMtimeMs === scan.fileMtimeMs && prev.fileSize === scan.fileSize) {
150
- continue;
151
- }
152
- out.push({ filePath, scan });
153
- }
154
- return out;
155
- }
156
- // ---------------------------------------------------------------------------
157
- // Multi-version directory scanning
158
- // ---------------------------------------------------------------------------
159
- /**
160
- * Collect all directories to scan for an agent's sessions. Deduplicates by
161
- * realpath to avoid double-counting symlinked version homes.
162
- */
163
- export function getAgentSessionDirs(agent, subdir) {
164
- const resolved = new Set();
165
- const dirs = [];
166
- function addDir(dir) {
167
- if (!fs.existsSync(dir))
168
- return;
169
- const real = safeRealpathSync(dir);
170
- const key = real || dir;
171
- if (resolved.has(key))
172
- return;
173
- resolved.add(key);
174
- dirs.push(dir);
175
- }
176
- addDir(path.join(HOME, `.${agent}`, subdir));
177
- const versionsBase = path.join(AGENTS_DIR, 'versions', agent);
178
- if (fs.existsSync(versionsBase)) {
179
- try {
180
- for (const version of fs.readdirSync(versionsBase)) {
181
- addDir(path.join(versionsBase, version, 'home', `.${agent}`, subdir));
182
- }
183
- }
184
- catch { /* dir unreadable */ }
185
- }
186
- const backupsBase = path.join(AGENTS_DIR, 'backups', agent);
187
- if (fs.existsSync(backupsBase)) {
188
- try {
189
- for (const ts of fs.readdirSync(backupsBase)) {
190
- addDir(path.join(backupsBase, ts, subdir));
191
- }
192
- }
193
- catch { /* dir unreadable */ }
194
- }
195
- return dirs;
196
- }
197
- // ---------------------------------------------------------------------------
198
- // Claude account info
199
- // ---------------------------------------------------------------------------
200
- let cachedClaudeAccount;
201
- /** Read the Claude OAuth account email from .claude.json across all version homes. */
202
- function getClaudeAccount() {
203
- if (cachedClaudeAccount !== undefined)
204
- return cachedClaudeAccount || undefined;
205
- // Claude's active config lives at $CLAUDE_CONFIG_DIR/.claude.json; for our shim
206
- // that's <version>/home/.claude/.claude.json. The home-level .claude.json is a
207
- // legacy path used when Claude runs without CLAUDE_CONFIG_DIR set.
208
- const candidates = [
209
- path.join(HOME, '.claude', '.claude.json'),
210
- path.join(HOME, '.claude.json'),
211
- ];
212
- const versionsBase = path.join(AGENTS_DIR, 'versions', 'claude');
213
- if (fs.existsSync(versionsBase)) {
214
- try {
215
- for (const version of fs.readdirSync(versionsBase)) {
216
- candidates.push(path.join(versionsBase, version, 'home', '.claude', '.claude.json'));
217
- candidates.push(path.join(versionsBase, version, 'home', '.claude.json'));
218
- }
219
- }
220
- catch { /* versions dir unreadable */ }
221
- }
222
- for (const candidate of candidates) {
223
- try {
224
- if (!fs.existsSync(candidate))
225
- continue;
226
- const data = JSON.parse(fs.readFileSync(candidate, 'utf-8'));
227
- const name = data.oauthAccount?.emailAddress || data.oauthAccount?.displayName;
228
- if (name) {
229
- cachedClaudeAccount = name;
230
- return name;
231
- }
232
- }
233
- catch { /* auth file unreadable or malformed */ }
234
- }
235
- cachedClaudeAccount = '';
236
- return undefined;
237
- }
238
- // ---------------------------------------------------------------------------
239
- // Claude
240
- // ---------------------------------------------------------------------------
241
- /**
242
- * Build a map of Claude sessionId -> user-given label from ~/.claude/sessions/*.json.
243
- * Each JSON has shape { pid, sessionId, cwd, startedAt, name?, ... }. The
244
- * `name` field only exists if the user ran /rename in that session.
245
- * For sessionId collisions (re-resume of the same session), prefer the most
246
- * recent startedAt.
247
- */
248
- function buildClaudeLabelMap() {
249
- const map = new Map();
250
- const dir = path.join(HOME, '.claude', 'sessions');
251
- if (!fs.existsSync(dir))
252
- return new Map();
253
- let files;
254
- try {
255
- files = fs.readdirSync(dir).filter(f => f.endsWith('.json'));
256
- }
257
- catch {
258
- return new Map();
259
- }
260
- for (const f of files) {
261
- try {
262
- const data = JSON.parse(fs.readFileSync(path.join(dir, f), 'utf-8'));
263
- if (typeof data.sessionId !== 'string')
264
- continue;
265
- const name = typeof data.name === 'string' && data.name.trim() ? data.name.trim() : null;
266
- const startedAt = typeof data.startedAt === 'number' ? data.startedAt : 0;
267
- const existing = map.get(data.sessionId);
268
- if (!existing || startedAt > existing.startedAt) {
269
- map.set(data.sessionId, { label: name, startedAt });
270
- }
271
- }
272
- catch { /* unreadable session metadata file */ }
273
- }
274
- const out = new Map();
275
- for (const [sid, { label }] of map)
276
- out.set(sid, label);
277
- return out;
278
- }
279
- /** Incrementally re-scan changed Claude session files and upsert into the DB. */
280
- async function scanClaudeIncremental(onProgress) {
281
- const account = getClaudeAccount();
282
- const labelMap = buildClaudeLabelMap();
283
- const filePaths = [];
284
- const seen = new Set();
285
- for (const projectsDir of getAgentSessionDirs('claude', 'projects')) {
286
- let projectDirs;
287
- try {
288
- projectDirs = fs.readdirSync(projectsDir);
289
- }
290
- catch {
291
- continue;
292
- }
293
- for (const dirName of projectDirs) {
294
- const dirPath = path.join(projectsDir, dirName);
295
- const stat = safeStatSync(dirPath);
296
- if (!stat?.isDirectory())
297
- continue;
298
- let files;
299
- try {
300
- files = fs.readdirSync(dirPath).filter(f => f.endsWith('.jsonl'));
301
- }
302
- catch {
303
- continue;
304
- }
305
- for (const file of files) {
306
- const sessionId = file.replace('.jsonl', '');
307
- if (seen.has(sessionId))
308
- continue;
309
- seen.add(sessionId);
310
- filePaths.push(path.join(dirPath, file));
311
- }
312
- }
313
- }
314
- const changed = filterChangedFiles(filePaths);
315
- if (changed.length > 0) {
316
- onProgress?.({ agent: 'claude', parsed: 0, total: changed.length });
317
- const entries = [];
318
- const touched = [];
319
- let parsed = 0;
320
- for (const { filePath, scan } of changed) {
321
- try {
322
- const sessionId = path.basename(filePath).replace('.jsonl', '');
323
- const label = labelMap.get(sessionId) ?? undefined;
324
- const result = await readClaudeMeta(filePath, sessionId, account, label);
325
- if (result) {
326
- entries.push({ meta: result.meta, content: result.content, scan });
327
- }
328
- else {
329
- touched.push({ filePath, scan });
330
- }
331
- }
332
- catch {
333
- touched.push({ filePath, scan });
334
- }
335
- parsed++;
336
- onProgress?.({ agent: 'claude', parsed, total: changed.length });
337
- }
338
- upsertSessionsBatch(entries);
339
- recordScans(touched);
340
- }
341
- // Pick up /rename changes on sessions whose JSONL didn't change.
342
- // Only bother for sessions we actually have a Claude row for.
343
- if (labelMap.size > 0)
344
- syncLabels(labelMap);
345
- }
346
- /** Stream-parse a single Claude JSONL file to extract session metadata. */
347
- async function readClaudeMeta(filePath, sessionId, account, label) {
348
- const scan = await scanClaudeSession(filePath);
349
- const isTeamOrigin = scan.entrypoint === 'sdk-cli';
350
- let meta;
351
- if (scan.timestamp) {
352
- const cwd = normalizeCwd(scan.cwd || '');
353
- meta = {
354
- id: sessionId,
355
- shortId: sessionId.slice(0, 8),
356
- agent: 'claude',
357
- timestamp: scan.timestamp,
358
- project: cwd ? path.basename(cwd) : undefined,
359
- cwd,
360
- filePath,
361
- gitBranch: scan.gitBranch,
362
- version: scan.version,
363
- account,
364
- topic: scan.topic,
365
- label,
366
- messageCount: scan.messageCount,
367
- tokenCount: scan.tokenCount,
368
- isTeamOrigin,
369
- };
370
- }
371
- else {
372
- const stat = safeStatSync(filePath);
373
- meta = {
374
- id: sessionId,
375
- shortId: sessionId.slice(0, 8),
376
- agent: 'claude',
377
- timestamp: stat ? stat.mtime.toISOString() : new Date().toISOString(),
378
- filePath,
379
- account,
380
- label,
381
- messageCount: scan.messageCount,
382
- tokenCount: scan.tokenCount,
383
- topic: scan.topic,
384
- isTeamOrigin,
385
- };
386
- }
387
- return { meta, content: scan.contentText || '' };
388
- }
389
- // ---------------------------------------------------------------------------
390
- // Codex account info
391
- // ---------------------------------------------------------------------------
392
- let cachedCodexAccount;
393
- /** Extract the Codex account email from the JWT id_token in auth.json. */
394
- function getCodexAccount() {
395
- if (cachedCodexAccount !== undefined)
396
- return cachedCodexAccount || undefined;
397
- const candidates = [path.join(HOME, '.codex', 'auth.json')];
398
- const versionsBase = path.join(AGENTS_DIR, 'versions', 'codex');
399
- if (fs.existsSync(versionsBase)) {
400
- try {
401
- for (const version of fs.readdirSync(versionsBase)) {
402
- candidates.push(path.join(versionsBase, version, 'home', '.codex', 'auth.json'));
403
- }
404
- }
405
- catch { /* versions dir unreadable */ }
406
- }
407
- for (const candidate of candidates) {
408
- try {
409
- if (!fs.existsSync(candidate))
410
- continue;
411
- const data = JSON.parse(fs.readFileSync(candidate, 'utf-8'));
412
- const idToken = data.tokens?.id_token;
413
- if (idToken) {
414
- const parts = idToken.split('.');
415
- if (parts.length >= 2) {
416
- const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8'));
417
- if (payload.email) {
418
- cachedCodexAccount = payload.email;
419
- return payload.email;
420
- }
421
- }
422
- }
423
- }
424
- catch { /* auth file or JWT malformed */ }
425
- }
426
- cachedCodexAccount = '';
427
- return undefined;
428
- }
429
- // ---------------------------------------------------------------------------
430
- // Codex
431
- // ---------------------------------------------------------------------------
432
- /** Incrementally re-scan changed Codex session files and upsert into the DB. */
433
- async function scanCodexIncremental(onProgress) {
434
- const account = getCodexAccount();
435
- const currentVersion = await getCurrentAgentVersion('codex');
436
- const filePaths = [];
437
- for (const sessionsDir of getAgentSessionDirs('codex', 'sessions')) {
438
- // High limit: we only stat files here, parsing is gated by ledger match.
439
- for (const fp of walkForFiles(sessionsDir, '.jsonl', 100_000)) {
440
- filePaths.push(fp);
441
- }
442
- }
443
- const changed = filterChangedFiles(filePaths);
444
- if (changed.length === 0)
445
- return;
446
- onProgress?.({ agent: 'codex', parsed: 0, total: changed.length });
447
- const entries = [];
448
- const touched = [];
449
- const seen = new Set();
450
- let parsed = 0;
451
- for (const { filePath, scan } of changed) {
452
- try {
453
- const result = await readCodexMeta(filePath, account, currentVersion);
454
- if (result && !seen.has(result.meta.id)) {
455
- seen.add(result.meta.id);
456
- entries.push({ meta: result.meta, content: result.content, scan });
457
- }
458
- else {
459
- touched.push({ filePath, scan });
460
- }
461
- }
462
- catch {
463
- touched.push({ filePath, scan });
464
- }
465
- parsed++;
466
- onProgress?.({ agent: 'codex', parsed, total: changed.length });
467
- }
468
- upsertSessionsBatch(entries);
469
- recordScans(touched);
470
- }
471
- /** Stream-parse a single Codex JSONL file to extract session metadata. */
472
- async function readCodexMeta(filePath, account, currentVersion) {
473
- const scan = await scanCodexSession(filePath);
474
- const sessionId = scan.sessionId || '';
475
- if (!sessionId)
476
- return null;
477
- const cwd = normalizeCwd(scan.cwd || '');
478
- const meta = {
479
- id: sessionId,
480
- shortId: sessionId.slice(0, 8),
481
- agent: 'codex',
482
- timestamp: scan.timestamp || new Date().toISOString(),
483
- project: cwd ? path.basename(cwd) : undefined,
484
- cwd,
485
- filePath,
486
- gitBranch: scan.gitBranch,
487
- version: resolveSessionVersion('codex', filePath, scan.version, currentVersion),
488
- topic: scan.topic,
489
- messageCount: scan.messageCount,
490
- tokenCount: scan.tokenCount,
491
- account,
492
- };
493
- return { meta, content: scan.contentText || '' };
494
- }
495
- // ---------------------------------------------------------------------------
496
- // Gemini
497
- // ---------------------------------------------------------------------------
498
- /** Incrementally re-scan changed Gemini session files and upsert into the DB. */
499
- async function scanGeminiIncremental(onProgress) {
500
- const currentVersion = await getCurrentAgentVersion('gemini');
501
- const projectMap = buildGeminiProjectMap();
502
- const filePaths = [];
503
- for (const tmpDir of getAgentSessionDirs('gemini', 'tmp')) {
504
- let hashDirs;
505
- try {
506
- hashDirs = fs.readdirSync(tmpDir);
507
- }
508
- catch {
509
- continue;
510
- }
511
- for (const hashDir of hashDirs) {
512
- const chatsDir = path.join(tmpDir, hashDir, 'chats');
513
- if (!fs.existsSync(chatsDir))
514
- continue;
515
- let chatFiles;
516
- try {
517
- chatFiles = fs.readdirSync(chatsDir).filter(f => f.endsWith('.json'));
518
- }
519
- catch {
520
- continue;
521
- }
522
- for (const file of chatFiles) {
523
- filePaths.push({ filePath: path.join(chatsDir, file), hashDir });
524
- }
525
- }
526
- }
527
- const changedPaths = filterChangedFiles(filePaths.map(f => f.filePath));
528
- const changedByPath = new Map(changedPaths.map(c => [c.filePath, c.scan]));
529
- if (changedByPath.size === 0)
530
- return;
531
- onProgress?.({ agent: 'gemini', parsed: 0, total: changedByPath.size });
532
- const entries = [];
533
- const touched = [];
534
- const seen = new Set();
535
- let parsed = 0;
536
- for (const { filePath, hashDir } of filePaths) {
537
- const scan = changedByPath.get(filePath);
538
- if (!scan)
539
- continue;
540
- try {
541
- const result = readGeminiMeta(filePath, hashDir, projectMap, currentVersion);
542
- if (result && !seen.has(result.meta.id)) {
543
- seen.add(result.meta.id);
544
- entries.push({ meta: result.meta, content: result.content, scan });
545
- }
546
- else {
547
- // Gemini file without a sessionId — record scan so we don't re-parse it next run.
548
- touched.push({ filePath, scan });
549
- }
550
- }
551
- catch {
552
- touched.push({ filePath, scan });
553
- }
554
- parsed++;
555
- onProgress?.({ agent: 'gemini', parsed, total: changedByPath.size });
556
- }
557
- upsertSessionsBatch(entries);
558
- recordScans(touched);
559
- }
560
- /** Parse a single Gemini JSON session file to extract session metadata. */
561
- function readGeminiMeta(filePath, hashDir, projectMap, currentVersion) {
562
- let session;
563
- try {
564
- session = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
565
- }
566
- catch {
567
- return null;
568
- }
569
- const sessionId = typeof session.sessionId === 'string' ? session.sessionId : '';
570
- const startTime = typeof session.startTime === 'string' ? session.startTime : '';
571
- const projectHash = typeof session.projectHash === 'string' ? session.projectHash : '';
572
- const embeddedVersion = typeof session.version === 'string'
573
- ? session.version
574
- : typeof session.cliVersion === 'string'
575
- ? session.cliVersion
576
- : undefined;
577
- if (!sessionId)
578
- return null;
579
- const projectInfo = projectMap.get(projectHash || hashDir);
580
- const project = projectInfo?.name || hashDir.slice(0, 12);
581
- const cwd = projectInfo?.path ? normalizeCwd(projectInfo.path) : undefined;
582
- const stat = safeStatSync(filePath);
583
- const messages = Array.isArray(session.messages) ? session.messages : [];
584
- let topic;
585
- let messageCount = 0;
586
- let tokenCount = 0;
587
- let sawTokenCount = false;
588
- const userTexts = [];
589
- for (const message of messages) {
590
- if (message.type === 'user') {
591
- const text = extractGeminiMessageText(message.content);
592
- if (text) {
593
- messageCount++;
594
- userTexts.push(text);
595
- if (!topic)
596
- topic = extractSessionTopic(text);
597
- }
598
- }
599
- else if (message.type === 'gemini') {
600
- if (extractGeminiMessageText(message.content)) {
601
- messageCount++;
602
- }
603
- }
604
- const total = getGeminiTokenCount(message.tokens);
605
- if (total !== null) {
606
- tokenCount += total;
607
- sawTokenCount = true;
608
- }
609
- }
610
- const meta = {
611
- id: sessionId,
612
- shortId: sessionId.slice(0, 8),
613
- agent: 'gemini',
614
- timestamp: startTime || (stat ? stat.mtime.toISOString() : new Date().toISOString()),
615
- project,
616
- cwd,
617
- filePath,
618
- version: resolveSessionVersion('gemini', filePath, embeddedVersion, currentVersion),
619
- topic,
620
- messageCount,
621
- tokenCount: sawTokenCount ? tokenCount : undefined,
622
- };
623
- return { meta, content: userTexts.join('\n') };
624
- }
625
- /** Build a hash-to-project mapping from Gemini's projects.json and history directories. */
626
- function buildGeminiProjectMap() {
627
- const map = new Map();
628
- const projectsJsonPath = path.join(HOME, '.gemini', 'projects.json');
629
- if (fs.existsSync(projectsJsonPath)) {
630
- try {
631
- const data = JSON.parse(fs.readFileSync(projectsJsonPath, 'utf-8'));
632
- const projects = data.projects;
633
- if (typeof projects === 'object' && projects !== null) {
634
- if (Array.isArray(projects)) {
635
- for (const p of projects) {
636
- if (typeof p === 'string') {
637
- const hash = sha256(p);
638
- map.set(hash, { name: path.basename(p), path: p });
639
- map.set(p, { name: path.basename(p), path: p });
640
- }
641
- }
642
- }
643
- else {
644
- for (const [p, name] of Object.entries(projects)) {
645
- const hash = sha256(p);
646
- map.set(hash, { name: String(name), path: p });
647
- }
648
- }
649
- }
650
- }
651
- catch { /* projects.json missing or malformed */ }
652
- }
653
- const historyDir = path.join(HOME, '.gemini', 'history');
654
- if (fs.existsSync(historyDir)) {
655
- try {
656
- for (const name of fs.readdirSync(historyDir)) {
657
- const rootFile = path.join(historyDir, name, '.project_root');
658
- if (fs.existsSync(rootFile)) {
659
- try {
660
- const projectPath = fs.readFileSync(rootFile, 'utf-8').trim();
661
- if (projectPath) {
662
- const hash = sha256(projectPath);
663
- map.set(hash, { name, path: projectPath });
664
- }
665
- }
666
- catch { /* history entry unreadable */ }
667
- }
668
- }
669
- }
670
- catch { /* history entry unreadable */ }
671
- }
672
- return map;
673
- }
674
- // ---------------------------------------------------------------------------
675
- // OpenCode
676
- // ---------------------------------------------------------------------------
677
- const OPENCODE_DB = path.join(HOME, '.local', 'share', 'opencode', 'opencode.db');
678
- let cachedOpenCodeAccount;
679
- /** Query the active OpenCode account email from its SQLite database. */
680
- function getOpenCodeAccount() {
681
- if (cachedOpenCodeAccount !== undefined)
682
- return cachedOpenCodeAccount || undefined;
683
- try {
684
- if (fs.existsSync(OPENCODE_DB)) {
685
- const out = execSync(`sqlite3 "${OPENCODE_DB}" "SELECT email FROM control_account WHERE active=1 LIMIT 1;"`, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
686
- if (out) {
687
- cachedOpenCodeAccount = out;
688
- return out;
689
- }
690
- }
691
- }
692
- catch { /* sqlite3 unavailable or DB locked */ }
693
- cachedOpenCodeAccount = '';
694
- return undefined;
695
- }
696
- /** Scan OpenCode sessions from its SQLite database when the DB file has changed. */
697
- async function scanOpenCodeIncremental() {
698
- if (!fs.existsSync(OPENCODE_DB))
699
- return;
700
- const stat = safeStatSync(OPENCODE_DB);
701
- if (!stat)
702
- return;
703
- // OpenCode is one big DB; we use its mtime/size as the ledger for the
704
- // entire fleet of OpenCode sessions.
705
- const currentScan = {
706
- fileMtimeMs: Math.floor(stat.mtimeMs),
707
- fileSize: stat.size,
708
- };
709
- const prev = getScanStampByPath(OPENCODE_DB);
710
- if (prev && prev.fileMtimeMs === currentScan.fileMtimeMs && prev.fileSize === currentScan.fileSize) {
711
- return;
712
- }
713
- const account = getOpenCodeAccount();
714
- const currentVersion = await getCurrentAgentVersion('opencode');
715
- try {
716
- const query = `
717
- SELECT
718
- s.id,
719
- s.title,
720
- s.directory,
721
- s.version,
722
- s.time_created,
723
- COALESCE(stats.message_count, 0),
724
- stats.token_count,
725
- COALESCE(stats.has_token_data, 0)
726
- FROM session s
727
- LEFT JOIN (
728
- SELECT
729
- session_id,
730
- COUNT(*) AS message_count,
731
- SUM(
732
- COALESCE(json_extract(data, '$.tokens.input'), 0) +
733
- COALESCE(json_extract(data, '$.tokens.output'), 0) +
734
- COALESCE(json_extract(data, '$.tokens.reasoning'), 0) +
735
- COALESCE(json_extract(data, '$.tokens.cache.read'), 0) +
736
- COALESCE(json_extract(data, '$.tokens.cache.write'), 0)
737
- ) AS token_count,
738
- MAX(CASE WHEN json_type(data, '$.tokens') IS NOT NULL THEN 1 ELSE 0 END) AS has_token_data
739
- FROM message
740
- GROUP BY session_id
741
- ) stats ON stats.session_id = s.id
742
- WHERE s.parent_id IS NULL
743
- ORDER BY time_created DESC
744
- LIMIT 1000;
745
- `.replace(/\n/g, ' ');
746
- const out = execSync(`sqlite3 -separator '|||' "${OPENCODE_DB}"`, { encoding: 'utf-8', input: query, stdio: ['pipe', 'pipe', 'ignore'], timeout: 5000 });
747
- const entries = [];
748
- for (const line of out.split('\n')) {
749
- if (!line.trim())
750
- continue;
751
- const [id, title, directory, version, timeCreatedStr, messageCountStr, tokenCountStr, hasTokenDataStr] = line.split('|||');
752
- if (!id)
753
- continue;
754
- const timeCreated = parseInt(timeCreatedStr, 10);
755
- const messageCount = parseInt(messageCountStr, 10);
756
- const tokenCount = parseInt(tokenCountStr, 10);
757
- const hasTokenData = hasTokenDataStr === '1';
758
- const timestamp = isNaN(timeCreated) ? new Date().toISOString() : new Date(timeCreated).toISOString();
759
- const topic = title || undefined;
760
- const meta = {
761
- id,
762
- shortId: id.replace(/^ses_/, '').slice(0, 8),
763
- agent: 'opencode',
764
- timestamp,
765
- project: directory ? path.basename(directory) : undefined,
766
- cwd: directory ? normalizeCwd(directory) : undefined,
767
- filePath: `${OPENCODE_DB}#${id}`,
768
- version: resolveSessionVersion('opencode', OPENCODE_DB, version || undefined, currentVersion),
769
- account,
770
- topic,
771
- messageCount: Number.isNaN(messageCount) ? undefined : messageCount,
772
- tokenCount: hasTokenData && !Number.isNaN(tokenCount) ? tokenCount : undefined,
773
- };
774
- entries.push({ meta, content: topic || '', scan: currentScan });
775
- }
776
- upsertSessionsBatch(entries);
777
- // Stamp the OpenCode DB itself so we can short-circuit on the next run.
778
- recordScans([{ filePath: OPENCODE_DB, scan: currentScan }]);
779
- }
780
- catch (err) {
781
- if (process.stderr.isTTY) {
782
- console.error(`Warning: Could not query OpenCode sessions: ${err.message}`);
783
- }
784
- }
785
- }
786
- // ---------------------------------------------------------------------------
787
- // OpenClaw
788
- // ---------------------------------------------------------------------------
789
- /** Scan active OpenClaw channels and cron jobs via the openclaw CLI. */
790
- async function scanOpenClawIncremental() {
791
- // Check if openclaw is installed — silently skip if not.
792
- try {
793
- execSync('which openclaw', { stdio: 'ignore' });
794
- }
795
- catch {
796
- return;
797
- }
798
- // TTL cache: skip subprocess calls if we scanned recently. Stored in the
799
- // meta table so we skip even when no channels/cron exist to produce rows.
800
- const db = getDB();
801
- const row = db.prepare(`SELECT value FROM meta WHERE key = 'openclaw_last_scan_ms'`).get();
802
- const lastScanMs = row ? parseInt(row.value, 10) : 0;
803
- if (lastScanMs && Date.now() - lastScanMs < OPENCLAW_TTL_MS) {
804
- return;
805
- }
806
- const currentVersion = await getCurrentAgentVersion('openclaw');
807
- const now = Date.now();
808
- const scan = { fileMtimeMs: now, fileSize: 0 };
809
- const entries = [];
810
- try {
811
- const output = execSync('openclaw channels status', {
812
- encoding: 'utf-8',
813
- stdio: ['ignore', 'pipe', 'ignore'],
814
- });
815
- for (const line of output.split('\n')) {
816
- const match = line.match(/^-\s+\w+\s+(\S+)\s+\((\w+)\):\s*(.+)/);
817
- if (!match)
818
- continue;
819
- const [, agentId, name, statusStr] = match;
820
- if (!statusStr.includes('running'))
821
- continue;
822
- entries.push({
823
- meta: {
824
- id: `openclaw-${agentId}`,
825
- shortId: agentId.slice(0, 8),
826
- agent: 'openclaw',
827
- timestamp: new Date().toISOString(),
828
- project: name,
829
- cwd: getOpenClawSessionCwd(agentId),
830
- version: currentVersion,
831
- filePath: '',
832
- },
833
- content: `${name} ${agentId}`,
834
- scan,
835
- });
836
- }
837
- }
838
- catch {
839
- /* channels command failed */
840
- }
841
- try {
842
- const output = execSync('openclaw cron list', {
843
- encoding: 'utf-8',
844
- stdio: ['ignore', 'pipe', 'ignore'],
845
- });
846
- const lines = output.split('\n');
847
- for (let i = 1; i < lines.length; i++) {
848
- const line = lines[i].trim();
849
- if (!line)
850
- continue;
851
- const headMatch = line.match(/^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\s+(\S+)/);
852
- if (!headMatch)
853
- continue;
854
- const jobId = headMatch[1];
855
- const jobName = headMatch[2];
856
- const rest = line.slice(headMatch[0].length).trim();
857
- const cols = rest.split(/\s{2,}/);
858
- const agentId = cols[4] || '';
859
- entries.push({
860
- meta: {
861
- id: `openclaw-cron-${jobId}`,
862
- shortId: jobId.slice(0, 8),
863
- agent: 'openclaw',
864
- timestamp: new Date().toISOString(),
865
- project: `${jobName} (${agentId || 'unknown'})`,
866
- cwd: getOpenClawSessionCwd(agentId),
867
- version: currentVersion,
868
- filePath: '',
869
- },
870
- content: `${jobName} ${agentId}`,
871
- scan,
872
- });
873
- }
874
- }
875
- catch {
876
- /* cron command failed */
877
- }
878
- upsertSessionsBatch(entries);
879
- db.prepare(`INSERT OR REPLACE INTO meta (key, value) VALUES ('openclaw_last_scan_ms', ?)`).run(String(Date.now()));
880
- }
881
- /** Stream a Claude JSONL file and extract scan-level metadata (timestamp, cwd, topic, tokens). */
882
- async function scanClaudeSession(filePath) {
883
- const stream = fs.createReadStream(filePath, { encoding: 'utf-8' });
884
- const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
885
- let timestamp;
886
- let cwd;
887
- let gitBranch;
888
- let version;
889
- let topic;
890
- let entrypoint;
891
- let messageCount = 0;
892
- let tokenCount = 0;
893
- let sawTokenCount = false;
894
- const seenAssistantIds = new Set();
895
- const userTexts = [];
896
- try {
897
- for await (const line of rl) {
898
- if (!line.trim())
899
- continue;
900
- let parsed;
901
- try {
902
- parsed = JSON.parse(line);
903
- }
904
- catch {
905
- continue;
906
- }
907
- // entrypoint ships on the first envelope event (attachment/user/assistant)
908
- // and is the clean structural signal for "was this a team spawn?"
909
- if (!entrypoint && typeof parsed.entrypoint === 'string') {
910
- entrypoint = parsed.entrypoint;
911
- }
912
- if (!timestamp && (parsed.type === 'user' || parsed.type === 'assistant') && parsed.timestamp) {
913
- timestamp = parsed.timestamp;
914
- cwd = parsed.cwd || '';
915
- gitBranch = parsed.gitBranch || undefined;
916
- version = parsed.version || undefined;
917
- }
918
- if (parsed.type === 'user') {
919
- const text = extractClaudeUserText(parsed);
920
- if (text) {
921
- messageCount++;
922
- userTexts.push(text);
923
- if (!topic)
924
- topic = extractSessionTopic(text);
925
- }
926
- continue;
927
- }
928
- if (parsed.type !== 'assistant')
929
- continue;
930
- const assistantId = typeof parsed.message?.id === 'string'
931
- ? parsed.message.id
932
- : typeof parsed.uuid === 'string'
933
- ? parsed.uuid
934
- : undefined;
935
- const logicalId = assistantId || `${parsed.timestamp || ''}:${seenAssistantIds.size}`;
936
- if (seenAssistantIds.has(logicalId))
937
- continue;
938
- seenAssistantIds.add(logicalId);
939
- messageCount++;
940
- const usage = getClaudeUsageTotal(parsed.message?.usage || parsed.usage);
941
- if (usage !== null) {
942
- tokenCount += usage;
943
- sawTokenCount = true;
944
- }
945
- }
946
- }
947
- finally {
948
- rl.close();
949
- stream.destroy();
950
- }
951
- return {
952
- timestamp,
953
- cwd,
954
- gitBranch,
955
- version,
956
- topic,
957
- entrypoint,
958
- messageCount,
959
- tokenCount: sawTokenCount ? tokenCount : undefined,
960
- contentText: userTexts.length > 0 ? userTexts.join('\n') : undefined,
961
- };
962
- }
963
- /** Stream a Codex JSONL file and extract scan-level metadata (session ID, cwd, topic, tokens). */
964
- async function scanCodexSession(filePath) {
965
- const stream = fs.createReadStream(filePath, { encoding: 'utf-8' });
966
- const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
967
- let sessionId;
968
- let timestamp;
969
- let cwd;
970
- let gitBranch;
971
- let version;
972
- let topic;
973
- let messageCount = 0;
974
- let tokenCount;
975
- const userTexts = [];
976
- try {
977
- for await (const line of rl) {
978
- if (!line.trim())
979
- continue;
980
- let parsed;
981
- try {
982
- parsed = JSON.parse(line);
983
- }
984
- catch {
985
- continue;
986
- }
987
- if (parsed.type === 'session_meta') {
988
- const payload = parsed.payload || {};
989
- sessionId = payload.id || sessionId;
990
- timestamp = payload.timestamp || parsed.timestamp || timestamp;
991
- cwd = payload.cwd || cwd;
992
- gitBranch = payload.git?.branch || gitBranch;
993
- version = payload.cli_version || payload.version || version;
994
- continue;
995
- }
996
- if (parsed.type === 'response_item' && parsed.payload?.type === 'message') {
997
- const role = parsed.payload.role === 'user' || parsed.payload.role === 'developer'
998
- ? 'user'
999
- : 'assistant';
1000
- const text = extractCodexMessageText(parsed.payload.content, role);
1001
- if (!text)
1002
- continue;
1003
- messageCount++;
1004
- if (role === 'user') {
1005
- userTexts.push(text);
1006
- if (!topic)
1007
- topic = extractSessionTopic(text);
1008
- }
1009
- continue;
1010
- }
1011
- if (parsed.type === 'event_msg' && parsed.payload?.type === 'token_count') {
1012
- const total = getCodexTokenCount(parsed.payload.info?.total_token_usage);
1013
- if (total !== null)
1014
- tokenCount = total;
1015
- }
1016
- }
1017
- }
1018
- finally {
1019
- rl.close();
1020
- stream.destroy();
1021
- }
1022
- return {
1023
- sessionId,
1024
- timestamp,
1025
- cwd,
1026
- gitBranch,
1027
- version,
1028
- topic,
1029
- messageCount,
1030
- tokenCount,
1031
- contentText: userTexts.length > 0 ? userTexts.join('\n') : undefined,
1032
- };
1033
- }
1034
- /** Resolve the working directory for an OpenClaw agent from its workspace config. */
1035
- function getOpenClawSessionCwd(agentId) {
1036
- const workspace = agentId ? getOpenClawWorkspaceMap().get(agentId) : undefined;
1037
- if (workspace)
1038
- return workspace;
1039
- const configDir = AGENTS.openclaw.configDir;
1040
- return safeRealpathSync(configDir) || configDir;
1041
- }
1042
- /** Build a cached map of OpenClaw agent ID to workspace path from openclaw.json. */
1043
- function getOpenClawWorkspaceMap() {
1044
- if (cachedOpenClawWorkspaces)
1045
- return cachedOpenClawWorkspaces;
1046
- const workspaces = new Map();
1047
- const configPath = path.join(AGENTS.openclaw.configDir, 'openclaw.json');
1048
- if (!fs.existsSync(configPath)) {
1049
- cachedOpenClawWorkspaces = workspaces;
1050
- return workspaces;
1051
- }
1052
- try {
1053
- const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
1054
- for (const agent of config.agents?.list || []) {
1055
- if (!agent.id || !agent.workspace)
1056
- continue;
1057
- workspaces.set(agent.id, safeRealpathSync(agent.workspace) || agent.workspace);
1058
- }
1059
- }
1060
- catch {
1061
- // Ignore invalid OpenClaw config and fall back to ~/.openclaw.
1062
- }
1063
- cachedOpenClawWorkspaces = workspaces;
1064
- return workspaces;
1065
- }
1066
- // ---------------------------------------------------------------------------
1067
- // Utilities
1068
- // ---------------------------------------------------------------------------
1069
- /** Read up to maxLines non-empty lines from the beginning of a file. */
1070
- export function readFirstLines(filePath, maxLines) {
1071
- return new Promise((resolve) => {
1072
- const lines = [];
1073
- const stream = fs.createReadStream(filePath, { encoding: 'utf-8' });
1074
- const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
1075
- rl.on('line', (line) => {
1076
- if (line.trim()) {
1077
- lines.push(line);
1078
- }
1079
- if (lines.length >= maxLines) {
1080
- rl.close();
1081
- stream.destroy();
1082
- }
1083
- });
1084
- rl.on('close', () => resolve(lines));
1085
- rl.on('error', () => resolve(lines));
1086
- });
1087
- }
1088
- /**
1089
- * Walk a directory recursively for files with a given extension.
1090
- */
1091
- export function walkForFiles(dir, ext, limit) {
1092
- const results = [];
1093
- function walk(d, depth) {
1094
- if (depth > 5)
1095
- return;
1096
- let entries;
1097
- try {
1098
- entries = fs.readdirSync(d);
1099
- }
1100
- catch {
1101
- return;
1102
- }
1103
- for (const entry of entries) {
1104
- const full = path.join(d, entry);
1105
- const stat = safeStatSync(full);
1106
- if (!stat)
1107
- continue;
1108
- if (stat.isDirectory()) {
1109
- walk(full, depth + 1);
1110
- }
1111
- else if (entry.endsWith(ext)) {
1112
- results.push({ path: full, mtime: stat.mtimeMs });
1113
- }
1114
- }
1115
- }
1116
- walk(dir, 0);
1117
- results.sort((a, b) => b.mtime - a.mtime);
1118
- return results.slice(0, limit).map(r => r.path);
1119
- }
1120
- /** Compute the SHA-256 hex digest of a string. */
1121
- function sha256(input) {
1122
- return crypto.createHash('sha256').update(input).digest('hex');
1123
- }
1124
- /** Stat a path, returning null on any error. */
1125
- function safeStatSync(p) {
1126
- try {
1127
- return fs.statSync(p);
1128
- }
1129
- catch {
1130
- return null;
1131
- }
1132
- }
1133
- /** Resolve a path to its real path, returning null on any error. */
1134
- function safeRealpathSync(p) {
1135
- try {
1136
- return fs.realpathSync(p);
1137
- }
1138
- catch {
1139
- return null;
1140
- }
1141
- }
1142
- /** Extract meaningful user text from a Claude JSONL user event, skipping meta and local-command messages. */
1143
- function extractClaudeUserText(parsed) {
1144
- if (parsed.isMeta === true)
1145
- return undefined;
1146
- const content = parsed.message?.content;
1147
- if (typeof content === 'string') {
1148
- const text = content.trim();
1149
- return isLocalCommandMessage(text) ? undefined : text || undefined;
1150
- }
1151
- if (!Array.isArray(content))
1152
- return undefined;
1153
- const text = content
1154
- .filter((block) => block.type === 'text')
1155
- .map((block) => String(block.text || '').trim())
1156
- .find((value) => value && !value.startsWith('[Request interrupted'));
1157
- if (!text || isLocalCommandMessage(text))
1158
- return undefined;
1159
- return text;
1160
- }
1161
- /** Check whether a message is a local-command wrapper rather than real user input. */
1162
- function isLocalCommandMessage(text) {
1163
- return /<local-command-caveat>|<bash-(input|stdout|stderr)>/i.test(text);
1164
- }
1165
- /** Sum all token usage fields from a Claude assistant message's usage object. */
1166
- function getClaudeUsageTotal(usage) {
1167
- if (!usage || typeof usage !== 'object')
1168
- return null;
1169
- return sumKnownNumbers([
1170
- usage.input_tokens,
1171
- usage.output_tokens,
1172
- usage.cache_creation_input_tokens,
1173
- usage.cache_read_input_tokens,
1174
- ]);
1175
- }
1176
- /** Extract text from Codex message content blocks, filtering out system instructions for user messages. */
1177
- function extractCodexMessageText(contentBlocks, role) {
1178
- if (!Array.isArray(contentBlocks))
1179
- return undefined;
1180
- const matches = role === 'user'
1181
- ? contentBlocks.filter((block) => block.type === 'input_text')
1182
- : contentBlocks.filter((block) => block.type === 'output_text');
1183
- const text = matches
1184
- .map((block) => String(block.text || '').trim())
1185
- .find((value) => {
1186
- if (!value)
1187
- return false;
1188
- if (role === 'user' && (value.length >= 2000 || value.includes('<permissions instructions>') || value.startsWith('# AGENTS.md instructions'))) {
1189
- return false;
1190
- }
1191
- return true;
1192
- });
1193
- return text || undefined;
1194
- }
1195
- /** Trim and normalize a version string, returning undefined for empty values. */
1196
- function normalizeVersion(version) {
1197
- const trimmed = version?.trim();
1198
- return trimmed ? trimmed : undefined;
1199
- }
1200
- /** Extract the version number from a managed ~/.agents/versions/<agent>/<version>/... path. */
1201
- function extractVersionFromManagedPath(agent, sourcePath) {
1202
- if (!sourcePath)
1203
- return undefined;
1204
- const candidates = [sourcePath, safeRealpathSync(sourcePath) || ''];
1205
- const marker = `/.agents/versions/${agent}/`;
1206
- for (const candidate of candidates) {
1207
- if (!candidate)
1208
- continue;
1209
- const normalized = candidate.split(path.sep).join('/');
1210
- const start = normalized.indexOf(marker);
1211
- if (start === -1)
1212
- continue;
1213
- const version = normalized.slice(start + marker.length).split('/')[0];
1214
- if (version)
1215
- return version;
1216
- }
1217
- return undefined;
1218
- }
1219
- /** Resolve the current version of an agent CLI (symlink version or live CLI output, cached). */
1220
- async function getCurrentAgentVersion(agent) {
1221
- const cached = cachedAgentVersions.get(agent);
1222
- if (cached)
1223
- return cached;
1224
- const promise = (async () => {
1225
- const symlinkVersion = normalizeVersion(getConfigSymlinkVersion(agent));
1226
- if (symlinkVersion)
1227
- return symlinkVersion;
1228
- return normalizeVersion(await getCliVersion(agent));
1229
- })();
1230
- cachedAgentVersions.set(agent, promise);
1231
- return promise;
1232
- }
1233
- /** Resolve a session's version: embedded in file > extracted from managed path > current CLI version. */
1234
- function resolveSessionVersion(agent, sourcePath, embeddedVersion, currentVersion) {
1235
- return normalizeVersion(embeddedVersion)
1236
- || extractVersionFromManagedPath(agent, sourcePath)
1237
- || normalizeVersion(currentVersion);
1238
- }
1239
- /** Sum all token usage fields from a Codex total_token_usage object. */
1240
- function getCodexTokenCount(totalTokenUsage) {
1241
- if (!totalTokenUsage || typeof totalTokenUsage !== 'object')
1242
- return null;
1243
- return sumKnownNumbers([
1244
- totalTokenUsage.input_tokens,
1245
- totalTokenUsage.cached_input_tokens,
1246
- totalTokenUsage.output_tokens,
1247
- totalTokenUsage.reasoning_output_tokens,
1248
- ]);
1249
- }
1250
- /** Extract text from a Gemini message content field (string or array of parts). */
1251
- function extractGeminiMessageText(content) {
1252
- if (typeof content === 'string')
1253
- return content.trim();
1254
- if (Array.isArray(content)) {
1255
- return content
1256
- .map((part) => {
1257
- if (typeof part === 'string')
1258
- return part;
1259
- if (typeof part?.text === 'string')
1260
- return part.text;
1261
- return '';
1262
- })
1263
- .join('\n')
1264
- .trim();
1265
- }
1266
- return '';
1267
- }
1268
- /** Extract the total token count from a Gemini message's tokens object. */
1269
- function getGeminiTokenCount(tokens) {
1270
- if (!tokens || typeof tokens !== 'object')
1271
- return null;
1272
- if (typeof tokens.total === 'number')
1273
- return tokens.total;
1274
- return sumKnownNumbers([
1275
- tokens.input,
1276
- tokens.output,
1277
- tokens.cached,
1278
- tokens.thoughts,
1279
- tokens.tool,
1280
- ]);
1281
- }
1282
- /** Sum all numeric values in an array, returning null if none are valid numbers. */
1283
- function sumKnownNumbers(values) {
1284
- let total = 0;
1285
- let found = false;
1286
- for (const value of values) {
1287
- if (typeof value !== 'number' || Number.isNaN(value))
1288
- continue;
1289
- total += value;
1290
- found = true;
1291
- }
1292
- return found ? total : null;
1293
- }
1294
- // ---------------------------------------------------------------------------
1295
- // Time range parsing
1296
- // ---------------------------------------------------------------------------
1297
- /** Parse a time filter string (relative like '7d' or ISO timestamp) into epoch milliseconds. */
1298
- export function parseTimeFilter(input) {
1299
- const relativeMatch = input.match(/^(\d+)([mhdw])$/i);
1300
- if (relativeMatch) {
1301
- const value = parseInt(relativeMatch[1], 10);
1302
- const unit = relativeMatch[2].toLowerCase();
1303
- if (unit === 'm')
1304
- return Date.now() - value * 60_000;
1305
- if (unit === 'h')
1306
- return Date.now() - value * 3_600_000;
1307
- if (unit === 'd')
1308
- return Date.now() - value * 86_400_000;
1309
- if (unit === 'w')
1310
- return Date.now() - value * 7 * 86_400_000;
1311
- }
1312
- const ts = new Date(input).getTime();
1313
- return Number.isNaN(ts) ? 0 : ts;
1314
- }
1315
- //# sourceMappingURL=discover.js.map