@ebowwa/coder 0.7.63 → 0.7.65

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 (364) hide show
  1. package/dist/core/__tests__/permissions.test.d.ts +12 -0
  2. package/dist/core/__tests__/permissions.test.d.ts.map +1 -0
  3. package/dist/core/__tests__/permissions.test.js +851 -0
  4. package/dist/core/agent-loop/__tests__/compaction.test.d.ts +5 -0
  5. package/dist/core/agent-loop/__tests__/compaction.test.d.ts.map +1 -0
  6. package/dist/core/agent-loop/__tests__/compaction.test.js +209 -0
  7. package/dist/core/agent-loop/__tests__/formatters.test.d.ts +5 -0
  8. package/dist/core/agent-loop/__tests__/formatters.test.d.ts.map +1 -0
  9. package/dist/core/agent-loop/__tests__/formatters.test.js +195 -0
  10. package/dist/core/agent-loop/__tests__/index.test.d.ts +5 -0
  11. package/dist/core/agent-loop/__tests__/index.test.d.ts.map +1 -0
  12. package/dist/core/agent-loop/__tests__/index.test.js +121 -0
  13. package/dist/core/agent-loop/__tests__/loop-state.test.d.ts +5 -0
  14. package/dist/core/agent-loop/__tests__/loop-state.test.d.ts.map +1 -0
  15. package/dist/core/agent-loop/__tests__/loop-state.test.js +340 -0
  16. package/dist/core/agent-loop/__tests__/message-builder.test.d.ts +5 -0
  17. package/dist/core/agent-loop/__tests__/message-builder.test.d.ts.map +1 -0
  18. package/dist/core/agent-loop/__tests__/message-builder.test.js +178 -0
  19. package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts +5 -0
  20. package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts.map +1 -0
  21. package/dist/core/agent-loop/__tests__/tool-executor.test.js +331 -0
  22. package/dist/core/agent-loop/compaction.d.ts +39 -0
  23. package/dist/core/agent-loop/compaction.d.ts.map +1 -0
  24. package/dist/core/agent-loop/compaction.js +51 -0
  25. package/dist/core/agent-loop/formatters.d.ts +21 -0
  26. package/dist/core/agent-loop/formatters.d.ts.map +1 -0
  27. package/dist/core/agent-loop/formatters.js +42 -0
  28. package/dist/core/agent-loop/index.d.ts +25 -0
  29. package/dist/core/agent-loop/index.d.ts.map +1 -0
  30. package/dist/core/agent-loop/index.js +83 -0
  31. package/dist/core/agent-loop/loop-state.d.ts +74 -0
  32. package/dist/core/agent-loop/loop-state.d.ts.map +1 -0
  33. package/dist/core/agent-loop/loop-state.js +147 -0
  34. package/dist/core/agent-loop/message-builder.d.ts +13 -0
  35. package/dist/core/agent-loop/message-builder.d.ts.map +1 -0
  36. package/dist/core/agent-loop/message-builder.js +49 -0
  37. package/dist/core/agent-loop/tool-executor.d.ts +23 -0
  38. package/dist/core/agent-loop/tool-executor.d.ts.map +1 -0
  39. package/dist/core/agent-loop/tool-executor.js +152 -0
  40. package/dist/core/agent-loop/turn-executor.d.ts +57 -0
  41. package/dist/core/agent-loop/turn-executor.d.ts.map +1 -0
  42. package/dist/core/agent-loop/turn-executor.js +124 -0
  43. package/dist/core/agent-loop/types.d.ts +141 -0
  44. package/dist/core/agent-loop/types.d.ts.map +1 -0
  45. package/dist/core/agent-loop/types.js +4 -0
  46. package/dist/core/agent-loop.d.ts +17 -0
  47. package/dist/core/agent-loop.d.ts.map +1 -0
  48. package/dist/core/agent-loop.js +16 -0
  49. package/dist/core/api-client-impl.d.ts +62 -0
  50. package/dist/core/api-client-impl.d.ts.map +1 -0
  51. package/dist/core/api-client-impl.js +479 -0
  52. package/dist/core/api-client.d.ts +6 -0
  53. package/dist/core/api-client.d.ts.map +1 -0
  54. package/dist/core/api-client.js +5 -0
  55. package/dist/core/checkpoints.d.ts +128 -0
  56. package/dist/core/checkpoints.d.ts.map +1 -0
  57. package/dist/core/checkpoints.js +438 -0
  58. package/dist/core/claude-md.d.ts +71 -0
  59. package/dist/core/claude-md.d.ts.map +1 -0
  60. package/dist/core/claude-md.js +198 -0
  61. package/dist/core/cognitive-security/hooks.d.ts +138 -0
  62. package/dist/core/cognitive-security/hooks.d.ts.map +1 -0
  63. package/dist/core/cognitive-security/hooks.js +389 -0
  64. package/dist/core/cognitive-security/index.d.ts +751 -0
  65. package/dist/core/cognitive-security/index.d.ts.map +1 -0
  66. package/dist/core/cognitive-security/index.js +1123 -0
  67. package/dist/core/cognitive-security/middleware.d.ts +136 -0
  68. package/dist/core/cognitive-security/middleware.d.ts.map +1 -0
  69. package/dist/core/cognitive-security/middleware.js +376 -0
  70. package/dist/core/config-loader.d.ts +127 -0
  71. package/dist/core/config-loader.d.ts.map +1 -0
  72. package/dist/core/config-loader.js +219 -0
  73. package/dist/core/context-compaction.d.ts +87 -0
  74. package/dist/core/context-compaction.d.ts.map +1 -0
  75. package/dist/core/context-compaction.js +428 -0
  76. package/dist/core/git-status.d.ts +25 -0
  77. package/dist/core/git-status.d.ts.map +1 -0
  78. package/dist/core/git-status.js +204 -0
  79. package/dist/core/image.d.ts +69 -0
  80. package/dist/core/image.d.ts.map +1 -0
  81. package/dist/core/image.js +290 -0
  82. package/dist/core/image.test.d.ts +2 -0
  83. package/dist/core/image.test.d.ts.map +1 -0
  84. package/dist/core/image.test.js +149 -0
  85. package/dist/core/models.d.ts +123 -0
  86. package/dist/core/models.d.ts.map +1 -0
  87. package/dist/core/models.js +325 -0
  88. package/dist/core/permissions.d.ts +81 -0
  89. package/dist/core/permissions.d.ts.map +1 -0
  90. package/dist/core/permissions.js +327 -0
  91. package/dist/core/retry.d.ts +25 -0
  92. package/dist/core/retry.d.ts.map +1 -0
  93. package/dist/core/retry.js +121 -0
  94. package/dist/core/session-store.d.ts +9 -0
  95. package/dist/core/session-store.d.ts.map +1 -0
  96. package/dist/core/session-store.js +10 -0
  97. package/dist/core/sessions/export.d.ts +47 -0
  98. package/dist/core/sessions/export.d.ts.map +1 -0
  99. package/dist/core/sessions/export.js +256 -0
  100. package/dist/core/sessions/index.d.ts +132 -0
  101. package/dist/core/sessions/index.d.ts.map +1 -0
  102. package/dist/core/sessions/index.js +442 -0
  103. package/dist/core/sessions/metadata.d.ts +77 -0
  104. package/dist/core/sessions/metadata.d.ts.map +1 -0
  105. package/dist/core/sessions/metadata.js +233 -0
  106. package/dist/core/sessions/persistence.d.ts +72 -0
  107. package/dist/core/sessions/persistence.d.ts.map +1 -0
  108. package/dist/core/sessions/persistence.js +201 -0
  109. package/dist/core/sessions/types.d.ts +110 -0
  110. package/dist/core/sessions/types.d.ts.map +1 -0
  111. package/dist/core/sessions/types.js +4 -0
  112. package/dist/core/stream-highlighter.d.ts +18 -0
  113. package/dist/core/stream-highlighter.d.ts.map +1 -0
  114. package/dist/core/stream-highlighter.js +916 -0
  115. package/dist/core/system-reminders.d.ts +89 -0
  116. package/dist/core/system-reminders.d.ts.map +1 -0
  117. package/dist/core/system-reminders.js +285 -0
  118. package/dist/ecosystem/hooks/__tests__/index.test.d.ts +5 -0
  119. package/dist/ecosystem/hooks/__tests__/index.test.d.ts.map +1 -0
  120. package/dist/ecosystem/hooks/__tests__/index.test.js +458 -0
  121. package/dist/ecosystem/hooks/index.d.ts +59 -0
  122. package/dist/ecosystem/hooks/index.d.ts.map +1 -0
  123. package/dist/ecosystem/hooks/index.js +294 -0
  124. package/dist/ecosystem/hooks/prompt-evaluator.d.ts +32 -0
  125. package/dist/ecosystem/hooks/prompt-evaluator.d.ts.map +1 -0
  126. package/dist/ecosystem/hooks/prompt-evaluator.js +229 -0
  127. package/dist/ecosystem/skills/index.d.ts +55 -0
  128. package/dist/ecosystem/skills/index.d.ts.map +1 -0
  129. package/dist/ecosystem/skills/index.js +258 -0
  130. package/dist/ecosystem/tools/__tests__/index.test.d.ts +7 -0
  131. package/dist/ecosystem/tools/__tests__/index.test.d.ts.map +1 -0
  132. package/dist/ecosystem/tools/__tests__/index.test.js +856 -0
  133. package/dist/ecosystem/tools/index.d.ts +24 -0
  134. package/dist/ecosystem/tools/index.d.ts.map +1 -0
  135. package/dist/ecosystem/tools/index.js +1709 -0
  136. package/dist/index.d.ts +24 -0
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.js +33688 -49712
  139. package/dist/interfaces/mcp/client.d.ts +40 -0
  140. package/dist/interfaces/mcp/client.d.ts.map +1 -0
  141. package/dist/interfaces/mcp/client.js +309 -0
  142. package/dist/interfaces/ui/index.d.ts +36 -0
  143. package/dist/interfaces/ui/index.d.ts.map +1 -0
  144. package/dist/interfaces/ui/index.js +61 -0
  145. package/dist/interfaces/ui/spinner.d.ts +140 -0
  146. package/dist/interfaces/ui/spinner.d.ts.map +1 -0
  147. package/dist/interfaces/ui/spinner.js +342 -0
  148. package/dist/interfaces/ui/terminal/cli/index.d.ts +12 -0
  149. package/dist/interfaces/ui/terminal/cli/index.d.ts.map +1 -0
  150. package/dist/interfaces/ui/terminal/cli/index.js +32012 -50526
  151. package/dist/interfaces/ui/terminal/native/README.md +53 -0
  152. package/dist/interfaces/ui/terminal/native/claude_code_native.darwin-x64.node +0 -0
  153. package/dist/interfaces/ui/terminal/native/claude_code_native.dylib +0 -0
  154. package/dist/interfaces/ui/terminal/native/index.d.ts +0 -0
  155. package/dist/interfaces/ui/terminal/native/index.darwin-arm64.node +0 -0
  156. package/dist/interfaces/ui/terminal/native/index.js +43 -0
  157. package/dist/interfaces/ui/terminal/native/index.node +0 -0
  158. package/dist/interfaces/ui/terminal/native/package.json +34 -0
  159. package/dist/interfaces/ui/terminal/shared/args.d.ts +39 -0
  160. package/dist/interfaces/ui/terminal/shared/args.d.ts.map +1 -0
  161. package/dist/interfaces/ui/terminal/shared/args.js +176 -0
  162. package/dist/interfaces/ui/terminal/shared/index.d.ts +11 -0
  163. package/dist/interfaces/ui/terminal/shared/index.d.ts.map +1 -0
  164. package/dist/interfaces/ui/terminal/shared/index.js +16 -0
  165. package/dist/interfaces/ui/terminal/shared/loading-state.d.ts +124 -0
  166. package/dist/interfaces/ui/terminal/shared/loading-state.d.ts.map +1 -0
  167. package/dist/interfaces/ui/terminal/shared/loading-state.js +246 -0
  168. package/dist/interfaces/ui/terminal/shared/query.d.ts +22 -0
  169. package/dist/interfaces/ui/terminal/shared/query.d.ts.map +1 -0
  170. package/dist/interfaces/ui/terminal/shared/query.js +100 -0
  171. package/dist/interfaces/ui/terminal/shared/setup.d.ts +33 -0
  172. package/dist/interfaces/ui/terminal/shared/setup.d.ts.map +1 -0
  173. package/dist/interfaces/ui/terminal/shared/setup.js +226 -0
  174. package/dist/interfaces/ui/terminal/shared/status-line.d.ts +117 -0
  175. package/dist/interfaces/ui/terminal/shared/status-line.d.ts.map +1 -0
  176. package/dist/interfaces/ui/terminal/shared/status-line.js +267 -0
  177. package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts +38 -0
  178. package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts.map +1 -0
  179. package/dist/interfaces/ui/terminal/shared/system-prompt.js +102 -0
  180. package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts +39 -0
  181. package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts.map +1 -0
  182. package/dist/interfaces/ui/terminal/tui/HelpPanel.js +215 -0
  183. package/dist/interfaces/ui/terminal/tui/InputContext.d.ts +91 -0
  184. package/dist/interfaces/ui/terminal/tui/InputContext.d.ts.map +1 -0
  185. package/dist/interfaces/ui/terminal/tui/InputContext.js +154 -0
  186. package/dist/interfaces/ui/terminal/tui/InputField.d.ts +18 -0
  187. package/dist/interfaces/ui/terminal/tui/InputField.d.ts.map +1 -0
  188. package/dist/interfaces/ui/terminal/tui/InputField.js +41 -0
  189. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts +16 -0
  190. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts.map +1 -0
  191. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.js +451 -0
  192. package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts +10 -0
  193. package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts.map +1 -0
  194. package/dist/interfaces/ui/terminal/tui/MessageArea.js +91 -0
  195. package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts +48 -0
  196. package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts.map +1 -0
  197. package/dist/interfaces/ui/terminal/tui/MessageStore.js +151 -0
  198. package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts +9 -0
  199. package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts.map +1 -0
  200. package/dist/interfaces/ui/terminal/tui/StatusBar.js +36 -0
  201. package/dist/interfaces/ui/terminal/tui/commands.d.ts +21 -0
  202. package/dist/interfaces/ui/terminal/tui/commands.d.ts.map +1 -0
  203. package/dist/interfaces/ui/terminal/tui/commands.js +359 -0
  204. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts +115 -0
  205. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts.map +1 -0
  206. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.js +306 -0
  207. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts +92 -0
  208. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts.map +1 -0
  209. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.js +399 -0
  210. package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts +59 -0
  211. package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts.map +1 -0
  212. package/dist/interfaces/ui/terminal/tui/components/PaneManager.js +139 -0
  213. package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts +68 -0
  214. package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts.map +1 -0
  215. package/dist/interfaces/ui/terminal/tui/components/Sidebar.js +340 -0
  216. package/dist/interfaces/ui/terminal/tui/components/index.d.ts +23 -0
  217. package/dist/interfaces/ui/terminal/tui/components/index.d.ts.map +1 -0
  218. package/dist/interfaces/ui/terminal/tui/components/index.js +51 -0
  219. package/dist/interfaces/ui/terminal/tui/console.d.ts +20 -0
  220. package/dist/interfaces/ui/terminal/tui/console.d.ts.map +1 -0
  221. package/dist/interfaces/ui/terminal/tui/console.js +46 -0
  222. package/dist/interfaces/ui/terminal/tui/index.d.ts +20 -0
  223. package/dist/interfaces/ui/terminal/tui/index.d.ts.map +1 -0
  224. package/dist/interfaces/ui/terminal/tui/index.js +28 -0
  225. package/dist/interfaces/ui/terminal/tui/run.d.ts +13 -0
  226. package/dist/interfaces/ui/terminal/tui/run.d.ts.map +1 -0
  227. package/dist/interfaces/ui/terminal/tui/run.js +31 -0
  228. package/dist/interfaces/ui/terminal/tui/spinner.d.ts +44 -0
  229. package/dist/interfaces/ui/terminal/tui/spinner.d.ts.map +1 -0
  230. package/dist/interfaces/ui/terminal/tui/spinner.js +59 -0
  231. package/dist/interfaces/ui/terminal/tui/tui-app.d.ts +39 -0
  232. package/dist/interfaces/ui/terminal/tui/tui-app.d.ts.map +1 -0
  233. package/dist/interfaces/ui/terminal/tui/tui-app.js +198 -0
  234. package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts +167 -0
  235. package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts.map +1 -0
  236. package/dist/interfaces/ui/terminal/tui/tui-footer.js +330 -0
  237. package/dist/interfaces/ui/terminal/tui/types.d.ts +165 -0
  238. package/dist/interfaces/ui/terminal/tui/types.d.ts.map +1 -0
  239. package/dist/interfaces/ui/terminal/tui/types.js +5 -0
  240. package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts +23 -0
  241. package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts.map +1 -0
  242. package/dist/interfaces/ui/terminal/tui/useInputHandler.js +72 -0
  243. package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts +90 -0
  244. package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts.map +1 -0
  245. package/dist/interfaces/ui/terminal/tui/useNativeInput.js +188 -0
  246. package/dist/native/README.md +53 -0
  247. package/dist/native/claude_code_native.darwin-x64.node +0 -0
  248. package/dist/native/claude_code_native.dylib +0 -0
  249. package/dist/native/index.d.ts +0 -0
  250. package/dist/native/index.d.ts.map +1 -0
  251. package/dist/native/index.darwin-arm64.node +0 -0
  252. package/dist/native/index.js +43 -0
  253. package/dist/native/index.node +0 -0
  254. package/dist/native/package.json +34 -0
  255. package/dist/teammates/index.d.ts +161 -0
  256. package/dist/teammates/index.d.ts.map +1 -0
  257. package/dist/teammates/index.js +827 -0
  258. package/dist/types/index.d.ts +482 -0
  259. package/dist/types/index.d.ts.map +1 -0
  260. package/dist/types/index.js +52 -0
  261. package/native/index.darwin-arm64.node +0 -0
  262. package/native/index.js +33 -19
  263. package/package.json +6 -3
  264. package/packages/src/core/__tests__/permissions.test.ts +1091 -0
  265. package/packages/src/core/agent-loop/__tests__/compaction.test.ts +283 -0
  266. package/packages/src/core/agent-loop/__tests__/formatters.test.ts +234 -0
  267. package/packages/src/core/agent-loop/__tests__/index.test.ts +162 -0
  268. package/packages/src/core/agent-loop/__tests__/loop-state.test.ts +413 -0
  269. package/packages/src/core/agent-loop/__tests__/message-builder.test.ts +229 -0
  270. package/packages/src/core/agent-loop/__tests__/tool-executor.test.ts +457 -0
  271. package/packages/src/core/agent-loop/compaction.ts +92 -0
  272. package/packages/src/core/agent-loop/formatters.ts +50 -0
  273. package/packages/src/core/agent-loop/index.ts +137 -0
  274. package/packages/src/core/agent-loop/loop-state.ts +187 -0
  275. package/packages/src/core/agent-loop/message-builder.ts +62 -0
  276. package/packages/src/core/agent-loop/tool-executor.ts +211 -0
  277. package/packages/src/core/agent-loop/turn-executor.ts +226 -0
  278. package/packages/src/core/agent-loop/types.ts +152 -0
  279. package/packages/src/core/agent-loop.ts +18 -0
  280. package/packages/src/core/api-client-impl.ts +729 -0
  281. package/packages/src/core/api-client.ts +6 -0
  282. package/packages/src/core/checkpoints.ts +606 -0
  283. package/packages/src/core/claude-md.ts +272 -0
  284. package/packages/src/core/cognitive-security/hooks.ts +591 -0
  285. package/packages/src/core/cognitive-security/index.ts +2041 -0
  286. package/packages/src/core/cognitive-security/middleware.ts +536 -0
  287. package/packages/src/core/config/todo +7 -0
  288. package/packages/src/core/config-loader.ts +324 -0
  289. package/packages/src/core/context/__tests__/integration.test.ts +334 -0
  290. package/packages/src/core/context/compaction.ts +170 -0
  291. package/packages/src/core/context/constants.ts +58 -0
  292. package/packages/src/core/context/extraction.ts +85 -0
  293. package/packages/src/core/context/index.ts +66 -0
  294. package/packages/src/core/context/summarization.ts +251 -0
  295. package/packages/src/core/context/token-estimation.ts +98 -0
  296. package/packages/src/core/context/types.ts +59 -0
  297. package/packages/src/core/git-status.ts +262 -0
  298. package/packages/src/core/image.test.ts +180 -0
  299. package/packages/src/core/image.ts +350 -0
  300. package/packages/src/core/lmdb.db +0 -0
  301. package/packages/src/core/lmdb.db-lock +0 -0
  302. package/packages/src/core/models.ts +507 -0
  303. package/packages/src/core/normalizers/todo +8 -0
  304. package/packages/src/core/permissions.ts +431 -0
  305. package/packages/src/core/providers/README.md +230 -0
  306. package/packages/src/core/providers/__tests__/providers.test.ts +135 -0
  307. package/packages/src/core/providers/index.ts +419 -0
  308. package/packages/src/core/providers/types.ts +132 -0
  309. package/packages/src/core/retry.ts +180 -0
  310. package/packages/src/core/session-store.ts +36 -0
  311. package/packages/src/core/sessions/export.ts +329 -0
  312. package/packages/src/core/sessions/index.ts +587 -0
  313. package/packages/src/core/sessions/metadata.ts +309 -0
  314. package/packages/src/core/sessions/persistence.ts +244 -0
  315. package/packages/src/core/sessions/types.ts +169 -0
  316. package/packages/src/core/stream-highlighter.ts +1123 -0
  317. package/packages/src/core/system-reminders.ts +402 -0
  318. package/packages/src/core/todo +8 -0
  319. package/packages/src/ecosystem/hooks/__tests__/index.test.ts +561 -0
  320. package/packages/src/ecosystem/hooks/index.ts +341 -0
  321. package/packages/src/ecosystem/hooks/prompt-evaluator.ts +300 -0
  322. package/packages/src/ecosystem/skills/index.ts +295 -0
  323. package/packages/src/ecosystem/tools/__tests__/index.test.ts +1335 -0
  324. package/packages/src/ecosystem/tools/index.ts +2051 -0
  325. package/packages/src/index.ts +141 -0
  326. package/packages/src/interfaces/mcp/client.ts +389 -0
  327. package/packages/src/interfaces/ui/index.ts +158 -0
  328. package/packages/src/interfaces/ui/lmdb.db +0 -0
  329. package/packages/src/interfaces/ui/lmdb.db-lock +0 -0
  330. package/packages/src/interfaces/ui/spinner.ts +451 -0
  331. package/packages/src/interfaces/ui/terminal/bridge/index.ts +370 -0
  332. package/packages/src/interfaces/ui/terminal/bridge/ipc.ts +829 -0
  333. package/packages/src/interfaces/ui/terminal/bridge/screen-export.ts +968 -0
  334. package/packages/src/interfaces/ui/terminal/bridge/types.ts +226 -0
  335. package/packages/src/interfaces/ui/terminal/bridge/useBridge.ts +210 -0
  336. package/packages/src/interfaces/ui/terminal/cli/bootstrap.ts +132 -0
  337. package/packages/src/interfaces/ui/terminal/cli/index.ts +415 -0
  338. package/packages/src/interfaces/ui/terminal/cli/interactive/index.ts +110 -0
  339. package/packages/src/interfaces/ui/terminal/cli/interactive/input-handler.ts +393 -0
  340. package/packages/src/interfaces/ui/terminal/cli/interactive/interactive-runner.ts +820 -0
  341. package/packages/src/interfaces/ui/terminal/cli/interactive/message-store.ts +299 -0
  342. package/packages/src/interfaces/ui/terminal/cli/interactive/types.ts +274 -0
  343. package/packages/src/interfaces/ui/terminal/lmdb.db +0 -0
  344. package/packages/src/interfaces/ui/terminal/lmdb.db-lock +0 -0
  345. package/packages/src/interfaces/ui/terminal/shared/args.ts +222 -0
  346. package/packages/src/interfaces/ui/terminal/shared/index.ts +84 -0
  347. package/packages/src/interfaces/ui/terminal/shared/loading-state.ts +322 -0
  348. package/packages/src/interfaces/ui/terminal/shared/query.ts +152 -0
  349. package/packages/src/interfaces/ui/terminal/shared/setup.ts +299 -0
  350. package/packages/src/interfaces/ui/terminal/shared/spinner-frames.ts +73 -0
  351. package/packages/src/interfaces/ui/terminal/shared/status-line.ts +366 -0
  352. package/packages/src/interfaces/ui/terminal/shared/system-prompt.ts +146 -0
  353. package/packages/src/lmdb.db +0 -0
  354. package/packages/src/lmdb.db-lock +0 -0
  355. package/packages/src/native/index.ts +2722 -0
  356. package/packages/src/native/tui_v2_types.ts +39 -0
  357. package/packages/src/teammates/coordination.test.ts +279 -0
  358. package/packages/src/teammates/coordination.ts +646 -0
  359. package/packages/src/teammates/index.ts +1052 -0
  360. package/packages/src/teammates/integration.test.ts +272 -0
  361. package/packages/src/teammates/runner.test.ts +235 -0
  362. package/packages/src/teammates/runner.ts +750 -0
  363. package/packages/src/teammates/schemas.ts +673 -0
  364. package/packages/src/types/index.ts +723 -0
@@ -0,0 +1,340 @@
1
+ /**
2
+ * LoopState Tests - State management for the agent loop
3
+ */
4
+ import { describe, it, expect, beforeEach } from "bun:test";
5
+ import { LoopState, createInitialCacheMetrics } from "../loop-state.js";
6
+ describe("createInitialCacheMetrics", () => {
7
+ it("should create initial cache metrics with zeros", () => {
8
+ const metrics = createInitialCacheMetrics();
9
+ expect(metrics.cacheHits).toBe(0);
10
+ expect(metrics.cacheMisses).toBe(0);
11
+ expect(metrics.totalCacheReadTokens).toBe(0);
12
+ expect(metrics.totalCacheWriteTokens).toBe(0);
13
+ expect(metrics.cacheHitRate).toBe(0);
14
+ expect(metrics.estimatedSavingsUSD).toBe(0);
15
+ });
16
+ });
17
+ describe("LoopState", () => {
18
+ let state;
19
+ let initialMessages;
20
+ beforeEach(() => {
21
+ initialMessages = [
22
+ { role: "user", content: [{ type: "text", text: "Hello" }] },
23
+ ];
24
+ state = new LoopState(initialMessages);
25
+ });
26
+ describe("constructor", () => {
27
+ it("should initialize with provided messages", () => {
28
+ expect(state.messages).toHaveLength(1);
29
+ expect(state.messages[0]?.role).toBe("user");
30
+ });
31
+ it("should create a copy of initial messages", () => {
32
+ // Modify original array
33
+ initialMessages.push({ role: "user", content: [{ type: "text", text: "New" }] });
34
+ // State should not be affected
35
+ expect(state.messages).toHaveLength(1);
36
+ });
37
+ it("should initialize all counters to zero", () => {
38
+ expect(state.metrics).toEqual([]);
39
+ expect(state.allToolsUsed).toEqual([]);
40
+ expect(state.totalCost).toBe(0);
41
+ expect(state.totalDuration).toBe(0);
42
+ expect(state.turnNumber).toBe(0);
43
+ expect(state.previousCost).toBe(0);
44
+ expect(state.compactionCount).toBe(0);
45
+ expect(state.totalTokensCompacted).toBe(0);
46
+ });
47
+ it("should initialize cache metrics", () => {
48
+ expect(state.cacheMetrics.cacheHits).toBe(0);
49
+ expect(state.cacheMetrics.cacheMisses).toBe(0);
50
+ });
51
+ });
52
+ describe("latestMetrics", () => {
53
+ it("should return undefined when no metrics exist", () => {
54
+ expect(state.latestMetrics).toBeUndefined();
55
+ });
56
+ it("should return the last metrics entry", () => {
57
+ state.addTurnResult({
58
+ message: { content: [], stop_reason: "end_turn", id: "msg1" },
59
+ usage: { input_tokens: 100, output_tokens: 50 },
60
+ costUSD: 0.01,
61
+ durationMs: 1000,
62
+ model: "claude-sonnet-4-6",
63
+ messageCount: 1,
64
+ });
65
+ state.addTurnResult({
66
+ message: { content: [], stop_reason: "end_turn", id: "msg2" },
67
+ usage: { input_tokens: 200, output_tokens: 100 },
68
+ costUSD: 0.02,
69
+ durationMs: 2000,
70
+ model: "claude-sonnet-4-6",
71
+ messageCount: 2,
72
+ });
73
+ expect(state.latestMetrics?.usage.input_tokens).toBe(200);
74
+ expect(state.latestMetrics?.requestId).toBe("msg2");
75
+ });
76
+ });
77
+ describe("currentUsage", () => {
78
+ it("should return zero usage when no metrics exist", () => {
79
+ expect(state.currentUsage).toEqual({
80
+ input_tokens: 0,
81
+ output_tokens: 0,
82
+ });
83
+ });
84
+ it("should return usage from latest metrics", () => {
85
+ state.addTurnResult({
86
+ message: { content: [], stop_reason: "end_turn", id: "msg1" },
87
+ usage: { input_tokens: 500, output_tokens: 250 },
88
+ costUSD: 0.05,
89
+ durationMs: 1500,
90
+ model: "claude-sonnet-4-6",
91
+ messageCount: 1,
92
+ });
93
+ expect(state.currentUsage.input_tokens).toBe(500);
94
+ expect(state.currentUsage.output_tokens).toBe(250);
95
+ });
96
+ });
97
+ describe("addTurnResult", () => {
98
+ it("should add metrics entry with correct values", () => {
99
+ const result = state.addTurnResult({
100
+ message: { content: [], stop_reason: "end_turn", id: "msg1" },
101
+ usage: { input_tokens: 100, output_tokens: 50 },
102
+ costUSD: 0.01,
103
+ durationMs: 1000,
104
+ model: "claude-sonnet-4-6",
105
+ messageCount: 1,
106
+ });
107
+ expect(result.model).toBe("claude-sonnet-4-6");
108
+ expect(result.messageCount).toBe(1);
109
+ expect(result.messageTokens).toBe(150);
110
+ expect(result.costUSD).toBe(0.01);
111
+ expect(result.stopReason).toBe("end_turn");
112
+ expect(result.requestId).toBe("msg1");
113
+ });
114
+ it("should accumulate total cost", () => {
115
+ state.addTurnResult({
116
+ message: { content: [], stop_reason: "end_turn", id: "msg1" },
117
+ usage: { input_tokens: 100, output_tokens: 50 },
118
+ costUSD: 0.01,
119
+ durationMs: 1000,
120
+ model: "claude-sonnet-4-6",
121
+ messageCount: 1,
122
+ });
123
+ state.addTurnResult({
124
+ message: { content: [], stop_reason: "end_turn", id: "msg2" },
125
+ usage: { input_tokens: 100, output_tokens: 50 },
126
+ costUSD: 0.02,
127
+ durationMs: 1000,
128
+ model: "claude-sonnet-4-6",
129
+ messageCount: 2,
130
+ });
131
+ expect(state.totalCost).toBe(0.03);
132
+ expect(state.previousCost).toBe(0.01);
133
+ });
134
+ it("should accumulate duration", () => {
135
+ state.addTurnResult({
136
+ message: { content: [], stop_reason: "end_turn", id: "msg1" },
137
+ usage: { input_tokens: 100, output_tokens: 50 },
138
+ costUSD: 0.01,
139
+ durationMs: 1000,
140
+ model: "claude-sonnet-4-6",
141
+ messageCount: 1,
142
+ });
143
+ state.addTurnResult({
144
+ message: { content: [], stop_reason: "end_turn", id: "msg2" },
145
+ usage: { input_tokens: 100, output_tokens: 50 },
146
+ costUSD: 0.01,
147
+ durationMs: 500,
148
+ model: "claude-sonnet-4-6",
149
+ messageCount: 2,
150
+ });
151
+ expect(state.totalDuration).toBe(1500);
152
+ });
153
+ it("should aggregate cache metrics", () => {
154
+ state.addTurnResult({
155
+ message: { content: [], stop_reason: "end_turn", id: "msg1" },
156
+ usage: { input_tokens: 100, output_tokens: 50 },
157
+ cacheMetrics: {
158
+ cacheHits: 5,
159
+ cacheMisses: 2,
160
+ totalCacheReadTokens: 1000,
161
+ totalCacheWriteTokens: 500,
162
+ cacheHitRate: 0.714,
163
+ estimatedSavingsUSD: 0.05,
164
+ },
165
+ costUSD: 0.01,
166
+ durationMs: 1000,
167
+ model: "claude-sonnet-4-6",
168
+ messageCount: 1,
169
+ });
170
+ state.addTurnResult({
171
+ message: { content: [], stop_reason: "end_turn", id: "msg2" },
172
+ usage: { input_tokens: 100, output_tokens: 50 },
173
+ cacheMetrics: {
174
+ cacheHits: 3,
175
+ cacheMisses: 1,
176
+ totalCacheReadTokens: 600,
177
+ totalCacheWriteTokens: 200,
178
+ cacheHitRate: 0.75,
179
+ estimatedSavingsUSD: 0.03,
180
+ },
181
+ costUSD: 0.01,
182
+ durationMs: 1000,
183
+ model: "claude-sonnet-4-6",
184
+ messageCount: 2,
185
+ });
186
+ expect(state.cacheMetrics.cacheHits).toBe(8);
187
+ expect(state.cacheMetrics.cacheMisses).toBe(3);
188
+ expect(state.cacheMetrics.totalCacheReadTokens).toBe(1600);
189
+ expect(state.cacheMetrics.totalCacheWriteTokens).toBe(700);
190
+ expect(state.cacheMetrics.estimatedSavingsUSD).toBe(0.08);
191
+ // Hit rate should be recalculated: 8/(8+3) = 0.727...
192
+ expect(state.cacheMetrics.cacheHitRate).toBeCloseTo(0.727, 2);
193
+ });
194
+ it("should handle missing cache metrics", () => {
195
+ state.addTurnResult({
196
+ message: { content: [], stop_reason: "end_turn", id: "msg1" },
197
+ usage: { input_tokens: 100, output_tokens: 50 },
198
+ costUSD: 0.01,
199
+ durationMs: 1000,
200
+ model: "claude-sonnet-4-6",
201
+ messageCount: 1,
202
+ });
203
+ // Cache metrics should remain at initial values
204
+ expect(state.cacheMetrics.cacheHits).toBe(0);
205
+ expect(state.cacheMetrics.cacheMisses).toBe(0);
206
+ });
207
+ });
208
+ describe("addAssistantMessage", () => {
209
+ it("should add assistant message to history", () => {
210
+ state.addAssistantMessage([{ type: "text", text: "Hello!" }]);
211
+ expect(state.messages).toHaveLength(2);
212
+ expect(state.messages[1]?.role).toBe("assistant");
213
+ });
214
+ it("should preserve message order", () => {
215
+ state.addAssistantMessage([{ type: "text", text: "First" }]);
216
+ state.addAssistantMessage([{ type: "text", text: "Second" }]);
217
+ expect(state.messages).toHaveLength(3);
218
+ expect(state.messages[1]?.content[0]).toEqual({ type: "text", text: "First" });
219
+ expect(state.messages[2]?.content[0]).toEqual({ type: "text", text: "Second" });
220
+ });
221
+ });
222
+ describe("addUserMessage", () => {
223
+ it("should add user message with tool results", () => {
224
+ state.addUserMessage([{
225
+ type: "tool_result",
226
+ tool_use_id: "tool1",
227
+ content: "result",
228
+ }]);
229
+ expect(state.messages).toHaveLength(2);
230
+ expect(state.messages[1]?.role).toBe("user");
231
+ });
232
+ });
233
+ describe("trackToolUse", () => {
234
+ it("should track tool use blocks", () => {
235
+ const toolBlocks = [
236
+ { type: "tool_use", id: "tool1", name: "Read", input: { file_path: "/test" } },
237
+ { type: "tool_use", id: "tool2", name: "Write", input: { file_path: "/test2" } },
238
+ ];
239
+ state.trackToolUse(toolBlocks);
240
+ expect(state.allToolsUsed).toHaveLength(2);
241
+ expect(state.allToolsUsed[0]?.name).toBe("Read");
242
+ expect(state.allToolsUsed[1]?.name).toBe("Write");
243
+ });
244
+ it("should accumulate tool uses across multiple calls", () => {
245
+ state.trackToolUse([{ type: "tool_use", id: "tool1", name: "Read", input: {} }]);
246
+ state.trackToolUse([{ type: "tool_use", id: "tool2", name: "Write", input: {} }]);
247
+ expect(state.allToolsUsed).toHaveLength(2);
248
+ });
249
+ });
250
+ describe("applyCompaction", () => {
251
+ it("should not apply compaction when didCompact is false", () => {
252
+ const result = state.applyCompaction({
253
+ messages: state.messages,
254
+ messagesRemoved: 0,
255
+ tokensBefore: 100,
256
+ tokensAfter: 100,
257
+ didCompact: false,
258
+ }, () => ({ reductionPercent: 0, tokensSaved: 0 }));
259
+ expect(result).toBe(false);
260
+ expect(state.compactionCount).toBe(0);
261
+ });
262
+ it("should not apply compaction when tokensAfter >= tokensBefore", () => {
263
+ const result = state.applyCompaction({
264
+ messages: state.messages,
265
+ messagesRemoved: 0,
266
+ tokensBefore: 100,
267
+ tokensAfter: 150, // Worse than before
268
+ didCompact: true,
269
+ }, () => ({ reductionPercent: 0, tokensSaved: 0 }));
270
+ expect(result).toBe(false);
271
+ expect(state.compactionCount).toBe(0);
272
+ });
273
+ it("should apply compaction and update state", () => {
274
+ const newMessages = [
275
+ { role: "user", content: [{ type: "text", text: "Compacted" }] },
276
+ ];
277
+ const result = state.applyCompaction({
278
+ messages: newMessages,
279
+ messagesRemoved: 1,
280
+ tokensBefore: 1000,
281
+ tokensAfter: 500,
282
+ didCompact: true,
283
+ }, () => ({ reductionPercent: 50, tokensSaved: 500 }));
284
+ expect(result).toBe(true);
285
+ expect(state.compactionCount).toBe(1);
286
+ expect(state.totalTokensCompacted).toBe(500);
287
+ expect(state.messages).toHaveLength(1);
288
+ expect(state.messages[0]?.content[0]).toEqual({ type: "text", text: "Compacted" });
289
+ });
290
+ it("should accumulate compaction counts", () => {
291
+ state.applyCompaction({
292
+ messages: state.messages,
293
+ messagesRemoved: 1,
294
+ tokensBefore: 1000,
295
+ tokensAfter: 500,
296
+ didCompact: true,
297
+ }, () => ({ reductionPercent: 50, tokensSaved: 500 }));
298
+ state.applyCompaction({
299
+ messages: state.messages,
300
+ messagesRemoved: 1,
301
+ tokensBefore: 500,
302
+ tokensAfter: 250,
303
+ didCompact: true,
304
+ }, () => ({ reductionPercent: 50, tokensSaved: 250 }));
305
+ expect(state.compactionCount).toBe(2);
306
+ expect(state.totalTokensCompacted).toBe(750);
307
+ });
308
+ });
309
+ describe("incrementTurn", () => {
310
+ it("should increment turn counter and return new value", () => {
311
+ expect(state.turnNumber).toBe(0);
312
+ const turn1 = state.incrementTurn();
313
+ expect(turn1).toBe(1);
314
+ expect(state.turnNumber).toBe(1);
315
+ const turn2 = state.incrementTurn();
316
+ expect(turn2).toBe(2);
317
+ expect(state.turnNumber).toBe(2);
318
+ });
319
+ });
320
+ describe("toResult", () => {
321
+ it("should convert state to AgentLoopResult", () => {
322
+ state.addTurnResult({
323
+ message: { content: [], stop_reason: "end_turn", id: "msg1" },
324
+ usage: { input_tokens: 100, output_tokens: 50 },
325
+ costUSD: 0.01,
326
+ durationMs: 1000,
327
+ model: "claude-sonnet-4-6",
328
+ messageCount: 1,
329
+ });
330
+ const result = state.toResult();
331
+ expect(result.messages).toHaveLength(1);
332
+ expect(result.metrics).toHaveLength(1);
333
+ expect(result.totalCost).toBe(0.01);
334
+ expect(result.totalDuration).toBe(1000);
335
+ expect(result.compactionCount).toBe(0);
336
+ expect(result.totalTokensCompacted).toBe(0);
337
+ expect(result.totalCacheMetrics).toBeDefined();
338
+ });
339
+ });
340
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Message Builder Tests - API message construction with reminder injection
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=message-builder.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-builder.test.d.ts","sourceRoot":"","sources":["../../../../packages/src/core/agent-loop/__tests__/message-builder.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Message Builder Tests - API message construction with reminder injection
3
+ */
4
+ import { describe, it, expect } from "bun:test";
5
+ import { buildAPIMessages, injectReminderIntoContent } from "../message-builder.js";
6
+ describe("injectReminderIntoContent", () => {
7
+ it("should append reminder to existing text block", () => {
8
+ const content = [
9
+ { type: "text", text: "Original text" },
10
+ ];
11
+ const result = injectReminderIntoContent(content, "System reminder");
12
+ expect(result).toHaveLength(1);
13
+ expect(result[0]?.type).toBe("text");
14
+ expect(result[0].text).toBe("Original text\n\nSystem reminder");
15
+ });
16
+ it("should not mutate original content array", () => {
17
+ const content = [
18
+ { type: "text", text: "Original text" },
19
+ ];
20
+ injectReminderIntoContent(content, "System reminder");
21
+ expect(content[0].text).toBe("Original text");
22
+ });
23
+ it("should add new text block if last block is not text", () => {
24
+ const content = [
25
+ { type: "image", source: { type: "base64", data: "abc", media_type: "image/png" } },
26
+ ];
27
+ const result = injectReminderIntoContent(content, "System reminder");
28
+ expect(result).toHaveLength(2);
29
+ expect(result[0]?.type).toBe("image");
30
+ expect(result[1]?.type).toBe("text");
31
+ expect(result[1].text).toBe("\n\nSystem reminder");
32
+ });
33
+ it("should add new text block if content is empty", () => {
34
+ const content = [];
35
+ const result = injectReminderIntoContent(content, "System reminder");
36
+ expect(result).toHaveLength(1);
37
+ expect(result[0]?.type).toBe("text");
38
+ expect(result[0].text).toBe("\n\nSystem reminder");
39
+ });
40
+ it("should handle multiple content blocks", () => {
41
+ const content = [
42
+ { type: "tool_use", id: "tool1", name: "Read", input: {} },
43
+ { type: "text", text: "After tool" },
44
+ ];
45
+ const result = injectReminderIntoContent(content, "Reminder");
46
+ expect(result).toHaveLength(2);
47
+ expect(result[1].text).toBe("After tool\n\nReminder");
48
+ });
49
+ it("should handle tool_result as last block", () => {
50
+ const content = [
51
+ { type: "tool_result", tool_use_id: "tool1", content: "result" },
52
+ ];
53
+ const result = injectReminderIntoContent(content, "Reminder");
54
+ expect(result).toHaveLength(2);
55
+ expect(result[0]?.type).toBe("tool_result");
56
+ expect(result[1]?.type).toBe("text");
57
+ });
58
+ });
59
+ describe("buildAPIMessages", () => {
60
+ it("should return messages unchanged when no reminder", () => {
61
+ const messages = [
62
+ { role: "user", content: [{ type: "text", text: "Hello" }] },
63
+ ];
64
+ const result = buildAPIMessages(messages, "System prompt");
65
+ expect(result).toEqual(messages);
66
+ });
67
+ it("should return messages unchanged when empty", () => {
68
+ const result = buildAPIMessages([], "System prompt", "Reminder");
69
+ expect(result).toEqual([]);
70
+ });
71
+ it("should inject reminder into last user message", () => {
72
+ const messages = [
73
+ { role: "user", content: [{ type: "text", text: "Hello" }] },
74
+ ];
75
+ const result = buildAPIMessages(messages, "System prompt", "Important reminder");
76
+ expect(result).toHaveLength(1);
77
+ expect(result[0]?.role).toBe("user");
78
+ const textBlock = result[0]?.content[0];
79
+ expect(textBlock.text).toContain("Hello");
80
+ expect(textBlock.text).toContain("Important reminder");
81
+ });
82
+ it("should not mutate original messages", () => {
83
+ const messages = [
84
+ { role: "user", content: [{ type: "text", text: "Hello" }] },
85
+ ];
86
+ buildAPIMessages(messages, "System prompt", "Reminder");
87
+ expect((messages[0]?.content[0]).text).toBe("Hello");
88
+ });
89
+ it("should find last user message in mixed conversation", () => {
90
+ const messages = [
91
+ { role: "user", content: [{ type: "text", text: "First user" }] },
92
+ { role: "assistant", content: [{ type: "text", text: "Response" }] },
93
+ { role: "user", content: [{ type: "text", text: "Second user" }] },
94
+ ];
95
+ const result = buildAPIMessages(messages, "System prompt", "Reminder");
96
+ expect(result).toHaveLength(3);
97
+ // First user message should be unchanged
98
+ expect((result[0]?.content[0]).text).toBe("First user");
99
+ // Last user message should have reminder
100
+ const lastUserText = (result[2]?.content[0]).text;
101
+ expect(lastUserText).toContain("Second user");
102
+ expect(lastUserText).toContain("Reminder");
103
+ });
104
+ it("should handle user message with tool results", () => {
105
+ const messages = [
106
+ {
107
+ role: "user",
108
+ content: [
109
+ { type: "tool_result", tool_use_id: "tool1", content: "Result 1" },
110
+ { type: "tool_result", tool_use_id: "tool2", content: "Result 2" },
111
+ ],
112
+ },
113
+ ];
114
+ const result = buildAPIMessages(messages, "System prompt", "Reminder");
115
+ expect(result).toHaveLength(1);
116
+ // Should add reminder as new text block since last block is tool_result
117
+ expect(result[0]?.content).toHaveLength(3);
118
+ expect(result[0]?.content[2]?.type).toBe("text");
119
+ });
120
+ it("should handle complex user message", () => {
121
+ const messages = [
122
+ {
123
+ role: "user",
124
+ content: [
125
+ { type: "text", text: "Query text" },
126
+ { type: "image", source: { type: "base64", data: "img", media_type: "image/png" } },
127
+ ],
128
+ },
129
+ ];
130
+ const result = buildAPIMessages(messages, "System prompt", "Reminder");
131
+ // Reminder should be added as new block since last is image
132
+ expect(result[0]?.content).toHaveLength(3);
133
+ expect(result[0]?.content[0]?.type).toBe("text");
134
+ expect(result[0]?.content[1]?.type).toBe("image");
135
+ expect(result[0]?.content[2]?.type).toBe("text");
136
+ });
137
+ it("should handle assistant-only conversation", () => {
138
+ const messages = [
139
+ { role: "assistant", content: [{ type: "text", text: "Hello" }] },
140
+ ];
141
+ const result = buildAPIMessages(messages, "System prompt", "Reminder");
142
+ // No user message to inject into, return unchanged
143
+ expect(result).toEqual(messages);
144
+ });
145
+ it("should handle multiline reminder", () => {
146
+ const messages = [
147
+ { role: "user", content: [{ type: "text", text: "Hello" }] },
148
+ ];
149
+ const multilineReminder = `Line 1
150
+ Line 2
151
+ Line 3`;
152
+ const result = buildAPIMessages(messages, "System prompt", multilineReminder);
153
+ const text = (result[0]?.content[0]).text;
154
+ expect(text).toContain("Line 1");
155
+ expect(text).toContain("Line 2");
156
+ expect(text).toContain("Line 3");
157
+ });
158
+ it("should preserve message order", () => {
159
+ const messages = [
160
+ { role: "user", content: [{ type: "text", text: "1" }] },
161
+ { role: "assistant", content: [{ type: "text", text: "2" }] },
162
+ { role: "user", content: [{ type: "text", text: "3" }] },
163
+ { role: "assistant", content: [{ type: "text", text: "4" }] },
164
+ { role: "user", content: [{ type: "text", text: "5" }] },
165
+ ];
166
+ const result = buildAPIMessages(messages, "System prompt", "Reminder");
167
+ expect(result[0]?.role).toBe("user");
168
+ expect(result[1]?.role).toBe("assistant");
169
+ expect(result[2]?.role).toBe("user");
170
+ expect(result[3]?.role).toBe("assistant");
171
+ expect(result[4]?.role).toBe("user");
172
+ // Only last user should have reminder
173
+ expect((result[0]?.content[0]).text).toBe("1");
174
+ expect((result[2]?.content[0]).text).toBe("3");
175
+ expect((result[4]?.content[0]).text).toContain("5");
176
+ expect((result[4]?.content[0]).text).toContain("Reminder");
177
+ });
178
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tool Executor Tests - Parallel tool execution with hooks and permissions
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=tool-executor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-executor.test.d.ts","sourceRoot":"","sources":["../../../../packages/src/core/agent-loop/__tests__/tool-executor.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}