@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,280 @@
1
+ /**
2
+ * Compaction Tests - Context compaction strategies
3
+ */
4
+
5
+ import { describe, it, expect, beforeEach } from "bun:test";
6
+ import {
7
+ handleProactiveCompaction,
8
+ handleReactiveCompaction,
9
+ needsCompaction,
10
+ DEFAULT_PROACTIVE_OPTIONS,
11
+ DEFAULT_REACTIVE_OPTIONS,
12
+ } from "../compaction.js";
13
+ import { LoopState } from "../loop-state.js";
14
+ import type { Message } from "../../../types/index.js";
15
+
16
+ // Helper to create messages with specific token counts
17
+ function createMessages(count: number, tokensPerMessage: number = 100): Message[] {
18
+ const messages: Message[] = [];
19
+ const charsPerMessage = tokensPerMessage * 4; // ~4 chars per token
20
+
21
+ for (let i = 0; i < count; i++) {
22
+ messages.push({
23
+ role: i % 2 === 0 ? "user" : "assistant",
24
+ content: [{
25
+ type: "text",
26
+ text: "x".repeat(charsPerMessage) + ` Message ${i}`,
27
+ }],
28
+ });
29
+ }
30
+
31
+ return messages;
32
+ }
33
+
34
+ describe("DEFAULT_PROACTIVE_OPTIONS", () => {
35
+ it("should have correct default values", () => {
36
+ expect(DEFAULT_PROACTIVE_OPTIONS.keepFirst).toBe(0);
37
+ expect(DEFAULT_PROACTIVE_OPTIONS.keepLast).toBe(3);
38
+ expect(DEFAULT_PROACTIVE_OPTIONS.preserveToolPairs).toBe(true);
39
+ });
40
+ });
41
+
42
+ describe("DEFAULT_REACTIVE_OPTIONS", () => {
43
+ it("should have correct default values", () => {
44
+ expect(DEFAULT_REACTIVE_OPTIONS.keepFirst).toBe(0);
45
+ expect(DEFAULT_REACTIVE_OPTIONS.keepLast).toBe(3);
46
+ expect(DEFAULT_REACTIVE_OPTIONS.preserveToolPairs).toBe(true);
47
+ });
48
+ });
49
+
50
+ describe("needsCompaction", () => {
51
+ it("should return false for small message sets", () => {
52
+ const messages = createMessages(5, 1000); // 5 messages, high tokens
53
+
54
+ // Should not need compaction because not enough messages
55
+ expect(needsCompaction(messages, 4096)).toBe(false);
56
+ });
57
+
58
+ it("should return false when under threshold", () => {
59
+ const messages = createMessages(10, 50); // 10 messages, low tokens each
60
+
61
+ // Under 90% threshold
62
+ expect(needsCompaction(messages, 4096)).toBe(false);
63
+ });
64
+
65
+ it("should return true when over threshold", () => {
66
+ const messages = createMessages(10, 500); // 10 messages, high tokens
67
+
68
+ // Over 90% threshold
69
+ expect(needsCompaction(messages, 4096)).toBe(true);
70
+ });
71
+
72
+ it("should respect custom threshold", () => {
73
+ // Create messages that are exactly at a specific token count
74
+ // 10 messages * 200 tokens = 2000 tokens total
75
+ const messages = createMessages(10, 200);
76
+ // Total ~2000 tokens, at 90% of 2000 = 1800 threshold
77
+ // 2000 >= 1800, so needs compaction at 0.9 threshold
78
+ expect(needsCompaction(messages, 2000, 0.9)).toBe(true);
79
+
80
+ // At 99% threshold (1980), 2000 >= 1980, so still needs compaction
81
+ expect(needsCompaction(messages, 2000, 0.99)).toBe(true);
82
+
83
+ // At 101% threshold (2020), 2000 < 2020, so no compaction needed
84
+ expect(needsCompaction(messages, 2000, 1.01)).toBe(false);
85
+ });
86
+ });
87
+
88
+ describe("handleProactiveCompaction", () => {
89
+ let state: LoopState;
90
+
91
+ beforeEach(() => {
92
+ // Create state with enough messages for compaction
93
+ const messages = createMessages(12, 500);
94
+ state = new LoopState(messages);
95
+ });
96
+
97
+ it("should return false when compaction not needed", async () => {
98
+ const smallState = new LoopState(createMessages(5, 50));
99
+
100
+ const result = await handleProactiveCompaction(smallState, 4096);
101
+
102
+ expect(result).toBe(false);
103
+ expect(smallState.compactionCount).toBe(0);
104
+ });
105
+
106
+ it("should apply compaction when needed", async () => {
107
+ const result = await handleProactiveCompaction(state, 4096);
108
+
109
+ // May or may not compact depending on actual token counts
110
+ // Just verify it doesn't throw
111
+ expect(typeof result).toBe("boolean");
112
+ });
113
+
114
+ it("should respect custom options", async () => {
115
+ const customOptions = {
116
+ keepFirst: 2,
117
+ keepLast: 5,
118
+ preserveToolPairs: false,
119
+ };
120
+
121
+ const result = await handleProactiveCompaction(state, 4096, customOptions);
122
+
123
+ expect(typeof result).toBe("boolean");
124
+ });
125
+ });
126
+
127
+ describe("handleReactiveCompaction", () => {
128
+ let state: LoopState;
129
+
130
+ beforeEach(() => {
131
+ const messages = createMessages(12, 500);
132
+ state = new LoopState(messages);
133
+ });
134
+
135
+ it("should attempt compaction on any message set", async () => {
136
+ const result = await handleReactiveCompaction(state, 4096);
137
+
138
+ expect(typeof result).toBe("boolean");
139
+ });
140
+
141
+ it("should return false if compaction does not reduce tokens", async () => {
142
+ // Very small state that can't be compacted meaningfully
143
+ const smallState = new LoopState(createMessages(2, 100));
144
+
145
+ const result = await handleReactiveCompaction(smallState, 4096);
146
+
147
+ expect(result).toBe(false);
148
+ });
149
+
150
+ it("should increment compaction count on success", async () => {
151
+ const initialCount = state.compactionCount;
152
+
153
+ await handleReactiveCompaction(state, 1000); // Force compaction with low limit
154
+
155
+ // If compaction succeeded, count should increase
156
+ // (depends on actual token counts)
157
+ });
158
+ });
159
+
160
+ describe("compaction with tool pairs", () => {
161
+ it("should preserve tool use/result pairs when enabled", async () => {
162
+ const messages: Message[] = [
163
+ { role: "user", content: [{ type: "text", text: "x".repeat(4000) }] },
164
+ { role: "assistant", content: [
165
+ { type: "tool_use", id: "tool1", name: "Read", input: { file_path: "/test" } },
166
+ ]},
167
+ { role: "user", content: [
168
+ { type: "tool_result", tool_use_id: "tool1", content: "result" },
169
+ ]},
170
+ { role: "assistant", content: [{ type: "text", text: "Done" }] },
171
+ ];
172
+
173
+ const state = new LoopState(messages);
174
+
175
+ // With preserveToolPairs: true
176
+ const result = await handleProactiveCompaction(state, 1000, {
177
+ keepFirst: 0,
178
+ keepLast: 1,
179
+ preserveToolPairs: true,
180
+ });
181
+
182
+ // Tool pairs should be considered for preservation
183
+ expect(typeof result).toBe("boolean");
184
+ });
185
+ });
186
+
187
+ describe("compaction state updates", () => {
188
+ it("should update state messages on successful compaction", async () => {
189
+ const messages = createMessages(15, 500);
190
+ const state = new LoopState(messages);
191
+ const originalLength = state.messages.length;
192
+
193
+ await handleProactiveCompaction(state, 2000); // Force compaction
194
+
195
+ // If compaction occurred, message count should decrease
196
+ // (depends on actual implementation)
197
+ });
198
+
199
+ it("should track total tokens compacted", async () => {
200
+ const messages = createMessages(15, 500);
201
+ const state = new LoopState(messages);
202
+
203
+ const initialCompacted = state.totalTokensCompacted;
204
+
205
+ await handleProactiveCompaction(state, 2000);
206
+
207
+ // If compaction succeeded, this should increase
208
+ // (depends on actual implementation)
209
+ });
210
+ });
211
+
212
+ describe("edge cases", () => {
213
+ it("should handle empty messages", async () => {
214
+ const state = new LoopState([]);
215
+
216
+ const result = await handleProactiveCompaction(state, 4096);
217
+
218
+ expect(result).toBe(false);
219
+ });
220
+
221
+ it("should handle single message", async () => {
222
+ const state = new LoopState(createMessages(1, 1000));
223
+
224
+ const result = await handleProactiveCompaction(state, 4096);
225
+
226
+ expect(result).toBe(false);
227
+ });
228
+
229
+ it("should handle messages exactly at threshold", async () => {
230
+ // Create messages that are exactly at the threshold
231
+ const messages = createMessages(8, 460); // ~3680 tokens, at 90% of 4096
232
+ const state = new LoopState(messages);
233
+
234
+ const result = await handleProactiveCompaction(state, 4096);
235
+
236
+ // Should need compaction at exactly 90%
237
+ expect(typeof result).toBe("boolean");
238
+ });
239
+
240
+ it("should handle very large individual messages", async () => {
241
+ const messages: Message[] = [
242
+ { role: "user", content: [{ type: "text", text: "x".repeat(100000) }] },
243
+ { role: "assistant", content: [{ type: "text", text: "Response" }] },
244
+ { role: "user", content: [{ type: "text", text: "Follow up" }] },
245
+ ];
246
+
247
+ const state = new LoopState(messages);
248
+
249
+ const result = await handleReactiveCompaction(state, 4096);
250
+
251
+ expect(typeof result).toBe("boolean");
252
+ });
253
+
254
+ it("should handle messages with mixed content types", async () => {
255
+ const messages: Message[] = [
256
+ { role: "user", content: [{ type: "text", text: "x".repeat(2000) }] },
257
+ { role: "assistant", content: [
258
+ { type: "tool_use", id: "t1", name: "Read", input: {} },
259
+ { type: "text", text: "Text after tool" },
260
+ ]},
261
+ { role: "user", content: [
262
+ { type: "tool_result", tool_use_id: "t1", content: "result" },
263
+ { type: "image", source: { type: "base64", data: "imagedata", media_type: "image/png" } },
264
+ ]},
265
+ ];
266
+
267
+ for (let i = 0; i < 6; i++) {
268
+ messages.push({
269
+ role: i % 2 === 0 ? "user" : "assistant",
270
+ content: [{ type: "text", text: "x".repeat(500) }],
271
+ });
272
+ }
273
+
274
+ const state = new LoopState(messages);
275
+
276
+ const result = await handleProactiveCompaction(state, 4096);
277
+
278
+ expect(typeof result).toBe("boolean");
279
+ });
280
+ });
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Formatters Tests - Cost and metrics display utilities
3
+ */
4
+
5
+ import { describe, it, expect } from "bun:test";
6
+ import {
7
+ formatCost,
8
+ formatMetrics,
9
+ formatCostBrief,
10
+ formatCacheMetrics,
11
+ } from "../formatters.js";
12
+ import type { QueryMetrics, CacheMetrics } from "../../../types/index.js";
13
+
14
+ describe("formatCost", () => {
15
+ it("should format small costs with 4 decimal places", () => {
16
+ expect(formatCost(0.001)).toBe("$0.0010");
17
+ expect(formatCost(0.0099)).toBe("$0.0099");
18
+ expect(formatCost(0.005)).toBe("$0.0050");
19
+ });
20
+
21
+ it("should format larger costs with 2 decimal places", () => {
22
+ expect(formatCost(0.01)).toBe("$0.01");
23
+ expect(formatCost(0.5)).toBe("$0.50");
24
+ expect(formatCost(1.0)).toBe("$1.00");
25
+ expect(formatCost(10.99)).toBe("$10.99");
26
+ expect(formatCost(100.0)).toBe("$100.00");
27
+ });
28
+
29
+ it("should handle zero cost", () => {
30
+ expect(formatCost(0)).toBe("$0.0000");
31
+ });
32
+
33
+ it("should handle very large costs", () => {
34
+ expect(formatCost(1000.0)).toBe("$1000.00");
35
+ expect(formatCost(9999.99)).toBe("$9999.99");
36
+ });
37
+ });
38
+
39
+ describe("formatMetrics", () => {
40
+ it("should format basic metrics without cache", () => {
41
+ const metrics: QueryMetrics = {
42
+ model: "claude-sonnet-4-6",
43
+ messageCount: 5,
44
+ messageTokens: 1500,
45
+ usage: { input_tokens: 1000, output_tokens: 500 },
46
+ durationMs: 2000,
47
+ ttftMs: 150,
48
+ costUSD: 0.05,
49
+ stopReason: "end_turn",
50
+ requestId: "req-123",
51
+ };
52
+
53
+ const result = formatMetrics(metrics);
54
+
55
+ expect(result).toContain("Cost: $0.05");
56
+ expect(result).toContain("1,000 input");
57
+ expect(result).toContain("500 output");
58
+ expect(result).not.toContain("Cache:");
59
+ });
60
+
61
+ it("should format metrics with cache information", () => {
62
+ const metrics: QueryMetrics = {
63
+ model: "claude-sonnet-4-6",
64
+ messageCount: 5,
65
+ messageTokens: 1500,
66
+ usage: {
67
+ input_tokens: 1000,
68
+ output_tokens: 500,
69
+ cache_read_input_tokens: 800,
70
+ cache_creation_input_tokens: 200,
71
+ },
72
+ durationMs: 2000,
73
+ ttftMs: 150,
74
+ costUSD: 0.03,
75
+ stopReason: "end_turn",
76
+ requestId: "req-123",
77
+ };
78
+
79
+ const result = formatMetrics(metrics);
80
+
81
+ expect(result).toContain("Cost: $0.03");
82
+ expect(result).toContain("800 read");
83
+ expect(result).toContain("200 write");
84
+ expect(result).toContain("Cache:");
85
+ });
86
+
87
+ it("should handle small costs with 4 decimals", () => {
88
+ const metrics: QueryMetrics = {
89
+ model: "claude-sonnet-4-6",
90
+ messageCount: 1,
91
+ messageTokens: 100,
92
+ usage: { input_tokens: 50, output_tokens: 50 },
93
+ durationMs: 500,
94
+ ttftMs: 100,
95
+ costUSD: 0.005,
96
+ stopReason: "end_turn",
97
+ requestId: "req-1",
98
+ };
99
+
100
+ const result = formatMetrics(metrics);
101
+ expect(result).toContain("$0.0050");
102
+ });
103
+
104
+ it("should format large token counts with locale separators", () => {
105
+ const metrics: QueryMetrics = {
106
+ model: "claude-sonnet-4-6",
107
+ messageCount: 100,
108
+ messageTokens: 500000,
109
+ usage: { input_tokens: 400000, output_tokens: 100000 },
110
+ durationMs: 10000,
111
+ ttftMs: 500,
112
+ costUSD: 5.0,
113
+ stopReason: "end_turn",
114
+ requestId: "req-123",
115
+ };
116
+
117
+ const result = formatMetrics(metrics);
118
+
119
+ expect(result).toContain("400,000 input");
120
+ expect(result).toContain("100,000 output");
121
+ });
122
+ });
123
+
124
+ describe("formatCostBrief", () => {
125
+ it("should format brief cost with total tokens", () => {
126
+ const metrics: QueryMetrics = {
127
+ model: "claude-sonnet-4-6",
128
+ messageCount: 5,
129
+ messageTokens: 1500,
130
+ usage: { input_tokens: 1000, output_tokens: 500 },
131
+ durationMs: 2000,
132
+ ttftMs: 150,
133
+ costUSD: 0.05,
134
+ stopReason: "end_turn",
135
+ requestId: "req-123",
136
+ };
137
+
138
+ const result = formatCostBrief(metrics);
139
+
140
+ expect(result).toContain("Cost: $0.05");
141
+ expect(result).toContain("1,500"); // Total tokens
142
+ expect(result).not.toContain("input");
143
+ expect(result).not.toContain("output");
144
+ });
145
+
146
+ it("should handle small costs", () => {
147
+ const metrics: QueryMetrics = {
148
+ model: "claude-sonnet-4-6",
149
+ messageCount: 1,
150
+ messageTokens: 100,
151
+ usage: { input_tokens: 50, output_tokens: 50 },
152
+ durationMs: 500,
153
+ ttftMs: 100,
154
+ costUSD: 0.001,
155
+ stopReason: "end_turn",
156
+ requestId: "req-1",
157
+ };
158
+
159
+ const result = formatCostBrief(metrics);
160
+ expect(result).toContain("$0.0010");
161
+ });
162
+ });
163
+
164
+ describe("formatCacheMetrics", () => {
165
+ it("should format cache metrics with all fields", () => {
166
+ const cacheMetrics: CacheMetrics = {
167
+ cacheHits: 50,
168
+ cacheMisses: 10,
169
+ totalCacheReadTokens: 50000,
170
+ totalCacheWriteTokens: 5000,
171
+ cacheHitRate: 0.833,
172
+ estimatedSavingsUSD: 0.25,
173
+ };
174
+
175
+ const result = formatCacheMetrics(cacheMetrics);
176
+
177
+ expect(result).toContain("83.3% hit rate");
178
+ expect(result).toContain("50,000 read");
179
+ expect(result).toContain("5,000 written");
180
+ expect(result).toContain("Saved: $0.25");
181
+ });
182
+
183
+ it("should handle zero cache activity", () => {
184
+ const cacheMetrics: CacheMetrics = {
185
+ cacheHits: 0,
186
+ cacheMisses: 0,
187
+ totalCacheReadTokens: 0,
188
+ totalCacheWriteTokens: 0,
189
+ cacheHitRate: 0,
190
+ estimatedSavingsUSD: 0,
191
+ };
192
+
193
+ const result = formatCacheMetrics(cacheMetrics);
194
+
195
+ expect(result).toContain("0.0% hit rate");
196
+ expect(result).toContain("0 read");
197
+ expect(result).toContain("0 written");
198
+ expect(result).toContain("Saved: $0.0000");
199
+ });
200
+
201
+ it("should handle 100% hit rate", () => {
202
+ const cacheMetrics: CacheMetrics = {
203
+ cacheHits: 100,
204
+ cacheMisses: 0,
205
+ totalCacheReadTokens: 100000,
206
+ totalCacheWriteTokens: 0,
207
+ cacheHitRate: 1.0,
208
+ estimatedSavingsUSD: 1.50,
209
+ };
210
+
211
+ const result = formatCacheMetrics(cacheMetrics);
212
+
213
+ expect(result).toContain("100.0% hit rate");
214
+ expect(result).toContain("100,000 read");
215
+ expect(result).toContain("Saved: $1.50");
216
+ });
217
+
218
+ it("should format large numbers with separators", () => {
219
+ const cacheMetrics: CacheMetrics = {
220
+ cacheHits: 1000,
221
+ cacheMisses: 100,
222
+ totalCacheReadTokens: 1000000,
223
+ totalCacheWriteTokens: 100000,
224
+ cacheHitRate: 0.909,
225
+ estimatedSavingsUSD: 10.0,
226
+ };
227
+
228
+ const result = formatCacheMetrics(cacheMetrics);
229
+
230
+ expect(result).toContain("1,000,000 read");
231
+ expect(result).toContain("100,000 written");
232
+ expect(result).toContain("90.9% hit rate");
233
+ });
234
+ });
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Agent Loop Index Tests - Main entry point and exports
3
+ */
4
+
5
+ import { describe, it, expect } from "bun:test";
6
+ import {
7
+ agentLoop,
8
+ formatCost,
9
+ formatMetrics,
10
+ formatCostBrief,
11
+ formatCacheMetrics,
12
+ LoopState,
13
+ executeTools,
14
+ buildAPIMessages,
15
+ injectReminderIntoContent,
16
+ handleProactiveCompaction,
17
+ handleReactiveCompaction,
18
+ needsCompaction,
19
+ estimateMessagesTokens,
20
+ DEFAULT_PROACTIVE_OPTIONS,
21
+ DEFAULT_REACTIVE_OPTIONS,
22
+ } from "../index.js";
23
+ import type { AgentLoopOptions, AgentLoopResult } from "../index.js";
24
+
25
+ describe("exports", () => {
26
+ it("should export agentLoop function", () => {
27
+ expect(typeof agentLoop).toBe("function");
28
+ });
29
+
30
+ it("should export formatter functions", () => {
31
+ expect(typeof formatCost).toBe("function");
32
+ expect(typeof formatMetrics).toBe("function");
33
+ expect(typeof formatCostBrief).toBe("function");
34
+ expect(typeof formatCacheMetrics).toBe("function");
35
+ });
36
+
37
+ it("should export LoopState class", () => {
38
+ expect(LoopState).toBeDefined();
39
+ expect(typeof LoopState).toBe("function");
40
+ });
41
+
42
+ it("should export executeTools function", () => {
43
+ expect(typeof executeTools).toBe("function");
44
+ });
45
+
46
+ it("should export message builder functions", () => {
47
+ expect(typeof buildAPIMessages).toBe("function");
48
+ expect(typeof injectReminderIntoContent).toBe("function");
49
+ });
50
+
51
+ it("should export compaction functions and constants", () => {
52
+ expect(typeof handleProactiveCompaction).toBe("function");
53
+ expect(typeof handleReactiveCompaction).toBe("function");
54
+ expect(typeof needsCompaction).toBe("function");
55
+ expect(typeof estimateMessagesTokens).toBe("function");
56
+ expect(DEFAULT_PROACTIVE_OPTIONS).toBeDefined();
57
+ expect(DEFAULT_REACTIVE_OPTIONS).toBeDefined();
58
+ });
59
+ });
60
+
61
+ describe("AgentLoopOptions type", () => {
62
+ it("should have required apiKey field", () => {
63
+ const options: AgentLoopOptions = {
64
+ apiKey: "test-key",
65
+ systemPrompt: "Test prompt",
66
+ tools: [],
67
+ permissionMode: "bypassPermissions",
68
+ workingDirectory: "/test",
69
+ };
70
+
71
+ expect(options.apiKey).toBe("test-key");
72
+ });
73
+
74
+ it("should have optional fields with defaults", () => {
75
+ const options: AgentLoopOptions = {
76
+ apiKey: "test-key",
77
+ systemPrompt: "Test prompt",
78
+ tools: [],
79
+ permissionMode: "default",
80
+ workingDirectory: "/test",
81
+ };
82
+
83
+ // Optional fields should be accessible
84
+ expect(options.model).toBeUndefined();
85
+ expect(options.maxTokens).toBeUndefined();
86
+ expect(options.hookManager).toBeUndefined();
87
+ });
88
+ });
89
+
90
+ describe("AgentLoopResult type", () => {
91
+ it("should contain all expected fields", () => {
92
+ // Create a result via LoopState to verify type compatibility
93
+ const state = new LoopState([]);
94
+ const result: AgentLoopResult = state.toResult();
95
+
96
+ expect(result.messages).toBeDefined();
97
+ expect(result.metrics).toBeDefined();
98
+ expect(typeof result.totalCost).toBe("number");
99
+ expect(typeof result.totalDuration).toBe("number");
100
+ expect(result.totalCacheMetrics).toBeDefined();
101
+ expect(typeof result.compactionCount).toBe("number");
102
+ expect(typeof result.totalTokensCompacted).toBe("number");
103
+ });
104
+ });
105
+
106
+ describe("agentLoop function signature", () => {
107
+ it("should accept AgentLoopOptions and return Promise<AgentLoopResult>", () => {
108
+ // Type check only - don't actually run it
109
+ const checkSignature = async (): Promise<void> => {
110
+ const options: AgentLoopOptions = {
111
+ apiKey: "test",
112
+ systemPrompt: "test",
113
+ tools: [],
114
+ permissionMode: "bypassPermissions",
115
+ workingDirectory: "/test",
116
+ };
117
+
118
+ // This would actually call the API, so we just verify the type
119
+ const _typeCheck: () => Promise<AgentLoopResult> = () => agentLoop([], options);
120
+
121
+ // Verify the function exists and has correct signature
122
+ expect(typeof agentLoop).toBe("function");
123
+ };
124
+
125
+ // Just verify no type errors
126
+ expect(checkSignature).toBeDefined();
127
+ });
128
+ });
129
+
130
+ describe("re-exports from submodules", () => {
131
+ it("should re-export LoopState correctly", () => {
132
+ const state = new LoopState([
133
+ { role: "user", content: [{ type: "text", text: "test" }] },
134
+ ]);
135
+
136
+ expect(state.messages).toHaveLength(1);
137
+ expect(state.turnNumber).toBe(0);
138
+ });
139
+
140
+ it("should re-export formatters with correct behavior", () => {
141
+ expect(formatCost(0.005)).toBe("$0.0050");
142
+ expect(formatCost(1.5)).toBe("$1.50");
143
+ });
144
+
145
+ it("should re-export message builder functions", () => {
146
+ const messages = [
147
+ { role: "user" as const, content: [{ type: "text" as const, text: "Hello" }] },
148
+ ];
149
+
150
+ const result = buildAPIMessages(messages, "System", "Reminder");
151
+
152
+ expect(result).toHaveLength(1);
153
+ expect((result[0]?.content[0] as any).text).toContain("Reminder");
154
+ });
155
+
156
+ it("should re-export compaction constants", () => {
157
+ expect(DEFAULT_PROACTIVE_OPTIONS.keepFirst).toBe(0);
158
+ expect(DEFAULT_PROACTIVE_OPTIONS.keepLast).toBe(3);
159
+ expect(DEFAULT_REACTIVE_OPTIONS.keepFirst).toBe(0);
160
+ expect(DEFAULT_REACTIVE_OPTIONS.keepLast).toBe(3);
161
+ });
162
+ });