@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,451 @@
1
+ /**
2
+ * Spinner Component for Coder CLI
3
+ *
4
+ * Re-exports spinner frames from tui/spinner.ts for backward compatibility.
5
+ */
6
+
7
+ import ora, { type Ora } from "ora";
8
+ import chalk from "chalk";
9
+
10
+ // Import spinner frames from the single source of truth
11
+ import {
12
+ spinnerFrames,
13
+ dotSpinnerFrames,
14
+ asciiSpinnerFrames,
15
+ arrowSpinnerFrames,
16
+ simpleDotFrames,
17
+ } from "./terminal/tui/spinner.js";
18
+
19
+ // Re-export for external use
20
+ export {
21
+ spinnerFrames,
22
+ dotSpinnerFrames,
23
+ asciiSpinnerFrames,
24
+ arrowSpinnerFrames,
25
+ simpleDotFrames,
26
+ };
27
+
28
+ // Legacy aliases for backward compatibility
29
+ export const defaultFrames = spinnerFrames;
30
+ export const dotFrames = simpleDotFrames;
31
+ export const arrowFrames = arrowSpinnerFrames;
32
+
33
+ // ============================================
34
+ // TYPES
35
+ // ============================================
36
+
37
+ export interface SpinnerOptions {
38
+ /** Tip text shown below spinner */
39
+ tip?: string;
40
+ /** Color override */
41
+ color?: SpinnerColor;
42
+ /** Show elapsed time */
43
+ showTime?: boolean;
44
+ /** Tool activity indicator */
45
+ hasActiveTools?: boolean;
46
+ /** Suffix text after spinner */
47
+ suffix?: string;
48
+ /** Verbose mode - show more details */
49
+ verbose?: boolean;
50
+ /** Spinner text prefix */
51
+ prefix?: string;
52
+ /** Disable spinner (for --no-progress) */
53
+ disabled?: boolean;
54
+ }
55
+
56
+ export type SpinnerColor =
57
+ | "cyan"
58
+ | "green"
59
+ | "yellow"
60
+ | "blue"
61
+ | "magenta"
62
+ | "red"
63
+ | "white"
64
+ | "gray";
65
+
66
+ export interface SpinnerState {
67
+ isSpinning: boolean;
68
+ startTime: number;
69
+ totalPausedMs: number;
70
+ pauseStartTime: number | null;
71
+ currentTip: string;
72
+ responseLength: number;
73
+ }
74
+
75
+ // ============================================
76
+ // SPINNER TIPS
77
+ // ============================================
78
+
79
+ /** Rotating tips shown during loading */
80
+ export const defaultTips = [
81
+ "Thinking...",
82
+ "Processing...",
83
+ "Analyzing...",
84
+ "Working on it...",
85
+ ];
86
+
87
+ /** Tips shown during tool execution */
88
+ export const toolTips = [
89
+ "Executing tool...",
90
+ "Running command...",
91
+ "Processing request...",
92
+ "Working...",
93
+ ];
94
+
95
+ /** Tips shown during API streaming */
96
+ export const streamingTips = [
97
+ "Receiving response...",
98
+ "Streaming...",
99
+ "Getting results...",
100
+ ];
101
+
102
+ // ============================================
103
+ // SPINNER CLASS
104
+ // ============================================
105
+
106
+ export class Spinner {
107
+ private ora: Ora | null = null;
108
+ private state: SpinnerState;
109
+ private options: SpinnerOptions;
110
+ private tipInterval: Timer | null = null;
111
+ private tipIndex = 0;
112
+ private customTips: string[] = [];
113
+
114
+ constructor(options: SpinnerOptions = {}) {
115
+ this.options = {
116
+ color: "cyan",
117
+ showTime: true,
118
+ ...options,
119
+ };
120
+
121
+ this.state = {
122
+ isSpinning: false,
123
+ startTime: 0,
124
+ totalPausedMs: 0,
125
+ pauseStartTime: null,
126
+ currentTip: options.tip || "",
127
+ responseLength: 0,
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Start the spinner
133
+ */
134
+ start(text?: string): this {
135
+ if (this.options.disabled || this.state.isSpinning) {
136
+ return this;
137
+ }
138
+
139
+ this.state.startTime = Date.now();
140
+ this.state.isSpinning = true;
141
+
142
+ const spinnerText = this.buildText(text || this.state.currentTip);
143
+
144
+ this.ora = ora({
145
+ text: spinnerText,
146
+ spinner: {
147
+ frames: [...spinnerFrames], // Convert readonly tuple to mutable array
148
+ interval: 80,
149
+ },
150
+ color: this.options.color,
151
+ prefixText: this.options.prefix,
152
+ }).start();
153
+
154
+ // Start rotating tips if enabled
155
+ if (!this.options.tip && this.customTips.length === 0) {
156
+ this.startTipRotation();
157
+ }
158
+
159
+ return this;
160
+ }
161
+
162
+ /**
163
+ * Stop the spinner
164
+ */
165
+ stop(options?: { clear?: boolean; text?: string; symbol?: string }): this {
166
+ if (!this.ora || !this.state.isSpinning) {
167
+ return this;
168
+ }
169
+
170
+ this.stopTipRotation();
171
+
172
+ if (options?.text) {
173
+ if (options?.symbol) {
174
+ this.ora.stopAndPersist({ symbol: options.symbol, text: options.text });
175
+ } else {
176
+ this.ora.succeed(options.text);
177
+ }
178
+ } else if (options?.clear) {
179
+ this.ora.stop();
180
+ } else {
181
+ this.ora.stop();
182
+ }
183
+
184
+ this.state.isSpinning = false;
185
+ this.ora = null;
186
+
187
+ return this;
188
+ }
189
+
190
+ /**
191
+ * Stop with success message
192
+ */
193
+ succeed(text?: string): this {
194
+ return this.stop({ text, symbol: chalk.green("✓") });
195
+ }
196
+
197
+ /**
198
+ * Stop with failure message
199
+ */
200
+ fail(text?: string): this {
201
+ return this.stop({ text, symbol: chalk.red("✗") });
202
+ }
203
+
204
+ /**
205
+ * Stop with warning message
206
+ */
207
+ warn(text?: string): this {
208
+ return this.stop({ text, symbol: chalk.yellow("⚠") });
209
+ }
210
+
211
+ /**
212
+ * Stop with info message
213
+ */
214
+ info(text?: string): this {
215
+ return this.stop({ text, symbol: chalk.blue("ℹ") });
216
+ }
217
+
218
+ /**
219
+ * Update spinner text
220
+ */
221
+ update(text: string): this {
222
+ if (this.ora && this.state.isSpinning) {
223
+ this.state.currentTip = text;
224
+ this.ora.text = this.buildText(text);
225
+ }
226
+ return this;
227
+ }
228
+
229
+ /**
230
+ * Update the tip text (shown below main text)
231
+ */
232
+ updateTip(tip: string): this {
233
+ this.stopTipRotation();
234
+ this.state.currentTip = tip;
235
+ if (this.ora && this.state.isSpinning) {
236
+ this.ora.text = this.buildText(this.state.currentTip);
237
+ }
238
+ return this;
239
+ }
240
+
241
+ /**
242
+ * Set custom tips for rotation
243
+ */
244
+ setTips(tips: string[]): this {
245
+ this.customTips = tips;
246
+ return this;
247
+ }
248
+
249
+ /**
250
+ * Update response length (for streaming progress)
251
+ */
252
+ updateResponseLength(length: number): this {
253
+ this.state.responseLength = length;
254
+ if (this.ora && this.state.isSpinning && this.options.verbose) {
255
+ this.ora.text = this.buildText(this.state.currentTip);
256
+ }
257
+ return this;
258
+ }
259
+
260
+ /**
261
+ * Set tool activity state
262
+ */
263
+ setToolActivity(active: boolean): this {
264
+ this.options.hasActiveTools = active;
265
+ if (this.ora && this.state.isSpinning) {
266
+ this.ora.text = this.buildText(this.state.currentTip);
267
+ }
268
+ return this;
269
+ }
270
+
271
+ /**
272
+ * Pause spinner (for user input, etc.)
273
+ */
274
+ pause(): this {
275
+ if (this.state.isSpinning && !this.state.pauseStartTime) {
276
+ this.state.pauseStartTime = Date.now();
277
+ if (this.ora) {
278
+ this.ora.stop();
279
+ }
280
+ }
281
+ return this;
282
+ }
283
+
284
+ /**
285
+ * Resume spinner after pause
286
+ */
287
+ resume(): this {
288
+ if (this.state.pauseStartTime) {
289
+ this.state.totalPausedMs += Date.now() - this.state.pauseStartTime;
290
+ this.state.pauseStartTime = null;
291
+ if (this.ora) {
292
+ this.ora.start();
293
+ }
294
+ }
295
+ return this;
296
+ }
297
+
298
+ /**
299
+ * Get elapsed time in seconds (excluding pauses)
300
+ */
301
+ getElapsedSeconds(): number {
302
+ const now = Date.now();
303
+ let elapsed = now - this.state.startTime - this.state.totalPausedMs;
304
+
305
+ // Subtract current pause if active
306
+ if (this.state.pauseStartTime) {
307
+ elapsed -= now - this.state.pauseStartTime;
308
+ }
309
+
310
+ return Math.floor(elapsed / 1000);
311
+ }
312
+
313
+ /**
314
+ * Get current state
315
+ */
316
+ getState(): SpinnerState {
317
+ return { ...this.state };
318
+ }
319
+
320
+ /**
321
+ * Check if spinner is active
322
+ */
323
+ isActive(): boolean {
324
+ return this.state.isSpinning;
325
+ }
326
+
327
+ /**
328
+ * Clear the spinner line
329
+ */
330
+ clear(): this {
331
+ if (this.ora) {
332
+ this.ora.clear();
333
+ }
334
+ return this;
335
+ }
336
+
337
+ /**
338
+ * Render spinner frame manually (for non-TTY)
339
+ */
340
+ renderFrame(): string {
341
+ const frame = spinnerFrames[this.tipIndex % spinnerFrames.length];
342
+ return `${frame} ${this.state.currentTip}`;
343
+ }
344
+
345
+ // ============================================
346
+ // PRIVATE METHODS
347
+ // ============================================
348
+
349
+ private buildText(baseText: string): string {
350
+ let text = baseText;
351
+
352
+ // Add suffix
353
+ if (this.options.suffix) {
354
+ text = `${text} ${this.options.suffix}`;
355
+ }
356
+
357
+ // Add elapsed time
358
+ if (this.options.showTime && this.state.startTime > 0) {
359
+ const elapsed = this.getElapsedSeconds();
360
+ if (elapsed > 0) {
361
+ text = `${text} ${chalk.gray(`[${formatTime(elapsed)}]`)}`;
362
+ }
363
+ }
364
+
365
+ // Add tool indicator
366
+ if (this.options.hasActiveTools) {
367
+ text = `${chalk.yellow("⚙")} ${text}`;
368
+ }
369
+
370
+ // Add response length in verbose mode
371
+ if (this.options.verbose && this.state.responseLength > 0) {
372
+ text = `${text} ${chalk.gray(`(${formatBytes(this.state.responseLength)})`)}`;
373
+ }
374
+
375
+ return text;
376
+ }
377
+
378
+ private startTipRotation(): void {
379
+ const tips = this.customTips.length > 0 ? this.customTips : defaultTips;
380
+ this.tipIndex = 0;
381
+
382
+ this.tipInterval = setInterval(() => {
383
+ this.tipIndex = (this.tipIndex + 1) % tips.length;
384
+ if (this.ora && this.state.isSpinning) {
385
+ this.ora.text = this.buildText(tips[this.tipIndex] ?? "");
386
+ }
387
+ }, 2000);
388
+ }
389
+
390
+ private stopTipRotation(): void {
391
+ if (this.tipInterval) {
392
+ clearInterval(this.tipInterval);
393
+ this.tipInterval = null;
394
+ }
395
+ }
396
+ }
397
+
398
+ // ============================================
399
+ // HELPER FUNCTIONS
400
+ // ============================================
401
+
402
+ /**
403
+ * Format seconds to human-readable time
404
+ */
405
+ function formatTime(seconds: number): string {
406
+ if (seconds < 60) {
407
+ return `${seconds}s`;
408
+ }
409
+ const mins = Math.floor(seconds / 60);
410
+ const secs = seconds % 60;
411
+ return `${mins}m${secs}s`;
412
+ }
413
+
414
+ /**
415
+ * Format bytes to human-readable size
416
+ */
417
+ function formatBytes(bytes: number): string {
418
+ if (bytes < 1024) {
419
+ return `${bytes}B`;
420
+ }
421
+ if (bytes < 1024 * 1024) {
422
+ return `${(bytes / 1024).toFixed(1)}KB`;
423
+ }
424
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
425
+ }
426
+
427
+ // ============================================
428
+ // SINGLETON INSTANCE
429
+ // ============================================
430
+
431
+ let globalSpinner: Spinner | null = null;
432
+
433
+ /**
434
+ * Get or create global spinner instance
435
+ */
436
+ export function getSpinner(options?: SpinnerOptions): Spinner {
437
+ if (!globalSpinner) {
438
+ globalSpinner = new Spinner(options);
439
+ }
440
+ return globalSpinner;
441
+ }
442
+
443
+ /**
444
+ * Reset global spinner (for testing)
445
+ */
446
+ export function resetSpinner(): void {
447
+ if (globalSpinner) {
448
+ globalSpinner.stop({ clear: true });
449
+ globalSpinner = null;
450
+ }
451
+ }
@@ -0,0 +1,228 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Coder - CLI Entry Point
4
+ * AI-powered terminal coding assistant
5
+ *
6
+ * This is a thin orchestrator that:
7
+ * 1. Parses arguments
8
+ * 2. Sets up session (config, MCP, hooks)
9
+ * 3. Dispatches to TUI or single-query mode
10
+ */
11
+
12
+ import type { Message } from "../../../../types/index.js";
13
+ import type { ToolDefinition, PermissionMode } from "../../../../types/index.js";
14
+ import type { builtInTools } from "../../../../ecosystem/tools/index.js";
15
+ import type { HookManager } from "../../../../ecosystem/hooks/index.js";
16
+ import type { SkillManager } from "../../../../ecosystem/skills/index.js";
17
+ import type { MCPClientImpl } from "../../../mcp/client.js";
18
+ import { SessionStore, printSessionsList } from "../../../../core/session-store.js";
19
+ import { getGitStatus } from "../../../../core/git-status.js";
20
+ import { renderStatusLine, getContextWindow, VERSION, type StatusLineOptions } from "../shared/status-line.js";
21
+ import { runInteractiveTUI } from "../tui/index.js";
22
+
23
+ // Shared modules
24
+ import {
25
+ parseArgs,
26
+ requireApiKey,
27
+ setupSession,
28
+ buildCompleteSystemPrompt,
29
+ runSingleQuery,
30
+ } from "../shared/index.js";
31
+
32
+ // ============================================
33
+ // MAIN ENTRY POINT
34
+ // ============================================
35
+
36
+ async function main(): Promise<void> {
37
+ const args = parseArgs();
38
+
39
+ // Handle --version flag
40
+ if (args.showVersion) {
41
+ console.log(`Coder v${VERSION}`);
42
+ console.log(`Model: ${args.model}`);
43
+ console.log(`Node: ${process.version}`);
44
+ console.log(`Platform: ${process.platform} ${process.arch}`);
45
+ process.exit(0);
46
+ }
47
+
48
+ // Initialize session store
49
+ const sessionStore = new SessionStore();
50
+ await sessionStore.init();
51
+
52
+ // Handle --sessions flag
53
+ if (args.listSessions) {
54
+ const sessions = await sessionStore.listSessions(20);
55
+ printSessionsList(sessions);
56
+ process.exit(0);
57
+ }
58
+
59
+ // Get API key
60
+ const apiKey = requireApiKey();
61
+
62
+ // Setup session (config, MCP, hooks, skills)
63
+ const setup = await setupSession({
64
+ args,
65
+ apiKey,
66
+ workingDirectory: process.cwd(),
67
+ });
68
+
69
+ // Get git status for system prompt
70
+ const gitStatus = await getGitStatus(process.cwd());
71
+
72
+ // Build system prompt
73
+ const systemPrompt = await buildCompleteSystemPrompt(process.cwd(), {
74
+ systemPrompt: args.systemPrompt,
75
+ appendSystemPrompt: args.appendSystemPrompt,
76
+ teammateMode: args.teammateMode,
77
+ agentId: args.agentId,
78
+ agentName: args.agentName,
79
+ teamName: args.teamName,
80
+ });
81
+
82
+ // Handle session resume
83
+ let messages: Message[] = [];
84
+ let sessionId: string;
85
+
86
+ if (args.resumeSession) {
87
+ const loadedSession = await sessionStore.resumeSession(args.resumeSession);
88
+ if (!loadedSession) {
89
+ console.error(`Error: Session not found: ${args.resumeSession}`);
90
+ process.exit(1);
91
+ }
92
+
93
+ messages = loadedSession.messages;
94
+ sessionId = args.resumeSession;
95
+
96
+ // Update args from session metadata
97
+ args.model = loadedSession.metadata.model as typeof args.model;
98
+ args.agentName = loadedSession.metadata.agentName;
99
+ args.agentColor = loadedSession.metadata.agentColor;
100
+ args.teamName = loadedSession.metadata.teamName;
101
+
102
+ console.log(`\x1b[90mResumed session: ${args.resumeSession}\x1b[0m`);
103
+ console.log(`\x1b[90mModel: ${args.model} | Messages: ${messages.length}\x1b[0m\n`);
104
+ } else {
105
+ // Create new session
106
+ sessionId = await sessionStore.createSession({
107
+ model: args.model,
108
+ workingDirectory: process.cwd(),
109
+ agentName: args.agentName,
110
+ agentColor: args.agentColor,
111
+ teamName: args.teamName,
112
+ });
113
+ }
114
+
115
+ // Get initial query
116
+ let query = args.query;
117
+ const firstArg = process.argv[2];
118
+ if (!query && process.argv.length > 2 && firstArg && !firstArg.startsWith("-")) {
119
+ query = process.argv.slice(2).join(" ");
120
+ }
121
+
122
+ if (!query) {
123
+ // Show initial status line
124
+ const initialStatusOptions: StatusLineOptions = {
125
+ permissionMode: setup.permissionMode,
126
+ tokensUsed: 0,
127
+ maxTokens: getContextWindow(args.model),
128
+ model: args.model,
129
+ isLoading: false,
130
+ };
131
+ console.log(`\x1b[90m${renderStatusLine(initialStatusOptions)}\x1b[0m`);
132
+ console.log(`\x1b[90mSession: ${sessionId}\x1b[0m`);
133
+ console.log("\x1b[90mType your message, ? for help, or /help for commands.\x1b[0m\n");
134
+
135
+ // Interactive mode
136
+ await runInteractiveMode(
137
+ apiKey,
138
+ args,
139
+ systemPrompt,
140
+ setup.tools,
141
+ setup.hookManager,
142
+ setup.skillManager,
143
+ sessionStore,
144
+ messages,
145
+ sessionId,
146
+ setup.mcpClients,
147
+ setup.permissionMode
148
+ );
149
+ } else {
150
+ // Single query mode
151
+ await runSingleQuery({
152
+ apiKey,
153
+ args,
154
+ systemPrompt,
155
+ tools: setup.tools,
156
+ query,
157
+ sessionStore,
158
+ sessionId,
159
+ hookManager: setup.hookManager,
160
+ workingDirectory: process.cwd(),
161
+ gitStatus,
162
+ });
163
+ }
164
+ }
165
+
166
+ // ============================================
167
+ // INTERACTIVE MODE
168
+ // ============================================
169
+
170
+ async function runInteractiveMode(
171
+ apiKey: string,
172
+ args: Awaited<ReturnType<typeof parseArgs>>,
173
+ systemPrompt: string,
174
+ tools: ToolDefinition[],
175
+ hookManager: HookManager,
176
+ skillManager: SkillManager,
177
+ sessionStore: SessionStore,
178
+ messages: Message[],
179
+ sessionId: string,
180
+ mcpClients: Map<string, MCPClientImpl>,
181
+ permissionMode: PermissionMode
182
+ ): Promise<void> {
183
+ // Check if stdin is a TTY (interactive terminal)
184
+ const isInteractive = process.stdin.isTTY;
185
+
186
+ // Allow force-interactive mode for testing
187
+ const forceInteractive = process.env.CLAUDE_FORCE_INTERACTIVE === "true";
188
+
189
+ if (!isInteractive && !forceInteractive) {
190
+ console.error("Error: Interactive mode requires a TTY. Use -q for single query mode.");
191
+ console.error(" Or set CLAUDE_FORCE_INTERACTIVE=true for testing.");
192
+ return;
193
+ }
194
+
195
+ // Create a mutable session ID holder for the TUI
196
+ let currentSessionId = sessionId;
197
+ const setSessionId = (newId: string) => {
198
+ currentSessionId = newId;
199
+ };
200
+
201
+ // Run the Ink-based React TUI
202
+ await runInteractiveTUI({
203
+ apiKey,
204
+ model: args.model,
205
+ permissionMode,
206
+ maxTokens: args.maxTokens,
207
+ systemPrompt,
208
+ tools,
209
+ hookManager,
210
+ sessionStore,
211
+ sessionId: currentSessionId,
212
+ setSessionId,
213
+ initialMessages: messages,
214
+ workingDirectory: process.cwd(),
215
+ onExit: () => {
216
+ console.log("\n\x1b[90mGoodbye!\x1b[0m");
217
+ },
218
+ });
219
+ }
220
+
221
+ // ============================================
222
+ // RUN MAIN
223
+ // ============================================
224
+
225
+ main().catch((error) => {
226
+ console.error("Fatal error:", error);
227
+ process.exit(1);
228
+ });