@ebowwa/coder 0.2.1 → 0.7.64

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 (401) hide show
  1. package/README.md +31 -32
  2. package/dist/core/__tests__/permissions.test.d.ts +12 -0
  3. package/dist/core/__tests__/permissions.test.d.ts.map +1 -0
  4. package/dist/core/__tests__/permissions.test.js +851 -0
  5. package/dist/core/agent-loop/__tests__/compaction.test.d.ts +5 -0
  6. package/dist/core/agent-loop/__tests__/compaction.test.d.ts.map +1 -0
  7. package/dist/core/agent-loop/__tests__/compaction.test.js +209 -0
  8. package/dist/core/agent-loop/__tests__/formatters.test.d.ts +5 -0
  9. package/dist/core/agent-loop/__tests__/formatters.test.d.ts.map +1 -0
  10. package/dist/core/agent-loop/__tests__/formatters.test.js +195 -0
  11. package/dist/core/agent-loop/__tests__/index.test.d.ts +5 -0
  12. package/dist/core/agent-loop/__tests__/index.test.d.ts.map +1 -0
  13. package/dist/core/agent-loop/__tests__/index.test.js +121 -0
  14. package/dist/core/agent-loop/__tests__/loop-state.test.d.ts +5 -0
  15. package/dist/core/agent-loop/__tests__/loop-state.test.d.ts.map +1 -0
  16. package/dist/core/agent-loop/__tests__/loop-state.test.js +340 -0
  17. package/dist/core/agent-loop/__tests__/message-builder.test.d.ts +5 -0
  18. package/dist/core/agent-loop/__tests__/message-builder.test.d.ts.map +1 -0
  19. package/dist/core/agent-loop/__tests__/message-builder.test.js +178 -0
  20. package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts +5 -0
  21. package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts.map +1 -0
  22. package/dist/core/agent-loop/__tests__/tool-executor.test.js +331 -0
  23. package/dist/core/agent-loop/compaction.d.ts +39 -0
  24. package/dist/core/agent-loop/compaction.d.ts.map +1 -0
  25. package/dist/core/agent-loop/compaction.js +51 -0
  26. package/dist/core/agent-loop/formatters.d.ts +21 -0
  27. package/dist/core/agent-loop/formatters.d.ts.map +1 -0
  28. package/dist/core/agent-loop/formatters.js +42 -0
  29. package/dist/core/agent-loop/index.d.ts +25 -0
  30. package/dist/core/agent-loop/index.d.ts.map +1 -0
  31. package/dist/core/agent-loop/index.js +83 -0
  32. package/dist/core/agent-loop/loop-state.d.ts +74 -0
  33. package/dist/core/agent-loop/loop-state.d.ts.map +1 -0
  34. package/dist/core/agent-loop/loop-state.js +147 -0
  35. package/dist/core/agent-loop/message-builder.d.ts +13 -0
  36. package/dist/core/agent-loop/message-builder.d.ts.map +1 -0
  37. package/dist/core/agent-loop/message-builder.js +49 -0
  38. package/dist/core/agent-loop/tool-executor.d.ts +23 -0
  39. package/dist/core/agent-loop/tool-executor.d.ts.map +1 -0
  40. package/dist/core/agent-loop/tool-executor.js +152 -0
  41. package/dist/core/agent-loop/turn-executor.d.ts +57 -0
  42. package/dist/core/agent-loop/turn-executor.d.ts.map +1 -0
  43. package/dist/core/agent-loop/turn-executor.js +124 -0
  44. package/dist/core/agent-loop/types.d.ts +141 -0
  45. package/dist/core/agent-loop/types.d.ts.map +1 -0
  46. package/dist/core/agent-loop/types.js +4 -0
  47. package/dist/core/agent-loop.d.ts +17 -0
  48. package/dist/core/agent-loop.d.ts.map +1 -0
  49. package/dist/core/agent-loop.js +16 -0
  50. package/dist/core/api-client-impl.d.ts +62 -0
  51. package/dist/core/api-client-impl.d.ts.map +1 -0
  52. package/dist/core/api-client-impl.js +479 -0
  53. package/dist/core/api-client.d.ts +6 -0
  54. package/dist/core/api-client.d.ts.map +1 -0
  55. package/dist/core/api-client.js +5 -0
  56. package/dist/core/checkpoints.d.ts +128 -0
  57. package/dist/core/checkpoints.d.ts.map +1 -0
  58. package/dist/core/checkpoints.js +438 -0
  59. package/dist/core/claude-md.d.ts +71 -0
  60. package/dist/core/claude-md.d.ts.map +1 -0
  61. package/dist/core/claude-md.js +198 -0
  62. package/dist/core/cognitive-security/hooks.d.ts +138 -0
  63. package/dist/core/cognitive-security/hooks.d.ts.map +1 -0
  64. package/dist/core/cognitive-security/hooks.js +389 -0
  65. package/dist/core/cognitive-security/index.d.ts +751 -0
  66. package/dist/core/cognitive-security/index.d.ts.map +1 -0
  67. package/dist/core/cognitive-security/index.js +1123 -0
  68. package/dist/core/cognitive-security/middleware.d.ts +136 -0
  69. package/dist/core/cognitive-security/middleware.d.ts.map +1 -0
  70. package/dist/core/cognitive-security/middleware.js +376 -0
  71. package/dist/core/config-loader.d.ts +127 -0
  72. package/dist/core/config-loader.d.ts.map +1 -0
  73. package/dist/core/config-loader.js +219 -0
  74. package/dist/core/context-compaction.d.ts +87 -0
  75. package/dist/core/context-compaction.d.ts.map +1 -0
  76. package/dist/core/context-compaction.js +428 -0
  77. package/dist/core/git-status.d.ts +25 -0
  78. package/dist/core/git-status.d.ts.map +1 -0
  79. package/dist/core/git-status.js +204 -0
  80. package/dist/core/image.d.ts +69 -0
  81. package/dist/core/image.d.ts.map +1 -0
  82. package/dist/core/image.js +290 -0
  83. package/dist/core/image.test.d.ts +2 -0
  84. package/dist/core/image.test.d.ts.map +1 -0
  85. package/dist/core/image.test.js +149 -0
  86. package/dist/core/models.d.ts +123 -0
  87. package/dist/core/models.d.ts.map +1 -0
  88. package/dist/core/models.js +325 -0
  89. package/dist/core/permissions.d.ts +81 -0
  90. package/dist/core/permissions.d.ts.map +1 -0
  91. package/dist/core/permissions.js +327 -0
  92. package/dist/core/retry.d.ts +25 -0
  93. package/dist/core/retry.d.ts.map +1 -0
  94. package/dist/core/retry.js +121 -0
  95. package/dist/core/session-store.d.ts +9 -0
  96. package/dist/core/session-store.d.ts.map +1 -0
  97. package/dist/core/session-store.js +10 -0
  98. package/dist/core/sessions/export.d.ts +47 -0
  99. package/dist/core/sessions/export.d.ts.map +1 -0
  100. package/dist/core/sessions/export.js +256 -0
  101. package/dist/core/sessions/index.d.ts +132 -0
  102. package/dist/core/sessions/index.d.ts.map +1 -0
  103. package/dist/core/sessions/index.js +442 -0
  104. package/dist/core/sessions/metadata.d.ts +77 -0
  105. package/dist/core/sessions/metadata.d.ts.map +1 -0
  106. package/dist/core/sessions/metadata.js +233 -0
  107. package/dist/core/sessions/persistence.d.ts +72 -0
  108. package/dist/core/sessions/persistence.d.ts.map +1 -0
  109. package/dist/core/sessions/persistence.js +201 -0
  110. package/dist/core/sessions/types.d.ts +110 -0
  111. package/dist/core/sessions/types.d.ts.map +1 -0
  112. package/dist/core/sessions/types.js +4 -0
  113. package/dist/core/stream-highlighter.d.ts +18 -0
  114. package/dist/core/stream-highlighter.d.ts.map +1 -0
  115. package/dist/core/stream-highlighter.js +916 -0
  116. package/dist/core/system-reminders.d.ts +89 -0
  117. package/dist/core/system-reminders.d.ts.map +1 -0
  118. package/dist/core/system-reminders.js +285 -0
  119. package/dist/ecosystem/hooks/__tests__/index.test.d.ts +5 -0
  120. package/dist/ecosystem/hooks/__tests__/index.test.d.ts.map +1 -0
  121. package/dist/ecosystem/hooks/__tests__/index.test.js +458 -0
  122. package/dist/ecosystem/hooks/index.d.ts +59 -0
  123. package/dist/ecosystem/hooks/index.d.ts.map +1 -0
  124. package/dist/ecosystem/hooks/index.js +294 -0
  125. package/dist/ecosystem/hooks/prompt-evaluator.d.ts +32 -0
  126. package/dist/ecosystem/hooks/prompt-evaluator.d.ts.map +1 -0
  127. package/dist/ecosystem/hooks/prompt-evaluator.js +229 -0
  128. package/dist/ecosystem/skills/index.d.ts +55 -0
  129. package/dist/ecosystem/skills/index.d.ts.map +1 -0
  130. package/dist/ecosystem/skills/index.js +258 -0
  131. package/dist/ecosystem/tools/__tests__/index.test.d.ts +7 -0
  132. package/dist/ecosystem/tools/__tests__/index.test.d.ts.map +1 -0
  133. package/dist/ecosystem/tools/__tests__/index.test.js +856 -0
  134. package/dist/ecosystem/tools/index.d.ts +24 -0
  135. package/dist/ecosystem/tools/index.d.ts.map +1 -0
  136. package/dist/ecosystem/tools/index.js +1709 -0
  137. package/dist/index.d.ts +24 -0
  138. package/dist/index.d.ts.map +1 -0
  139. package/dist/index.js +32 -2
  140. package/dist/interfaces/mcp/client.d.ts +40 -0
  141. package/dist/interfaces/mcp/client.d.ts.map +1 -0
  142. package/dist/interfaces/mcp/client.js +309 -0
  143. package/dist/interfaces/ui/index.d.ts +36 -0
  144. package/dist/interfaces/ui/index.d.ts.map +1 -0
  145. package/dist/interfaces/ui/index.js +61 -0
  146. package/dist/interfaces/ui/spinner.d.ts +140 -0
  147. package/dist/interfaces/ui/spinner.d.ts.map +1 -0
  148. package/dist/interfaces/ui/spinner.js +342 -0
  149. package/dist/interfaces/ui/terminal/cli/index.d.ts +12 -0
  150. package/dist/interfaces/ui/terminal/cli/index.d.ts.map +1 -0
  151. package/dist/interfaces/ui/terminal/cli/index.js +167 -0
  152. package/dist/interfaces/ui/terminal/shared/args.d.ts +39 -0
  153. package/dist/interfaces/ui/terminal/shared/args.d.ts.map +1 -0
  154. package/dist/interfaces/ui/terminal/shared/args.js +176 -0
  155. package/dist/interfaces/ui/terminal/shared/index.d.ts +11 -0
  156. package/dist/interfaces/ui/terminal/shared/index.d.ts.map +1 -0
  157. package/dist/interfaces/ui/terminal/shared/index.js +16 -0
  158. package/dist/interfaces/ui/terminal/shared/loading-state.d.ts +124 -0
  159. package/dist/interfaces/ui/terminal/shared/loading-state.d.ts.map +1 -0
  160. package/dist/interfaces/ui/terminal/shared/loading-state.js +246 -0
  161. package/dist/interfaces/ui/terminal/shared/query.d.ts +22 -0
  162. package/dist/interfaces/ui/terminal/shared/query.d.ts.map +1 -0
  163. package/dist/interfaces/ui/terminal/shared/query.js +100 -0
  164. package/dist/interfaces/ui/terminal/shared/setup.d.ts +33 -0
  165. package/dist/interfaces/ui/terminal/shared/setup.d.ts.map +1 -0
  166. package/dist/interfaces/ui/terminal/shared/setup.js +226 -0
  167. package/dist/interfaces/ui/terminal/shared/status-line.d.ts +117 -0
  168. package/dist/interfaces/ui/terminal/shared/status-line.d.ts.map +1 -0
  169. package/dist/interfaces/ui/terminal/shared/status-line.js +267 -0
  170. package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts +38 -0
  171. package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts.map +1 -0
  172. package/dist/interfaces/ui/terminal/shared/system-prompt.js +102 -0
  173. package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts +39 -0
  174. package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts.map +1 -0
  175. package/dist/interfaces/ui/terminal/tui/HelpPanel.js +215 -0
  176. package/dist/interfaces/ui/terminal/tui/InputContext.d.ts +91 -0
  177. package/dist/interfaces/ui/terminal/tui/InputContext.d.ts.map +1 -0
  178. package/dist/interfaces/ui/terminal/tui/InputContext.js +154 -0
  179. package/dist/interfaces/ui/terminal/tui/InputField.d.ts +18 -0
  180. package/dist/interfaces/ui/terminal/tui/InputField.d.ts.map +1 -0
  181. package/dist/interfaces/ui/terminal/tui/InputField.js +41 -0
  182. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts +16 -0
  183. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts.map +1 -0
  184. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.js +451 -0
  185. package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts +10 -0
  186. package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts.map +1 -0
  187. package/dist/interfaces/ui/terminal/tui/MessageArea.js +91 -0
  188. package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts +48 -0
  189. package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts.map +1 -0
  190. package/dist/interfaces/ui/terminal/tui/MessageStore.js +151 -0
  191. package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts +9 -0
  192. package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts.map +1 -0
  193. package/dist/interfaces/ui/terminal/tui/StatusBar.js +36 -0
  194. package/dist/interfaces/ui/terminal/tui/commands.d.ts +21 -0
  195. package/dist/interfaces/ui/terminal/tui/commands.d.ts.map +1 -0
  196. package/dist/interfaces/ui/terminal/tui/commands.js +359 -0
  197. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts +115 -0
  198. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts.map +1 -0
  199. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.js +306 -0
  200. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts +92 -0
  201. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts.map +1 -0
  202. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.js +399 -0
  203. package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts +59 -0
  204. package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts.map +1 -0
  205. package/dist/interfaces/ui/terminal/tui/components/PaneManager.js +139 -0
  206. package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts +68 -0
  207. package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts.map +1 -0
  208. package/dist/interfaces/ui/terminal/tui/components/Sidebar.js +340 -0
  209. package/dist/interfaces/ui/terminal/tui/components/index.d.ts +23 -0
  210. package/dist/interfaces/ui/terminal/tui/components/index.d.ts.map +1 -0
  211. package/dist/interfaces/ui/terminal/tui/components/index.js +51 -0
  212. package/dist/interfaces/ui/terminal/tui/console.d.ts +20 -0
  213. package/dist/interfaces/ui/terminal/tui/console.d.ts.map +1 -0
  214. package/dist/interfaces/ui/terminal/tui/console.js +46 -0
  215. package/dist/interfaces/ui/terminal/tui/index.d.ts +20 -0
  216. package/dist/interfaces/ui/terminal/tui/index.d.ts.map +1 -0
  217. package/dist/interfaces/ui/terminal/tui/index.js +28 -0
  218. package/dist/interfaces/ui/terminal/tui/run.d.ts +13 -0
  219. package/dist/interfaces/ui/terminal/tui/run.d.ts.map +1 -0
  220. package/dist/interfaces/ui/terminal/tui/run.js +31 -0
  221. package/dist/interfaces/ui/terminal/tui/spinner.d.ts +44 -0
  222. package/dist/interfaces/ui/terminal/tui/spinner.d.ts.map +1 -0
  223. package/dist/interfaces/ui/terminal/tui/spinner.js +59 -0
  224. package/dist/interfaces/ui/terminal/tui/tui-app.d.ts +39 -0
  225. package/dist/interfaces/ui/terminal/tui/tui-app.d.ts.map +1 -0
  226. package/dist/interfaces/ui/terminal/tui/tui-app.js +198 -0
  227. package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts +167 -0
  228. package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts.map +1 -0
  229. package/dist/interfaces/ui/terminal/tui/tui-footer.js +330 -0
  230. package/dist/interfaces/ui/terminal/tui/types.d.ts +165 -0
  231. package/dist/interfaces/ui/terminal/tui/types.d.ts.map +1 -0
  232. package/dist/interfaces/ui/terminal/tui/types.js +5 -0
  233. package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts +23 -0
  234. package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts.map +1 -0
  235. package/dist/interfaces/ui/terminal/tui/useInputHandler.js +72 -0
  236. package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts +90 -0
  237. package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts.map +1 -0
  238. package/dist/interfaces/ui/terminal/tui/useNativeInput.js +188 -0
  239. package/dist/native/index.d.ts +480 -0
  240. package/dist/native/index.d.ts.map +1 -0
  241. package/dist/native/index.js +1625 -0
  242. package/dist/teammates/index.d.ts +161 -0
  243. package/dist/teammates/index.d.ts.map +1 -0
  244. package/dist/teammates/index.js +827 -0
  245. package/dist/types/index.d.ts +482 -0
  246. package/dist/types/index.d.ts.map +1 -0
  247. package/dist/types/index.js +52 -0
  248. package/native/README.md +5 -5
  249. package/native/index.darwin-arm64.node +0 -0
  250. package/native/index.node +0 -0
  251. package/native/package.json +4 -4
  252. package/package.json +33 -16
  253. package/packages/src/core/__tests__/permissions.test.ts +1091 -0
  254. package/packages/src/core/agent-loop/__tests__/compaction.test.ts +280 -0
  255. package/packages/src/core/agent-loop/__tests__/formatters.test.ts +234 -0
  256. package/packages/src/core/agent-loop/__tests__/index.test.ts +162 -0
  257. package/packages/src/core/agent-loop/__tests__/loop-state.test.ts +413 -0
  258. package/packages/src/core/agent-loop/__tests__/message-builder.test.ts +229 -0
  259. package/packages/src/core/agent-loop/__tests__/tool-executor.test.ts +457 -0
  260. package/packages/src/core/agent-loop/compaction.ts +88 -0
  261. package/packages/src/core/agent-loop/formatters.ts +50 -0
  262. package/packages/src/core/agent-loop/index.ts +135 -0
  263. package/packages/src/core/agent-loop/loop-state.ts +187 -0
  264. package/packages/src/core/agent-loop/message-builder.ts +62 -0
  265. package/packages/src/core/agent-loop/tool-executor.ts +211 -0
  266. package/packages/src/core/agent-loop/turn-executor.ts +222 -0
  267. package/packages/src/core/agent-loop/types.ts +148 -0
  268. package/packages/src/core/agent-loop.ts +18 -0
  269. package/packages/src/core/api-client-impl.ts +619 -0
  270. package/packages/src/core/api-client.ts +6 -0
  271. package/packages/src/core/checkpoints.ts +606 -0
  272. package/packages/src/core/claude-md.ts +272 -0
  273. package/packages/src/core/cognitive-security/hooks.ts +590 -0
  274. package/packages/src/core/cognitive-security/index.ts +2041 -0
  275. package/packages/src/core/cognitive-security/middleware.ts +536 -0
  276. package/packages/src/core/config-loader.ts +324 -0
  277. package/packages/src/core/context-compaction.ts +578 -0
  278. package/packages/src/core/git-status.ts +262 -0
  279. package/packages/src/core/image.test.ts +180 -0
  280. package/packages/src/core/image.ts +350 -0
  281. package/packages/src/core/lmdb.db +0 -0
  282. package/packages/src/core/lmdb.db-lock +0 -0
  283. package/packages/src/core/models.ts +430 -0
  284. package/packages/src/core/normalizers/todo +4 -0
  285. package/packages/src/core/permissions.ts +431 -0
  286. package/packages/src/core/retry.ts +170 -0
  287. package/packages/src/core/session-store.ts +36 -0
  288. package/packages/src/core/sessions/export.ts +329 -0
  289. package/packages/src/core/sessions/index.ts +587 -0
  290. package/packages/src/core/sessions/metadata.ts +309 -0
  291. package/packages/src/core/sessions/persistence.ts +244 -0
  292. package/packages/src/core/sessions/types.ts +169 -0
  293. package/packages/src/core/stream-highlighter.ts +1123 -0
  294. package/packages/src/core/system-reminders.ts +402 -0
  295. package/packages/src/core/todo +8 -0
  296. package/packages/src/ecosystem/hooks/__tests__/index.test.ts +561 -0
  297. package/packages/src/ecosystem/hooks/index.ts +341 -0
  298. package/packages/src/ecosystem/hooks/prompt-evaluator.ts +300 -0
  299. package/packages/src/ecosystem/skills/index.ts +295 -0
  300. package/packages/src/ecosystem/tools/__tests__/index.test.ts +1335 -0
  301. package/packages/src/ecosystem/tools/index.ts +1877 -0
  302. package/packages/src/index.ts +120 -0
  303. package/packages/src/interfaces/mcp/client.ts +389 -0
  304. package/packages/src/interfaces/ui/Screenshot 2026-03-02 at 9.23.10/342/200/257PM.png +0 -0
  305. package/packages/src/interfaces/ui/Screenshot 2026-03-03 at 10.55.11/342/200/257AM.png +0 -0
  306. package/packages/src/interfaces/ui/index.ts +161 -0
  307. package/packages/src/interfaces/ui/lmdb.db +0 -0
  308. package/packages/src/interfaces/ui/lmdb.db-lock +0 -0
  309. package/packages/src/interfaces/ui/spinner.ts +451 -0
  310. package/packages/src/interfaces/ui/terminal/cli/index.ts +228 -0
  311. package/packages/src/interfaces/ui/terminal/lmdb.db +0 -0
  312. package/packages/src/interfaces/ui/terminal/lmdb.db-lock +0 -0
  313. package/packages/src/interfaces/ui/terminal/shared/args.ts +222 -0
  314. package/packages/src/interfaces/ui/terminal/shared/index.ts +71 -0
  315. package/packages/src/interfaces/ui/terminal/shared/loading-state.ts +322 -0
  316. package/packages/src/interfaces/ui/terminal/shared/query.ts +146 -0
  317. package/packages/src/interfaces/ui/terminal/shared/setup.ts +295 -0
  318. package/packages/src/interfaces/ui/terminal/shared/status-line.ts +358 -0
  319. package/packages/src/interfaces/ui/terminal/shared/system-prompt.ts +146 -0
  320. package/packages/src/interfaces/ui/terminal/tui/HelpPanel.tsx +262 -0
  321. package/packages/src/interfaces/ui/terminal/tui/InputContext.tsx +232 -0
  322. package/packages/src/interfaces/ui/terminal/tui/InputField.tsx +62 -0
  323. package/packages/src/interfaces/ui/terminal/tui/InteractiveTUI.tsx +537 -0
  324. package/packages/src/interfaces/ui/terminal/tui/MessageArea.tsx +107 -0
  325. package/packages/src/interfaces/ui/terminal/tui/MessageStore.tsx +240 -0
  326. package/packages/src/interfaces/ui/terminal/tui/StatusBar.tsx +54 -0
  327. package/packages/src/interfaces/ui/terminal/tui/commands.ts +438 -0
  328. package/packages/src/interfaces/ui/terminal/tui/components/InteractiveElements.tsx +584 -0
  329. package/packages/src/interfaces/ui/terminal/tui/components/MultilineInput.tsx +614 -0
  330. package/packages/src/interfaces/ui/terminal/tui/components/PaneManager.tsx +333 -0
  331. package/packages/src/interfaces/ui/terminal/tui/components/Sidebar.tsx +604 -0
  332. package/packages/src/interfaces/ui/terminal/tui/components/index.ts +118 -0
  333. package/packages/src/interfaces/ui/terminal/tui/console.ts +49 -0
  334. package/packages/src/interfaces/ui/terminal/tui/index.ts +90 -0
  335. package/packages/src/interfaces/ui/terminal/tui/run.tsx +42 -0
  336. package/packages/src/interfaces/ui/terminal/tui/spinner.ts +69 -0
  337. package/packages/src/interfaces/ui/terminal/tui/tui-app.tsx +390 -0
  338. package/packages/src/interfaces/ui/terminal/tui/tui-footer.ts +422 -0
  339. package/packages/src/interfaces/ui/terminal/tui/types.ts +186 -0
  340. package/packages/src/interfaces/ui/terminal/tui/useInputHandler.ts +104 -0
  341. package/packages/src/interfaces/ui/terminal/tui/useNativeInput.ts +239 -0
  342. package/packages/src/lmdb.db +0 -0
  343. package/packages/src/lmdb.db-lock +0 -0
  344. package/packages/src/native/index.ts +2345 -0
  345. package/packages/src/teammates/index.ts +982 -0
  346. package/packages/src/types/index.ts +722 -0
  347. package/dist/cli.js +0 -148
  348. package/dist/index-0pkak453.js +0 -136
  349. package/dist/index-0qd0x8b4.js +0 -110
  350. package/dist/index-0x3kprq6.js +0 -240
  351. package/dist/index-1eawy937.js +0 -308
  352. package/dist/index-24m2aygy.js +0 -240
  353. package/dist/index-29xcjnne.js +0 -280
  354. package/dist/index-2avyytn5.js +0 -349
  355. package/dist/index-4ms367ey.js +0 -136
  356. package/dist/index-4w2t3b0m.js +0 -240
  357. package/dist/index-4xfgd8nz.js +0 -261
  358. package/dist/index-5acjp9gc.js +0 -157
  359. package/dist/index-5s15hr56.js +0 -136
  360. package/dist/index-6e4wf341.js +0 -349
  361. package/dist/index-6fvnkedw.js +0 -240
  362. package/dist/index-6rqpmd4g.js +0 -128
  363. package/dist/index-77ckwnbm.js +0 -280
  364. package/dist/index-9knxy49k.js +0 -128
  365. package/dist/index-9zrnw4zx.js +0 -128
  366. package/dist/index-bk21w99v.js +0 -280
  367. package/dist/index-c41n76fv.js +0 -240
  368. package/dist/index-cb4ppjdt.js +0 -255
  369. package/dist/index-cfb2edt6.js +0 -240
  370. package/dist/index-cmfa38hh.js +0 -308
  371. package/dist/index-datjz8q1.js +0 -257
  372. package/dist/index-eadf4wvn.js +0 -240
  373. package/dist/index-em5k0m3z.js +0 -345
  374. package/dist/index-gh8r333a.js +0 -110
  375. package/dist/index-gkx6k2tr.js +0 -261
  376. package/dist/index-h5cabfks.js +0 -155
  377. package/dist/index-hcrpwyy3.js +0 -261
  378. package/dist/index-hk7fwwa8.js +0 -257
  379. package/dist/index-jb8cw7f8.js +0 -136
  380. package/dist/index-kbyw4th1.js +0 -347
  381. package/dist/index-kgj5gqnm.js +0 -345
  382. package/dist/index-mdf6xp1z.js +0 -255
  383. package/dist/index-mrhv8kvc.js +0 -280
  384. package/dist/index-mt4743dd.js +0 -161
  385. package/dist/index-qnwsg97q.js +0 -240
  386. package/dist/index-qwdy6x44.js +0 -261
  387. package/dist/index-rmj77261.js +0 -157
  388. package/dist/index-sbbw1a61.js +0 -349
  389. package/dist/index-svy5bcpn.js +0 -345
  390. package/dist/index-tvmy7tm9.js +0 -261
  391. package/dist/index-tzz4vzkj.js +0 -312
  392. package/dist/index-vz80zmhe.js +0 -110
  393. package/dist/index-wed2fk67.js +0 -240
  394. package/dist/index-wksgzz8e.js +0 -280
  395. package/dist/index-wn2m4wma.js +0 -240
  396. package/dist/index-xha05vjc.js +0 -257
  397. package/dist/index-yc6eh8p8.js +0 -136
  398. package/dist/index-ycjxx9ft.js +0 -240
  399. package/dist/index-z0gzd0fc.js +0 -110
  400. package/dist/index-z8cwtf8j.js +0 -240
  401. package/dist/index-zy5mtt00.js +0 -128
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Session Metadata - Manage session metadata and summaries
3
+ */
4
+
5
+ import type {
6
+ SessionMetadata,
7
+ SessionSummary,
8
+ SessionEntry,
9
+ SessionMessage,
10
+ SessionMetrics,
11
+ SessionFilter,
12
+ } from "./types.js";
13
+ import type { ContentBlock, Message } from "../../types/index.js";
14
+ import { SessionPersistence } from "./persistence.js";
15
+
16
+ export class SessionMetadataManager {
17
+ private persistence: SessionPersistence;
18
+
19
+ constructor(persistence: SessionPersistence) {
20
+ this.persistence = persistence;
21
+ }
22
+
23
+ /**
24
+ * Generate a new session ID
25
+ */
26
+ generateId(): string {
27
+ const timestamp = Date.now().toString(36);
28
+ const random = Math.random().toString(36).slice(2, 8);
29
+ return `${timestamp}-${random}`;
30
+ }
31
+
32
+ /**
33
+ * Create metadata for a new session
34
+ */
35
+ createMetadata(options: {
36
+ id?: string;
37
+ model: string;
38
+ workingDirectory: string;
39
+ agentName?: string;
40
+ agentColor?: string;
41
+ teamName?: string;
42
+ }): SessionMetadata {
43
+ return {
44
+ type: "metadata",
45
+ id: options.id ?? this.generateId(),
46
+ created: Date.now(),
47
+ updated: Date.now(),
48
+ model: options.model,
49
+ workingDirectory: options.workingDirectory,
50
+ agentName: options.agentName,
51
+ agentColor: options.agentColor,
52
+ teamName: options.teamName,
53
+ totalCost: 0,
54
+ totalTokens: { input: 0, output: 0 },
55
+ };
56
+ }
57
+
58
+ /**
59
+ * Update metadata timestamps
60
+ */
61
+ touch(metadata: SessionMetadata): SessionMetadata {
62
+ return {
63
+ ...metadata,
64
+ updated: Date.now(),
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Merge updated fields into metadata
70
+ */
71
+ merge(
72
+ metadata: SessionMetadata,
73
+ updates: Partial<SessionMetadata>
74
+ ): SessionMetadata {
75
+ return {
76
+ ...metadata,
77
+ ...updates,
78
+ updated: Date.now(),
79
+ };
80
+ }
81
+
82
+ /**
83
+ * Get summary from session entries
84
+ */
85
+ async getSummary(sessionId: string): Promise<SessionSummary | null> {
86
+ const entries = await this.persistence.read(sessionId);
87
+ return this.entriesToSummary(sessionId, entries);
88
+ }
89
+
90
+ /**
91
+ * Convert entries to summary
92
+ */
93
+ entriesToSummary(
94
+ sessionId: string,
95
+ entries: SessionEntry[]
96
+ ): SessionSummary | null {
97
+ let metadata: SessionMetadata | null = null;
98
+ let messageCount = 0;
99
+ let totalCost = 0;
100
+ let totalInput = 0;
101
+ let totalOutput = 0;
102
+ let firstMessage: string | undefined;
103
+ let lastActivity: number | undefined;
104
+
105
+ for (const entry of entries) {
106
+ // All entries have a type field now
107
+ if ("type" in entry) {
108
+ switch (entry.type) {
109
+ case "metadata":
110
+ metadata = entry as SessionMetadata;
111
+ break;
112
+ case "message":
113
+ messageCount++;
114
+ lastActivity = entry.timestamp;
115
+ const msg = (entry as SessionMessage).data as Message;
116
+ if (!firstMessage && msg.role === "user") {
117
+ const textBlock = msg.content.find(
118
+ (b: ContentBlock) => b.type === "text"
119
+ );
120
+ if (textBlock && "text" in textBlock) {
121
+ firstMessage = textBlock.text.slice(0, 100);
122
+ if (textBlock.text.length > 100) {
123
+ firstMessage += "...";
124
+ }
125
+ }
126
+ }
127
+ break;
128
+
129
+ case "metrics":
130
+ const metrics = (entry as SessionMetrics).data;
131
+ totalCost += metrics.costUSD;
132
+ totalInput += metrics.usage.input_tokens;
133
+ totalOutput += metrics.usage.output_tokens;
134
+ lastActivity = entry.timestamp;
135
+ break;
136
+
137
+ case "tool_use":
138
+ case "context":
139
+ case "checkpoint":
140
+ lastActivity = entry.timestamp;
141
+ break;
142
+ }
143
+ }
144
+ }
145
+
146
+ if (!metadata) {
147
+ return null;
148
+ }
149
+
150
+ return {
151
+ id: sessionId,
152
+ created: metadata.created,
153
+ updated: metadata.updated,
154
+ lastActivity,
155
+ model: metadata.model,
156
+ messageCount,
157
+ totalCost,
158
+ totalTokens: { input: totalInput, output: totalOutput },
159
+ firstMessage,
160
+ workingDirectory: metadata.workingDirectory,
161
+ metadata: {
162
+ agentName: metadata.agentName,
163
+ agentColor: metadata.agentColor,
164
+ teamName: metadata.teamName,
165
+ },
166
+ };
167
+ }
168
+
169
+ /**
170
+ * Filter sessions based on criteria
171
+ */
172
+ filterSessions(
173
+ sessions: SessionSummary[],
174
+ filter: SessionFilter
175
+ ): SessionSummary[] {
176
+ return sessions.filter((session) => {
177
+ // Filter by model
178
+ if (filter.model && session.model !== filter.model) {
179
+ return false;
180
+ }
181
+
182
+ // Filter by working directory
183
+ if (
184
+ filter.workingDirectory &&
185
+ session.workingDirectory !== filter.workingDirectory
186
+ ) {
187
+ return false;
188
+ }
189
+
190
+ // Filter by minimum messages
191
+ if (filter.minMessages && session.messageCount < filter.minMessages) {
192
+ return false;
193
+ }
194
+
195
+ // Filter by age (maxAge = maximum age in ms)
196
+ if (filter.maxAge) {
197
+ const age = Date.now() - session.created;
198
+ if (age > filter.maxAge) {
199
+ return false;
200
+ }
201
+ }
202
+
203
+ // Filter by timestamp (since = minimum created timestamp)
204
+ if (filter.since && session.created < filter.since) {
205
+ return false;
206
+ }
207
+
208
+ return true;
209
+ });
210
+ }
211
+
212
+ /**
213
+ * Sort sessions by various criteria
214
+ */
215
+ sortSessions(
216
+ sessions: SessionSummary[],
217
+ sortBy: "created" | "updated" | "lastActivity" | "messageCount" | "cost" = "lastActivity",
218
+ order: "asc" | "desc" = "desc"
219
+ ): SessionSummary[] {
220
+ return [...sessions].sort((a, b) => {
221
+ let comparison = 0;
222
+
223
+ switch (sortBy) {
224
+ case "created":
225
+ comparison = a.created - b.created;
226
+ break;
227
+ case "updated":
228
+ comparison = a.updated - b.updated;
229
+ break;
230
+ case "lastActivity":
231
+ comparison = (a.lastActivity ?? a.updated) - (b.lastActivity ?? b.updated);
232
+ break;
233
+ case "messageCount":
234
+ comparison = a.messageCount - b.messageCount;
235
+ break;
236
+ case "cost":
237
+ comparison = a.totalCost - b.totalCost;
238
+ break;
239
+ }
240
+
241
+ return order === "desc" ? -comparison : comparison;
242
+ });
243
+ }
244
+
245
+ /**
246
+ * Find empty sessions (no messages)
247
+ */
248
+ findEmptySessions(sessions: SessionSummary[]): SessionSummary[] {
249
+ return sessions.filter((s) => s.messageCount === 0);
250
+ }
251
+
252
+ /**
253
+ * Find sessions by partial ID match
254
+ */
255
+ findById(sessions: SessionSummary[], partialId: string): SessionSummary | undefined {
256
+ return sessions.find((s) => s.id.startsWith(partialId) || s.id.includes(partialId));
257
+ }
258
+
259
+ /**
260
+ * Get unique models from sessions
261
+ */
262
+ getUniqueModels(sessions: SessionSummary[]): string[] {
263
+ const models = new Set(sessions.map((s) => s.model));
264
+ return [...models].sort();
265
+ }
266
+
267
+ /**
268
+ * Get unique working directories from sessions
269
+ */
270
+ getUniqueDirectories(sessions: SessionSummary[]): string[] {
271
+ const dirs = new Set(sessions.map((s) => s.workingDirectory));
272
+ return [...dirs].sort();
273
+ }
274
+
275
+ /**
276
+ * Calculate aggregate statistics
277
+ */
278
+ calculateStats(sessions: SessionSummary[]): {
279
+ totalSessions: number;
280
+ totalMessages: number;
281
+ totalCost: number;
282
+ totalInputTokens: number;
283
+ totalOutputTokens: number;
284
+ averageMessagesPerSession: number;
285
+ averageCostPerSession: number;
286
+ } {
287
+ const totalSessions = sessions.length;
288
+ const totalMessages = sessions.reduce((sum, s) => sum + s.messageCount, 0);
289
+ const totalCost = sessions.reduce((sum, s) => sum + s.totalCost, 0);
290
+ const totalInputTokens = sessions.reduce(
291
+ (sum, s) => sum + s.totalTokens.input,
292
+ 0
293
+ );
294
+ const totalOutputTokens = sessions.reduce(
295
+ (sum, s) => sum + s.totalTokens.output,
296
+ 0
297
+ );
298
+
299
+ return {
300
+ totalSessions,
301
+ totalMessages,
302
+ totalCost,
303
+ totalInputTokens,
304
+ totalOutputTokens,
305
+ averageMessagesPerSession: totalSessions > 0 ? totalMessages / totalSessions : 0,
306
+ averageCostPerSession: totalSessions > 0 ? totalCost / totalSessions : 0,
307
+ };
308
+ }
309
+ }
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Session Persistence - File operations for session storage
3
+ * Handles JSONL file I/O with atomic writes and queue management
4
+ */
5
+
6
+ import { homedir } from "os";
7
+ import { join } from "path";
8
+ import type {
9
+ SessionEntry,
10
+ SessionMetadata,
11
+ ISessionPersistence,
12
+ } from "./types.js";
13
+
14
+ export class SessionPersistence implements ISessionPersistence {
15
+ private sessionsDir: string;
16
+ private writeQueues: Map<string, Promise<void>> = new Map();
17
+
18
+ constructor(sessionsDir?: string) {
19
+ this.sessionsDir = sessionsDir ?? join(homedir(), ".claude", "sessions");
20
+ }
21
+
22
+ /**
23
+ * Get the sessions directory path
24
+ */
25
+ getSessionsDir(): string {
26
+ return this.sessionsDir;
27
+ }
28
+
29
+ /**
30
+ * Get the file path for a session
31
+ */
32
+ getSessionPath(sessionId: string): string {
33
+ return join(this.sessionsDir, `${sessionId}.jsonl`);
34
+ }
35
+
36
+ /**
37
+ * Initialize the sessions directory
38
+ */
39
+ async init(): Promise<void> {
40
+ try {
41
+ await Bun.write(join(this.sessionsDir, ".gitkeep"), "");
42
+ } catch {
43
+ // Directory might already exist
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Check if a session file exists
49
+ */
50
+ async exists(sessionId: string): Promise<boolean> {
51
+ const file = Bun.file(this.getSessionPath(sessionId));
52
+ return file.exists();
53
+ }
54
+
55
+ /**
56
+ * Read all entries from a session file
57
+ */
58
+ async read(sessionId: string): Promise<SessionEntry[]> {
59
+ const sessionFile = this.getSessionPath(sessionId);
60
+
61
+ try {
62
+ const content = await Bun.file(sessionFile).text();
63
+ if (!content) {
64
+ return [];
65
+ }
66
+
67
+ const entries: SessionEntry[] = [];
68
+ const lines = content.trim().split("\n");
69
+
70
+ for (const line of lines) {
71
+ if (!line.trim()) continue;
72
+ try {
73
+ entries.push(JSON.parse(line) as SessionEntry);
74
+ } catch {
75
+ // Skip malformed lines
76
+ }
77
+ }
78
+
79
+ return entries;
80
+ } catch {
81
+ return [];
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Append an entry to a session file (queued for atomic writes)
87
+ */
88
+ async append(
89
+ sessionId: string,
90
+ entry: SessionEntry | SessionMetadata
91
+ ): Promise<void> {
92
+ const sessionFile = this.getSessionPath(sessionId);
93
+
94
+ // Queue writes per session to ensure order
95
+ const existingQueue = this.writeQueues.get(sessionId) || Promise.resolve();
96
+
97
+ const newQueue = existingQueue.then(async () => {
98
+ const line = JSON.stringify(entry) + "\n";
99
+ const file = Bun.file(sessionFile);
100
+ const existing = (await file.exists()) ? await file.text() : "";
101
+ await Bun.write(sessionFile, existing + line);
102
+ });
103
+
104
+ this.writeQueues.set(sessionId, newQueue);
105
+
106
+ try {
107
+ await newQueue;
108
+ } finally {
109
+ // Clean up completed queue
110
+ if (this.writeQueues.get(sessionId) === newQueue) {
111
+ this.writeQueues.delete(sessionId);
112
+ }
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Write all entries to a session file (replaces existing)
118
+ */
119
+ async writeAll(sessionId: string, entries: SessionEntry[]): Promise<void> {
120
+ const sessionFile = this.getSessionPath(sessionId);
121
+ const content = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
122
+ await Bun.write(sessionFile, content);
123
+ }
124
+
125
+ /**
126
+ * Delete a session file
127
+ */
128
+ async delete(sessionId: string): Promise<boolean> {
129
+ const sessionFile = this.getSessionPath(sessionId);
130
+
131
+ try {
132
+ const file = Bun.file(sessionFile);
133
+ if (await file.exists()) {
134
+ const { unlink } = await import("fs/promises");
135
+ await unlink(sessionFile);
136
+ return true;
137
+ }
138
+ return false;
139
+ } catch {
140
+ return false;
141
+ }
142
+ }
143
+
144
+ /**
145
+ * List all session files in the directory
146
+ */
147
+ async listFiles(): Promise<string[]> {
148
+ await this.init();
149
+
150
+ try {
151
+ const glob = new Bun.Glob("*.jsonl");
152
+ const files = [...glob.scanSync(this.sessionsDir)];
153
+ return files.map((f) => f.replace(".jsonl", ""));
154
+ } catch {
155
+ return [];
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Get file stats for a session
161
+ */
162
+ async getStats(sessionId: string): Promise<{
163
+ exists: boolean;
164
+ size: number;
165
+ mtime: Date | null;
166
+ }> {
167
+ const sessionFile = this.getSessionPath(sessionId);
168
+
169
+ try {
170
+ const file = Bun.file(sessionFile);
171
+ const stat = await file.stat();
172
+
173
+ return {
174
+ exists: true,
175
+ size: stat?.size ?? 0,
176
+ mtime: stat?.mtime ?? null,
177
+ };
178
+ } catch {
179
+ return { exists: false, size: 0, mtime: null };
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Get modification times for multiple sessions
185
+ */
186
+ async getModificationTimes(sessionIds: string[]): Promise<Map<string, Date>> {
187
+ const times = new Map<string, Date>();
188
+
189
+ await Promise.all(
190
+ sessionIds.map(async (id) => {
191
+ const stats = await this.getStats(id);
192
+ if (stats.exists && stats.mtime) {
193
+ times.set(id, stats.mtime);
194
+ }
195
+ })
196
+ );
197
+
198
+ return times;
199
+ }
200
+
201
+ /**
202
+ * Read the first line (metadata) of a session file
203
+ */
204
+ async readMetadata(sessionId: string): Promise<SessionMetadata | null> {
205
+ const entries = await this.read(sessionId);
206
+
207
+ for (const entry of entries) {
208
+ // Metadata has explicit type field now
209
+ if ("type" in entry && entry.type === "metadata") {
210
+ return entry as SessionMetadata;
211
+ }
212
+ }
213
+
214
+ return null;
215
+ }
216
+
217
+ /**
218
+ * Read the last N entries from a session file
219
+ */
220
+ async readLast(sessionId: string, count: number): Promise<SessionEntry[]> {
221
+ const entries = await this.read(sessionId);
222
+ return entries.slice(-count);
223
+ }
224
+
225
+ /**
226
+ * Count entries in a session file
227
+ */
228
+ async countEntries(sessionId: string): Promise<number> {
229
+ const entries = await this.read(sessionId);
230
+ return entries.length;
231
+ }
232
+ }
233
+
234
+ // Singleton instance for convenience
235
+ let defaultPersistence: SessionPersistence | null = null;
236
+
237
+ export function getSessionPersistence(
238
+ sessionsDir?: string
239
+ ): SessionPersistence {
240
+ if (!defaultPersistence) {
241
+ defaultPersistence = new SessionPersistence(sessionsDir);
242
+ }
243
+ return defaultPersistence;
244
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Session Types - All type definitions for session handling
3
+ */
4
+
5
+ import type { Message, QueryMetrics } from "../../types/index.js";
6
+
7
+ // ============================================
8
+ // SESSION METADATA
9
+ // ============================================
10
+
11
+ export interface SessionMetadata {
12
+ type: "metadata";
13
+ id: string;
14
+ created: number;
15
+ updated: number;
16
+ model: string;
17
+ workingDirectory: string;
18
+ agentName?: string;
19
+ agentColor?: string;
20
+ teamName?: string;
21
+ totalCost?: number;
22
+ totalTokens?: { input: number; output: number };
23
+ }
24
+
25
+ // ============================================
26
+ // SESSION ENTRIES (JSONL lines)
27
+ // ============================================
28
+
29
+ export interface SessionMessage {
30
+ type: "message";
31
+ timestamp: number;
32
+ data: Message;
33
+ }
34
+
35
+ export interface SessionToolUse {
36
+ type: "tool_use";
37
+ timestamp: number;
38
+ toolId: string;
39
+ toolName: string;
40
+ input: Record<string, unknown>;
41
+ result?: string;
42
+ isError?: boolean;
43
+ }
44
+
45
+ export interface SessionMetrics {
46
+ type: "metrics";
47
+ timestamp: number;
48
+ data: QueryMetrics;
49
+ }
50
+
51
+ export interface SessionContext {
52
+ type: "context";
53
+ timestamp: number;
54
+ workingDirectory: string;
55
+ gitBranch?: string;
56
+ systemPrompt?: string;
57
+ }
58
+
59
+ export interface SessionCheckpoint {
60
+ type: "checkpoint";
61
+ timestamp: number;
62
+ checkpointId: string;
63
+ label?: string;
64
+ messageCount: number;
65
+ }
66
+
67
+ export type SessionEntry =
68
+ | SessionMetadata
69
+ | SessionMessage
70
+ | SessionToolUse
71
+ | SessionMetrics
72
+ | SessionContext
73
+ | SessionCheckpoint;
74
+
75
+ // ============================================
76
+ // LOADED SESSION
77
+ // ============================================
78
+
79
+ export interface LoadedSession {
80
+ metadata: SessionMetadata;
81
+ messages: Message[];
82
+ tools: SessionToolUse[];
83
+ metrics: QueryMetrics[];
84
+ context: SessionContext | null;
85
+ checkpoints: SessionCheckpoint[];
86
+ }
87
+
88
+ // ============================================
89
+ // SESSION SUMMARY (for listing)
90
+ // ============================================
91
+
92
+ export interface SessionSummary {
93
+ id: string;
94
+ created: number;
95
+ updated: number;
96
+ lastActivity?: number;
97
+ model: string;
98
+ messageCount: number;
99
+ totalCost: number;
100
+ totalTokens: { input: number; output: number };
101
+ firstMessage?: string;
102
+ workingDirectory: string;
103
+ metadata?: Record<string, unknown>;
104
+ // Additional fields for TUI compatibility
105
+ agentName?: string;
106
+ agentColor?: string;
107
+ teamName?: string;
108
+ }
109
+
110
+ // ============================================
111
+ // SESSION FILTERS
112
+ // ============================================
113
+
114
+ export interface SessionFilter {
115
+ model?: string;
116
+ workingDirectory?: string;
117
+ minMessages?: number;
118
+ maxAge?: number; // milliseconds
119
+ since?: number; // timestamp
120
+ }
121
+
122
+ // ============================================
123
+ // SESSION EVENTS
124
+ // ============================================
125
+
126
+ export type SessionEventType =
127
+ | "created"
128
+ | "resumed"
129
+ | "message_saved"
130
+ | "metrics_saved"
131
+ | "checkpoint_created"
132
+ | "deleted";
133
+
134
+ export interface SessionEvent {
135
+ type: SessionEventType;
136
+ sessionId: string;
137
+ timestamp: number;
138
+ data?: unknown;
139
+ }
140
+
141
+ export type SessionEventHandler = (event: SessionEvent) => void | Promise<void>;
142
+
143
+ // ============================================
144
+ // PERSISTENCE INTERFACE
145
+ // ============================================
146
+
147
+ export interface ISessionPersistence {
148
+ init(): Promise<void>;
149
+ read(sessionId: string): Promise<SessionEntry[]>;
150
+ append(sessionId: string, entry: SessionEntry | SessionMetadata): Promise<void>;
151
+ delete(sessionId: string): Promise<boolean>;
152
+ exists(sessionId: string): Promise<boolean>;
153
+ listFiles(): Promise<string[]>;
154
+ }
155
+
156
+ // ============================================
157
+ // EXPORT INTERFACE
158
+ // ============================================
159
+
160
+ export type ExportFormat = "jsonl" | "json" | "markdown";
161
+
162
+ export interface ISessionExporter {
163
+ export(session: LoadedSession, format: ExportFormat): string;
164
+ exportToFile(
165
+ sessionId: string,
166
+ format: ExportFormat,
167
+ outputPath?: string
168
+ ): Promise<string>;
169
+ }