orquesta-cli 0.1.12

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 (851) hide show
  1. package/.eslintrc.json +26 -0
  2. package/.prettierrc.json +10 -0
  3. package/CLAUDE.md +199 -0
  4. package/LICENSE +21 -0
  5. package/README.md +280 -0
  6. package/SECURITY.md +290 -0
  7. package/TEST_LOCAL.md +245 -0
  8. package/dist/agents/base/base-agent.d.ts +38 -0
  9. package/dist/agents/base/base-agent.d.ts.map +1 -0
  10. package/dist/agents/base/base-agent.js +69 -0
  11. package/dist/agents/base/base-agent.js.map +1 -0
  12. package/dist/agents/docs-search/index.d.ts +33 -0
  13. package/dist/agents/docs-search/index.d.ts.map +1 -0
  14. package/dist/agents/docs-search/index.js +244 -0
  15. package/dist/agents/docs-search/index.js.map +1 -0
  16. package/dist/agents/index.d.ts +4 -0
  17. package/dist/agents/index.d.ts.map +1 -0
  18. package/dist/agents/index.js +4 -0
  19. package/dist/agents/index.js.map +1 -0
  20. package/dist/agents/planner/index.d.ts +17 -0
  21. package/dist/agents/planner/index.d.ts.map +1 -0
  22. package/dist/agents/planner/index.js +250 -0
  23. package/dist/agents/planner/index.js.map +1 -0
  24. package/dist/cli.d.ts +3 -0
  25. package/dist/cli.d.ts.map +1 -0
  26. package/dist/cli.js +144 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/constants.d.ts +8 -0
  29. package/dist/constants.d.ts.map +1 -0
  30. package/dist/constants.js +10 -0
  31. package/dist/constants.js.map +1 -0
  32. package/dist/core/compact/compact-manager.d.ts +22 -0
  33. package/dist/core/compact/compact-manager.d.ts.map +1 -0
  34. package/dist/core/compact/compact-manager.js +75 -0
  35. package/dist/core/compact/compact-manager.js.map +1 -0
  36. package/dist/core/compact/compact-prompts.d.ts +11 -0
  37. package/dist/core/compact/compact-prompts.d.ts.map +1 -0
  38. package/dist/core/compact/compact-prompts.js +90 -0
  39. package/dist/core/compact/compact-prompts.js.map +1 -0
  40. package/dist/core/compact/context-tracker.d.ts +28 -0
  41. package/dist/core/compact/context-tracker.d.ts.map +1 -0
  42. package/dist/core/compact/context-tracker.js +71 -0
  43. package/dist/core/compact/context-tracker.js.map +1 -0
  44. package/dist/core/compact/index.d.ts +4 -0
  45. package/dist/core/compact/index.d.ts.map +1 -0
  46. package/dist/core/compact/index.js +4 -0
  47. package/dist/core/compact/index.js.map +1 -0
  48. package/dist/core/config/config-manager.d.ts +44 -0
  49. package/dist/core/config/config-manager.d.ts.map +1 -0
  50. package/dist/core/config/config-manager.js +259 -0
  51. package/dist/core/config/config-manager.js.map +1 -0
  52. package/dist/core/config/index.d.ts +2 -0
  53. package/dist/core/config/index.d.ts.map +1 -0
  54. package/dist/core/config/index.js +2 -0
  55. package/dist/core/config/index.js.map +1 -0
  56. package/dist/core/docs-manager.d.ts +46 -0
  57. package/dist/core/docs-manager.d.ts.map +1 -0
  58. package/dist/core/docs-manager.js +475 -0
  59. package/dist/core/docs-manager.js.map +1 -0
  60. package/dist/core/git-auto-updater.d.ts +58 -0
  61. package/dist/core/git-auto-updater.d.ts.map +1 -0
  62. package/dist/core/git-auto-updater.js +374 -0
  63. package/dist/core/git-auto-updater.js.map +1 -0
  64. package/dist/core/llm/index.d.ts +2 -0
  65. package/dist/core/llm/index.d.ts.map +1 -0
  66. package/dist/core/llm/index.js +2 -0
  67. package/dist/core/llm/index.js.map +1 -0
  68. package/dist/core/llm/llm-client.d.ts +97 -0
  69. package/dist/core/llm/llm-client.d.ts.map +1 -0
  70. package/dist/core/llm/llm-client.js +1000 -0
  71. package/dist/core/llm/llm-client.js.map +1 -0
  72. package/dist/core/session/index.d.ts +2 -0
  73. package/dist/core/session/index.d.ts.map +1 -0
  74. package/dist/core/session/index.js +2 -0
  75. package/dist/core/session/index.js.map +1 -0
  76. package/dist/core/session/session-manager.d.ts +71 -0
  77. package/dist/core/session/session-manager.d.ts.map +1 -0
  78. package/dist/core/session/session-manager.js +250 -0
  79. package/dist/core/session/session-manager.js.map +1 -0
  80. package/dist/core/slash-command-handler.d.ts +31 -0
  81. package/dist/core/slash-command-handler.d.ts.map +1 -0
  82. package/dist/core/slash-command-handler.js +302 -0
  83. package/dist/core/slash-command-handler.js.map +1 -0
  84. package/dist/core/usage-tracker.d.ts +70 -0
  85. package/dist/core/usage-tracker.d.ts.map +1 -0
  86. package/dist/core/usage-tracker.js +251 -0
  87. package/dist/core/usage-tracker.js.map +1 -0
  88. package/dist/errors/base.d.ts +22 -0
  89. package/dist/errors/base.d.ts.map +1 -0
  90. package/dist/errors/base.js +43 -0
  91. package/dist/errors/base.js.map +1 -0
  92. package/dist/errors/file.d.ts +31 -0
  93. package/dist/errors/file.d.ts.map +1 -0
  94. package/dist/errors/file.js +110 -0
  95. package/dist/errors/file.js.map +1 -0
  96. package/dist/errors/index.d.ts +10 -0
  97. package/dist/errors/index.d.ts.map +1 -0
  98. package/dist/errors/index.js +41 -0
  99. package/dist/errors/index.js.map +1 -0
  100. package/dist/errors/llm.d.ts +26 -0
  101. package/dist/errors/llm.d.ts.map +1 -0
  102. package/dist/errors/llm.js +86 -0
  103. package/dist/errors/llm.js.map +1 -0
  104. package/dist/errors/network.d.ts +19 -0
  105. package/dist/errors/network.d.ts.map +1 -0
  106. package/dist/errors/network.js +82 -0
  107. package/dist/errors/network.js.map +1 -0
  108. package/dist/errors/validation.d.ts +19 -0
  109. package/dist/errors/validation.d.ts.map +1 -0
  110. package/dist/errors/validation.js +62 -0
  111. package/dist/errors/validation.js.map +1 -0
  112. package/dist/eval/eval-runner.d.ts +24 -0
  113. package/dist/eval/eval-runner.d.ts.map +1 -0
  114. package/dist/eval/eval-runner.js +309 -0
  115. package/dist/eval/eval-runner.js.map +1 -0
  116. package/dist/eval/index.d.ts +3 -0
  117. package/dist/eval/index.d.ts.map +1 -0
  118. package/dist/eval/index.js +3 -0
  119. package/dist/eval/index.js.map +1 -0
  120. package/dist/eval/types.d.ts +77 -0
  121. package/dist/eval/types.d.ts.map +1 -0
  122. package/dist/eval/types.js +2 -0
  123. package/dist/eval/types.js.map +1 -0
  124. package/dist/index.d.ts +4 -0
  125. package/dist/index.d.ts.map +1 -0
  126. package/dist/index.js +6 -0
  127. package/dist/index.js.map +1 -0
  128. package/dist/orchestration/index.d.ts +4 -0
  129. package/dist/orchestration/index.d.ts.map +1 -0
  130. package/dist/orchestration/index.js +3 -0
  131. package/dist/orchestration/index.js.map +1 -0
  132. package/dist/orchestration/plan-executor.d.ts +28 -0
  133. package/dist/orchestration/plan-executor.d.ts.map +1 -0
  134. package/dist/orchestration/plan-executor.js +382 -0
  135. package/dist/orchestration/plan-executor.js.map +1 -0
  136. package/dist/orchestration/types.d.ts +66 -0
  137. package/dist/orchestration/types.d.ts.map +1 -0
  138. package/dist/orchestration/types.js +2 -0
  139. package/dist/orchestration/types.js.map +1 -0
  140. package/dist/orchestration/utils.d.ts +13 -0
  141. package/dist/orchestration/utils.d.ts.map +1 -0
  142. package/dist/orchestration/utils.js +78 -0
  143. package/dist/orchestration/utils.js.map +1 -0
  144. package/dist/orquesta/connection.d.ts +35 -0
  145. package/dist/orquesta/connection.d.ts.map +1 -0
  146. package/dist/orquesta/connection.js +189 -0
  147. package/dist/orquesta/connection.js.map +1 -0
  148. package/dist/prompts/agents/docs-search-decision.d.ts +6 -0
  149. package/dist/prompts/agents/docs-search-decision.d.ts.map +1 -0
  150. package/dist/prompts/agents/docs-search-decision.js +46 -0
  151. package/dist/prompts/agents/docs-search-decision.js.map +1 -0
  152. package/dist/prompts/agents/docs-search.d.ts +4 -0
  153. package/dist/prompts/agents/docs-search.d.ts.map +1 -0
  154. package/dist/prompts/agents/docs-search.js +70 -0
  155. package/dist/prompts/agents/docs-search.js.map +1 -0
  156. package/dist/prompts/agents/planning.d.ts +4 -0
  157. package/dist/prompts/agents/planning.d.ts.map +1 -0
  158. package/dist/prompts/agents/planning.js +119 -0
  159. package/dist/prompts/agents/planning.js.map +1 -0
  160. package/dist/prompts/index.d.ts +10 -0
  161. package/dist/prompts/index.d.ts.map +1 -0
  162. package/dist/prompts/index.js +10 -0
  163. package/dist/prompts/index.js.map +1 -0
  164. package/dist/prompts/shared/codebase-rules.d.ts +4 -0
  165. package/dist/prompts/shared/codebase-rules.d.ts.map +1 -0
  166. package/dist/prompts/shared/codebase-rules.js +16 -0
  167. package/dist/prompts/shared/codebase-rules.js.map +1 -0
  168. package/dist/prompts/shared/git-rules.d.ts +2 -0
  169. package/dist/prompts/shared/git-rules.d.ts.map +1 -0
  170. package/dist/prompts/shared/git-rules.js +87 -0
  171. package/dist/prompts/shared/git-rules.js.map +1 -0
  172. package/dist/prompts/shared/language-rules.d.ts +4 -0
  173. package/dist/prompts/shared/language-rules.d.ts.map +1 -0
  174. package/dist/prompts/shared/language-rules.js +22 -0
  175. package/dist/prompts/shared/language-rules.js.map +1 -0
  176. package/dist/prompts/shared/tool-usage.d.ts +12 -0
  177. package/dist/prompts/shared/tool-usage.d.ts.map +1 -0
  178. package/dist/prompts/shared/tool-usage.js +51 -0
  179. package/dist/prompts/shared/tool-usage.js.map +1 -0
  180. package/dist/prompts/system/compact.d.ts +3 -0
  181. package/dist/prompts/system/compact.d.ts.map +1 -0
  182. package/dist/prompts/system/compact.js +73 -0
  183. package/dist/prompts/system/compact.js.map +1 -0
  184. package/dist/prompts/system/plan-execute.d.ts +3 -0
  185. package/dist/prompts/system/plan-execute.d.ts.map +1 -0
  186. package/dist/prompts/system/plan-execute.js +83 -0
  187. package/dist/prompts/system/plan-execute.js.map +1 -0
  188. package/dist/tools/browser/browser-client.d.ts +107 -0
  189. package/dist/tools/browser/browser-client.d.ts.map +1 -0
  190. package/dist/tools/browser/browser-client.js +958 -0
  191. package/dist/tools/browser/browser-client.js.map +1 -0
  192. package/dist/tools/browser/browser-tools.d.ts +17 -0
  193. package/dist/tools/browser/browser-tools.d.ts.map +1 -0
  194. package/dist/tools/browser/browser-tools.js +972 -0
  195. package/dist/tools/browser/browser-tools.js.map +1 -0
  196. package/dist/tools/browser/index.d.ts +7 -0
  197. package/dist/tools/browser/index.d.ts.map +1 -0
  198. package/dist/tools/browser/index.js +17 -0
  199. package/dist/tools/browser/index.js.map +1 -0
  200. package/dist/tools/index.d.ts +4 -0
  201. package/dist/tools/index.d.ts.map +1 -0
  202. package/dist/tools/index.js +4 -0
  203. package/dist/tools/index.js.map +1 -0
  204. package/dist/tools/llm/agents/docs-search-tools.d.ts +17 -0
  205. package/dist/tools/llm/agents/docs-search-tools.d.ts.map +1 -0
  206. package/dist/tools/llm/agents/docs-search-tools.js +265 -0
  207. package/dist/tools/llm/agents/docs-search-tools.js.map +1 -0
  208. package/dist/tools/llm/agents/index.d.ts +4 -0
  209. package/dist/tools/llm/agents/index.d.ts.map +1 -0
  210. package/dist/tools/llm/agents/index.js +3 -0
  211. package/dist/tools/llm/agents/index.js.map +1 -0
  212. package/dist/tools/llm/index.d.ts +3 -0
  213. package/dist/tools/llm/index.d.ts.map +1 -0
  214. package/dist/tools/llm/index.js +3 -0
  215. package/dist/tools/llm/index.js.map +1 -0
  216. package/dist/tools/llm/simple/ask-user-tool.d.ts +5 -0
  217. package/dist/tools/llm/simple/ask-user-tool.d.ts.map +1 -0
  218. package/dist/tools/llm/simple/ask-user-tool.js +7 -0
  219. package/dist/tools/llm/simple/ask-user-tool.js.map +1 -0
  220. package/dist/tools/llm/simple/background-bash-tool.d.ts +30 -0
  221. package/dist/tools/llm/simple/background-bash-tool.d.ts.map +1 -0
  222. package/dist/tools/llm/simple/background-bash-tool.js +323 -0
  223. package/dist/tools/llm/simple/background-bash-tool.js.map +1 -0
  224. package/dist/tools/llm/simple/background-powershell-tool.d.ts +30 -0
  225. package/dist/tools/llm/simple/background-powershell-tool.d.ts.map +1 -0
  226. package/dist/tools/llm/simple/background-powershell-tool.js +305 -0
  227. package/dist/tools/llm/simple/background-powershell-tool.js.map +1 -0
  228. package/dist/tools/llm/simple/bash-tool.d.ts +4 -0
  229. package/dist/tools/llm/simple/bash-tool.d.ts.map +1 -0
  230. package/dist/tools/llm/simple/bash-tool.js +178 -0
  231. package/dist/tools/llm/simple/bash-tool.js.map +1 -0
  232. package/dist/tools/llm/simple/docs-search-agent-tool.d.ts +6 -0
  233. package/dist/tools/llm/simple/docs-search-agent-tool.d.ts.map +1 -0
  234. package/dist/tools/llm/simple/docs-search-agent-tool.js +104 -0
  235. package/dist/tools/llm/simple/docs-search-agent-tool.js.map +1 -0
  236. package/dist/tools/llm/simple/file-tools.d.ts +13 -0
  237. package/dist/tools/llm/simple/file-tools.d.ts.map +1 -0
  238. package/dist/tools/llm/simple/file-tools.js +785 -0
  239. package/dist/tools/llm/simple/file-tools.js.map +1 -0
  240. package/dist/tools/llm/simple/final-response-tool.d.ts +12 -0
  241. package/dist/tools/llm/simple/final-response-tool.d.ts.map +1 -0
  242. package/dist/tools/llm/simple/final-response-tool.js +107 -0
  243. package/dist/tools/llm/simple/final-response-tool.js.map +1 -0
  244. package/dist/tools/llm/simple/index.d.ts +11 -0
  245. package/dist/tools/llm/simple/index.d.ts.map +1 -0
  246. package/dist/tools/llm/simple/index.js +20 -0
  247. package/dist/tools/llm/simple/index.js.map +1 -0
  248. package/dist/tools/llm/simple/planning-tools.d.ts +5 -0
  249. package/dist/tools/llm/simple/planning-tools.d.ts.map +1 -0
  250. package/dist/tools/llm/simple/planning-tools.js +117 -0
  251. package/dist/tools/llm/simple/planning-tools.js.map +1 -0
  252. package/dist/tools/llm/simple/powershell-tool.d.ts +4 -0
  253. package/dist/tools/llm/simple/powershell-tool.d.ts.map +1 -0
  254. package/dist/tools/llm/simple/powershell-tool.js +178 -0
  255. package/dist/tools/llm/simple/powershell-tool.js.map +1 -0
  256. package/dist/tools/llm/simple/simple-tool-executor.d.ts +38 -0
  257. package/dist/tools/llm/simple/simple-tool-executor.d.ts.map +1 -0
  258. package/dist/tools/llm/simple/simple-tool-executor.js +134 -0
  259. package/dist/tools/llm/simple/simple-tool-executor.js.map +1 -0
  260. package/dist/tools/llm/simple/todo-tools.d.ts +15 -0
  261. package/dist/tools/llm/simple/todo-tools.d.ts.map +1 -0
  262. package/dist/tools/llm/simple/todo-tools.js +145 -0
  263. package/dist/tools/llm/simple/todo-tools.js.map +1 -0
  264. package/dist/tools/llm/simple/user-interaction-tools.d.ts +22 -0
  265. package/dist/tools/llm/simple/user-interaction-tools.d.ts.map +1 -0
  266. package/dist/tools/llm/simple/user-interaction-tools.js +168 -0
  267. package/dist/tools/llm/simple/user-interaction-tools.js.map +1 -0
  268. package/dist/tools/office/common/constants.d.ts +194 -0
  269. package/dist/tools/office/common/constants.d.ts.map +1 -0
  270. package/dist/tools/office/common/constants.js +169 -0
  271. package/dist/tools/office/common/constants.js.map +1 -0
  272. package/dist/tools/office/common/index.d.ts +4 -0
  273. package/dist/tools/office/common/index.d.ts.map +1 -0
  274. package/dist/tools/office/common/index.js +3 -0
  275. package/dist/tools/office/common/index.js.map +1 -0
  276. package/dist/tools/office/common/types.d.ts +82 -0
  277. package/dist/tools/office/common/types.d.ts.map +1 -0
  278. package/dist/tools/office/common/types.js +2 -0
  279. package/dist/tools/office/common/types.js.map +1 -0
  280. package/dist/tools/office/common/utils.d.ts +14 -0
  281. package/dist/tools/office/common/utils.d.ts.map +1 -0
  282. package/dist/tools/office/common/utils.js +58 -0
  283. package/dist/tools/office/common/utils.js.map +1 -0
  284. package/dist/tools/office/excel-client.d.ts +123 -0
  285. package/dist/tools/office/excel-client.d.ts.map +1 -0
  286. package/dist/tools/office/excel-client.js +1037 -0
  287. package/dist/tools/office/excel-client.js.map +1 -0
  288. package/dist/tools/office/excel-tools/cells.d.ts +10 -0
  289. package/dist/tools/office/excel-tools/cells.d.ts.map +1 -0
  290. package/dist/tools/office/excel-tools/cells.js +279 -0
  291. package/dist/tools/office/excel-tools/cells.js.map +1 -0
  292. package/dist/tools/office/excel-tools/charts.d.ts +6 -0
  293. package/dist/tools/office/excel-tools/charts.d.ts.map +1 -0
  294. package/dist/tools/office/excel-tools/charts.js +124 -0
  295. package/dist/tools/office/excel-tools/charts.js.map +1 -0
  296. package/dist/tools/office/excel-tools/comments.d.ts +6 -0
  297. package/dist/tools/office/excel-tools/comments.d.ts.map +1 -0
  298. package/dist/tools/office/excel-tools/comments.js +114 -0
  299. package/dist/tools/office/excel-tools/comments.js.map +1 -0
  300. package/dist/tools/office/excel-tools/data-ops.d.ts +10 -0
  301. package/dist/tools/office/excel-tools/data-ops.d.ts.map +1 -0
  302. package/dist/tools/office/excel-tools/data-ops.js +266 -0
  303. package/dist/tools/office/excel-tools/data-ops.js.map +1 -0
  304. package/dist/tools/office/excel-tools/export.d.ts +5 -0
  305. package/dist/tools/office/excel-tools/export.d.ts.map +1 -0
  306. package/dist/tools/office/excel-tools/export.js +75 -0
  307. package/dist/tools/office/excel-tools/export.js.map +1 -0
  308. package/dist/tools/office/excel-tools/formatting.d.ts +10 -0
  309. package/dist/tools/office/excel-tools/formatting.d.ts.map +1 -0
  310. package/dist/tools/office/excel-tools/formatting.js +276 -0
  311. package/dist/tools/office/excel-tools/formatting.js.map +1 -0
  312. package/dist/tools/office/excel-tools/index.d.ts +16 -0
  313. package/dist/tools/office/excel-tools/index.d.ts.map +1 -0
  314. package/dist/tools/office/excel-tools/index.js +42 -0
  315. package/dist/tools/office/excel-tools/index.js.map +1 -0
  316. package/dist/tools/office/excel-tools/launch.d.ts +10 -0
  317. package/dist/tools/office/excel-tools/launch.d.ts.map +1 -0
  318. package/dist/tools/office/excel-tools/launch.js +248 -0
  319. package/dist/tools/office/excel-tools/launch.js.map +1 -0
  320. package/dist/tools/office/excel-tools/media.d.ts +5 -0
  321. package/dist/tools/office/excel-tools/media.d.ts.map +1 -0
  322. package/dist/tools/office/excel-tools/media.js +84 -0
  323. package/dist/tools/office/excel-tools/media.js.map +1 -0
  324. package/dist/tools/office/excel-tools/named-ranges.d.ts +6 -0
  325. package/dist/tools/office/excel-tools/named-ranges.d.ts.map +1 -0
  326. package/dist/tools/office/excel-tools/named-ranges.js +113 -0
  327. package/dist/tools/office/excel-tools/named-ranges.js.map +1 -0
  328. package/dist/tools/office/excel-tools/protection.d.ts +5 -0
  329. package/dist/tools/office/excel-tools/protection.d.ts.map +1 -0
  330. package/dist/tools/office/excel-tools/protection.js +75 -0
  331. package/dist/tools/office/excel-tools/protection.js.map +1 -0
  332. package/dist/tools/office/excel-tools/rows-columns.d.ts +11 -0
  333. package/dist/tools/office/excel-tools/rows-columns.d.ts.map +1 -0
  334. package/dist/tools/office/excel-tools/rows-columns.js +293 -0
  335. package/dist/tools/office/excel-tools/rows-columns.js.map +1 -0
  336. package/dist/tools/office/excel-tools/sheets.d.ts +8 -0
  337. package/dist/tools/office/excel-tools/sheets.d.ts.map +1 -0
  338. package/dist/tools/office/excel-tools/sheets.js +177 -0
  339. package/dist/tools/office/excel-tools/sheets.js.map +1 -0
  340. package/dist/tools/office/excel-tools/validation.d.ts +7 -0
  341. package/dist/tools/office/excel-tools/validation.d.ts.map +1 -0
  342. package/dist/tools/office/excel-tools/validation.js +175 -0
  343. package/dist/tools/office/excel-tools/validation.js.map +1 -0
  344. package/dist/tools/office/excel-tools.d.ts +3 -0
  345. package/dist/tools/office/excel-tools.d.ts.map +1 -0
  346. package/dist/tools/office/excel-tools.js +3 -0
  347. package/dist/tools/office/excel-tools.js.map +1 -0
  348. package/dist/tools/office/index.d.ts +6 -0
  349. package/dist/tools/office/index.d.ts.map +1 -0
  350. package/dist/tools/office/index.js +9 -0
  351. package/dist/tools/office/index.js.map +1 -0
  352. package/dist/tools/office/office-client-base.d.ts +31 -0
  353. package/dist/tools/office/office-client-base.d.ts.map +1 -0
  354. package/dist/tools/office/office-client-base.js +154 -0
  355. package/dist/tools/office/office-client-base.js.map +1 -0
  356. package/dist/tools/office/office-client.d.ts +196 -0
  357. package/dist/tools/office/office-client.d.ts.map +1 -0
  358. package/dist/tools/office/office-client.js +200 -0
  359. package/dist/tools/office/office-client.js.map +1 -0
  360. package/dist/tools/office/powerpoint-client.d.ts +135 -0
  361. package/dist/tools/office/powerpoint-client.d.ts.map +1 -0
  362. package/dist/tools/office/powerpoint-client.js +1136 -0
  363. package/dist/tools/office/powerpoint-client.js.map +1 -0
  364. package/dist/tools/office/powerpoint-tools/effects.d.ts +9 -0
  365. package/dist/tools/office/powerpoint-tools/effects.d.ts.map +1 -0
  366. package/dist/tools/office/powerpoint-tools/effects.js +246 -0
  367. package/dist/tools/office/powerpoint-tools/effects.js.map +1 -0
  368. package/dist/tools/office/powerpoint-tools/export.d.ts +6 -0
  369. package/dist/tools/office/powerpoint-tools/export.d.ts.map +1 -0
  370. package/dist/tools/office/powerpoint-tools/export.js +108 -0
  371. package/dist/tools/office/powerpoint-tools/export.js.map +1 -0
  372. package/dist/tools/office/powerpoint-tools/index.d.ts +13 -0
  373. package/dist/tools/office/powerpoint-tools/index.d.ts.map +1 -0
  374. package/dist/tools/office/powerpoint-tools/index.js +33 -0
  375. package/dist/tools/office/powerpoint-tools/index.js.map +1 -0
  376. package/dist/tools/office/powerpoint-tools/launch.d.ts +9 -0
  377. package/dist/tools/office/powerpoint-tools/launch.d.ts.map +1 -0
  378. package/dist/tools/office/powerpoint-tools/launch.js +214 -0
  379. package/dist/tools/office/powerpoint-tools/launch.js.map +1 -0
  380. package/dist/tools/office/powerpoint-tools/media.d.ts +8 -0
  381. package/dist/tools/office/powerpoint-tools/media.d.ts.map +1 -0
  382. package/dist/tools/office/powerpoint-tools/media.js +211 -0
  383. package/dist/tools/office/powerpoint-tools/media.js.map +1 -0
  384. package/dist/tools/office/powerpoint-tools/notes.d.ts +8 -0
  385. package/dist/tools/office/powerpoint-tools/notes.d.ts.map +1 -0
  386. package/dist/tools/office/powerpoint-tools/notes.js +171 -0
  387. package/dist/tools/office/powerpoint-tools/notes.js.map +1 -0
  388. package/dist/tools/office/powerpoint-tools/sections.d.ts +6 -0
  389. package/dist/tools/office/powerpoint-tools/sections.d.ts.map +1 -0
  390. package/dist/tools/office/powerpoint-tools/sections.js +104 -0
  391. package/dist/tools/office/powerpoint-tools/sections.js.map +1 -0
  392. package/dist/tools/office/powerpoint-tools/shapes.d.ts +22 -0
  393. package/dist/tools/office/powerpoint-tools/shapes.d.ts.map +1 -0
  394. package/dist/tools/office/powerpoint-tools/shapes.js +681 -0
  395. package/dist/tools/office/powerpoint-tools/shapes.js.map +1 -0
  396. package/dist/tools/office/powerpoint-tools/slides.d.ts +11 -0
  397. package/dist/tools/office/powerpoint-tools/slides.d.ts.map +1 -0
  398. package/dist/tools/office/powerpoint-tools/slides.js +283 -0
  399. package/dist/tools/office/powerpoint-tools/slides.js.map +1 -0
  400. package/dist/tools/office/powerpoint-tools/tables.d.ts +6 -0
  401. package/dist/tools/office/powerpoint-tools/tables.d.ts.map +1 -0
  402. package/dist/tools/office/powerpoint-tools/tables.js +132 -0
  403. package/dist/tools/office/powerpoint-tools/tables.js.map +1 -0
  404. package/dist/tools/office/powerpoint-tools/text.d.ts +12 -0
  405. package/dist/tools/office/powerpoint-tools/text.d.ts.map +1 -0
  406. package/dist/tools/office/powerpoint-tools/text.js +366 -0
  407. package/dist/tools/office/powerpoint-tools/text.js.map +1 -0
  408. package/dist/tools/office/powerpoint-tools.d.ts +3 -0
  409. package/dist/tools/office/powerpoint-tools.d.ts.map +1 -0
  410. package/dist/tools/office/powerpoint-tools.js +3 -0
  411. package/dist/tools/office/powerpoint-tools.js.map +1 -0
  412. package/dist/tools/office/word-client.d.ts +147 -0
  413. package/dist/tools/office/word-client.d.ts.map +1 -0
  414. package/dist/tools/office/word-client.js +1341 -0
  415. package/dist/tools/office/word-client.js.map +1 -0
  416. package/dist/tools/office/word-tools/bookmarks.d.ts +7 -0
  417. package/dist/tools/office/word-tools/bookmarks.d.ts.map +1 -0
  418. package/dist/tools/office/word-tools/bookmarks.js +146 -0
  419. package/dist/tools/office/word-tools/bookmarks.js.map +1 -0
  420. package/dist/tools/office/word-tools/comments.d.ts +7 -0
  421. package/dist/tools/office/word-tools/comments.d.ts.map +1 -0
  422. package/dist/tools/office/word-tools/comments.js +146 -0
  423. package/dist/tools/office/word-tools/comments.js.map +1 -0
  424. package/dist/tools/office/word-tools/content.d.ts +7 -0
  425. package/dist/tools/office/word-tools/content.d.ts.map +1 -0
  426. package/dist/tools/office/word-tools/content.js +168 -0
  427. package/dist/tools/office/word-tools/content.js.map +1 -0
  428. package/dist/tools/office/word-tools/export.d.ts +5 -0
  429. package/dist/tools/office/word-tools/export.d.ts.map +1 -0
  430. package/dist/tools/office/word-tools/export.js +73 -0
  431. package/dist/tools/office/word-tools/export.js.map +1 -0
  432. package/dist/tools/office/word-tools/formatting.d.ts +6 -0
  433. package/dist/tools/office/word-tools/formatting.d.ts.map +1 -0
  434. package/dist/tools/office/word-tools/formatting.js +129 -0
  435. package/dist/tools/office/word-tools/formatting.js.map +1 -0
  436. package/dist/tools/office/word-tools/headers-footers.d.ts +6 -0
  437. package/dist/tools/office/word-tools/headers-footers.d.ts.map +1 -0
  438. package/dist/tools/office/word-tools/headers-footers.js +117 -0
  439. package/dist/tools/office/word-tools/headers-footers.js.map +1 -0
  440. package/dist/tools/office/word-tools/index.d.ts +16 -0
  441. package/dist/tools/office/word-tools/index.d.ts.map +1 -0
  442. package/dist/tools/office/word-tools/index.js +45 -0
  443. package/dist/tools/office/word-tools/index.js.map +1 -0
  444. package/dist/tools/office/word-tools/launch.d.ts +10 -0
  445. package/dist/tools/office/word-tools/launch.d.ts.map +1 -0
  446. package/dist/tools/office/word-tools/launch.js +255 -0
  447. package/dist/tools/office/word-tools/launch.js.map +1 -0
  448. package/dist/tools/office/word-tools/lists.d.ts +5 -0
  449. package/dist/tools/office/word-tools/lists.d.ts.map +1 -0
  450. package/dist/tools/office/word-tools/lists.js +73 -0
  451. package/dist/tools/office/word-tools/lists.js.map +1 -0
  452. package/dist/tools/office/word-tools/navigation.d.ts +5 -0
  453. package/dist/tools/office/word-tools/navigation.d.ts.map +1 -0
  454. package/dist/tools/office/word-tools/navigation.js +85 -0
  455. package/dist/tools/office/word-tools/navigation.js.map +1 -0
  456. package/dist/tools/office/word-tools/page-setup.d.ts +7 -0
  457. package/dist/tools/office/word-tools/page-setup.d.ts.map +1 -0
  458. package/dist/tools/office/word-tools/page-setup.js +152 -0
  459. package/dist/tools/office/word-tools/page-setup.js.map +1 -0
  460. package/dist/tools/office/word-tools/tables.d.ts +8 -0
  461. package/dist/tools/office/word-tools/tables.d.ts.map +1 -0
  462. package/dist/tools/office/word-tools/tables.js +197 -0
  463. package/dist/tools/office/word-tools/tables.js.map +1 -0
  464. package/dist/tools/office/word-tools/text.d.ts +9 -0
  465. package/dist/tools/office/word-tools/text.d.ts.map +1 -0
  466. package/dist/tools/office/word-tools/text.js +235 -0
  467. package/dist/tools/office/word-tools/text.js.map +1 -0
  468. package/dist/tools/office/word-tools/undo-redo.d.ts +5 -0
  469. package/dist/tools/office/word-tools/undo-redo.d.ts.map +1 -0
  470. package/dist/tools/office/word-tools/undo-redo.js +73 -0
  471. package/dist/tools/office/word-tools/undo-redo.js.map +1 -0
  472. package/dist/tools/office/word-tools/watermarks.d.ts +5 -0
  473. package/dist/tools/office/word-tools/watermarks.d.ts.map +1 -0
  474. package/dist/tools/office/word-tools/watermarks.js +81 -0
  475. package/dist/tools/office/word-tools/watermarks.js.map +1 -0
  476. package/dist/tools/office/word-tools.d.ts +3 -0
  477. package/dist/tools/office/word-tools.d.ts.map +1 -0
  478. package/dist/tools/office/word-tools.js +3 -0
  479. package/dist/tools/office/word-tools.js.map +1 -0
  480. package/dist/tools/registry.d.ts +53 -0
  481. package/dist/tools/registry.d.ts.map +1 -0
  482. package/dist/tools/registry.js +278 -0
  483. package/dist/tools/registry.js.map +1 -0
  484. package/dist/tools/types.d.ts +88 -0
  485. package/dist/tools/types.d.ts.map +1 -0
  486. package/dist/tools/types.js +19 -0
  487. package/dist/tools/types.js.map +1 -0
  488. package/dist/types/index.d.ts +126 -0
  489. package/dist/types/index.d.ts.map +1 -0
  490. package/dist/types/index.js +2 -0
  491. package/dist/types/index.js.map +1 -0
  492. package/dist/ui/PlanExecuteView.d.ts +11 -0
  493. package/dist/ui/PlanExecuteView.d.ts.map +1 -0
  494. package/dist/ui/PlanExecuteView.js +29 -0
  495. package/dist/ui/PlanExecuteView.js.map +1 -0
  496. package/dist/ui/TodoPanel.d.ts +13 -0
  497. package/dist/ui/TodoPanel.d.ts.map +1 -0
  498. package/dist/ui/TodoPanel.js +135 -0
  499. package/dist/ui/TodoPanel.js.map +1 -0
  500. package/dist/ui/UpdateNotification.d.ts +13 -0
  501. package/dist/ui/UpdateNotification.d.ts.map +1 -0
  502. package/dist/ui/UpdateNotification.js +42 -0
  503. package/dist/ui/UpdateNotification.js.map +1 -0
  504. package/dist/ui/components/ActivityIndicator.d.ts +25 -0
  505. package/dist/ui/components/ActivityIndicator.d.ts.map +1 -0
  506. package/dist/ui/components/ActivityIndicator.js +115 -0
  507. package/dist/ui/components/ActivityIndicator.js.map +1 -0
  508. package/dist/ui/components/CommandBrowser.d.ts +10 -0
  509. package/dist/ui/components/CommandBrowser.d.ts.map +1 -0
  510. package/dist/ui/components/CommandBrowser.js +53 -0
  511. package/dist/ui/components/CommandBrowser.js.map +1 -0
  512. package/dist/ui/components/CustomTextInput.d.ts +13 -0
  513. package/dist/ui/components/CustomTextInput.d.ts.map +1 -0
  514. package/dist/ui/components/CustomTextInput.js +245 -0
  515. package/dist/ui/components/CustomTextInput.js.map +1 -0
  516. package/dist/ui/components/DocsSearchProgress.d.ts +13 -0
  517. package/dist/ui/components/DocsSearchProgress.d.ts.map +1 -0
  518. package/dist/ui/components/DocsSearchProgress.js +37 -0
  519. package/dist/ui/components/DocsSearchProgress.js.map +1 -0
  520. package/dist/ui/components/FileBrowser.d.ts +11 -0
  521. package/dist/ui/components/FileBrowser.d.ts.map +1 -0
  522. package/dist/ui/components/FileBrowser.js +45 -0
  523. package/dist/ui/components/FileBrowser.js.map +1 -0
  524. package/dist/ui/components/LLMSetupWizard.d.ts +8 -0
  525. package/dist/ui/components/LLMSetupWizard.d.ts.map +1 -0
  526. package/dist/ui/components/LLMSetupWizard.js +192 -0
  527. package/dist/ui/components/LLMSetupWizard.js.map +1 -0
  528. package/dist/ui/components/Logo.d.ts +19 -0
  529. package/dist/ui/components/Logo.d.ts.map +1 -0
  530. package/dist/ui/components/Logo.js +55 -0
  531. package/dist/ui/components/Logo.js.map +1 -0
  532. package/dist/ui/components/MarkdownRenderer.d.ts +9 -0
  533. package/dist/ui/components/MarkdownRenderer.d.ts.map +1 -0
  534. package/dist/ui/components/MarkdownRenderer.js +198 -0
  535. package/dist/ui/components/MarkdownRenderer.js.map +1 -0
  536. package/dist/ui/components/ModelSelector.d.ts +8 -0
  537. package/dist/ui/components/ModelSelector.d.ts.map +1 -0
  538. package/dist/ui/components/ModelSelector.js +111 -0
  539. package/dist/ui/components/ModelSelector.js.map +1 -0
  540. package/dist/ui/components/PlanExecuteApp.d.ts +23 -0
  541. package/dist/ui/components/PlanExecuteApp.d.ts.map +1 -0
  542. package/dist/ui/components/PlanExecuteApp.js +1324 -0
  543. package/dist/ui/components/PlanExecuteApp.js.map +1 -0
  544. package/dist/ui/components/ProgressBar.d.ts +10 -0
  545. package/dist/ui/components/ProgressBar.d.ts.map +1 -0
  546. package/dist/ui/components/ProgressBar.js +26 -0
  547. package/dist/ui/components/ProgressBar.js.map +1 -0
  548. package/dist/ui/components/StatusBar.d.ts +23 -0
  549. package/dist/ui/components/StatusBar.d.ts.map +1 -0
  550. package/dist/ui/components/StatusBar.js +162 -0
  551. package/dist/ui/components/StatusBar.js.map +1 -0
  552. package/dist/ui/components/ThinkingIndicator.d.ts +14 -0
  553. package/dist/ui/components/ThinkingIndicator.d.ts.map +1 -0
  554. package/dist/ui/components/ThinkingIndicator.js +63 -0
  555. package/dist/ui/components/ThinkingIndicator.js.map +1 -0
  556. package/dist/ui/components/TodoListView.d.ts +11 -0
  557. package/dist/ui/components/TodoListView.d.ts.map +1 -0
  558. package/dist/ui/components/TodoListView.js +69 -0
  559. package/dist/ui/components/TodoListView.js.map +1 -0
  560. package/dist/ui/components/ToolSelector.d.ts +7 -0
  561. package/dist/ui/components/ToolSelector.d.ts.map +1 -0
  562. package/dist/ui/components/ToolSelector.js +111 -0
  563. package/dist/ui/components/ToolSelector.js.map +1 -0
  564. package/dist/ui/components/dialogs/ApprovalDialog.d.ts +13 -0
  565. package/dist/ui/components/dialogs/ApprovalDialog.d.ts.map +1 -0
  566. package/dist/ui/components/dialogs/ApprovalDialog.js +173 -0
  567. package/dist/ui/components/dialogs/ApprovalDialog.js.map +1 -0
  568. package/dist/ui/components/dialogs/AskUserDialog.d.ts +9 -0
  569. package/dist/ui/components/dialogs/AskUserDialog.d.ts.map +1 -0
  570. package/dist/ui/components/dialogs/AskUserDialog.js +111 -0
  571. package/dist/ui/components/dialogs/AskUserDialog.js.map +1 -0
  572. package/dist/ui/components/dialogs/DocsBrowser.d.ts +8 -0
  573. package/dist/ui/components/dialogs/DocsBrowser.d.ts.map +1 -0
  574. package/dist/ui/components/dialogs/DocsBrowser.js +127 -0
  575. package/dist/ui/components/dialogs/DocsBrowser.js.map +1 -0
  576. package/dist/ui/components/dialogs/SettingsDialog.d.ts +10 -0
  577. package/dist/ui/components/dialogs/SettingsDialog.d.ts.map +1 -0
  578. package/dist/ui/components/dialogs/SettingsDialog.js +563 -0
  579. package/dist/ui/components/dialogs/SettingsDialog.js.map +1 -0
  580. package/dist/ui/components/dialogs/index.d.ts +4 -0
  581. package/dist/ui/components/dialogs/index.d.ts.map +1 -0
  582. package/dist/ui/components/dialogs/index.js +4 -0
  583. package/dist/ui/components/dialogs/index.js.map +1 -0
  584. package/dist/ui/components/index.d.ts +12 -0
  585. package/dist/ui/components/index.d.ts.map +1 -0
  586. package/dist/ui/components/index.js +9 -0
  587. package/dist/ui/components/index.js.map +1 -0
  588. package/dist/ui/components/panels/LogPanel.d.ts +7 -0
  589. package/dist/ui/components/panels/LogPanel.d.ts.map +1 -0
  590. package/dist/ui/components/panels/LogPanel.js +280 -0
  591. package/dist/ui/components/panels/LogPanel.js.map +1 -0
  592. package/dist/ui/components/panels/SessionPanel.d.ts +8 -0
  593. package/dist/ui/components/panels/SessionPanel.d.ts.map +1 -0
  594. package/dist/ui/components/panels/SessionPanel.js +81 -0
  595. package/dist/ui/components/panels/SessionPanel.js.map +1 -0
  596. package/dist/ui/components/panels/index.d.ts +4 -0
  597. package/dist/ui/components/panels/index.d.ts.map +1 -0
  598. package/dist/ui/components/panels/index.js +4 -0
  599. package/dist/ui/components/panels/index.js.map +1 -0
  600. package/dist/ui/components/views/ChatView.d.ts +12 -0
  601. package/dist/ui/components/views/ChatView.d.ts.map +1 -0
  602. package/dist/ui/components/views/ChatView.js +289 -0
  603. package/dist/ui/components/views/ChatView.js.map +1 -0
  604. package/dist/ui/components/views/index.d.ts +2 -0
  605. package/dist/ui/components/views/index.d.ts.map +1 -0
  606. package/dist/ui/components/views/index.js +2 -0
  607. package/dist/ui/components/views/index.js.map +1 -0
  608. package/dist/ui/contexts/TokenContext.d.ts +29 -0
  609. package/dist/ui/contexts/TokenContext.d.ts.map +1 -0
  610. package/dist/ui/contexts/TokenContext.js +79 -0
  611. package/dist/ui/contexts/TokenContext.js.map +1 -0
  612. package/dist/ui/hooks/atFileProcessor.d.ts +15 -0
  613. package/dist/ui/hooks/atFileProcessor.d.ts.map +1 -0
  614. package/dist/ui/hooks/atFileProcessor.js +88 -0
  615. package/dist/ui/hooks/atFileProcessor.js.map +1 -0
  616. package/dist/ui/hooks/index.d.ts +8 -0
  617. package/dist/ui/hooks/index.d.ts.map +1 -0
  618. package/dist/ui/hooks/index.js +8 -0
  619. package/dist/ui/hooks/index.js.map +1 -0
  620. package/dist/ui/hooks/slashCommandProcessor.d.ts +21 -0
  621. package/dist/ui/hooks/slashCommandProcessor.d.ts.map +1 -0
  622. package/dist/ui/hooks/slashCommandProcessor.js +100 -0
  623. package/dist/ui/hooks/slashCommandProcessor.js.map +1 -0
  624. package/dist/ui/hooks/useCommandBrowserState.d.ts +12 -0
  625. package/dist/ui/hooks/useCommandBrowserState.d.ts.map +1 -0
  626. package/dist/ui/hooks/useCommandBrowserState.js +66 -0
  627. package/dist/ui/hooks/useCommandBrowserState.js.map +1 -0
  628. package/dist/ui/hooks/useFileBrowserState.d.ts +15 -0
  629. package/dist/ui/hooks/useFileBrowserState.d.ts.map +1 -0
  630. package/dist/ui/hooks/useFileBrowserState.js +80 -0
  631. package/dist/ui/hooks/useFileBrowserState.js.map +1 -0
  632. package/dist/ui/hooks/useFileList.d.ts +20 -0
  633. package/dist/ui/hooks/useFileList.d.ts.map +1 -0
  634. package/dist/ui/hooks/useFileList.js +57 -0
  635. package/dist/ui/hooks/useFileList.js.map +1 -0
  636. package/dist/ui/hooks/useInputHistory.d.ts +9 -0
  637. package/dist/ui/hooks/useInputHistory.d.ts.map +1 -0
  638. package/dist/ui/hooks/useInputHistory.js +68 -0
  639. package/dist/ui/hooks/useInputHistory.js.map +1 -0
  640. package/dist/ui/hooks/usePlanExecution.d.ts +8 -0
  641. package/dist/ui/hooks/usePlanExecution.d.ts.map +1 -0
  642. package/dist/ui/hooks/usePlanExecution.js +214 -0
  643. package/dist/ui/hooks/usePlanExecution.js.map +1 -0
  644. package/dist/ui/index.d.ts +7 -0
  645. package/dist/ui/index.d.ts.map +1 -0
  646. package/dist/ui/index.js +7 -0
  647. package/dist/ui/index.js.map +1 -0
  648. package/dist/ui/ink-entry.d.ts +3 -0
  649. package/dist/ui/ink-entry.d.ts.map +1 -0
  650. package/dist/ui/ink-entry.js +22 -0
  651. package/dist/ui/ink-entry.js.map +1 -0
  652. package/dist/utils/env-filter.d.ts +4 -0
  653. package/dist/utils/env-filter.d.ts.map +1 -0
  654. package/dist/utils/env-filter.js +101 -0
  655. package/dist/utils/env-filter.js.map +1 -0
  656. package/dist/utils/file-system.d.ts +9 -0
  657. package/dist/utils/file-system.d.ts.map +1 -0
  658. package/dist/utils/file-system.js +99 -0
  659. package/dist/utils/file-system.js.map +1 -0
  660. package/dist/utils/git-utils.d.ts +2 -0
  661. package/dist/utils/git-utils.d.ts.map +1 -0
  662. package/dist/utils/git-utils.js +16 -0
  663. package/dist/utils/git-utils.js.map +1 -0
  664. package/dist/utils/json-stream-logger.d.ts +74 -0
  665. package/dist/utils/json-stream-logger.d.ts.map +1 -0
  666. package/dist/utils/json-stream-logger.js +808 -0
  667. package/dist/utils/json-stream-logger.js.map +1 -0
  668. package/dist/utils/logger.d.ts +152 -0
  669. package/dist/utils/logger.d.ts.map +1 -0
  670. package/dist/utils/logger.js +1672 -0
  671. package/dist/utils/logger.js.map +1 -0
  672. package/dist/utils/platform-utils.d.ts +19 -0
  673. package/dist/utils/platform-utils.d.ts.map +1 -0
  674. package/dist/utils/platform-utils.js +134 -0
  675. package/dist/utils/platform-utils.js.map +1 -0
  676. package/dist/utils/wsl-utils.d.ts +4 -0
  677. package/dist/utils/wsl-utils.d.ts.map +1 -0
  678. package/dist/utils/wsl-utils.js +72 -0
  679. package/dist/utils/wsl-utils.js.map +1 -0
  680. package/electron.vite.config.ts +63 -0
  681. package/google374b9eba0c52b043.html +1 -0
  682. package/package.json +122 -0
  683. package/src/agents/base/base-agent.ts +159 -0
  684. package/src/agents/docs-search/index.ts +365 -0
  685. package/src/agents/index.ts +34 -0
  686. package/src/agents/planner/index.ts +544 -0
  687. package/src/cli.ts +201 -0
  688. package/src/constants.ts +47 -0
  689. package/src/core/compact/compact-manager.ts +160 -0
  690. package/src/core/compact/compact-prompts.ts +150 -0
  691. package/src/core/compact/context-tracker.ts +164 -0
  692. package/src/core/compact/index.ts +25 -0
  693. package/src/core/config/config-manager.ts +460 -0
  694. package/src/core/config/index.ts +5 -0
  695. package/src/core/docs-manager.ts +678 -0
  696. package/src/core/llm/index.ts +7 -0
  697. package/src/core/llm/llm-client.ts +1550 -0
  698. package/src/core/session/index.ts +5 -0
  699. package/src/core/session/session-manager.ts +464 -0
  700. package/src/core/slash-command-handler.ts +410 -0
  701. package/src/core/usage-tracker.ts +438 -0
  702. package/src/errors/base.ts +81 -0
  703. package/src/errors/file.ts +183 -0
  704. package/src/errors/index.ts +95 -0
  705. package/src/errors/llm.ts +151 -0
  706. package/src/errors/network.ts +124 -0
  707. package/src/errors/validation.ts +111 -0
  708. package/src/eval/eval-runner.ts +456 -0
  709. package/src/eval/index.ts +8 -0
  710. package/src/eval/types.ts +139 -0
  711. package/src/index.ts +22 -0
  712. package/src/orchestration/index.ts +30 -0
  713. package/src/orchestration/plan-executor.ts +652 -0
  714. package/src/orchestration/types.ts +127 -0
  715. package/src/orchestration/utils.ts +119 -0
  716. package/src/orquesta/connection.ts +291 -0
  717. package/src/prompts/agents/docs-search-decision.ts +74 -0
  718. package/src/prompts/agents/docs-search.ts +84 -0
  719. package/src/prompts/agents/planning.ts +143 -0
  720. package/src/prompts/index.ts +31 -0
  721. package/src/prompts/shared/codebase-rules.ts +29 -0
  722. package/src/prompts/shared/git-rules.ts +94 -0
  723. package/src/prompts/shared/language-rules.ts +36 -0
  724. package/src/prompts/shared/tool-usage.ts +72 -0
  725. package/src/prompts/system/compact.ts +80 -0
  726. package/src/prompts/system/plan-execute.ts +89 -0
  727. package/src/tools/browser/browser-client.ts +1363 -0
  728. package/src/tools/browser/browser-tools.ts +1139 -0
  729. package/src/tools/browser/index.ts +65 -0
  730. package/src/tools/index.ts +23 -0
  731. package/src/tools/llm/agents/docs-search-tools.ts +368 -0
  732. package/src/tools/llm/agents/index.ts +22 -0
  733. package/src/tools/llm/index.ts +11 -0
  734. package/src/tools/llm/simple/ask-user-tool.ts +25 -0
  735. package/src/tools/llm/simple/background-bash-tool.ts +443 -0
  736. package/src/tools/llm/simple/background-powershell-tool.ts +421 -0
  737. package/src/tools/llm/simple/bash-tool.ts +238 -0
  738. package/src/tools/llm/simple/docs-search-agent-tool.ts +146 -0
  739. package/src/tools/llm/simple/file-tools.ts +1051 -0
  740. package/src/tools/llm/simple/final-response-tool.ts +180 -0
  741. package/src/tools/llm/simple/index.ts +42 -0
  742. package/src/tools/llm/simple/planning-tools.ts +143 -0
  743. package/src/tools/llm/simple/powershell-tool.ts +241 -0
  744. package/src/tools/llm/simple/simple-tool-executor.ts +279 -0
  745. package/src/tools/llm/simple/todo-tools.ts +207 -0
  746. package/src/tools/llm/simple/user-interaction-tools.ts +277 -0
  747. package/src/tools/office/common/constants.ts +335 -0
  748. package/src/tools/office/common/index.ts +133 -0
  749. package/src/tools/office/common/types.ts +286 -0
  750. package/src/tools/office/common/utils.ts +116 -0
  751. package/src/tools/office/excel-client.ts +1336 -0
  752. package/src/tools/office/excel-tools/cells.ts +359 -0
  753. package/src/tools/office/excel-tools/charts.ts +166 -0
  754. package/src/tools/office/excel-tools/comments.ts +155 -0
  755. package/src/tools/office/excel-tools/data-ops.ts +349 -0
  756. package/src/tools/office/excel-tools/export.ts +105 -0
  757. package/src/tools/office/excel-tools/formatting.ts +357 -0
  758. package/src/tools/office/excel-tools/index.ts +55 -0
  759. package/src/tools/office/excel-tools/launch.ts +303 -0
  760. package/src/tools/office/excel-tools/media.ts +117 -0
  761. package/src/tools/office/excel-tools/named-ranges.ts +148 -0
  762. package/src/tools/office/excel-tools/protection.ts +105 -0
  763. package/src/tools/office/excel-tools/rows-columns.ts +386 -0
  764. package/src/tools/office/excel-tools/sheets.ts +228 -0
  765. package/src/tools/office/excel-tools/validation.ts +226 -0
  766. package/src/tools/office/excel-tools.ts +9 -0
  767. package/src/tools/office/index.ts +259 -0
  768. package/src/tools/office/office-client-base.ts +242 -0
  769. package/src/tools/office/office-client.ts +377 -0
  770. package/src/tools/office/powerpoint-client.ts +1498 -0
  771. package/src/tools/office/powerpoint-tools/effects.ts +315 -0
  772. package/src/tools/office/powerpoint-tools/export.ts +138 -0
  773. package/src/tools/office/powerpoint-tools/index.ts +45 -0
  774. package/src/tools/office/powerpoint-tools/launch.ts +263 -0
  775. package/src/tools/office/powerpoint-tools/media.ts +291 -0
  776. package/src/tools/office/powerpoint-tools/notes.ts +220 -0
  777. package/src/tools/office/powerpoint-tools/sections.ts +140 -0
  778. package/src/tools/office/powerpoint-tools/shapes.ts +870 -0
  779. package/src/tools/office/powerpoint-tools/slides.ts +350 -0
  780. package/src/tools/office/powerpoint-tools/tables.ts +182 -0
  781. package/src/tools/office/powerpoint-tools/text.ts +473 -0
  782. package/src/tools/office/powerpoint-tools.ts +9 -0
  783. package/src/tools/office/word-client.ts +1697 -0
  784. package/src/tools/office/word-tools/bookmarks.ts +186 -0
  785. package/src/tools/office/word-tools/comments.ts +185 -0
  786. package/src/tools/office/word-tools/content.ts +229 -0
  787. package/src/tools/office/word-tools/export.ts +97 -0
  788. package/src/tools/office/word-tools/formatting.ts +161 -0
  789. package/src/tools/office/word-tools/headers-footers.ts +155 -0
  790. package/src/tools/office/word-tools/index.ts +57 -0
  791. package/src/tools/office/word-tools/launch.ts +312 -0
  792. package/src/tools/office/word-tools/lists.ts +97 -0
  793. package/src/tools/office/word-tools/navigation.ts +114 -0
  794. package/src/tools/office/word-tools/page-setup.ts +195 -0
  795. package/src/tools/office/word-tools/tables.ts +262 -0
  796. package/src/tools/office/word-tools/text.ts +294 -0
  797. package/src/tools/office/word-tools/undo-redo.ts +97 -0
  798. package/src/tools/office/word-tools/watermarks.ts +105 -0
  799. package/src/tools/office/word-tools.ts +9 -0
  800. package/src/tools/registry.ts +527 -0
  801. package/src/tools/types.ts +231 -0
  802. package/src/types/index.ts +181 -0
  803. package/src/ui/PlanExecuteView.tsx +119 -0
  804. package/src/ui/TodoPanel.tsx +240 -0
  805. package/src/ui/UpdateNotification.tsx +105 -0
  806. package/src/ui/components/ActivityIndicator.tsx +234 -0
  807. package/src/ui/components/CommandBrowser.tsx +114 -0
  808. package/src/ui/components/CustomTextInput.tsx +389 -0
  809. package/src/ui/components/DocsSearchProgress.tsx +85 -0
  810. package/src/ui/components/FileBrowser.tsx +93 -0
  811. package/src/ui/components/LLMSetupWizard.tsx +333 -0
  812. package/src/ui/components/Logo.tsx +125 -0
  813. package/src/ui/components/MarkdownRenderer.tsx +358 -0
  814. package/src/ui/components/ModelSelector.tsx +203 -0
  815. package/src/ui/components/PlanExecuteApp.tsx +2007 -0
  816. package/src/ui/components/ProgressBar.tsx +51 -0
  817. package/src/ui/components/StatusBar.tsx +302 -0
  818. package/src/ui/components/ThinkingIndicator.tsx +120 -0
  819. package/src/ui/components/TodoListView.tsx +140 -0
  820. package/src/ui/components/ToolSelector.tsx +215 -0
  821. package/src/ui/components/dialogs/ApprovalDialog.tsx +259 -0
  822. package/src/ui/components/dialogs/AskUserDialog.tsx +159 -0
  823. package/src/ui/components/dialogs/DocsBrowser.tsx +222 -0
  824. package/src/ui/components/dialogs/SettingsDialog.tsx +939 -0
  825. package/src/ui/components/dialogs/index.ts +13 -0
  826. package/src/ui/components/index.ts +27 -0
  827. package/src/ui/components/panels/LogPanel.tsx +385 -0
  828. package/src/ui/components/panels/SessionPanel.tsx +146 -0
  829. package/src/ui/components/panels/index.ts +13 -0
  830. package/src/ui/components/views/ChatView.tsx +447 -0
  831. package/src/ui/components/views/index.ts +5 -0
  832. package/src/ui/contexts/TokenContext.tsx +139 -0
  833. package/src/ui/hooks/atFileProcessor.ts +167 -0
  834. package/src/ui/hooks/index.ts +11 -0
  835. package/src/ui/hooks/slashCommandProcessor.ts +174 -0
  836. package/src/ui/hooks/useCommandBrowserState.ts +97 -0
  837. package/src/ui/hooks/useFileBrowserState.ts +116 -0
  838. package/src/ui/hooks/useFileList.ts +132 -0
  839. package/src/ui/hooks/useInputHistory.ts +89 -0
  840. package/src/ui/hooks/usePlanExecution.ts +339 -0
  841. package/src/ui/index.ts +10 -0
  842. package/src/ui/ink-entry.tsx +36 -0
  843. package/src/utils/env-filter.ts +164 -0
  844. package/src/utils/file-system.ts +133 -0
  845. package/src/utils/git-utils.ts +30 -0
  846. package/src/utils/json-stream-logger.ts +1259 -0
  847. package/src/utils/logger.ts +2767 -0
  848. package/src/utils/platform-utils.ts +256 -0
  849. package/src/utils/wsl-utils.ts +113 -0
  850. package/tsconfig.electron.json +39 -0
  851. package/tsconfig.json +64 -0
@@ -0,0 +1,2007 @@
1
+ /**
2
+ * Plan & Execute Interactive App
3
+ *
4
+ * Enhanced interactive mode with Plan-and-Execute Architecture
5
+ * Refactored to use modular hooks and components
6
+ */
7
+
8
+ import React, { useState, useCallback, useEffect, useMemo } from 'react';
9
+ import { Box, Text, useInput, useApp, Static } from 'ink';
10
+ import Spinner from 'ink-spinner';
11
+ import os from 'os';
12
+ import { spawn } from 'child_process';
13
+ import { detectGitRepo } from '../../utils/git-utils.js';
14
+ import { getShellConfig, isNativeWindows } from '../../utils/platform-utils.js';
15
+
16
+ /**
17
+ * Log entry types for Static scrollable output
18
+ */
19
+ export type LogEntryType =
20
+ | 'logo'
21
+ | 'user_input'
22
+ | 'assistant_message'
23
+ | 'tool_start'
24
+ | 'tool_result'
25
+ | 'shell_result'
26
+ | 'tell_user'
27
+ | 'plan_created'
28
+ | 'todo_start'
29
+ | 'todo_complete'
30
+ | 'todo_fail'
31
+ | 'compact'
32
+ | 'approval_request'
33
+ | 'approval_response'
34
+ | 'interrupt'
35
+ | 'session_restored'
36
+ | 'docs_search'
37
+ | 'reasoning'
38
+ | 'git_info';
39
+
40
+ export interface LogEntry {
41
+ id: string;
42
+ type: LogEntryType;
43
+ content: string;
44
+ details?: string;
45
+ toolArgs?: Record<string, unknown>; // For tool_start (all args)
46
+ success?: boolean;
47
+ items?: string[]; // For plan_created (todo list)
48
+ diff?: string[]; // For tool_result with diff
49
+ }
50
+ import { CustomTextInput } from './CustomTextInput.js';
51
+ import { LLMClient, createLLMClient } from '../../core/llm/llm-client.js';
52
+ import { Message } from '../../types/index.js';
53
+ import { TodoPanel, TodoStatusBar } from '../TodoPanel.js';
54
+ import { sessionManager } from '../../core/session/session-manager.js';
55
+ import { initializeDocsDirectory, setDocsSearchProgressCallback } from '../../agents/docs-search/index.js';
56
+ import { DocsSearchProgress, type DocsSearchLog } from './DocsSearchProgress.js';
57
+ import { FileBrowser } from './FileBrowser.js';
58
+ import { SessionBrowser, LogBrowser } from './panels/index.js';
59
+ import { SettingsBrowser } from './dialogs/SettingsDialog.js';
60
+ import { LLMSetupWizard } from './LLMSetupWizard.js';
61
+ import { ModelSelector } from './ModelSelector.js';
62
+ import { ToolSelector } from './ToolSelector.js';
63
+ import { AskUserDialog } from './dialogs/AskUserDialog.js';
64
+ import { ApprovalDialog } from './dialogs/ApprovalDialog.js';
65
+ // DISABLED: DocsBrowser removed - docs feature disabled
66
+ // import { DocsBrowser } from './dialogs/DocsBrowser.js';
67
+ import { CommandBrowser } from './CommandBrowser.js';
68
+ // ChatView removed - using Static log instead
69
+ import { Logo } from './Logo.js';
70
+ import { MarkdownRenderer } from './MarkdownRenderer.js';
71
+ import { ActivityIndicator, type ActivityType, type SubActivity } from './ActivityIndicator.js';
72
+ import { useFileBrowserState } from '../hooks/useFileBrowserState.js';
73
+ import { useCommandBrowserState } from '../hooks/useCommandBrowserState.js';
74
+ import { usePlanExecution } from '../hooks/usePlanExecution.js';
75
+ import { useInputHistory } from '../hooks/useInputHistory.js';
76
+ import { isValidCommand } from '../hooks/slashCommandProcessor.js';
77
+ import { processFileReferences } from '../hooks/atFileProcessor.js';
78
+ import {
79
+ executeSlashCommand,
80
+ isSlashCommand,
81
+ type CommandHandlerContext,
82
+ type PlanningMode,
83
+ } from '../../core/slash-command-handler.js';
84
+ import { closeJsonStreamLogger } from '../../utils/json-stream-logger.js';
85
+ import { configManager } from '../../core/config/config-manager.js';
86
+ import { logger } from '../../utils/logger.js';
87
+ import { usageTracker } from '../../core/usage-tracker.js';
88
+ import {
89
+ setToolExecutionCallback,
90
+ setTellToUserCallback,
91
+ setToolResponseCallback,
92
+ setPlanCreatedCallback,
93
+ setTodoStartCallback,
94
+ setTodoCompleteCallback,
95
+ setTodoFailCallback,
96
+ setCompactCallback,
97
+ setAssistantResponseCallback,
98
+ setToolApprovalCallback,
99
+ setReasoningCallback,
100
+ type ToolApprovalResult,
101
+ } from '../../tools/llm/simple/file-tools.js';
102
+ import { createRequire } from 'module';
103
+
104
+ // Get version from package.json
105
+ const require = createRequire(import.meta.url);
106
+ const pkg = require('../../../package.json') as { version: string };
107
+ const VERSION = pkg.version;
108
+
109
+ // Initialization steps for detailed progress display
110
+ type InitStep = 'health' | 'docs' | 'config' | 'done';
111
+
112
+ // Tools that require user approval in Supervised Mode
113
+ // File-modifying tools and bash commands need approval (read-only and internal tools are auto-approved)
114
+ const TOOLS_REQUIRING_APPROVAL = new Set(['create_file', 'edit_file', 'bash']);
115
+
116
+ // Clean startup tip - shown once at start
117
+ const STARTUP_TIP = 'Type /help for available commands. Type /model to switch models.';
118
+
119
+ // Helper function to shorten path with ~ for home directory
120
+ function shortenPath(fullPath: string): string {
121
+ const homeDir = os.homedir();
122
+ if (fullPath.startsWith(homeDir)) {
123
+ return fullPath.replace(homeDir, '~');
124
+ }
125
+ return fullPath;
126
+ }
127
+
128
+ // Helper functions for status bar
129
+ function formatElapsedTime(seconds: number): string {
130
+ if (seconds < 60) {
131
+ return `${seconds}s`;
132
+ }
133
+ const mins = Math.floor(seconds / 60);
134
+ const secs = seconds % 60;
135
+ return `${mins}m ${secs}s`;
136
+ }
137
+
138
+ function formatTokensCompact(count: number): string {
139
+ if (count < 1000) return count.toString();
140
+ if (count < 1000000) return `${(count / 1000).toFixed(1)}k`;
141
+ return `${(count / 1000000).toFixed(2)}M`;
142
+ }
143
+
144
+ // Helper function for status bar text
145
+ interface StatusTextParams {
146
+ phase: string;
147
+ todos: { status: string }[];
148
+ currentToolName: string | null;
149
+ }
150
+
151
+ function getStatusText({ phase, todos, currentToolName }: StatusTextParams): string {
152
+ const completedCount = todos.filter(t => t.status === 'completed').length;
153
+ const totalCount = todos.length;
154
+ const allTodosCompleted = totalCount > 0 && todos.every(t => t.status === 'completed' || t.status === 'failed');
155
+
156
+ // Build progress prefix (only show when tasks exist)
157
+ const progressPrefix = totalCount > 0 ? `${completedCount}/${totalCount} tasks · ` : '';
158
+
159
+ // Compacting
160
+ if (phase === 'compacting') {
161
+ return 'Compacting conversation';
162
+ }
163
+ // All TODOs completed, generating final response
164
+ if (phase === 'executing' && allTodosCompleted) {
165
+ return `${progressPrefix}Generating response`;
166
+ }
167
+ // Planning/Thinking
168
+ if (phase === 'planning') {
169
+ return 'Thinking';
170
+ }
171
+ // Tool is running - show tool name
172
+ if (currentToolName) {
173
+ return `${progressPrefix}${currentToolName}`;
174
+ }
175
+ // Default: processing
176
+ return `${progressPrefix}Processing`;
177
+ }
178
+
179
+ // Status bar uses ink-spinner for animation (avoids custom render issues)
180
+
181
+ interface PlanExecuteAppProps {
182
+ llmClient: LLMClient | null;
183
+ modelInfo: {
184
+ model: string;
185
+ endpoint: string;
186
+ };
187
+ }
188
+
189
+ export const PlanExecuteApp: React.FC<PlanExecuteAppProps> = ({ llmClient: initialLlmClient, modelInfo }) => {
190
+ const { exit } = useApp();
191
+ const [messages, setMessages] = useState<Message[]>([]);
192
+ const { input, setInput, handleHistoryPrev, handleHistoryNext, addToHistory } = useInputHistory();
193
+ const [isProcessing, setIsProcessing] = useState(false);
194
+ // Planning mode is always 'auto' - mode selection has been removed
195
+ const planningMode: PlanningMode = 'auto';
196
+
197
+ // LLM Client state - replace with new client when model changes
198
+ const [llmClient, setLlmClient] = useState<LLMClient | null>(initialLlmClient);
199
+
200
+ // Activity tracking for detailed status display
201
+ const [activityType, setActivityType] = useState<ActivityType>('thinking');
202
+ const [activityStartTime, setActivityStartTime] = useState<number>(Date.now());
203
+ const [activityDetail, setActivityDetail] = useState<string>('');
204
+ const [subActivities, setSubActivities] = useState<SubActivity[]>([]);
205
+
206
+ // Session usage tracking for Claude Code style status bar
207
+ const [sessionTokens, setSessionTokens] = useState(0);
208
+ const [sessionElapsed, setSessionElapsed] = useState(0);
209
+
210
+ // Current tool being executed (for status bar)
211
+ const [currentToolName, setCurrentToolName] = useState<string | null>(null);
212
+
213
+ // Session browser state
214
+ const [showSessionBrowser, setShowSessionBrowser] = useState(false);
215
+
216
+ // Settings browser state
217
+ const [showSettings, setShowSettings] = useState(false);
218
+
219
+ // LLM Setup Wizard state
220
+ const [showSetupWizard, setShowSetupWizard] = useState(false);
221
+ const [isInitializing, setIsInitializing] = useState(true);
222
+ const [initStep, setInitStep] = useState<InitStep>('docs');
223
+ const [healthStatus, setHealthStatus] = useState<'checking' | 'healthy' | 'unhealthy' | 'unknown'>('checking');
224
+
225
+ // Model Selector state
226
+ const [showModelSelector, setShowModelSelector] = useState(false);
227
+ const [currentModelInfo, setCurrentModelInfo] = useState(modelInfo);
228
+
229
+ // DISABLED: Docs Browser state removed - docs feature disabled
230
+ // const [showDocsBrowser, setShowDocsBrowser] = useState(false);
231
+ const showDocsBrowser = false; // Always false - docs feature disabled
232
+
233
+ // Tool Selector state
234
+ const [showToolSelector, setShowToolSelector] = useState(false);
235
+
236
+ // Log files visibility (Ctrl+O toggle)
237
+ const [showLogFiles, setShowLogFiles] = useState(false);
238
+
239
+ // Execution mode: 'auto' (autonomous) or 'supervised' (requires user approval)
240
+ const [executionMode, setExecutionMode] = useState<'auto' | 'supervised'>('auto');
241
+
242
+ // Auto-approved tools for this session (only in supervised mode)
243
+ const [autoApprovedTools, setAutoApprovedTools] = useState<Set<string>>(new Set());
244
+
245
+ // Pending tool approval state
246
+ const [pendingToolApproval, setPendingToolApproval] = useState<{
247
+ toolName: string;
248
+ args: Record<string, unknown>;
249
+ reason?: string;
250
+ resolve: (result: 'approve' | 'always' | { reject: true; comment: string }) => void;
251
+ } | null>(null);
252
+
253
+ // Static log entries for scrollable history
254
+ const [logEntries, setLogEntries] = useState<LogEntry[]>([]);
255
+ const logIdCounter = React.useRef(0);
256
+ const lastToolArgsRef = React.useRef<Record<string, unknown> | null>(null);
257
+
258
+ // Docs search progress state
259
+ const [docsSearchLogs, setDocsSearchLogs] = useState<DocsSearchLog[]>([]);
260
+ const [isDocsSearching, setIsDocsSearching] = useState(false);
261
+
262
+ // Pending user message queue (for messages entered during LLM processing)
263
+ const [pendingUserMessage, setPendingUserMessage] = useState<string | null>(null);
264
+ const pendingUserMessageRef = React.useRef<string | null>(null);
265
+
266
+ // Keep ref in sync with state for synchronous access in LLM loop
267
+ useEffect(() => {
268
+ pendingUserMessageRef.current = pendingUserMessage;
269
+ }, [pendingUserMessage]);
270
+
271
+ // Pending message callbacks for mid-execution injection
272
+ const pendingMessageCallbacks = useMemo(() => ({
273
+ getPendingMessage: () => pendingUserMessageRef.current,
274
+ clearPendingMessage: () => {
275
+ pendingUserMessageRef.current = null;
276
+ setPendingUserMessage(null);
277
+ },
278
+ }), []);
279
+
280
+ // Ctrl+C double-tap tracking for exit
281
+ const lastCtrlCTimeRef = React.useRef<number>(0);
282
+ const DOUBLE_TAP_THRESHOLD = 1500; // 1.5 seconds
283
+
284
+ // Helper: add log entry (skip if content is empty/whitespace only)
285
+ const addLog = useCallback((entry: Omit<LogEntry, 'id'>) => {
286
+ // Skip empty content to prevent blank lines
287
+ if (!entry.content || entry.content.trim() === '') {
288
+ return;
289
+ }
290
+ const id = `log-${++logIdCounter.current}`;
291
+ setLogEntries(prev => [...prev, { ...entry, id }]);
292
+ }, []);
293
+
294
+ // Helper: clear logs (for compact)
295
+ const clearLogs = useCallback(() => {
296
+ setLogEntries([]);
297
+ logIdCounter.current = 0;
298
+ }, []);
299
+
300
+ // Sync log entries to session manager for auto-save
301
+ useEffect(() => {
302
+ sessionManager.setLogEntries(logEntries);
303
+ }, [logEntries]);
304
+
305
+ // Use modular hooks
306
+ const fileBrowserState = useFileBrowserState(input, isProcessing);
307
+ const commandBrowserState = useCommandBrowserState(input, isProcessing);
308
+ const planExecutionState = usePlanExecution(pendingMessageCallbacks);
309
+
310
+ // Sync todos to session manager for auto-save (only in-progress/pending)
311
+ useEffect(() => {
312
+ sessionManager.setTodos(planExecutionState.todos);
313
+ }, [planExecutionState.todos]);
314
+
315
+ // Print logo at startup
316
+ useEffect(() => {
317
+ addLog({
318
+ type: 'logo',
319
+ content: `v${VERSION} │ ${modelInfo.model}`,
320
+ });
321
+
322
+ // Check for .git and show notification
323
+ const isGitRepo = detectGitRepo();
324
+ if (isGitRepo) {
325
+ addLog({
326
+ type: 'git_info',
327
+ content: 'Git repository detected! Commit assistance enabled.',
328
+ });
329
+ }
330
+ }, []);
331
+
332
+ // Log component mount
333
+ useEffect(() => {
334
+ logger.enter('PlanExecuteApp', { modelInfo });
335
+ return () => {
336
+ logger.exit('PlanExecuteApp', { messageCount: messages.length });
337
+ };
338
+ }, []);
339
+
340
+ // Setup tool execution callback - adds to Static log
341
+ useEffect(() => {
342
+ setToolExecutionCallback((toolName, reason, args) => {
343
+ // Save args for tool_result to use (for create_file content display)
344
+ lastToolArgsRef.current = args;
345
+ // Track current tool for status bar
346
+ setCurrentToolName(toolName);
347
+ addLog({
348
+ type: 'tool_start',
349
+ content: toolName,
350
+ details: reason, // don't truncate reason
351
+ toolArgs: args,
352
+ });
353
+ logger.debug('Tool execution started', { toolName, reason, args });
354
+ });
355
+
356
+ return () => {
357
+ setToolExecutionCallback(null);
358
+ };
359
+ }, [addLog]);
360
+
361
+ // Setup tool response callback - adds to Static log
362
+ useEffect(() => {
363
+ setToolResponseCallback((toolName, success, result) => {
364
+ // Clear current tool when done
365
+ setCurrentToolName(null);
366
+
367
+ // Try parsing diff content
368
+ let diff: string[] | undefined;
369
+ try {
370
+ const parsed = JSON.parse(result);
371
+ if (parsed.diff && Array.isArray(parsed.diff)) {
372
+ diff = parsed.diff;
373
+ }
374
+ } catch {
375
+ // not JSON, use as-is
376
+ }
377
+
378
+ // Get saved args for create_file content display
379
+ const savedArgs = lastToolArgsRef.current;
380
+ lastToolArgsRef.current = null;
381
+
382
+ addLog({
383
+ type: 'tool_result',
384
+ content: toolName,
385
+ details: result, // preserve full content
386
+ success,
387
+ diff,
388
+ toolArgs: savedArgs || undefined, // Pass args for create_file
389
+ });
390
+ logger.debug('Tool execution completed', { toolName, success, result });
391
+ });
392
+
393
+ return () => {
394
+ setToolResponseCallback(null);
395
+ };
396
+ }, [addLog]);
397
+
398
+ // Setup tell_to_user callback - adds to Static log
399
+ useEffect(() => {
400
+ setTellToUserCallback((message) => {
401
+ addLog({
402
+ type: 'tell_user',
403
+ content: message, // don't truncate
404
+ });
405
+ logger.debug('Message to user', { message });
406
+ });
407
+
408
+ return () => {
409
+ setTellToUserCallback(null);
410
+ };
411
+ }, [addLog]);
412
+
413
+ // Setup assistant response callback - adds to Static log
414
+ useEffect(() => {
415
+ setAssistantResponseCallback((content) => {
416
+ addLog({
417
+ type: 'assistant_message',
418
+ content,
419
+ });
420
+ logger.debug('Assistant response received', { contentLength: content.length });
421
+ });
422
+
423
+ return () => {
424
+ setAssistantResponseCallback(null);
425
+ };
426
+ }, [addLog]);
427
+
428
+ // Setup reasoning callback - adds to Static log (non-streaming only)
429
+ // Note: Streaming updates to Static items cause render issues, so we only support non-streaming
430
+ useEffect(() => {
431
+ setReasoningCallback((content, _isStreaming) => {
432
+ // Always add as new entry (don't update existing Static items)
433
+ addLog({
434
+ type: 'reasoning',
435
+ content,
436
+ });
437
+ logger.debug('Reasoning received', { contentLength: content.length });
438
+ });
439
+
440
+ return () => {
441
+ setReasoningCallback(null);
442
+ };
443
+ }, [addLog]);
444
+
445
+ // Setup tool approval callback (Supervised Mode)
446
+ useEffect(() => {
447
+ setToolApprovalCallback(async (toolName, args, reason) => {
448
+ // Auto mode: no approval needed
449
+ if (executionMode === 'auto') {
450
+ return 'approve';
451
+ }
452
+
453
+ // Only file-modifying tools require approval
454
+ if (!TOOLS_REQUIRING_APPROVAL.has(toolName)) {
455
+ return 'approve';
456
+ }
457
+
458
+ // Check if this tool is already auto-approved for this session
459
+ if (autoApprovedTools.has(toolName)) {
460
+ logger.debug('Tool auto-approved from session', { toolName });
461
+ return 'approve';
462
+ }
463
+
464
+ // Add approval request to log
465
+ addLog({
466
+ type: 'approval_request',
467
+ content: toolName,
468
+ details: reason,
469
+ toolArgs: args,
470
+ });
471
+
472
+ // Request approval from user via dialog
473
+ return new Promise<ToolApprovalResult>((resolve) => {
474
+ setPendingToolApproval({
475
+ toolName,
476
+ args,
477
+ reason,
478
+ resolve,
479
+ });
480
+ });
481
+ });
482
+
483
+ return () => {
484
+ setToolApprovalCallback(null);
485
+ };
486
+ }, [executionMode, autoApprovedTools, addLog]);
487
+
488
+ // Setup docs search progress callback
489
+ useEffect(() => {
490
+ setDocsSearchProgressCallback((type, message, data) => {
491
+ // Handle completion
492
+ if (type === 'complete') {
493
+ // Add result to static log with summary
494
+ addLog({
495
+ type: 'docs_search',
496
+ content: data?.summary || message,
497
+ details: data?.findings,
498
+ });
499
+
500
+ // Clear progress state
501
+ setIsDocsSearching(false);
502
+ setDocsSearchLogs([]);
503
+ return;
504
+ }
505
+
506
+ // Start docs search on first log
507
+ setIsDocsSearching(true);
508
+
509
+ // Map callback type to log type
510
+ const logType: DocsSearchLog['type'] = type === 'tell_user' ? 'result' : 'info';
511
+
512
+ // Add log entry (max 8, remove oldest if exceeding)
513
+ setDocsSearchLogs(prev => {
514
+ const newLog: DocsSearchLog = {
515
+ type: logType,
516
+ message,
517
+ timestamp: Date.now(),
518
+ };
519
+ const updated = [...prev, newLog];
520
+ return updated.slice(-8); // Keep only last 8
521
+ });
522
+ });
523
+
524
+ return () => {
525
+ setDocsSearchProgressCallback(null);
526
+ };
527
+ }, [addLog]);
528
+
529
+ // Handle approval dialog response
530
+ const handleApprovalResponse = useCallback((result: ToolApprovalResult) => {
531
+ if (!pendingToolApproval) return;
532
+
533
+ const { toolName, resolve } = pendingToolApproval;
534
+
535
+ // Log the approval response
536
+ if (result === 'approve') {
537
+ addLog({
538
+ type: 'approval_response',
539
+ content: toolName,
540
+ details: 'approved',
541
+ success: true,
542
+ });
543
+ } else if (result === 'always') {
544
+ setAutoApprovedTools(prev => new Set([...prev, toolName]));
545
+ addLog({
546
+ type: 'approval_response',
547
+ content: toolName,
548
+ details: 'always_approved',
549
+ success: true,
550
+ });
551
+ } else if (typeof result === 'object' && result.reject) {
552
+ addLog({
553
+ type: 'approval_response',
554
+ content: toolName,
555
+ details: result.comment || 'rejected',
556
+ success: false,
557
+ });
558
+ }
559
+
560
+ // Resolve the promise
561
+ resolve(result);
562
+ setPendingToolApproval(null);
563
+
564
+ logger.debug('Approval response', { toolName, result });
565
+ }, [pendingToolApproval, addLog]);
566
+
567
+ // Setup plan/todo callbacks - adds to Static log
568
+ useEffect(() => {
569
+ setPlanCreatedCallback((todoTitles) => {
570
+ // Reset session time and tokens when new TODO plan is created
571
+ // Note: /usage still shows cumulative total (stored in usageTracker.data)
572
+ usageTracker.resetSession();
573
+ setSessionTokens(0);
574
+ setSessionElapsed(0);
575
+
576
+ addLog({
577
+ type: 'plan_created',
578
+ content: `Created ${todoTitles.length} task${todoTitles.length > 1 ? 's' : ''}`,
579
+ items: todoTitles,
580
+ });
581
+ });
582
+
583
+ setTodoStartCallback((title) => {
584
+ addLog({
585
+ type: 'todo_start',
586
+ content: title,
587
+ });
588
+ });
589
+
590
+ // Remove todo_complete log - TodoPanel already shows status, avoiding duplication
591
+ setTodoCompleteCallback(() => {
592
+ // No-op: TodoPanel handles visual feedback
593
+ });
594
+
595
+ setTodoFailCallback((title) => {
596
+ addLog({
597
+ type: 'todo_fail',
598
+ content: title,
599
+ });
600
+ });
601
+
602
+ setCompactCallback((originalCount, newCount) => {
603
+ // Clear existing logs and add compact entry
604
+ clearLogs();
605
+ addLog({
606
+ type: 'compact',
607
+ content: `Conversation compacted: ${originalCount} → ${newCount} messages`,
608
+ });
609
+ });
610
+
611
+ return () => {
612
+ setPlanCreatedCallback(null);
613
+ setTodoStartCallback(null);
614
+ setTodoCompleteCallback(null);
615
+ setTodoFailCallback(null);
616
+ setCompactCallback(null);
617
+ };
618
+ }, [addLog, clearLogs]);
619
+
620
+ // Update session usage and elapsed time in real-time
621
+ useEffect(() => {
622
+ if (!isProcessing) {
623
+ return;
624
+ }
625
+
626
+ const interval = setInterval(() => {
627
+ const sessionUsage = usageTracker.getSessionUsage();
628
+ setSessionTokens(sessionUsage.totalTokens);
629
+ setSessionElapsed(usageTracker.getSessionElapsedSeconds());
630
+ }, 500); // Update every 500ms
631
+
632
+ return () => clearInterval(interval);
633
+ }, [isProcessing]);
634
+
635
+ // Initialize on startup: git update check -> health check -> docs -> config
636
+ useEffect(() => {
637
+ const initialize = async () => {
638
+ logger.flow('Starting initialization');
639
+ logger.startTimer('app-init');
640
+
641
+ try {
642
+ // Step 1: Run health check (only if endpoints configured)
643
+ setInitStep('health');
644
+ logger.flow('Running health check');
645
+ setHealthStatus('checking');
646
+
647
+ if (configManager.hasEndpoints()) {
648
+ const healthResults = await LLMClient.healthCheckAll();
649
+
650
+ // Check if any model is healthy
651
+ let hasHealthy = false;
652
+ for (const [endpointId, modelResults] of healthResults) {
653
+ logger.vars(
654
+ { name: 'endpointId', value: endpointId },
655
+ { name: 'healthyModels', value: modelResults.filter(r => r.healthy).length }
656
+ );
657
+ if (modelResults.some((r) => r.healthy)) {
658
+ hasHealthy = true;
659
+ }
660
+ }
661
+
662
+ logger.state('Health status', 'checking', hasHealthy ? 'healthy' : 'unhealthy');
663
+ setHealthStatus(hasHealthy ? 'healthy' : 'unhealthy');
664
+
665
+ // Update health status in config
666
+ await configManager.updateAllHealthStatus(healthResults);
667
+ } else {
668
+ setHealthStatus('unknown');
669
+ }
670
+
671
+ // Step 2: Initialize docs directory
672
+ setInitStep('docs');
673
+ logger.flow('Initializing docs directory');
674
+ await initializeDocsDirectory().catch((err) => {
675
+ logger.warn('Docs directory initialization warning', { error: err });
676
+ });
677
+
678
+ // Step 3: Check config (show setup wizard if no endpoints)
679
+ setInitStep('config');
680
+ logger.flow('Checking configuration');
681
+ if (!configManager.hasEndpoints()) {
682
+ logger.debug('No endpoints configured, showing setup wizard');
683
+ setShowSetupWizard(true);
684
+ setIsInitializing(false);
685
+ logger.endTimer('app-init');
686
+ return;
687
+ }
688
+
689
+ setInitStep('done');
690
+ } catch (error) {
691
+ logger.error('Initialization failed', error as Error);
692
+ setHealthStatus('unknown');
693
+ } finally {
694
+ setIsInitializing(false);
695
+ logger.endTimer('app-init');
696
+ }
697
+ };
698
+
699
+ initialize();
700
+ }, []);
701
+
702
+ // Wrapped exit function to ensure cleanup
703
+ const handleExit = useCallback(async () => {
704
+ logger.flow('Exiting application');
705
+ await closeJsonStreamLogger();
706
+ exit();
707
+ }, [exit]);
708
+
709
+ // Keyboard shortcuts
710
+ useInput((inputChar: string, key: { ctrl: boolean; shift: boolean; meta: boolean; escape: boolean; tab?: boolean }) => {
711
+ // Ctrl+C: Smart handling (clear input / cancel task / double-tap exit)
712
+ if (key.ctrl && inputChar === 'c') {
713
+ const now = Date.now();
714
+ const timeSinceLastCtrlC = now - lastCtrlCTimeRef.current;
715
+
716
+ // Case 1: AI is processing - interrupt the task
717
+ if (isProcessing) {
718
+ logger.flow('Ctrl+C pressed - interrupting execution');
719
+
720
+ // Abort any active LLM request
721
+ if (llmClient) {
722
+ llmClient.abort();
723
+ }
724
+
725
+ // Set interrupt flag
726
+ planExecutionState.handleInterrupt();
727
+
728
+ // Add red "Interrupted" message to log immediately
729
+ addLog({
730
+ type: 'interrupt',
731
+ content: '⎿ Interrupted',
732
+ });
733
+
734
+ // Force stop processing state
735
+ setIsProcessing(false);
736
+ lastCtrlCTimeRef.current = now;
737
+ return;
738
+ }
739
+
740
+ // Case 2: Input has content - clear the input
741
+ if (input.length > 0) {
742
+ logger.debug('Ctrl+C pressed - clearing input');
743
+ setInput('');
744
+ lastCtrlCTimeRef.current = now;
745
+ return;
746
+ }
747
+
748
+ // Case 3: Input is empty - check for double-tap to exit
749
+ if (timeSinceLastCtrlC < DOUBLE_TAP_THRESHOLD) {
750
+ // Double-tap detected - exit
751
+ logger.flow('Ctrl+C double-tap detected - exiting');
752
+ handleExit().catch((err) => logger.error('Exit failed', err));
753
+ return;
754
+ }
755
+
756
+ // First tap with empty input - show exit hint
757
+ lastCtrlCTimeRef.current = now;
758
+ addLog({
759
+ type: 'assistant_message',
760
+ content: '^C again to exit',
761
+ });
762
+ logger.debug('Ctrl+C pressed - waiting for double-tap to exit');
763
+ return;
764
+ }
765
+ // ESC: First = pause, Second = complete stop
766
+ if (key.escape && (isProcessing || planExecutionState.isInterrupted)) {
767
+ logger.flow('ESC pressed');
768
+
769
+ // Abort any active LLM request
770
+ if (llmClient) {
771
+ llmClient.abort();
772
+ }
773
+
774
+ // Handle interrupt (returns 'paused', 'stopped', or 'none')
775
+ const result = planExecutionState.handleInterrupt();
776
+
777
+ if (result === 'paused') {
778
+ // First ESC - pause
779
+ addLog({
780
+ type: 'interrupt',
781
+ content: '⏸️ Paused (type message to resume, ESC to stop completely)',
782
+ });
783
+ } else if (result === 'stopped') {
784
+ // Second ESC - complete stop
785
+ addLog({
786
+ type: 'interrupt',
787
+ content: '⏹️ Stopped - TODO list cleared',
788
+ });
789
+ }
790
+
791
+ // Force stop processing state
792
+ setIsProcessing(false);
793
+ }
794
+ // Tab key: toggle execution mode (auto/supervised) - only when no dropdown is open
795
+ if (key.tab && !isProcessing && !pendingToolApproval && !fileBrowserState.showFileBrowser && !commandBrowserState.showCommandBrowser) {
796
+ const newMode = executionMode === 'auto' ? 'supervised' : 'auto';
797
+ setExecutionMode(newMode);
798
+ // Clear auto-approved tools when switching to auto mode
799
+ if (newMode === 'auto') {
800
+ setAutoApprovedTools(new Set());
801
+ }
802
+ addLog({
803
+ type: 'assistant_message',
804
+ content: `Execution mode changed: ${newMode === 'auto' ? '🚀 Auto Mode (autonomous execution)' : '👁️ Supervised Mode (approval required)'}`,
805
+ });
806
+ logger.debug('Execution mode toggled', { newMode });
807
+ }
808
+ // Ctrl+O: toggle log files visibility
809
+ if (key.ctrl && inputChar === 'o') {
810
+ setShowLogFiles(prev => !prev);
811
+ }
812
+ }); // Ctrl+C must always work, other keys have internal conditions
813
+
814
+ // Handle file selection from browser
815
+ const handleFileSelect = useCallback((filePaths: string[]) => {
816
+ logger.debug('File selected', { filePaths });
817
+ const newInput = fileBrowserState.handleFileSelect(filePaths, input);
818
+ setInput(newInput);
819
+ }, [fileBrowserState, input]);
820
+
821
+ // Handle command selection from browser
822
+ const handleCommandSelect = useCallback((command: string, shouldSubmit: boolean) => {
823
+ logger.debug('Command selected', { command, shouldSubmit });
824
+ const result = commandBrowserState.handleCommandSelect(command, shouldSubmit, input, handleSubmit);
825
+ if (result !== null) {
826
+ setInput(result);
827
+ }
828
+ }, [commandBrowserState, input]);
829
+
830
+ // Handle session selection from browser
831
+ const handleSessionSelect = useCallback(async (sessionId: string) => {
832
+ logger.enter('handleSessionSelect', { sessionId });
833
+ setShowSessionBrowser(false);
834
+
835
+ try {
836
+ const sessionData = await sessionManager.loadSession(sessionId);
837
+
838
+ if (!sessionData) {
839
+ const errorMessage = `Session not found: ${sessionId}`;
840
+ logger.warn('Session not found', { sessionId });
841
+ setMessages(prev => [
842
+ ...prev,
843
+ { role: 'assistant' as const, content: errorMessage },
844
+ ]);
845
+ return;
846
+ }
847
+
848
+ const hasTodos = sessionData.todos && sessionData.todos.length > 0;
849
+
850
+ logger.debug('Session loaded', {
851
+ sessionId,
852
+ messageCount: sessionData.messages.length,
853
+ logEntryCount: sessionData.logEntries?.length || 0,
854
+ todoCount: hasTodos ? sessionData.todos!.length : 0,
855
+ });
856
+
857
+ // Restore messages
858
+ setMessages(sessionData.messages);
859
+
860
+ // Reset auto-approved tools (Supervised mode security)
861
+ setAutoApprovedTools(new Set());
862
+ logger.debug('Auto-approved tools cleared on session load');
863
+
864
+ // Restore in-progress TODOs if available
865
+ if (hasTodos) {
866
+ // Convert SessionTodoItem to TodoItem format (add required fields with defaults)
867
+ const restoredTodos = sessionData.todos!.map(todo => ({
868
+ id: todo.id,
869
+ title: todo.title,
870
+ description: todo.description || '',
871
+ status: todo.status,
872
+ requiresDocsSearch: todo.requiresDocsSearch ?? false,
873
+ dependencies: todo.dependencies ?? [],
874
+ result: todo.result,
875
+ error: todo.error,
876
+ }));
877
+ planExecutionState.setTodos(restoredTodos);
878
+ logger.debug('Restored in-progress TODOs', { count: restoredTodos.length });
879
+ }
880
+
881
+ // Build restore details message
882
+ const detailParts: string[] = [];
883
+ detailParts.push(`${sessionData.messages.length} messages`);
884
+ if (sessionData.logEntries?.length) {
885
+ detailParts.push(`${sessionData.logEntries.length} logs`);
886
+ }
887
+ if (hasTodos) {
888
+ detailParts.push(`${sessionData.todos!.length} TODOs restored`);
889
+ }
890
+
891
+ // Restore log entries if available
892
+ if (sessionData.logEntries && sessionData.logEntries.length > 0) {
893
+ // Clear current logs and add session restored header
894
+ const restoredLogs: LogEntry[] = [
895
+ {
896
+ id: `log-restored-header`,
897
+ type: 'session_restored',
898
+ content: `Session restored: ${new Date(sessionData.metadata.updatedAt).toLocaleString('en-US')}`,
899
+ details: detailParts.join(', '),
900
+ },
901
+ ...sessionData.logEntries.map((entry, idx) => ({
902
+ ...entry,
903
+ id: `log-restored-${idx}`,
904
+ })) as LogEntry[],
905
+ ];
906
+ setLogEntries(restoredLogs);
907
+ logIdCounter.current = restoredLogs.length;
908
+ } else {
909
+ // No log entries saved, show session restored message only
910
+ clearLogs();
911
+ addLog({
912
+ type: 'session_restored',
913
+ content: `Session restored: ${new Date(sessionData.metadata.updatedAt).toLocaleString('en-US')}`,
914
+ details: detailParts.join(', ') + (sessionData.logEntries?.length ? '' : ' (no log history)'),
915
+ });
916
+ }
917
+ } catch (error) {
918
+ const errorMessage = `Session load failed: ${error instanceof Error ? error.message : 'Unknown error'}`;
919
+ logger.error(`Session load failed (sessionId: ${sessionId})`, error as Error);
920
+ setMessages(prev => [
921
+ ...prev,
922
+ { role: 'assistant' as const, content: errorMessage },
923
+ ]);
924
+ }
925
+ logger.exit('handleSessionSelect', { sessionId });
926
+ }, [addLog, clearLogs]);
927
+
928
+ // Planning mode change handler removed - always auto mode
929
+ // Kept for backward compatibility with SettingsBrowser interface
930
+ const handleSettingsPlanningModeChange = useCallback((_mode: PlanningMode) => {
931
+ // No-op: planning mode is always 'auto'
932
+ logger.debug('Planning mode change ignored - always auto');
933
+ }, []);
934
+
935
+ // Handle settings close
936
+ const handleSettingsClose = useCallback(() => {
937
+ logger.debug('Settings closed');
938
+ setShowSettings(false);
939
+ }, []);
940
+
941
+ // Handle setup wizard completion
942
+ const handleSetupComplete = useCallback(() => {
943
+ logger.debug('Setup wizard completed');
944
+ setShowSetupWizard(false);
945
+
946
+ // Reload config and create LLMClient
947
+ try {
948
+ const endpoint = configManager.getCurrentEndpoint();
949
+ const model = configManager.getCurrentModel();
950
+
951
+ if (endpoint && model) {
952
+ setCurrentModelInfo({
953
+ model: model.name,
954
+ endpoint: endpoint.baseUrl,
955
+ });
956
+
957
+ const newClient = createLLMClient();
958
+ setLlmClient(newClient);
959
+ logger.debug('LLMClient created after setup', { modelId: model.id, modelName: model.name });
960
+ }
961
+ } catch (error) {
962
+ logger.error('Failed to create LLMClient after setup', error as Error);
963
+ }
964
+ }, []);
965
+
966
+ // Handle setup wizard skip
967
+ const handleSetupSkip = useCallback(() => {
968
+ logger.debug('Setup wizard skipped');
969
+ setShowSetupWizard(false);
970
+ }, []);
971
+
972
+ // Handle model selection
973
+ const handleModelSelect = useCallback(
974
+ (endpointId: string, modelId: string) => {
975
+ logger.enter('handleModelSelect', { endpointId, modelId });
976
+ const endpoint = configManager.getAllEndpoints().find((ep) => ep.id === endpointId);
977
+ const model = endpoint?.models.find((m) => m.id === modelId);
978
+
979
+ if (endpoint && model) {
980
+ logger.state('Current model', currentModelInfo.model, model.name);
981
+ setCurrentModelInfo({
982
+ model: model.name,
983
+ endpoint: endpoint.baseUrl,
984
+ });
985
+
986
+ // Create new LLMClient (already saved in configManager, just recreate)
987
+ try {
988
+ const newClient = createLLMClient();
989
+ setLlmClient(newClient);
990
+ logger.debug('LLMClient recreated with new model', { modelId, modelName: model.name });
991
+ } catch (error) {
992
+ logger.error('Failed to create new LLMClient', error as Error);
993
+ }
994
+ }
995
+
996
+ setShowModelSelector(false);
997
+
998
+ // Add confirmation message
999
+ setMessages((prev) => [
1000
+ ...prev,
1001
+ {
1002
+ role: 'assistant' as const,
1003
+ content: `Model changed: ${model?.name || modelId} (${endpoint?.name || endpointId})`,
1004
+ },
1005
+ ]);
1006
+ logger.exit('handleModelSelect', { model: model?.name });
1007
+ },
1008
+ [currentModelInfo.model]
1009
+ );
1010
+
1011
+ // Handle model selector cancel
1012
+ const handleModelSelectorCancel = useCallback(() => {
1013
+ logger.debug('Model selector cancelled');
1014
+ setShowModelSelector(false);
1015
+ }, []);
1016
+
1017
+ // Handle tool selector close
1018
+ const handleToolSelectorClose = useCallback(() => {
1019
+ logger.debug('Tool selector closed');
1020
+ setShowToolSelector(false);
1021
+ }, []);
1022
+
1023
+ const handleSubmit = useCallback(async (value: string) => {
1024
+ // If processing and user submits a message, queue it for injection at next LLM invoke
1025
+ if (isProcessing && value.trim()) {
1026
+ const queuedMessage = value.trim();
1027
+ setPendingUserMessage(queuedMessage);
1028
+ logger.flow('User message queued for mid-execution injection', { message: queuedMessage });
1029
+ addLog({
1030
+ type: 'user_input',
1031
+ content: `(→ passing to next call) ${queuedMessage}`,
1032
+ });
1033
+ setInput('');
1034
+ return;
1035
+ }
1036
+
1037
+ if (!value.trim() || fileBrowserState.showFileBrowser || showSessionBrowser || showSettings || showSetupWizard || showDocsBrowser) {
1038
+ return;
1039
+ }
1040
+
1041
+ logger.enter('handleSubmit', { valueLength: value.length });
1042
+
1043
+ const userMessage = value.trim();
1044
+
1045
+ // Allow /settings command even without LLM configured
1046
+ const isSettingsCommand = userMessage === '/settings';
1047
+
1048
+ if (!llmClient && !isSettingsCommand) {
1049
+ logger.warn('LLM client not configured');
1050
+ setMessages((prev) => [
1051
+ ...prev,
1052
+ { role: 'assistant' as const, content: 'LLM not configured. Please configure in /settings → LLMs.' },
1053
+ ]);
1054
+ return;
1055
+ }
1056
+
1057
+ if (commandBrowserState.showCommandBrowser && !isValidCommand(userMessage)) {
1058
+ return;
1059
+ }
1060
+
1061
+ if (commandBrowserState.showCommandBrowser) {
1062
+ commandBrowserState.resetCommandBrowser();
1063
+ }
1064
+
1065
+ setInput('');
1066
+ addToHistory(userMessage);
1067
+
1068
+ // Handle shell commands (! prefix)
1069
+ if (userMessage.startsWith('!')) {
1070
+ const shellCommand = userMessage.slice(1).trim();
1071
+ if (!shellCommand) {
1072
+ addLog({
1073
+ type: 'assistant_message',
1074
+ content: 'Usage: !<command> (e.g., !ls -la, !dir)',
1075
+ });
1076
+ return;
1077
+ }
1078
+
1079
+ addLog({
1080
+ type: 'user_input',
1081
+ content: userMessage,
1082
+ });
1083
+
1084
+ const shellConfig = getShellConfig();
1085
+ const shellLabel = isNativeWindows() ? 'PowerShell' : 'Bash';
1086
+
1087
+ addLog({
1088
+ type: 'tool_start',
1089
+ content: `${shellLabel}: ${shellCommand}`,
1090
+ });
1091
+
1092
+ try {
1093
+ const child = spawn(shellConfig.shell, shellConfig.args(shellCommand), {
1094
+ cwd: process.cwd(),
1095
+ env: process.env,
1096
+ });
1097
+
1098
+ let stdout = '';
1099
+ let stderr = '';
1100
+
1101
+ child.stdout?.on('data', (data: Buffer) => {
1102
+ stdout += data.toString();
1103
+ });
1104
+
1105
+ child.stderr?.on('data', (data: Buffer) => {
1106
+ stderr += data.toString();
1107
+ });
1108
+
1109
+ child.on('close', (code: number | null) => {
1110
+ const output = stdout + (stderr ? `\n${stderr}` : '');
1111
+ const success = code === 0;
1112
+
1113
+ addLog({
1114
+ type: 'shell_result',
1115
+ content: output.trim() || (success ? '(no output)' : `Exit code: ${code}`),
1116
+ success,
1117
+ });
1118
+ });
1119
+
1120
+ child.on('error', (err: Error) => {
1121
+ addLog({
1122
+ type: 'shell_result',
1123
+ content: `Error: ${err.message}`,
1124
+ success: false,
1125
+ });
1126
+ });
1127
+ } catch (err) {
1128
+ addLog({
1129
+ type: 'shell_result',
1130
+ content: `Error: ${err instanceof Error ? err.message : String(err)}`,
1131
+ success: false,
1132
+ });
1133
+ }
1134
+
1135
+ logger.exit('handleSubmit', { shellCommand: true });
1136
+ return;
1137
+ }
1138
+
1139
+ // Handle slash commands
1140
+ if (isSlashCommand(userMessage)) {
1141
+ logger.flow('Executing slash command');
1142
+
1143
+ // Add user input to log for slash commands
1144
+ addLog({
1145
+ type: 'user_input',
1146
+ content: userMessage,
1147
+ });
1148
+
1149
+ const commandContext: CommandHandlerContext = {
1150
+ planningMode,
1151
+ messages,
1152
+ todos: planExecutionState.todos,
1153
+ setPlanningMode: () => {}, // No-op: planning mode is always 'auto'
1154
+ setMessages,
1155
+ setTodos: planExecutionState.setTodos,
1156
+ exit: handleExit,
1157
+ onShowSessionBrowser: () => setShowSessionBrowser(true),
1158
+ onShowSettings: () => setShowSettings(true),
1159
+ onShowModelSelector: () => setShowModelSelector(true),
1160
+ // DISABLED: onShowDocsBrowser removed - docs feature disabled
1161
+ onShowToolSelector: () => setShowToolSelector(true),
1162
+ onCompact: llmClient
1163
+ ? () => planExecutionState.performCompact(llmClient, messages, setMessages)
1164
+ : undefined,
1165
+ };
1166
+
1167
+ const result = await executeSlashCommand(userMessage, commandContext);
1168
+
1169
+ if (result.handled) {
1170
+ // If the command added an assistant message, display it in the log
1171
+ if (result.updatedContext?.messages) {
1172
+ const lastMessage = result.updatedContext.messages[result.updatedContext.messages.length - 1];
1173
+ if (lastMessage && lastMessage.role === 'assistant') {
1174
+ addLog({
1175
+ type: 'assistant_message',
1176
+ content: lastMessage.content,
1177
+ });
1178
+ }
1179
+ }
1180
+ logger.exit('handleSubmit', { handled: true });
1181
+ return;
1182
+ }
1183
+ }
1184
+
1185
+ // Add user input to Static log (show original message)
1186
+ addLog({
1187
+ type: 'user_input',
1188
+ content: userMessage,
1189
+ });
1190
+
1191
+ // Process @file references - read file contents and include in message
1192
+ const processedResult = await processFileReferences(userMessage);
1193
+ const processedMessage = processedResult.content;
1194
+
1195
+ // Log if files were included
1196
+ if (processedResult.includedFiles.length > 0) {
1197
+ logger.debug('Files included in message', {
1198
+ files: processedResult.includedFiles,
1199
+ failedFiles: processedResult.failedFiles,
1200
+ });
1201
+ }
1202
+
1203
+ // Add processed message to messages (with file contents for LLM)
1204
+ let updatedMessages: Message[] = [...messages, { role: 'user' as const, content: processedMessage }];
1205
+ setMessages(updatedMessages);
1206
+
1207
+ setIsProcessing(true);
1208
+ setActivityStartTime(Date.now());
1209
+ setSubActivities([]);
1210
+
1211
+ // Reset interrupt flag for new operation
1212
+ if (llmClient) {
1213
+ llmClient.resetInterrupt();
1214
+ }
1215
+
1216
+ // Reset session usage for new task
1217
+ usageTracker.resetSession();
1218
+ setSessionTokens(0);
1219
+ setSessionElapsed(0);
1220
+
1221
+ logger.startTimer('message-processing');
1222
+
1223
+ try {
1224
+ // Check for auto-compact before processing (70% threshold)
1225
+ if (planExecutionState.shouldAutoCompact()) {
1226
+ logger.flow('Auto-compact triggered');
1227
+ setActivityType('thinking');
1228
+ setActivityDetail('Compacting conversation...');
1229
+
1230
+ const compactResult = await planExecutionState.performCompact(llmClient!, updatedMessages, setMessages);
1231
+ if (compactResult.success && compactResult.compactedMessages) {
1232
+ // Update local variable with compacted messages for subsequent LLM calls
1233
+ updatedMessages = compactResult.compactedMessages;
1234
+ logger.debug('Auto-compact completed', {
1235
+ originalCount: compactResult.originalMessageCount,
1236
+ newCount: compactResult.newMessageCount,
1237
+ });
1238
+ } else if (!compactResult.success) {
1239
+ logger.warn('Auto-compact failed, continuing without compact', { error: compactResult.error });
1240
+ }
1241
+ }
1242
+
1243
+ // Check if we should resume TODO execution instead of starting fresh
1244
+ const hasPendingTodos = planExecutionState.todos.some(
1245
+ t => t.status === 'pending' || t.status === 'in_progress'
1246
+ );
1247
+
1248
+ if (hasPendingTodos && planExecutionState.isInterrupted) {
1249
+ // Resume TODO execution with the new message
1250
+ logger.flow('Resuming TODO execution after pause');
1251
+ setActivityType('executing');
1252
+ setActivityDetail('Resuming...');
1253
+ await planExecutionState.resumeTodoExecution(processedMessage, llmClient!, messages, setMessages);
1254
+ } else {
1255
+ // Phase 1: Use auto mode with LLM-based request classification
1256
+ setActivityType('thinking');
1257
+ setActivityDetail('Analyzing request...');
1258
+
1259
+ logger.vars(
1260
+ { name: 'planningMode', value: planningMode },
1261
+ { name: 'messageLength', value: processedMessage.length }
1262
+ );
1263
+
1264
+ // Use executeAutoMode which handles classification internally
1265
+ await planExecutionState.executeAutoMode(processedMessage, llmClient!, updatedMessages, setMessages);
1266
+ }
1267
+
1268
+ } catch (error) {
1269
+ logger.error('Message processing failed', error as Error);
1270
+ } finally {
1271
+ setIsProcessing(false);
1272
+ logger.endTimer('message-processing');
1273
+ logger.exit('handleSubmit', { success: true });
1274
+ }
1275
+ }, [
1276
+ isProcessing,
1277
+ fileBrowserState.showFileBrowser,
1278
+ showSessionBrowser,
1279
+ showSettings,
1280
+ showSetupWizard,
1281
+ showDocsBrowser,
1282
+ commandBrowserState,
1283
+ planningMode,
1284
+ messages,
1285
+ planExecutionState,
1286
+ llmClient,
1287
+ handleExit,
1288
+ addLog,
1289
+ ]);
1290
+
1291
+ // Process pending user message after LLM processing completes
1292
+ // This handles the edge case where execution finishes before the pending message could be injected
1293
+ useEffect(() => {
1294
+ if (!isProcessing && pendingUserMessage && llmClient) {
1295
+ logger.flow('Processing remaining pending user message after execution complete');
1296
+
1297
+ // Clear the pending message
1298
+ const queuedMessage = pendingUserMessage;
1299
+ setPendingUserMessage(null);
1300
+ pendingUserMessageRef.current = null;
1301
+
1302
+ // Check if we have pending TODOs to resume
1303
+ const hasPendingTodos = planExecutionState.todos.some(
1304
+ t => t.status === 'pending' || t.status === 'in_progress'
1305
+ );
1306
+
1307
+ // Add to log
1308
+ addLog({
1309
+ type: 'user_input',
1310
+ content: `📩 ${queuedMessage}`,
1311
+ });
1312
+
1313
+ // Process @file references and then execute
1314
+ const processAndExecute = async () => {
1315
+ // Process file references
1316
+ const processedResult = await processFileReferences(queuedMessage);
1317
+ const processedMessage = processedResult.content;
1318
+
1319
+ // Start processing
1320
+ setIsProcessing(true);
1321
+ setActivityStartTime(Date.now());
1322
+
1323
+ try {
1324
+ if (hasPendingTodos) {
1325
+ // Resume TODO execution with the new message
1326
+ logger.flow('Resuming TODO execution with user message');
1327
+ await planExecutionState.resumeTodoExecution(processedMessage, llmClient, messages, setMessages);
1328
+ } else {
1329
+ // No pending TODOs - start fresh with executeAutoMode
1330
+ logger.flow('No pending TODOs - starting fresh execution');
1331
+ const updatedMessages: Message[] = [...messages, { role: 'user' as const, content: processedMessage }];
1332
+ setMessages(updatedMessages);
1333
+ await planExecutionState.executeAutoMode(processedMessage, llmClient, updatedMessages, setMessages);
1334
+ }
1335
+ } catch (error) {
1336
+ logger.error('Queued message processing failed', error as Error);
1337
+ } finally {
1338
+ setIsProcessing(false);
1339
+ }
1340
+ };
1341
+
1342
+ processAndExecute();
1343
+ }
1344
+ }, [isProcessing, pendingUserMessage, llmClient, messages, planExecutionState, addLog]);
1345
+
1346
+ // Show loading screen - DEXTER style (clean, no animations)
1347
+ if (isInitializing) {
1348
+ const getInitStepText = () => {
1349
+ switch (initStep) {
1350
+ case 'health':
1351
+ return 'Checking model health';
1352
+ case 'docs':
1353
+ return 'Initializing documentation';
1354
+ case 'config':
1355
+ return 'Loading configuration';
1356
+ default:
1357
+ return 'Ready';
1358
+ }
1359
+ };
1360
+
1361
+ return (
1362
+ <Box flexDirection="column" paddingX={2} paddingY={1}>
1363
+ <Logo showVersion={true} showTagline={true} />
1364
+ <Box marginTop={1}>
1365
+ <Text color="gray">{getInitStepText()}...</Text>
1366
+ </Box>
1367
+ </Box>
1368
+ );
1369
+ }
1370
+
1371
+ // Show setup wizard if no endpoints configured
1372
+ if (showSetupWizard) {
1373
+ return (
1374
+ <Box flexDirection="column" padding={1}>
1375
+ <LLMSetupWizard onComplete={handleSetupComplete} onSkip={handleSetupSkip} />
1376
+ </Box>
1377
+ );
1378
+ }
1379
+
1380
+ // Get health status indicator
1381
+ const getHealthIndicator = () => {
1382
+ switch (healthStatus) {
1383
+ case 'checking':
1384
+ return <Text color="yellow">⋯</Text>;
1385
+ case 'healthy':
1386
+ return <Text color="green">●</Text>;
1387
+ case 'unhealthy':
1388
+ return <Text color="red">●</Text>;
1389
+ default:
1390
+ return <Text color="gray">○</Text>;
1391
+ }
1392
+ };
1393
+
1394
+ // Get activity type based on execution phase
1395
+ const getCurrentActivityType = (): ActivityType => {
1396
+ if (planExecutionState.executionPhase === 'planning') return 'planning';
1397
+ if (planExecutionState.executionPhase === 'executing') return 'executing';
1398
+ return activityType;
1399
+ };
1400
+
1401
+ // Check if any panel is open (for disabling history navigation)
1402
+ const isAnyPanelOpen =
1403
+ fileBrowserState.showFileBrowser ||
1404
+ commandBrowserState.showCommandBrowser ||
1405
+ showToolSelector ||
1406
+ showSettings ||
1407
+ showModelSelector ||
1408
+ showSessionBrowser ||
1409
+ showDocsBrowser ||
1410
+ showLogFiles;
1411
+
1412
+ // Render a single log entry
1413
+ const renderLogEntry = (entry: LogEntry) => {
1414
+ switch (entry.type) {
1415
+ case 'logo': {
1416
+ return (
1417
+ <Box key={entry.id} flexDirection="column" marginBottom={1}>
1418
+ <Logo
1419
+ showVersion={true}
1420
+ showTagline={false}
1421
+ animate={false}
1422
+ modelName={currentModelInfo.model}
1423
+ workingDirectory={shortenPath(process.cwd())}
1424
+ />
1425
+ <Text>{' '}</Text>
1426
+ <Box>
1427
+ <Text color="gray">{STARTUP_TIP}</Text>
1428
+ </Box>
1429
+ </Box>
1430
+ );
1431
+ }
1432
+
1433
+ case 'user_input':
1434
+ return (
1435
+ <Box key={entry.id} marginTop={1}>
1436
+ <Text color="green" bold>❯ </Text>
1437
+ <Text>{entry.content}</Text>
1438
+ </Box>
1439
+ );
1440
+
1441
+ case 'assistant_message':
1442
+ return (
1443
+ <Box key={entry.id} marginTop={1} marginBottom={1} flexDirection="column">
1444
+ <Text color="magenta" bold>● Assistant</Text>
1445
+ <Box paddingLeft={2}>
1446
+ <MarkdownRenderer content={entry.content} />
1447
+ </Box>
1448
+ </Box>
1449
+ );
1450
+
1451
+ case 'interrupt':
1452
+ return (
1453
+ <Box key={entry.id} marginTop={1}>
1454
+ <Text color="red" bold>{entry.content}</Text>
1455
+ </Box>
1456
+ );
1457
+
1458
+ case 'session_restored':
1459
+ return (
1460
+ <Box key={entry.id} marginTop={1} flexDirection="column">
1461
+ <Text color="cyan" bold>📂 {entry.content}</Text>
1462
+ {entry.details && <Text color="gray" dimColor> {entry.details}</Text>}
1463
+ </Box>
1464
+ );
1465
+
1466
+ case 'git_info':
1467
+ return (
1468
+ <Box key={entry.id} marginTop={0} marginBottom={0} flexDirection="column">
1469
+ <Text color="yellow"> 🔀 {entry.content}</Text>
1470
+ </Box>
1471
+ );
1472
+
1473
+ case 'docs_search': {
1474
+ // Truncate both content and details if more than 5 lines (UI only)
1475
+ // Handle both actual newlines and literal \n strings
1476
+ const truncateText = (text: string, maxLines: number = 5): string => {
1477
+ const lines = text.split(/\\n|\n/);
1478
+ if (lines.length > maxLines) {
1479
+ return lines.slice(0, maxLines).join('\n') + `\n... (${lines.length - maxLines} more lines)`;
1480
+ }
1481
+ return lines.join('\n');
1482
+ };
1483
+
1484
+ const displayContent = truncateText(entry.content);
1485
+ const displayDetails = entry.details ? truncateText(entry.details) : undefined;
1486
+
1487
+ return (
1488
+ <Box key={entry.id} marginTop={1} flexDirection="column">
1489
+ <Text color="yellow" bold>📚 Document Search Complete</Text>
1490
+ {displayDetails && <Text color="gray" dimColor> {displayDetails}</Text>}
1491
+ <Box paddingLeft={3} marginTop={0}>
1492
+ <Text color="gray">{displayContent}</Text>
1493
+ </Box>
1494
+ </Box>
1495
+ );
1496
+ }
1497
+
1498
+ case 'tool_start': {
1499
+ // Tool icon mapping
1500
+ const getToolIcon = (toolName: string): string => {
1501
+ // Office tools (prefix matching)
1502
+ if (toolName.startsWith('word_')) return '📄'; // Word
1503
+ if (toolName.startsWith('excel_')) return '📊'; // Excel
1504
+ if (toolName.startsWith('powerpoint_')) return '📽️'; // PowerPoint
1505
+ if (toolName.startsWith('browser_')) return '🌐'; // Browser
1506
+
1507
+ switch (toolName) {
1508
+ case 'read_file':
1509
+ return '📖'; // Read
1510
+ case 'create_file':
1511
+ return '📝'; // Create file
1512
+ case 'edit_file':
1513
+ return '✏️'; // Edit
1514
+ case 'list_files':
1515
+ return '📂'; // Folder list
1516
+ case 'find_files':
1517
+ return '🔍'; // Search
1518
+ case 'tell_to_user':
1519
+ return '💬'; // Message
1520
+ case 'bash':
1521
+ return '⚡'; // Terminal/shell command
1522
+ default:
1523
+ return '🔧'; // Default tool
1524
+ }
1525
+ };
1526
+
1527
+ // Extract key parameters per tool
1528
+ const getToolParams = (toolName: string, args: Record<string, unknown> | undefined): string => {
1529
+ if (!args) return '';
1530
+
1531
+ // Office tool parameters (prefix matching)
1532
+ if (toolName.startsWith('word_') || toolName.startsWith('excel_') || toolName.startsWith('powerpoint_')) {
1533
+ // Show file path if available
1534
+ const filePath = args['file_path'] as string;
1535
+ if (filePath) return filePath;
1536
+ // Show cell/range if available
1537
+ const cell = args['cell'] as string;
1538
+ const range = args['range'] as string;
1539
+ if (cell) return cell;
1540
+ if (range) return range;
1541
+ // Show slide number if available
1542
+ const slideNumber = args['slide_number'] as number;
1543
+ if (slideNumber) return `slide ${slideNumber}`;
1544
+ return '';
1545
+ }
1546
+
1547
+ switch (toolName) {
1548
+ case 'read_file':
1549
+ return args['file_path'] as string || '';
1550
+ case 'create_file':
1551
+ return args['file_path'] as string || '';
1552
+ case 'edit_file': {
1553
+ const filePath = args['file_path'] as string || '';
1554
+ const edits = args['edits'] as Array<unknown> || [];
1555
+ return `${filePath}, ${edits.length} edits`;
1556
+ }
1557
+ case 'list_files': {
1558
+ const dir = args['directory_path'] as string || '.';
1559
+ const recursive = args['recursive'] ? ', recursive' : '';
1560
+ return `${dir}${recursive}`;
1561
+ }
1562
+ case 'find_files': {
1563
+ const pattern = args['pattern'] as string || '';
1564
+ const dir = args['directory_path'] as string;
1565
+ return dir ? `${pattern} in ${dir}` : pattern;
1566
+ }
1567
+ case 'tell_to_user':
1568
+ return ''; // tell_to_user doesn't show parameters
1569
+ case 'bash':
1570
+ return args['command'] as string || '';
1571
+ default:
1572
+ return '';
1573
+ }
1574
+ };
1575
+
1576
+ const icon = getToolIcon(entry.content);
1577
+ const params = getToolParams(entry.content, entry.toolArgs);
1578
+ const toolName = entry.content;
1579
+
1580
+ // Truncate reason if too long
1581
+ const reason = entry.details || '';
1582
+ const maxReasonLen = 80;
1583
+ const truncatedReason = reason.length > maxReasonLen
1584
+ ? reason.substring(0, maxReasonLen) + '...'
1585
+ : reason;
1586
+
1587
+ // Unified 2-line format for all tools
1588
+ return (
1589
+ <Box key={entry.id} flexDirection="column" marginTop={1}>
1590
+ <Box>
1591
+ <Text color="cyan" bold>{icon} {toolName}</Text>
1592
+ {params && <Text color="gray"> ({params})</Text>}
1593
+ </Box>
1594
+ {truncatedReason && (
1595
+ <Box marginLeft={2}>
1596
+ <Text color="gray">⎿ </Text>
1597
+ <Text color="yellow">💭 </Text>
1598
+ <Text color="gray">{truncatedReason}</Text>
1599
+ </Box>
1600
+ )}
1601
+ </Box>
1602
+ );
1603
+ }
1604
+
1605
+ case 'tool_result':
1606
+ // Remove tool_result display - only show reason in tool_start
1607
+ return null;
1608
+
1609
+ case 'shell_result':
1610
+ return (
1611
+ <Box key={entry.id} marginLeft={2}>
1612
+ <Text color="gray">⎿ </Text>
1613
+ <Text color={entry.success ? 'white' : 'red'}>{entry.content}</Text>
1614
+ </Box>
1615
+ );
1616
+
1617
+ case 'tell_user':
1618
+ return (
1619
+ <Box key={entry.id} marginTop={1}>
1620
+ <Text color="yellow" bold>● </Text>
1621
+ <Text>{entry.content}</Text>
1622
+ </Box>
1623
+ );
1624
+
1625
+ case 'plan_created':
1626
+ return (
1627
+ <Box key={entry.id} flexDirection="column" marginTop={1}>
1628
+ <Text color="magenta" bold>● 📋 {entry.content}</Text>
1629
+ {entry.items?.map((item, idx) => (
1630
+ <Box key={idx} marginLeft={2}>
1631
+ <Text color="gray">⎿ </Text>
1632
+ <Text>{idx + 1}. {item}</Text>
1633
+ </Box>
1634
+ ))}
1635
+ </Box>
1636
+ );
1637
+
1638
+ case 'todo_start':
1639
+ return (
1640
+ <Box key={entry.id} marginTop={1}>
1641
+ <Text color="blue" bold>● ▶ </Text>
1642
+ <Text bold>{entry.content}</Text>
1643
+ </Box>
1644
+ );
1645
+
1646
+ case 'todo_complete':
1647
+ return (
1648
+ <Box key={entry.id} marginLeft={2}>
1649
+ <Text color="gray">⎿ </Text>
1650
+ <Text color="green">✓ Complete</Text>
1651
+ </Box>
1652
+ );
1653
+
1654
+ case 'todo_fail':
1655
+ return (
1656
+ <Box key={entry.id} marginLeft={2}>
1657
+ <Text color="gray">⎿ </Text>
1658
+ <Text color="red">✗ Failed</Text>
1659
+ </Box>
1660
+ );
1661
+
1662
+ case 'compact':
1663
+ return (
1664
+ <Box key={entry.id} flexDirection="column" marginTop={1}>
1665
+ <Logo
1666
+ showVersion={true}
1667
+ showTagline={false}
1668
+ animate={false}
1669
+ modelName={currentModelInfo.model}
1670
+ workingDirectory={shortenPath(process.cwd())}
1671
+ />
1672
+ <Text color="gray">── {entry.content} ──</Text>
1673
+ </Box>
1674
+ );
1675
+
1676
+ case 'approval_request': {
1677
+ // Format tool args for display
1678
+ const formatArg = (_key: string, value: unknown): string => {
1679
+ if (typeof value === 'string') {
1680
+ if (value.length > 100) return value.substring(0, 100) + '...';
1681
+ return value;
1682
+ }
1683
+ return JSON.stringify(value);
1684
+ };
1685
+
1686
+ return (
1687
+ <Box key={entry.id} flexDirection="column" marginTop={1}>
1688
+ <Box>
1689
+ <Text color="yellow" bold>⚠️ Approval request: </Text>
1690
+ <Text color="cyan" bold>{entry.content}</Text>
1691
+ </Box>
1692
+ {entry.details && (
1693
+ <Box marginLeft={2}>
1694
+ <Text color="gray">⎿ </Text>
1695
+ <Text>{entry.details}</Text>
1696
+ </Box>
1697
+ )}
1698
+ {entry.toolArgs && Object.entries(entry.toolArgs).map(([key, value], idx) => {
1699
+ if (key === 'reason') return null;
1700
+ return (
1701
+ <Box key={idx} marginLeft={2}>
1702
+ <Text color="gray">⎿ </Text>
1703
+ <Text color="magenta">{key}: </Text>
1704
+ <Text color="gray">{formatArg(key, value)}</Text>
1705
+ </Box>
1706
+ );
1707
+ })}
1708
+ </Box>
1709
+ );
1710
+ }
1711
+
1712
+ case 'approval_response':
1713
+ return (
1714
+ <Box key={entry.id} marginLeft={2}>
1715
+ <Text color="gray">⎿ </Text>
1716
+ {entry.success ? (
1717
+ <Text color="green">
1718
+ ✓ {entry.details === 'always_approved' ? 'Always approved' : 'Approved'}
1719
+ </Text>
1720
+ ) : (
1721
+ <Text color="red">
1722
+ ✗ Rejected{entry.details && entry.details !== 'rejected' ? `: ${entry.details}` : ''}
1723
+ </Text>
1724
+ )}
1725
+ </Box>
1726
+ );
1727
+
1728
+ case 'reasoning':
1729
+ // Hide reasoning content - just show indicator
1730
+ return (
1731
+ <Box key={entry.id} marginTop={1}>
1732
+ <Text color="gray">💭 Thinking...</Text>
1733
+ </Box>
1734
+ );
1735
+
1736
+ default:
1737
+ return null;
1738
+ }
1739
+ };
1740
+
1741
+ return (
1742
+ <Box flexDirection="column" height="100%">
1743
+ {/* Static: Scrollable log history (logo, user input, tool calls, etc.) */}
1744
+ <Static items={logEntries}>
1745
+ {(entry) => renderLogEntry(entry)}
1746
+ </Static>
1747
+
1748
+ {/* Tool Approval Dialog (Supervised Mode) - shown in scrollable area */}
1749
+ {pendingToolApproval && (
1750
+ <Box marginY={1}>
1751
+ <ApprovalDialog
1752
+ toolName={pendingToolApproval.toolName}
1753
+ args={pendingToolApproval.args}
1754
+ reason={pendingToolApproval.reason}
1755
+ onResponse={handleApprovalResponse}
1756
+ />
1757
+ </Box>
1758
+ )}
1759
+
1760
+ {/* Activity Indicator (shown when processing/planning, regardless of TODO count) */}
1761
+ {isProcessing && (planExecutionState.executionPhase === 'planning' || planExecutionState.todos.length === 0) && !pendingToolApproval && !isDocsSearching && (
1762
+ <Box marginY={1}>
1763
+ <ActivityIndicator
1764
+ activity={getCurrentActivityType()}
1765
+ startTime={activityStartTime}
1766
+ detail={activityDetail}
1767
+ subActivities={subActivities}
1768
+ modelName={currentModelInfo.model}
1769
+ />
1770
+ </Box>
1771
+ )}
1772
+
1773
+ {/* Docs Search Progress (shown when searching documents) */}
1774
+ {isDocsSearching && (
1775
+ <DocsSearchProgress
1776
+ logs={docsSearchLogs}
1777
+ isSearching={isDocsSearching}
1778
+ />
1779
+ )}
1780
+
1781
+ {/* TODO Panel (always visible when there are todos) */}
1782
+ {planExecutionState.todos.length > 0 && (
1783
+ <Box marginTop={2} marginBottom={1}>
1784
+ <TodoPanel
1785
+ todos={planExecutionState.todos}
1786
+ currentTodoId={planExecutionState.currentTodoId}
1787
+ isProcessing={isProcessing}
1788
+ />
1789
+ </Box>
1790
+ )}
1791
+
1792
+ {/* Input Area */}
1793
+ <Box borderStyle="single" borderColor="gray" paddingX={1} flexDirection="column">
1794
+ <Box>
1795
+ <Text color="green" bold>&gt; </Text>
1796
+ <Box flexGrow={1}>
1797
+ <CustomTextInput
1798
+ value={input}
1799
+ onChange={(value) => {
1800
+ if (showSessionBrowser || showSettings || showDocsBrowser) {
1801
+ return;
1802
+ }
1803
+ setInput(value);
1804
+ }}
1805
+ onSubmit={handleSubmit}
1806
+ onHistoryPrev={isAnyPanelOpen ? undefined : handleHistoryPrev}
1807
+ onHistoryNext={isAnyPanelOpen ? undefined : handleHistoryNext}
1808
+ placeholder={
1809
+ isProcessing
1810
+ ? "AI is working..."
1811
+ : showSessionBrowser
1812
+ ? "Select a session or press ESC..."
1813
+ : showSettings
1814
+ ? "Press ESC to close settings..."
1815
+ : showDocsBrowser
1816
+ ? "Select a doc source or press ESC..."
1817
+ : "Type your message... (@ files, / commands, Alt+Enter newline)"
1818
+ }
1819
+ focus={!showSessionBrowser && !showSettings && !showDocsBrowser && !planExecutionState.askUserRequest}
1820
+ />
1821
+ </Box>
1822
+ {/* Character counter */}
1823
+ {input.length > 0 && (
1824
+ <Text color={input.length > 4000 ? 'red' : input.length > 2000 ? 'yellow' : 'gray'} dimColor>
1825
+ {input.length.toLocaleString()}
1826
+ </Text>
1827
+ )}
1828
+ </Box>
1829
+ </Box>
1830
+
1831
+ {/* File Browser (shown when '@' is typed) */}
1832
+ {fileBrowserState.showFileBrowser && !isProcessing && (
1833
+ <Box marginTop={0}>
1834
+ {fileBrowserState.isLoadingFiles ? (
1835
+ <Box borderStyle="single" borderColor="yellow" paddingX={1}>
1836
+ <Spinner type="dots" />
1837
+ <Text color="yellow"> Loading files...</Text>
1838
+ </Box>
1839
+ ) : (
1840
+ <FileBrowser
1841
+ filter={fileBrowserState.filterText}
1842
+ onSelect={handleFileSelect}
1843
+ onCancel={fileBrowserState.handleFileBrowserCancel}
1844
+ cachedFiles={fileBrowserState.cachedFileList}
1845
+ />
1846
+ )}
1847
+ </Box>
1848
+ )}
1849
+
1850
+ {/* Command Browser (shown when '/' is typed at start) */}
1851
+ {commandBrowserState.showCommandBrowser && !isProcessing && !fileBrowserState.showFileBrowser && (
1852
+ <Box marginTop={0}>
1853
+ <CommandBrowser
1854
+ partialCommand={commandBrowserState.partialCommand}
1855
+ args={commandBrowserState.commandArgs}
1856
+ onSelect={handleCommandSelect}
1857
+ onCancel={commandBrowserState.handleCommandBrowserCancel}
1858
+ />
1859
+ </Box>
1860
+ )}
1861
+
1862
+ {/* Session Browser (shown when /load command is submitted) */}
1863
+ {showSessionBrowser && !isProcessing && (
1864
+ <Box marginTop={0}>
1865
+ <SessionBrowser
1866
+ onSelect={handleSessionSelect}
1867
+ onCancel={() => setShowSessionBrowser(false)}
1868
+ />
1869
+ </Box>
1870
+ )}
1871
+
1872
+ {/* Settings Browser (shown when /settings command is submitted) */}
1873
+ {showSettings && !isProcessing && (
1874
+ <Box marginTop={0}>
1875
+ <SettingsBrowser
1876
+ currentPlanningMode={planningMode}
1877
+ onPlanningModeChange={handleSettingsPlanningModeChange}
1878
+ onClose={handleSettingsClose}
1879
+ />
1880
+ </Box>
1881
+ )}
1882
+
1883
+ {/* Model Selector (shown when /model command is submitted) */}
1884
+ {showModelSelector && !isProcessing && (
1885
+ <Box marginTop={0}>
1886
+ <ModelSelector
1887
+ onSelect={handleModelSelect}
1888
+ onCancel={handleModelSelectorCancel}
1889
+ />
1890
+ </Box>
1891
+ )}
1892
+
1893
+ {/* DISABLED: Docs Browser removed - docs feature disabled */}
1894
+
1895
+ {/* Tool Selector (shown when /tool command is submitted) */}
1896
+ {showToolSelector && !isProcessing && (
1897
+ <Box marginTop={0}>
1898
+ <ToolSelector
1899
+ onClose={handleToolSelectorClose}
1900
+ />
1901
+ </Box>
1902
+ )}
1903
+
1904
+ {/* Ask User Dialog */}
1905
+ {planExecutionState.askUserRequest && (
1906
+ <Box marginTop={1}>
1907
+ <AskUserDialog
1908
+ request={planExecutionState.askUserRequest}
1909
+ onResponse={planExecutionState.handleAskUserResponse}
1910
+ />
1911
+ </Box>
1912
+ )}
1913
+
1914
+ {/* Status Bar - Claude Code style when processing */}
1915
+ <Box justifyContent="space-between" paddingX={1}>
1916
+ {isProcessing || planExecutionState.executionPhase === 'compacting' ? (
1917
+ // Claude Code style with pulsing star animation (shark for compacting)
1918
+ <>
1919
+ <Box flexDirection="column">
1920
+ {planExecutionState.executionPhase === 'compacting' ? (
1921
+ // Shark spinner for compacting (full width)
1922
+ <Box>
1923
+ <Text color="cyan"><Spinner type="shark" /></Text>
1924
+ </Box>
1925
+ ) : null}
1926
+ <Box>
1927
+ <Text color="magenta">
1928
+ <Spinner type="star" />
1929
+ </Text>
1930
+ <Text color="white">{' '}
1931
+ {getStatusText({
1932
+ phase: planExecutionState.executionPhase,
1933
+ todos: planExecutionState.todos,
1934
+ currentToolName,
1935
+ })}…
1936
+ </Text>
1937
+ <Text color="gray">
1938
+ {' '}(esc to interrupt · {formatElapsedTime(sessionElapsed)}
1939
+ {sessionTokens > 0 && ` · ↑ ${formatTokensCompact(sessionTokens)} tokens`})
1940
+ </Text>
1941
+ </Box>
1942
+ </Box>
1943
+ <Box>
1944
+ {/* Context usage indicator (tokens / percent) */}
1945
+ {(() => {
1946
+ const ctxInfo = planExecutionState.getContextUsageInfo();
1947
+ const ctxColor = ctxInfo.percent < 50 ? 'green' : ctxInfo.percent < 80 ? 'yellow' : 'red';
1948
+ return (
1949
+ <>
1950
+ <Text color={ctxColor}>Context ({formatTokensCompact(ctxInfo.tokens)} / {ctxInfo.percent}%)</Text>
1951
+ <Text color="gray"> │ </Text>
1952
+ </>
1953
+ );
1954
+ })()}
1955
+ <Text color="cyan">{currentModelInfo.model}</Text>
1956
+ </Box>
1957
+ </>
1958
+ ) : (
1959
+ // Default status bar
1960
+ <>
1961
+ <Box>
1962
+ {/* Execution mode indicator */}
1963
+ <Text color={executionMode === 'auto' ? 'green' : 'yellow'} bold>
1964
+ [{executionMode === 'auto' ? 'Auto' : 'Supervised'}]
1965
+ </Text>
1966
+ <Text color="gray"> │ </Text>
1967
+ {/* Context usage indicator (tokens / percent) */}
1968
+ {(() => {
1969
+ const ctxInfo = planExecutionState.getContextUsageInfo();
1970
+ const ctxColor = ctxInfo.percent < 50 ? 'green' : ctxInfo.percent < 80 ? 'yellow' : 'red';
1971
+ return (
1972
+ <>
1973
+ <Text color={ctxColor}>Context ({formatTokensCompact(ctxInfo.tokens)} / {ctxInfo.percent}%)</Text>
1974
+ <Text color="gray"> │ </Text>
1975
+ </>
1976
+ );
1977
+ })()}
1978
+ {/* Model info - always visible */}
1979
+ <Text color="gray">{getHealthIndicator()} </Text>
1980
+ <Text color="cyan">{currentModelInfo.model}</Text>
1981
+ <Text color="gray"> │ </Text>
1982
+ <Text color="gray">{shortenPath(process.cwd())}</Text>
1983
+ {planExecutionState.todos.length > 0 && (
1984
+ <>
1985
+ <Text color="gray"> │ </Text>
1986
+ <TodoStatusBar todos={planExecutionState.todos} />
1987
+ </>
1988
+ )}
1989
+ </Box>
1990
+ <Text color="gray" dimColor>
1991
+ Tab: mode │ /help
1992
+ </Text>
1993
+ </>
1994
+ )}
1995
+ </Box>
1996
+
1997
+ {/* Log Browser (Ctrl+O to toggle) */}
1998
+ {showLogFiles && (
1999
+ <Box marginTop={0}>
2000
+ <LogBrowser onClose={() => setShowLogFiles(false)} />
2001
+ </Box>
2002
+ )}
2003
+ </Box>
2004
+ );
2005
+ };
2006
+
2007
+ export default PlanExecuteApp;