orquesta-cli 0.1.2

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