@code0123/opencode-android-arm64 1.1.55 → 1.1.56

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 (359) hide show
  1. package/bin/opencode +3 -1
  2. package/package.json +1 -77
  3. package/runtime/highlights-eq9cgrbb.scm +604 -0
  4. package/runtime/highlights-ghv9g403.scm +205 -0
  5. package/runtime/highlights-hk7bwhj4.scm +284 -0
  6. package/runtime/highlights-r812a2qc.scm +150 -0
  7. package/runtime/highlights-x6tmsnaa.scm +115 -0
  8. package/runtime/index.js +287124 -0
  9. package/runtime/injections-73j83es3.scm +27 -0
  10. package/runtime/parser.worker.js +4081 -0
  11. package/runtime/tree-sitter-3jzf13jk.wasm +0 -0
  12. package/runtime/tree-sitter-bash-hq5s6fxb.wasm +0 -0
  13. package/runtime/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  14. package/runtime/tree-sitter-markdown-411r6y9b.wasm +0 -0
  15. package/runtime/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  16. package/runtime/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  17. package/runtime/tree-sitter-zig-e78zbjpm.wasm +0 -0
  18. package/runtime/worker.js +208338 -0
  19. package/parsers-config.ts +0 -253
  20. package/src/acp/README.md +0 -164
  21. package/src/acp/agent.ts +0 -1676
  22. package/src/acp/session.ts +0 -117
  23. package/src/acp/types.ts +0 -23
  24. package/src/agent/agent.ts +0 -338
  25. package/src/agent/generate.txt +0 -75
  26. package/src/agent/prompt/compaction.txt +0 -12
  27. package/src/agent/prompt/explore.txt +0 -18
  28. package/src/agent/prompt/summary.txt +0 -11
  29. package/src/agent/prompt/title.txt +0 -44
  30. package/src/auth/index.ts +0 -70
  31. package/src/bun/index.ts +0 -137
  32. package/src/bun/registry.ts +0 -48
  33. package/src/bus/bus-event.ts +0 -43
  34. package/src/bus/global.ts +0 -10
  35. package/src/bus/index.ts +0 -105
  36. package/src/cli/bootstrap.ts +0 -17
  37. package/src/cli/cmd/acp.ts +0 -70
  38. package/src/cli/cmd/agent.ts +0 -257
  39. package/src/cli/cmd/auth.ts +0 -400
  40. package/src/cli/cmd/cmd.ts +0 -7
  41. package/src/cli/cmd/debug/agent.ts +0 -167
  42. package/src/cli/cmd/debug/config.ts +0 -16
  43. package/src/cli/cmd/debug/file.ts +0 -97
  44. package/src/cli/cmd/debug/index.ts +0 -48
  45. package/src/cli/cmd/debug/lsp.ts +0 -52
  46. package/src/cli/cmd/debug/ripgrep.ts +0 -87
  47. package/src/cli/cmd/debug/scrap.ts +0 -16
  48. package/src/cli/cmd/debug/skill.ts +0 -16
  49. package/src/cli/cmd/debug/snapshot.ts +0 -52
  50. package/src/cli/cmd/export.ts +0 -88
  51. package/src/cli/cmd/generate.ts +0 -38
  52. package/src/cli/cmd/github.ts +0 -1540
  53. package/src/cli/cmd/import.ts +0 -147
  54. package/src/cli/cmd/mcp.ts +0 -755
  55. package/src/cli/cmd/models.ts +0 -77
  56. package/src/cli/cmd/pr.ts +0 -112
  57. package/src/cli/cmd/run.ts +0 -598
  58. package/src/cli/cmd/serve.ts +0 -20
  59. package/src/cli/cmd/session.ts +0 -135
  60. package/src/cli/cmd/stats.ts +0 -426
  61. package/src/cli/cmd/tui/app.tsx +0 -801
  62. package/src/cli/cmd/tui/attach.ts +0 -52
  63. package/src/cli/cmd/tui/component/border.tsx +0 -21
  64. package/src/cli/cmd/tui/component/dialog-agent.tsx +0 -31
  65. package/src/cli/cmd/tui/component/dialog-command.tsx +0 -148
  66. package/src/cli/cmd/tui/component/dialog-mcp.tsx +0 -86
  67. package/src/cli/cmd/tui/component/dialog-model.tsx +0 -234
  68. package/src/cli/cmd/tui/component/dialog-provider.tsx +0 -266
  69. package/src/cli/cmd/tui/component/dialog-session-list.tsx +0 -108
  70. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +0 -31
  71. package/src/cli/cmd/tui/component/dialog-skill.tsx +0 -36
  72. package/src/cli/cmd/tui/component/dialog-stash.tsx +0 -87
  73. package/src/cli/cmd/tui/component/dialog-status.tsx +0 -177
  74. package/src/cli/cmd/tui/component/dialog-tag.tsx +0 -44
  75. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +0 -50
  76. package/src/cli/cmd/tui/component/logo.tsx +0 -85
  77. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +0 -666
  78. package/src/cli/cmd/tui/component/prompt/frecency.tsx +0 -89
  79. package/src/cli/cmd/tui/component/prompt/history.tsx +0 -108
  80. package/src/cli/cmd/tui/component/prompt/index.tsx +0 -1132
  81. package/src/cli/cmd/tui/component/prompt/stash.tsx +0 -101
  82. package/src/cli/cmd/tui/component/spinner.tsx +0 -24
  83. package/src/cli/cmd/tui/component/textarea-keybindings.ts +0 -73
  84. package/src/cli/cmd/tui/component/tips.tsx +0 -153
  85. package/src/cli/cmd/tui/component/todo-item.tsx +0 -32
  86. package/src/cli/cmd/tui/context/args.tsx +0 -15
  87. package/src/cli/cmd/tui/context/directory.ts +0 -13
  88. package/src/cli/cmd/tui/context/exit.tsx +0 -52
  89. package/src/cli/cmd/tui/context/helper.tsx +0 -25
  90. package/src/cli/cmd/tui/context/keybind.tsx +0 -100
  91. package/src/cli/cmd/tui/context/kv.tsx +0 -52
  92. package/src/cli/cmd/tui/context/local.tsx +0 -409
  93. package/src/cli/cmd/tui/context/prompt.tsx +0 -18
  94. package/src/cli/cmd/tui/context/route.tsx +0 -46
  95. package/src/cli/cmd/tui/context/sdk.tsx +0 -101
  96. package/src/cli/cmd/tui/context/sync.tsx +0 -470
  97. package/src/cli/cmd/tui/context/theme/aura.json +0 -69
  98. package/src/cli/cmd/tui/context/theme/ayu.json +0 -80
  99. package/src/cli/cmd/tui/context/theme/carbonfox.json +0 -248
  100. package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +0 -233
  101. package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +0 -233
  102. package/src/cli/cmd/tui/context/theme/catppuccin.json +0 -112
  103. package/src/cli/cmd/tui/context/theme/cobalt2.json +0 -228
  104. package/src/cli/cmd/tui/context/theme/cursor.json +0 -249
  105. package/src/cli/cmd/tui/context/theme/dracula.json +0 -219
  106. package/src/cli/cmd/tui/context/theme/everforest.json +0 -241
  107. package/src/cli/cmd/tui/context/theme/flexoki.json +0 -237
  108. package/src/cli/cmd/tui/context/theme/github.json +0 -233
  109. package/src/cli/cmd/tui/context/theme/gruvbox.json +0 -242
  110. package/src/cli/cmd/tui/context/theme/kanagawa.json +0 -77
  111. package/src/cli/cmd/tui/context/theme/lucent-orng.json +0 -237
  112. package/src/cli/cmd/tui/context/theme/material.json +0 -235
  113. package/src/cli/cmd/tui/context/theme/matrix.json +0 -77
  114. package/src/cli/cmd/tui/context/theme/mercury.json +0 -252
  115. package/src/cli/cmd/tui/context/theme/monokai.json +0 -221
  116. package/src/cli/cmd/tui/context/theme/nightowl.json +0 -221
  117. package/src/cli/cmd/tui/context/theme/nord.json +0 -223
  118. package/src/cli/cmd/tui/context/theme/one-dark.json +0 -84
  119. package/src/cli/cmd/tui/context/theme/opencode.json +0 -245
  120. package/src/cli/cmd/tui/context/theme/orng.json +0 -249
  121. package/src/cli/cmd/tui/context/theme/osaka-jade.json +0 -93
  122. package/src/cli/cmd/tui/context/theme/palenight.json +0 -222
  123. package/src/cli/cmd/tui/context/theme/rosepine.json +0 -234
  124. package/src/cli/cmd/tui/context/theme/solarized.json +0 -223
  125. package/src/cli/cmd/tui/context/theme/synthwave84.json +0 -226
  126. package/src/cli/cmd/tui/context/theme/tokyonight.json +0 -243
  127. package/src/cli/cmd/tui/context/theme/vercel.json +0 -245
  128. package/src/cli/cmd/tui/context/theme/vesper.json +0 -218
  129. package/src/cli/cmd/tui/context/theme/zenburn.json +0 -223
  130. package/src/cli/cmd/tui/context/theme.tsx +0 -1152
  131. package/src/cli/cmd/tui/event.ts +0 -48
  132. package/src/cli/cmd/tui/routes/home.tsx +0 -140
  133. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +0 -64
  134. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +0 -109
  135. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +0 -26
  136. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +0 -47
  137. package/src/cli/cmd/tui/routes/session/footer.tsx +0 -91
  138. package/src/cli/cmd/tui/routes/session/header.tsx +0 -142
  139. package/src/cli/cmd/tui/routes/session/index.tsx +0 -2126
  140. package/src/cli/cmd/tui/routes/session/permission.tsx +0 -508
  141. package/src/cli/cmd/tui/routes/session/question.tsx +0 -466
  142. package/src/cli/cmd/tui/routes/session/sidebar.tsx +0 -313
  143. package/src/cli/cmd/tui/thread.ts +0 -175
  144. package/src/cli/cmd/tui/ui/dialog-alert.tsx +0 -68
  145. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +0 -93
  146. package/src/cli/cmd/tui/ui/dialog-export-options.tsx +0 -215
  147. package/src/cli/cmd/tui/ui/dialog-help.tsx +0 -49
  148. package/src/cli/cmd/tui/ui/dialog-prompt.tsx +0 -88
  149. package/src/cli/cmd/tui/ui/dialog-select.tsx +0 -399
  150. package/src/cli/cmd/tui/ui/dialog.tsx +0 -167
  151. package/src/cli/cmd/tui/ui/link.tsx +0 -28
  152. package/src/cli/cmd/tui/ui/spinner.ts +0 -368
  153. package/src/cli/cmd/tui/ui/toast.tsx +0 -100
  154. package/src/cli/cmd/tui/util/clipboard.ts +0 -159
  155. package/src/cli/cmd/tui/util/editor.ts +0 -32
  156. package/src/cli/cmd/tui/util/signal.ts +0 -7
  157. package/src/cli/cmd/tui/util/terminal.ts +0 -114
  158. package/src/cli/cmd/tui/util/transcript.ts +0 -98
  159. package/src/cli/cmd/tui/worker.ts +0 -152
  160. package/src/cli/cmd/uninstall.ts +0 -357
  161. package/src/cli/cmd/upgrade.ts +0 -73
  162. package/src/cli/cmd/web.ts +0 -81
  163. package/src/cli/error.ts +0 -57
  164. package/src/cli/logo.ts +0 -6
  165. package/src/cli/network.ts +0 -60
  166. package/src/cli/ui.ts +0 -113
  167. package/src/cli/upgrade.ts +0 -25
  168. package/src/command/index.ts +0 -150
  169. package/src/command/template/initialize.txt +0 -10
  170. package/src/command/template/review.txt +0 -99
  171. package/src/config/config.ts +0 -1477
  172. package/src/config/markdown.ts +0 -98
  173. package/src/env/index.ts +0 -28
  174. package/src/file/ignore.ts +0 -83
  175. package/src/file/index.ts +0 -583
  176. package/src/file/ripgrep.ts +0 -384
  177. package/src/file/time.ts +0 -69
  178. package/src/file/watcher.ts +0 -148
  179. package/src/flag/flag.ts +0 -93
  180. package/src/format/formatter.ts +0 -366
  181. package/src/format/index.ts +0 -137
  182. package/src/global/index.ts +0 -55
  183. package/src/id/id.ts +0 -83
  184. package/src/ide/index.ts +0 -76
  185. package/src/index.ts +0 -159
  186. package/src/installation/index.ts +0 -246
  187. package/src/lsp/client.ts +0 -252
  188. package/src/lsp/index.ts +0 -485
  189. package/src/lsp/language.ts +0 -119
  190. package/src/lsp/server.ts +0 -2046
  191. package/src/mcp/auth.ts +0 -132
  192. package/src/mcp/index.ts +0 -934
  193. package/src/mcp/oauth-callback.ts +0 -200
  194. package/src/mcp/oauth-provider.ts +0 -154
  195. package/src/patch/index.ts +0 -680
  196. package/src/permission/arity.ts +0 -163
  197. package/src/permission/index.ts +0 -210
  198. package/src/permission/next.ts +0 -280
  199. package/src/plugin/codex.ts +0 -624
  200. package/src/plugin/copilot.ts +0 -327
  201. package/src/plugin/index.ts +0 -138
  202. package/src/project/bootstrap.ts +0 -35
  203. package/src/project/instance.ts +0 -114
  204. package/src/project/project.ts +0 -371
  205. package/src/project/state.ts +0 -70
  206. package/src/project/vcs.ts +0 -76
  207. package/src/provider/auth.ts +0 -147
  208. package/src/provider/models-snapshot.ts +0 -38414
  209. package/src/provider/models.ts +0 -133
  210. package/src/provider/provider.ts +0 -1262
  211. package/src/provider/sdk/copilot/README.md +0 -5
  212. package/src/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts +0 -164
  213. package/src/provider/sdk/copilot/chat/get-response-metadata.ts +0 -15
  214. package/src/provider/sdk/copilot/chat/map-openai-compatible-finish-reason.ts +0 -17
  215. package/src/provider/sdk/copilot/chat/openai-compatible-api-types.ts +0 -64
  216. package/src/provider/sdk/copilot/chat/openai-compatible-chat-language-model.ts +0 -780
  217. package/src/provider/sdk/copilot/chat/openai-compatible-chat-options.ts +0 -28
  218. package/src/provider/sdk/copilot/chat/openai-compatible-metadata-extractor.ts +0 -44
  219. package/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts +0 -87
  220. package/src/provider/sdk/copilot/copilot-provider.ts +0 -100
  221. package/src/provider/sdk/copilot/index.ts +0 -2
  222. package/src/provider/sdk/copilot/openai-compatible-error.ts +0 -27
  223. package/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.ts +0 -303
  224. package/src/provider/sdk/copilot/responses/map-openai-responses-finish-reason.ts +0 -22
  225. package/src/provider/sdk/copilot/responses/openai-config.ts +0 -18
  226. package/src/provider/sdk/copilot/responses/openai-error.ts +0 -22
  227. package/src/provider/sdk/copilot/responses/openai-responses-api-types.ts +0 -207
  228. package/src/provider/sdk/copilot/responses/openai-responses-language-model.ts +0 -1732
  229. package/src/provider/sdk/copilot/responses/openai-responses-prepare-tools.ts +0 -177
  230. package/src/provider/sdk/copilot/responses/openai-responses-settings.ts +0 -1
  231. package/src/provider/sdk/copilot/responses/tool/code-interpreter.ts +0 -88
  232. package/src/provider/sdk/copilot/responses/tool/file-search.ts +0 -128
  233. package/src/provider/sdk/copilot/responses/tool/image-generation.ts +0 -115
  234. package/src/provider/sdk/copilot/responses/tool/local-shell.ts +0 -65
  235. package/src/provider/sdk/copilot/responses/tool/web-search-preview.ts +0 -104
  236. package/src/provider/sdk/copilot/responses/tool/web-search.ts +0 -103
  237. package/src/provider/transform.ts +0 -828
  238. package/src/pty/index.ts +0 -250
  239. package/src/question/index.ts +0 -171
  240. package/src/scheduler/index.ts +0 -61
  241. package/src/server/error.ts +0 -36
  242. package/src/server/event.ts +0 -7
  243. package/src/server/mdns.ts +0 -60
  244. package/src/server/routes/config.ts +0 -92
  245. package/src/server/routes/experimental.ts +0 -208
  246. package/src/server/routes/file.ts +0 -197
  247. package/src/server/routes/global.ts +0 -183
  248. package/src/server/routes/mcp.ts +0 -225
  249. package/src/server/routes/permission.ts +0 -68
  250. package/src/server/routes/project.ts +0 -82
  251. package/src/server/routes/provider.ts +0 -165
  252. package/src/server/routes/pty.ts +0 -169
  253. package/src/server/routes/question.ts +0 -98
  254. package/src/server/routes/session.ts +0 -939
  255. package/src/server/routes/tui.ts +0 -379
  256. package/src/server/server.ts +0 -613
  257. package/src/session/compaction.ts +0 -226
  258. package/src/session/index.ts +0 -517
  259. package/src/session/instruction.ts +0 -197
  260. package/src/session/llm.ts +0 -289
  261. package/src/session/message-v2.ts +0 -802
  262. package/src/session/message.ts +0 -189
  263. package/src/session/processor.ts +0 -407
  264. package/src/session/prompt/anthropic-20250930.txt +0 -166
  265. package/src/session/prompt/anthropic.txt +0 -105
  266. package/src/session/prompt/beast.txt +0 -147
  267. package/src/session/prompt/build-switch.txt +0 -5
  268. package/src/session/prompt/codex_header.txt +0 -79
  269. package/src/session/prompt/copilot-gpt-5.txt +0 -143
  270. package/src/session/prompt/gemini.txt +0 -155
  271. package/src/session/prompt/max-steps.txt +0 -16
  272. package/src/session/prompt/plan-reminder-anthropic.txt +0 -67
  273. package/src/session/prompt/plan.txt +0 -26
  274. package/src/session/prompt/qwen.txt +0 -109
  275. package/src/session/prompt/trinity.txt +0 -97
  276. package/src/session/prompt.ts +0 -1866
  277. package/src/session/retry.ts +0 -97
  278. package/src/session/revert.ts +0 -121
  279. package/src/session/status.ts +0 -76
  280. package/src/session/summary.ts +0 -217
  281. package/src/session/system.ts +0 -54
  282. package/src/session/todo.ts +0 -37
  283. package/src/share/share-next.ts +0 -200
  284. package/src/share/share.ts +0 -92
  285. package/src/shell/shell.ts +0 -67
  286. package/src/skill/discovery.ts +0 -97
  287. package/src/skill/index.ts +0 -1
  288. package/src/skill/skill.ts +0 -188
  289. package/src/snapshot/index.ts +0 -255
  290. package/src/storage/storage.ts +0 -227
  291. package/src/tool/apply_patch.ts +0 -281
  292. package/src/tool/apply_patch.txt +0 -33
  293. package/src/tool/bash.ts +0 -269
  294. package/src/tool/bash.txt +0 -115
  295. package/src/tool/batch.ts +0 -175
  296. package/src/tool/batch.txt +0 -24
  297. package/src/tool/codesearch.ts +0 -132
  298. package/src/tool/codesearch.txt +0 -12
  299. package/src/tool/edit.ts +0 -655
  300. package/src/tool/edit.txt +0 -10
  301. package/src/tool/external-directory.ts +0 -32
  302. package/src/tool/glob.ts +0 -78
  303. package/src/tool/glob.txt +0 -6
  304. package/src/tool/grep.ts +0 -147
  305. package/src/tool/grep.txt +0 -8
  306. package/src/tool/invalid.ts +0 -17
  307. package/src/tool/ls.ts +0 -121
  308. package/src/tool/ls.txt +0 -1
  309. package/src/tool/lsp.ts +0 -96
  310. package/src/tool/lsp.txt +0 -19
  311. package/src/tool/multiedit.ts +0 -46
  312. package/src/tool/multiedit.txt +0 -41
  313. package/src/tool/plan-enter.txt +0 -14
  314. package/src/tool/plan-exit.txt +0 -13
  315. package/src/tool/plan.ts +0 -130
  316. package/src/tool/question.ts +0 -33
  317. package/src/tool/question.txt +0 -10
  318. package/src/tool/read.ts +0 -211
  319. package/src/tool/read.txt +0 -12
  320. package/src/tool/registry.ts +0 -160
  321. package/src/tool/skill.ts +0 -123
  322. package/src/tool/task.ts +0 -165
  323. package/src/tool/task.txt +0 -60
  324. package/src/tool/todo.ts +0 -53
  325. package/src/tool/todoread.txt +0 -14
  326. package/src/tool/todowrite.txt +0 -167
  327. package/src/tool/tool.ts +0 -89
  328. package/src/tool/truncation.ts +0 -106
  329. package/src/tool/webfetch.ts +0 -186
  330. package/src/tool/webfetch.txt +0 -13
  331. package/src/tool/websearch.ts +0 -150
  332. package/src/tool/websearch.txt +0 -14
  333. package/src/tool/write.ts +0 -85
  334. package/src/tool/write.txt +0 -8
  335. package/src/util/abort.ts +0 -35
  336. package/src/util/archive.ts +0 -16
  337. package/src/util/color.ts +0 -19
  338. package/src/util/context.ts +0 -25
  339. package/src/util/defer.ts +0 -12
  340. package/src/util/eventloop.ts +0 -20
  341. package/src/util/filesystem.ts +0 -93
  342. package/src/util/fn.ts +0 -11
  343. package/src/util/format.ts +0 -20
  344. package/src/util/iife.ts +0 -3
  345. package/src/util/keybind.ts +0 -103
  346. package/src/util/lazy.ts +0 -18
  347. package/src/util/locale.ts +0 -81
  348. package/src/util/lock.ts +0 -98
  349. package/src/util/log.ts +0 -180
  350. package/src/util/proxied.ts +0 -3
  351. package/src/util/queue.ts +0 -32
  352. package/src/util/rpc.ts +0 -66
  353. package/src/util/scrap.ts +0 -10
  354. package/src/util/signal.ts +0 -12
  355. package/src/util/timeout.ts +0 -14
  356. package/src/util/token.ts +0 -7
  357. package/src/util/wildcard.ts +0 -56
  358. package/src/worktree/index.ts +0 -574
  359. package/tsconfig.json +0 -10
@@ -1,135 +0,0 @@
1
- import type { Argv } from "yargs"
2
- import { cmd } from "./cmd"
3
- import { Session } from "../../session"
4
- import { bootstrap } from "../bootstrap"
5
- import { UI } from "../ui"
6
- import { Locale } from "../../util/locale"
7
- import { Flag } from "../../flag/flag"
8
- import { EOL } from "os"
9
- import path from "path"
10
-
11
- function pagerCmd(): string[] {
12
- const lessOptions = ["-R", "-S"]
13
- if (process.platform !== "win32") {
14
- return ["less", ...lessOptions]
15
- }
16
-
17
- // user could have less installed via other options
18
- const lessOnPath = Bun.which("less")
19
- if (lessOnPath) {
20
- if (Bun.file(lessOnPath).size) return [lessOnPath, ...lessOptions]
21
- }
22
-
23
- if (Flag.OPENCODE_GIT_BASH_PATH) {
24
- const less = path.join(Flag.OPENCODE_GIT_BASH_PATH, "..", "..", "usr", "bin", "less.exe")
25
- if (Bun.file(less).size) return [less, ...lessOptions]
26
- }
27
-
28
- const git = Bun.which("git")
29
- if (git) {
30
- const less = path.join(git, "..", "..", "usr", "bin", "less.exe")
31
- if (Bun.file(less).size) return [less, ...lessOptions]
32
- }
33
-
34
- // Fall back to Windows built-in more (via cmd.exe)
35
- return ["cmd", "/c", "more"]
36
- }
37
-
38
- export const SessionCommand = cmd({
39
- command: "session",
40
- describe: "manage sessions",
41
- builder: (yargs: Argv) => yargs.command(SessionListCommand).demandCommand(),
42
- async handler() {},
43
- })
44
-
45
- export const SessionListCommand = cmd({
46
- command: "list",
47
- describe: "list sessions",
48
- builder: (yargs: Argv) => {
49
- return yargs
50
- .option("max-count", {
51
- alias: "n",
52
- describe: "limit to N most recent sessions",
53
- type: "number",
54
- })
55
- .option("format", {
56
- describe: "output format",
57
- type: "string",
58
- choices: ["table", "json"],
59
- default: "table",
60
- })
61
- },
62
- handler: async (args) => {
63
- await bootstrap(process.cwd(), async () => {
64
- const sessions = []
65
- for await (const session of Session.list()) {
66
- if (!session.parentID) {
67
- sessions.push(session)
68
- }
69
- }
70
-
71
- sessions.sort((a, b) => b.time.updated - a.time.updated)
72
-
73
- const limitedSessions = args.maxCount ? sessions.slice(0, args.maxCount) : sessions
74
-
75
- if (limitedSessions.length === 0) {
76
- return
77
- }
78
-
79
- let output: string
80
- if (args.format === "json") {
81
- output = formatSessionJSON(limitedSessions)
82
- } else {
83
- output = formatSessionTable(limitedSessions)
84
- }
85
-
86
- const shouldPaginate = process.stdout.isTTY && !args.maxCount && args.format === "table"
87
-
88
- if (shouldPaginate) {
89
- const proc = Bun.spawn({
90
- cmd: pagerCmd(),
91
- stdin: "pipe",
92
- stdout: "inherit",
93
- stderr: "inherit",
94
- })
95
-
96
- proc.stdin.write(output)
97
- proc.stdin.end()
98
- await proc.exited
99
- } else {
100
- console.log(output)
101
- }
102
- })
103
- },
104
- })
105
-
106
- function formatSessionTable(sessions: Session.Info[]): string {
107
- const lines: string[] = []
108
-
109
- const maxIdWidth = Math.max(20, ...sessions.map((s) => s.id.length))
110
- const maxTitleWidth = Math.max(25, ...sessions.map((s) => s.title.length))
111
-
112
- const header = `Session ID${" ".repeat(maxIdWidth - 10)} Title${" ".repeat(maxTitleWidth - 5)} Updated`
113
- lines.push(header)
114
- lines.push("─".repeat(header.length))
115
- for (const session of sessions) {
116
- const truncatedTitle = Locale.truncate(session.title, maxTitleWidth)
117
- const timeStr = Locale.todayTimeOrDateTime(session.time.updated)
118
- const line = `${session.id.padEnd(maxIdWidth)} ${truncatedTitle.padEnd(maxTitleWidth)} ${timeStr}`
119
- lines.push(line)
120
- }
121
-
122
- return lines.join(EOL)
123
- }
124
-
125
- function formatSessionJSON(sessions: Session.Info[]): string {
126
- const jsonData = sessions.map((session) => ({
127
- id: session.id,
128
- title: session.title,
129
- updated: session.time.updated,
130
- created: session.time.created,
131
- projectId: session.projectID,
132
- directory: session.directory,
133
- }))
134
- return JSON.stringify(jsonData, null, 2)
135
- }
@@ -1,426 +0,0 @@
1
- import type { Argv } from "yargs"
2
- import { cmd } from "./cmd"
3
- import { Session } from "../../session"
4
- import { bootstrap } from "../bootstrap"
5
- import { Storage } from "../../storage/storage"
6
- import { Project } from "../../project/project"
7
- import { Instance } from "../../project/instance"
8
-
9
- interface SessionStats {
10
- totalSessions: number
11
- totalMessages: number
12
- totalCost: number
13
- totalTokens: {
14
- input: number
15
- output: number
16
- reasoning: number
17
- cache: {
18
- read: number
19
- write: number
20
- }
21
- }
22
- toolUsage: Record<string, number>
23
- modelUsage: Record<
24
- string,
25
- {
26
- messages: number
27
- tokens: {
28
- input: number
29
- output: number
30
- cache: {
31
- read: number
32
- write: number
33
- }
34
- }
35
- cost: number
36
- }
37
- >
38
- dateRange: {
39
- earliest: number
40
- latest: number
41
- }
42
- days: number
43
- costPerDay: number
44
- tokensPerSession: number
45
- medianTokensPerSession: number
46
- }
47
-
48
- export const StatsCommand = cmd({
49
- command: "stats",
50
- describe: "show token usage and cost statistics",
51
- builder: (yargs: Argv) => {
52
- return yargs
53
- .option("days", {
54
- describe: "show stats for the last N days (default: all time)",
55
- type: "number",
56
- })
57
- .option("tools", {
58
- describe: "number of tools to show (default: all)",
59
- type: "number",
60
- })
61
- .option("models", {
62
- describe: "show model statistics (default: hidden). Pass a number to show top N, otherwise shows all",
63
- })
64
- .option("project", {
65
- describe: "filter by project (default: all projects, empty string: current project)",
66
- type: "string",
67
- })
68
- },
69
- handler: async (args) => {
70
- await bootstrap(process.cwd(), async () => {
71
- const stats = await aggregateSessionStats(args.days, args.project)
72
-
73
- let modelLimit: number | undefined
74
- if (args.models === true) {
75
- modelLimit = Infinity
76
- } else if (typeof args.models === "number") {
77
- modelLimit = args.models
78
- }
79
-
80
- displayStats(stats, args.tools, modelLimit)
81
- })
82
- },
83
- })
84
-
85
- async function getCurrentProject(): Promise<Project.Info> {
86
- return Instance.project
87
- }
88
-
89
- async function getAllSessions(): Promise<Session.Info[]> {
90
- const sessions: Session.Info[] = []
91
-
92
- const projectKeys = await Storage.list(["project"])
93
- const projects = await Promise.all(projectKeys.map((key) => Storage.read<Project.Info>(key)))
94
-
95
- for (const project of projects) {
96
- if (!project) continue
97
-
98
- const sessionKeys = await Storage.list(["session", project.id])
99
- const projectSessions = await Promise.all(sessionKeys.map((key) => Storage.read<Session.Info>(key)))
100
-
101
- for (const session of projectSessions) {
102
- if (session) {
103
- sessions.push(session)
104
- }
105
- }
106
- }
107
-
108
- return sessions
109
- }
110
-
111
- export async function aggregateSessionStats(days?: number, projectFilter?: string): Promise<SessionStats> {
112
- const sessions = await getAllSessions()
113
- const MS_IN_DAY = 24 * 60 * 60 * 1000
114
-
115
- const cutoffTime = (() => {
116
- if (days === undefined) return 0
117
- if (days === 0) {
118
- const now = new Date()
119
- now.setHours(0, 0, 0, 0)
120
- return now.getTime()
121
- }
122
- return Date.now() - days * MS_IN_DAY
123
- })()
124
-
125
- const windowDays = (() => {
126
- if (days === undefined) return
127
- if (days === 0) return 1
128
- return days
129
- })()
130
-
131
- let filteredSessions = cutoffTime > 0 ? sessions.filter((session) => session.time.updated >= cutoffTime) : sessions
132
-
133
- if (projectFilter !== undefined) {
134
- if (projectFilter === "") {
135
- const currentProject = await getCurrentProject()
136
- filteredSessions = filteredSessions.filter((session) => session.projectID === currentProject.id)
137
- } else {
138
- filteredSessions = filteredSessions.filter((session) => session.projectID === projectFilter)
139
- }
140
- }
141
-
142
- const stats: SessionStats = {
143
- totalSessions: filteredSessions.length,
144
- totalMessages: 0,
145
- totalCost: 0,
146
- totalTokens: {
147
- input: 0,
148
- output: 0,
149
- reasoning: 0,
150
- cache: {
151
- read: 0,
152
- write: 0,
153
- },
154
- },
155
- toolUsage: {},
156
- modelUsage: {},
157
- dateRange: {
158
- earliest: Date.now(),
159
- latest: Date.now(),
160
- },
161
- days: 0,
162
- costPerDay: 0,
163
- tokensPerSession: 0,
164
- medianTokensPerSession: 0,
165
- }
166
-
167
- if (filteredSessions.length > 1000) {
168
- console.log(`Large dataset detected (${filteredSessions.length} sessions). This may take a while...`)
169
- }
170
-
171
- if (filteredSessions.length === 0) {
172
- stats.days = windowDays ?? 0
173
- return stats
174
- }
175
-
176
- let earliestTime = Date.now()
177
- let latestTime = 0
178
-
179
- const sessionTotalTokens: number[] = []
180
-
181
- const BATCH_SIZE = 20
182
- for (let i = 0; i < filteredSessions.length; i += BATCH_SIZE) {
183
- const batch = filteredSessions.slice(i, i + BATCH_SIZE)
184
-
185
- const batchPromises = batch.map(async (session) => {
186
- const messages = await Session.messages({ sessionID: session.id })
187
-
188
- let sessionCost = 0
189
- let sessionTokens = { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } }
190
- let sessionToolUsage: Record<string, number> = {}
191
- let sessionModelUsage: Record<
192
- string,
193
- {
194
- messages: number
195
- tokens: {
196
- input: number
197
- output: number
198
- cache: {
199
- read: number
200
- write: number
201
- }
202
- }
203
- cost: number
204
- }
205
- > = {}
206
-
207
- for (const message of messages) {
208
- if (message.info.role === "assistant") {
209
- sessionCost += message.info.cost || 0
210
-
211
- const modelKey = `${message.info.providerID}/${message.info.modelID}`
212
- if (!sessionModelUsage[modelKey]) {
213
- sessionModelUsage[modelKey] = {
214
- messages: 0,
215
- tokens: { input: 0, output: 0, cache: { read: 0, write: 0 } },
216
- cost: 0,
217
- }
218
- }
219
- sessionModelUsage[modelKey].messages++
220
- sessionModelUsage[modelKey].cost += message.info.cost || 0
221
-
222
- if (message.info.tokens) {
223
- sessionTokens.input += message.info.tokens.input || 0
224
- sessionTokens.output += message.info.tokens.output || 0
225
- sessionTokens.reasoning += message.info.tokens.reasoning || 0
226
- sessionTokens.cache.read += message.info.tokens.cache?.read || 0
227
- sessionTokens.cache.write += message.info.tokens.cache?.write || 0
228
-
229
- sessionModelUsage[modelKey].tokens.input += message.info.tokens.input || 0
230
- sessionModelUsage[modelKey].tokens.output +=
231
- (message.info.tokens.output || 0) + (message.info.tokens.reasoning || 0)
232
- sessionModelUsage[modelKey].tokens.cache.read += message.info.tokens.cache?.read || 0
233
- sessionModelUsage[modelKey].tokens.cache.write += message.info.tokens.cache?.write || 0
234
- }
235
- }
236
-
237
- for (const part of message.parts) {
238
- if (part.type === "tool" && part.tool) {
239
- sessionToolUsage[part.tool] = (sessionToolUsage[part.tool] || 0) + 1
240
- }
241
- }
242
- }
243
-
244
- return {
245
- messageCount: messages.length,
246
- sessionCost,
247
- sessionTokens,
248
- sessionTotalTokens:
249
- sessionTokens.input +
250
- sessionTokens.output +
251
- sessionTokens.reasoning +
252
- sessionTokens.cache.read +
253
- sessionTokens.cache.write,
254
- sessionToolUsage,
255
- sessionModelUsage,
256
- earliestTime: cutoffTime > 0 ? session.time.updated : session.time.created,
257
- latestTime: session.time.updated,
258
- }
259
- })
260
-
261
- const batchResults = await Promise.all(batchPromises)
262
-
263
- for (const result of batchResults) {
264
- earliestTime = Math.min(earliestTime, result.earliestTime)
265
- latestTime = Math.max(latestTime, result.latestTime)
266
- sessionTotalTokens.push(result.sessionTotalTokens)
267
-
268
- stats.totalMessages += result.messageCount
269
- stats.totalCost += result.sessionCost
270
- stats.totalTokens.input += result.sessionTokens.input
271
- stats.totalTokens.output += result.sessionTokens.output
272
- stats.totalTokens.reasoning += result.sessionTokens.reasoning
273
- stats.totalTokens.cache.read += result.sessionTokens.cache.read
274
- stats.totalTokens.cache.write += result.sessionTokens.cache.write
275
-
276
- for (const [tool, count] of Object.entries(result.sessionToolUsage)) {
277
- stats.toolUsage[tool] = (stats.toolUsage[tool] || 0) + count
278
- }
279
-
280
- for (const [model, usage] of Object.entries(result.sessionModelUsage)) {
281
- if (!stats.modelUsage[model]) {
282
- stats.modelUsage[model] = {
283
- messages: 0,
284
- tokens: { input: 0, output: 0, cache: { read: 0, write: 0 } },
285
- cost: 0,
286
- }
287
- }
288
- stats.modelUsage[model].messages += usage.messages
289
- stats.modelUsage[model].tokens.input += usage.tokens.input
290
- stats.modelUsage[model].tokens.output += usage.tokens.output
291
- stats.modelUsage[model].tokens.cache.read += usage.tokens.cache.read
292
- stats.modelUsage[model].tokens.cache.write += usage.tokens.cache.write
293
- stats.modelUsage[model].cost += usage.cost
294
- }
295
- }
296
- }
297
-
298
- const rangeDays = Math.max(1, Math.ceil((latestTime - earliestTime) / MS_IN_DAY))
299
- const effectiveDays = windowDays ?? rangeDays
300
- stats.dateRange = {
301
- earliest: earliestTime,
302
- latest: latestTime,
303
- }
304
- stats.days = effectiveDays
305
- stats.costPerDay = stats.totalCost / effectiveDays
306
- const totalTokens =
307
- stats.totalTokens.input +
308
- stats.totalTokens.output +
309
- stats.totalTokens.reasoning +
310
- stats.totalTokens.cache.read +
311
- stats.totalTokens.cache.write
312
- stats.tokensPerSession = filteredSessions.length > 0 ? totalTokens / filteredSessions.length : 0
313
- sessionTotalTokens.sort((a, b) => a - b)
314
- const mid = Math.floor(sessionTotalTokens.length / 2)
315
- stats.medianTokensPerSession =
316
- sessionTotalTokens.length === 0
317
- ? 0
318
- : sessionTotalTokens.length % 2 === 0
319
- ? (sessionTotalTokens[mid - 1] + sessionTotalTokens[mid]) / 2
320
- : sessionTotalTokens[mid]
321
-
322
- return stats
323
- }
324
-
325
- export function displayStats(stats: SessionStats, toolLimit?: number, modelLimit?: number) {
326
- const width = 56
327
-
328
- function renderRow(label: string, value: string): string {
329
- const availableWidth = width - 1
330
- const paddingNeeded = availableWidth - label.length - value.length
331
- const padding = Math.max(0, paddingNeeded)
332
- return `│${label}${" ".repeat(padding)}${value} │`
333
- }
334
-
335
- // Overview section
336
- console.log("┌────────────────────────────────────────────────────────┐")
337
- console.log("│ OVERVIEW │")
338
- console.log("├────────────────────────────────────────────────────────┤")
339
- console.log(renderRow("Sessions", stats.totalSessions.toLocaleString()))
340
- console.log(renderRow("Messages", stats.totalMessages.toLocaleString()))
341
- console.log(renderRow("Days", stats.days.toString()))
342
- console.log("└────────────────────────────────────────────────────────┘")
343
- console.log()
344
-
345
- // Cost & Tokens section
346
- console.log("┌────────────────────────────────────────────────────────┐")
347
- console.log("│ COST & TOKENS │")
348
- console.log("├────────────────────────────────────────────────────────┤")
349
- const cost = isNaN(stats.totalCost) ? 0 : stats.totalCost
350
- const costPerDay = isNaN(stats.costPerDay) ? 0 : stats.costPerDay
351
- const tokensPerSession = isNaN(stats.tokensPerSession) ? 0 : stats.tokensPerSession
352
- console.log(renderRow("Total Cost", `$${cost.toFixed(2)}`))
353
- console.log(renderRow("Avg Cost/Day", `$${costPerDay.toFixed(2)}`))
354
- console.log(renderRow("Avg Tokens/Session", formatNumber(Math.round(tokensPerSession))))
355
- const medianTokensPerSession = isNaN(stats.medianTokensPerSession) ? 0 : stats.medianTokensPerSession
356
- console.log(renderRow("Median Tokens/Session", formatNumber(Math.round(medianTokensPerSession))))
357
- console.log(renderRow("Input", formatNumber(stats.totalTokens.input)))
358
- console.log(renderRow("Output", formatNumber(stats.totalTokens.output)))
359
- console.log(renderRow("Cache Read", formatNumber(stats.totalTokens.cache.read)))
360
- console.log(renderRow("Cache Write", formatNumber(stats.totalTokens.cache.write)))
361
- console.log("└────────────────────────────────────────────────────────┘")
362
- console.log()
363
-
364
- // Model Usage section
365
- if (modelLimit !== undefined && Object.keys(stats.modelUsage).length > 0) {
366
- const sortedModels = Object.entries(stats.modelUsage).sort(([, a], [, b]) => b.messages - a.messages)
367
- const modelsToDisplay = modelLimit === Infinity ? sortedModels : sortedModels.slice(0, modelLimit)
368
-
369
- console.log("┌────────────────────────────────────────────────────────┐")
370
- console.log("│ MODEL USAGE │")
371
- console.log("├────────────────────────────────────────────────────────┤")
372
-
373
- for (const [model, usage] of modelsToDisplay) {
374
- console.log(`│ ${model.padEnd(54)} │`)
375
- console.log(renderRow(" Messages", usage.messages.toLocaleString()))
376
- console.log(renderRow(" Input Tokens", formatNumber(usage.tokens.input)))
377
- console.log(renderRow(" Output Tokens", formatNumber(usage.tokens.output)))
378
- console.log(renderRow(" Cache Read", formatNumber(usage.tokens.cache.read)))
379
- console.log(renderRow(" Cache Write", formatNumber(usage.tokens.cache.write)))
380
- console.log(renderRow(" Cost", `$${usage.cost.toFixed(4)}`))
381
- console.log("├────────────────────────────────────────────────────────┤")
382
- }
383
- // Remove last separator and add bottom border
384
- process.stdout.write("\x1B[1A") // Move up one line
385
- console.log("└────────────────────────────────────────────────────────┘")
386
- }
387
- console.log()
388
-
389
- // Tool Usage section
390
- if (Object.keys(stats.toolUsage).length > 0) {
391
- const sortedTools = Object.entries(stats.toolUsage).sort(([, a], [, b]) => b - a)
392
- const toolsToDisplay = toolLimit ? sortedTools.slice(0, toolLimit) : sortedTools
393
-
394
- console.log("┌────────────────────────────────────────────────────────┐")
395
- console.log("│ TOOL USAGE │")
396
- console.log("├────────────────────────────────────────────────────────┤")
397
-
398
- const maxCount = Math.max(...toolsToDisplay.map(([, count]) => count))
399
- const totalToolUsage = Object.values(stats.toolUsage).reduce((a, b) => a + b, 0)
400
-
401
- for (const [tool, count] of toolsToDisplay) {
402
- const barLength = Math.max(1, Math.floor((count / maxCount) * 20))
403
- const bar = "█".repeat(barLength)
404
- const percentage = ((count / totalToolUsage) * 100).toFixed(1)
405
-
406
- const maxToolLength = 18
407
- const truncatedTool = tool.length > maxToolLength ? tool.substring(0, maxToolLength - 2) + ".." : tool
408
- const toolName = truncatedTool.padEnd(maxToolLength)
409
-
410
- const content = ` ${toolName} ${bar.padEnd(20)} ${count.toString().padStart(3)} (${percentage.padStart(4)}%)`
411
- const padding = Math.max(0, width - content.length - 1)
412
- console.log(`│${content}${" ".repeat(padding)} │`)
413
- }
414
- console.log("└────────────────────────────────────────────────────────┘")
415
- }
416
- console.log()
417
- }
418
-
419
- function formatNumber(num: number): string {
420
- if (num >= 1000000) {
421
- return (num / 1000000).toFixed(1) + "M"
422
- } else if (num >= 1000) {
423
- return (num / 1000).toFixed(1) + "K"
424
- }
425
- return num.toString()
426
- }