lonny-agent 0.2.6 → 0.2.7

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 (475) hide show
  1. package/.github/workflows/ci.yml +21 -0
  2. package/AGENTS.md +106 -0
  3. package/CHANGELOG.md +24 -0
  4. package/dist/agent/__tests__/session-restore.test.d.ts +2 -0
  5. package/dist/agent/__tests__/session-restore.test.d.ts.map +1 -0
  6. package/dist/agent/__tests__/session-restore.test.js +260 -0
  7. package/dist/agent/__tests__/session-restore.test.js.map +1 -0
  8. package/dist/agent/commands.d.ts +26 -0
  9. package/dist/agent/commands.d.ts.map +1 -0
  10. package/dist/agent/commands.js +253 -0
  11. package/dist/agent/commands.js.map +1 -0
  12. package/dist/agent/compaction.js +8 -1
  13. package/dist/agent/compaction.js.map +1 -1
  14. package/dist/agent/index.d.ts +2 -1
  15. package/dist/agent/index.d.ts.map +1 -1
  16. package/dist/agent/index.js +2 -2
  17. package/dist/agent/index.js.map +1 -1
  18. package/dist/agent/memory.d.ts +12 -0
  19. package/dist/agent/memory.d.ts.map +1 -0
  20. package/dist/agent/memory.js +51 -0
  21. package/dist/agent/memory.js.map +1 -0
  22. package/dist/agent/prompt-builder.d.ts +6 -1
  23. package/dist/agent/prompt-builder.d.ts.map +1 -1
  24. package/dist/agent/prompt-builder.js +89 -26
  25. package/dist/agent/prompt-builder.js.map +1 -1
  26. package/dist/agent/providers/openai.d.ts +1 -0
  27. package/dist/agent/providers/openai.d.ts.map +1 -1
  28. package/dist/agent/providers/openai.js +16 -3
  29. package/dist/agent/providers/openai.js.map +1 -1
  30. package/dist/agent/session-chat.d.ts +3 -0
  31. package/dist/agent/session-chat.d.ts.map +1 -0
  32. package/dist/agent/session-chat.js +384 -0
  33. package/dist/agent/session-chat.js.map +1 -0
  34. package/dist/agent/session-display.d.ts +29 -0
  35. package/dist/agent/session-display.d.ts.map +1 -0
  36. package/dist/agent/session-display.js +179 -0
  37. package/dist/agent/session-display.js.map +1 -0
  38. package/dist/agent/session-persistence.d.ts +55 -0
  39. package/dist/agent/session-persistence.d.ts.map +1 -0
  40. package/dist/agent/session-persistence.js +101 -0
  41. package/dist/agent/session-persistence.js.map +1 -0
  42. package/dist/agent/session-utils.d.ts +5 -0
  43. package/dist/agent/session-utils.d.ts.map +1 -0
  44. package/dist/agent/session-utils.js +51 -0
  45. package/dist/agent/session-utils.js.map +1 -0
  46. package/dist/agent/session.d.ts +15 -17
  47. package/dist/agent/session.d.ts.map +1 -1
  48. package/dist/agent/session.js +226 -608
  49. package/dist/agent/session.js.map +1 -1
  50. package/dist/cli/index.d.ts +4 -0
  51. package/dist/cli/index.d.ts.map +1 -1
  52. package/dist/cli/index.js +67 -2
  53. package/dist/cli/index.js.map +1 -1
  54. package/dist/config/index.d.ts +2 -2
  55. package/dist/config/index.d.ts.map +1 -1
  56. package/dist/index.js +24 -3
  57. package/dist/index.js.map +1 -1
  58. package/dist/tools/__tests__/bash.test.js +168 -1
  59. package/dist/tools/__tests__/bash.test.js.map +1 -1
  60. package/dist/tools/__tests__/edit.test.js +253 -6
  61. package/dist/tools/__tests__/edit.test.js.map +1 -1
  62. package/dist/tools/__tests__/fetch.test.js +1 -1
  63. package/dist/tools/__tests__/fetch.test.js.map +1 -1
  64. package/dist/tools/__tests__/glob.test.js +1 -1
  65. package/dist/tools/__tests__/glob.test.js.map +1 -1
  66. package/dist/tools/__tests__/grep.test.js +1 -1
  67. package/dist/tools/__tests__/grep.test.js.map +1 -1
  68. package/dist/tools/__tests__/ls.test.js +1 -1
  69. package/dist/tools/__tests__/ls.test.js.map +1 -1
  70. package/dist/tools/__tests__/read.test.js +1 -1
  71. package/dist/tools/__tests__/read.test.js.map +1 -1
  72. package/dist/tools/__tests__/registry.test.js +313 -0
  73. package/dist/tools/__tests__/registry.test.js.map +1 -1
  74. package/dist/tools/__tests__/write_plan.test.js +1 -1
  75. package/dist/tools/__tests__/write_plan.test.js.map +1 -1
  76. package/dist/tools/bash.d.ts.map +1 -1
  77. package/dist/tools/bash.js +659 -39
  78. package/dist/tools/bash.js.map +1 -1
  79. package/dist/tools/codebase/ast/__tests__/ast-edit-demo.d.ts +2 -0
  80. package/dist/tools/codebase/ast/__tests__/ast-edit-demo.d.ts.map +1 -0
  81. package/dist/tools/codebase/ast/__tests__/ast-edit-demo.js +7 -0
  82. package/dist/tools/codebase/ast/__tests__/ast-edit-demo.js.map +1 -0
  83. package/dist/tools/codebase/ast/__tests__/ast-edit-final.d.ts +6 -0
  84. package/dist/tools/codebase/ast/__tests__/ast-edit-final.d.ts.map +1 -0
  85. package/dist/tools/codebase/ast/__tests__/ast-edit-final.js +11 -0
  86. package/dist/tools/codebase/ast/__tests__/ast-edit-final.js.map +1 -0
  87. package/dist/tools/codebase/ast/__tests__/ast-edit-test.d.ts +2 -0
  88. package/dist/tools/codebase/ast/__tests__/ast-edit-test.d.ts.map +1 -0
  89. package/dist/tools/codebase/ast/__tests__/ast-edit-test.js +9 -0
  90. package/dist/tools/codebase/ast/__tests__/ast-edit-test.js.map +1 -0
  91. package/dist/tools/codebase/ast/__tests__/integration.test.d.ts +2 -0
  92. package/dist/tools/codebase/ast/__tests__/integration.test.d.ts.map +1 -0
  93. package/dist/tools/codebase/ast/__tests__/integration.test.js +415 -0
  94. package/dist/tools/codebase/ast/__tests__/integration.test.js.map +1 -0
  95. package/dist/tools/codebase/ast/__tests__/tree-sitter.test.d.ts +2 -0
  96. package/dist/tools/codebase/ast/__tests__/tree-sitter.test.d.ts.map +1 -0
  97. package/dist/tools/codebase/ast/__tests__/tree-sitter.test.js +414 -0
  98. package/dist/tools/codebase/ast/__tests__/tree-sitter.test.js.map +1 -0
  99. package/dist/tools/codebase/ast/adapter.d.ts +23 -0
  100. package/dist/tools/codebase/ast/adapter.d.ts.map +1 -0
  101. package/dist/tools/codebase/ast/adapter.js +11 -0
  102. package/dist/tools/codebase/ast/adapter.js.map +1 -0
  103. package/dist/tools/codebase/ast/tools.d.ts +3 -0
  104. package/dist/tools/codebase/ast/tools.d.ts.map +1 -0
  105. package/dist/tools/codebase/ast/tools.js +286 -0
  106. package/dist/tools/codebase/ast/tools.js.map +1 -0
  107. package/dist/tools/codebase/ast/tree-sitter-adapter.d.ts +3 -0
  108. package/dist/tools/codebase/ast/tree-sitter-adapter.d.ts.map +1 -0
  109. package/dist/tools/codebase/ast/tree-sitter-adapter.js +412 -0
  110. package/dist/tools/codebase/ast/tree-sitter-adapter.js.map +1 -0
  111. package/dist/tools/codebase/ast/tree-sitter-converters.d.ts +4 -0
  112. package/dist/tools/codebase/ast/tree-sitter-converters.d.ts.map +1 -0
  113. package/dist/tools/codebase/ast/tree-sitter-converters.js +447 -0
  114. package/dist/tools/codebase/ast/tree-sitter-converters.js.map +1 -0
  115. package/dist/tools/codebase/ast/types.d.ts +103 -0
  116. package/dist/tools/codebase/ast/types.d.ts.map +1 -0
  117. package/dist/tools/codebase/ast/types.js +2 -0
  118. package/dist/tools/codebase/ast/types.js.map +1 -0
  119. package/dist/tools/codebase/ast/wasm/tree-sitter-python.wasm +0 -0
  120. package/dist/tools/codebase/ast/wasm/tree-sitter-tsx.wasm +0 -0
  121. package/dist/tools/codebase/ast/wasm/tree-sitter-typescript.wasm +0 -0
  122. package/dist/tools/codebase/ast/wasm/tree-sitter.wasm +0 -0
  123. package/dist/tools/codebase/ast/wasm/web-tree-sitter.wasm +0 -0
  124. package/dist/tools/codebase/find.d.ts +3 -0
  125. package/dist/tools/codebase/find.d.ts.map +1 -0
  126. package/dist/tools/codebase/find.js +61 -0
  127. package/dist/tools/codebase/find.js.map +1 -0
  128. package/dist/tools/codebase/glob.d.ts +3 -0
  129. package/dist/tools/codebase/glob.d.ts.map +1 -0
  130. package/dist/tools/codebase/glob.js +37 -0
  131. package/dist/tools/codebase/glob.js.map +1 -0
  132. package/dist/tools/codebase/grep.d.ts +3 -0
  133. package/dist/tools/codebase/grep.d.ts.map +1 -0
  134. package/dist/tools/codebase/grep.js +169 -0
  135. package/dist/tools/codebase/grep.js.map +1 -0
  136. package/dist/tools/codebase/ls.d.ts +3 -0
  137. package/dist/tools/codebase/ls.d.ts.map +1 -0
  138. package/dist/tools/codebase/ls.js +39 -0
  139. package/dist/tools/codebase/ls.js.map +1 -0
  140. package/dist/tools/codebase/read.d.ts +10 -0
  141. package/dist/tools/codebase/read.d.ts.map +1 -0
  142. package/dist/tools/codebase/read.js +81 -0
  143. package/dist/tools/codebase/read.js.map +1 -0
  144. package/dist/tools/delete_memory.d.ts +3 -0
  145. package/dist/tools/delete_memory.d.ts.map +1 -0
  146. package/dist/tools/delete_memory.js +46 -0
  147. package/dist/tools/delete_memory.js.map +1 -0
  148. package/dist/tools/edit/diff-compute.d.ts +4 -0
  149. package/dist/tools/edit/diff-compute.d.ts.map +1 -0
  150. package/dist/tools/edit/diff-compute.js +18 -0
  151. package/dist/tools/edit/diff-compute.js.map +1 -0
  152. package/dist/tools/edit/diff-render.d.ts +18 -0
  153. package/dist/tools/edit/diff-render.d.ts.map +1 -0
  154. package/dist/tools/edit/diff-render.js +128 -0
  155. package/dist/tools/edit/diff-render.js.map +1 -0
  156. package/dist/tools/edit/edit.d.ts +4 -0
  157. package/dist/tools/edit/edit.d.ts.map +1 -0
  158. package/dist/tools/edit/edit.js +440 -0
  159. package/dist/tools/edit/edit.js.map +1 -0
  160. package/dist/tools/edit/matcher.d.ts +24 -0
  161. package/dist/tools/edit/matcher.d.ts.map +1 -0
  162. package/dist/tools/edit/matcher.js +66 -0
  163. package/dist/tools/edit/matcher.js.map +1 -0
  164. package/dist/tools/edit/parser.d.ts +10 -0
  165. package/dist/tools/edit/parser.d.ts.map +1 -0
  166. package/dist/tools/edit/parser.js +120 -0
  167. package/dist/tools/edit/parser.js.map +1 -0
  168. package/dist/tools/edit/types.d.ts +16 -0
  169. package/dist/tools/edit/types.d.ts.map +1 -0
  170. package/dist/tools/edit/types.js +2 -0
  171. package/dist/tools/edit/types.js.map +1 -0
  172. package/dist/tools/edit/write_plan.d.ts +5 -0
  173. package/dist/tools/edit/write_plan.d.ts.map +1 -0
  174. package/dist/tools/edit/write_plan.js +98 -0
  175. package/dist/tools/edit/write_plan.js.map +1 -0
  176. package/dist/tools/edit.d.ts.map +1 -1
  177. package/dist/tools/edit.js +66 -1
  178. package/dist/tools/edit.js.map +1 -1
  179. package/dist/tools/execute/bash/constants.d.ts +24 -0
  180. package/dist/tools/execute/bash/constants.d.ts.map +1 -0
  181. package/dist/tools/execute/bash/constants.js +88 -0
  182. package/dist/tools/execute/bash/constants.js.map +1 -0
  183. package/dist/tools/execute/bash/errors.d.ts +39 -0
  184. package/dist/tools/execute/bash/errors.d.ts.map +1 -0
  185. package/dist/tools/execute/bash/errors.js +249 -0
  186. package/dist/tools/execute/bash/errors.js.map +1 -0
  187. package/dist/tools/execute/bash/execution.d.ts +18 -0
  188. package/dist/tools/execute/bash/execution.d.ts.map +1 -0
  189. package/dist/tools/execute/bash/execution.js +207 -0
  190. package/dist/tools/execute/bash/execution.js.map +1 -0
  191. package/dist/tools/execute/bash/index.d.ts +3 -0
  192. package/dist/tools/execute/bash/index.d.ts.map +1 -0
  193. package/dist/tools/execute/bash/index.js +117 -0
  194. package/dist/tools/execute/bash/index.js.map +1 -0
  195. package/dist/tools/execute/bash/platform.d.ts +6 -0
  196. package/dist/tools/execute/bash/platform.d.ts.map +1 -0
  197. package/dist/tools/execute/bash/platform.js +64 -0
  198. package/dist/tools/execute/bash/platform.js.map +1 -0
  199. package/dist/tools/execute/bash/security.d.ts +12 -0
  200. package/dist/tools/execute/bash/security.d.ts.map +1 -0
  201. package/dist/tools/execute/bash/security.js +26 -0
  202. package/dist/tools/execute/bash/security.js.map +1 -0
  203. package/dist/tools/execute/bash/validation.d.ts +16 -0
  204. package/dist/tools/execute/bash/validation.d.ts.map +1 -0
  205. package/dist/tools/execute/bash/validation.js +57 -0
  206. package/dist/tools/execute/bash/validation.js.map +1 -0
  207. package/dist/tools/execute/bash.d.ts +3 -0
  208. package/dist/tools/execute/bash.d.ts.map +1 -0
  209. package/dist/tools/execute/bash.js +728 -0
  210. package/dist/tools/execute/bash.js.map +1 -0
  211. package/dist/tools/execute/git.d.ts +3 -0
  212. package/dist/tools/execute/git.d.ts.map +1 -0
  213. package/dist/tools/execute/git.js +183 -0
  214. package/dist/tools/execute/git.js.map +1 -0
  215. package/dist/tools/execute/task_complete.d.ts +7 -0
  216. package/dist/tools/execute/task_complete.d.ts.map +1 -0
  217. package/dist/tools/execute/task_complete.js +38 -0
  218. package/dist/tools/execute/task_complete.js.map +1 -0
  219. package/dist/tools/fetch.d.ts.map +1 -1
  220. package/dist/tools/fetch.js +2 -0
  221. package/dist/tools/fetch.js.map +1 -1
  222. package/dist/tools/find.d.ts.map +1 -1
  223. package/dist/tools/find.js +2 -0
  224. package/dist/tools/find.js.map +1 -1
  225. package/dist/tools/git.d.ts.map +1 -1
  226. package/dist/tools/git.js +2 -0
  227. package/dist/tools/git.js.map +1 -1
  228. package/dist/tools/glob.d.ts.map +1 -1
  229. package/dist/tools/glob.js +2 -0
  230. package/dist/tools/glob.js.map +1 -1
  231. package/dist/tools/grep.d.ts.map +1 -1
  232. package/dist/tools/grep.js +2 -0
  233. package/dist/tools/grep.js.map +1 -1
  234. package/dist/tools/install/clawhub.d.ts +26 -0
  235. package/dist/tools/install/clawhub.d.ts.map +1 -0
  236. package/dist/tools/install/clawhub.js +182 -0
  237. package/dist/tools/install/clawhub.js.map +1 -0
  238. package/dist/tools/install/constants.d.ts +5 -0
  239. package/dist/tools/install/constants.d.ts.map +1 -0
  240. package/dist/tools/install/constants.js +5 -0
  241. package/dist/tools/install/constants.js.map +1 -0
  242. package/dist/tools/install/install_skill.d.ts +3 -0
  243. package/dist/tools/install/install_skill.d.ts.map +1 -0
  244. package/dist/tools/install/install_skill.js +132 -0
  245. package/dist/tools/install/install_skill.js.map +1 -0
  246. package/dist/tools/install/npm.d.ts +8 -0
  247. package/dist/tools/install/npm.d.ts.map +1 -0
  248. package/dist/tools/install/npm.js +52 -0
  249. package/dist/tools/install/npm.js.map +1 -0
  250. package/dist/tools/install/skill-content.d.ts +9 -0
  251. package/dist/tools/install/skill-content.d.ts.map +1 -0
  252. package/dist/tools/install/skill-content.js +89 -0
  253. package/dist/tools/install/skill-content.js.map +1 -0
  254. package/dist/tools/install_skill.d.ts.map +1 -1
  255. package/dist/tools/install_skill.js +2 -0
  256. package/dist/tools/install_skill.js.map +1 -1
  257. package/dist/tools/list_memory.d.ts +3 -0
  258. package/dist/tools/list_memory.d.ts.map +1 -0
  259. package/dist/tools/list_memory.js +55 -0
  260. package/dist/tools/list_memory.js.map +1 -0
  261. package/dist/tools/ls.d.ts.map +1 -1
  262. package/dist/tools/ls.js +2 -0
  263. package/dist/tools/ls.js.map +1 -1
  264. package/dist/tools/memory/delete_memory.d.ts +3 -0
  265. package/dist/tools/memory/delete_memory.d.ts.map +1 -0
  266. package/dist/tools/memory/delete_memory.js +46 -0
  267. package/dist/tools/memory/delete_memory.js.map +1 -0
  268. package/dist/tools/memory/list_memory.d.ts +3 -0
  269. package/dist/tools/memory/list_memory.d.ts.map +1 -0
  270. package/dist/tools/memory/list_memory.js +55 -0
  271. package/dist/tools/memory/list_memory.js.map +1 -0
  272. package/dist/tools/memory/save_memory.d.ts +3 -0
  273. package/dist/tools/memory/save_memory.d.ts.map +1 -0
  274. package/dist/tools/memory/save_memory.js +45 -0
  275. package/dist/tools/memory/save_memory.js.map +1 -0
  276. package/dist/tools/read.d.ts.map +1 -1
  277. package/dist/tools/read.js +2 -0
  278. package/dist/tools/read.js.map +1 -1
  279. package/dist/tools/registry.d.ts +7 -2
  280. package/dist/tools/registry.d.ts.map +1 -1
  281. package/dist/tools/registry.js +112 -17
  282. package/dist/tools/registry.js.map +1 -1
  283. package/dist/tools/save_memory.d.ts +3 -0
  284. package/dist/tools/save_memory.d.ts.map +1 -0
  285. package/dist/tools/save_memory.js +45 -0
  286. package/dist/tools/save_memory.js.map +1 -0
  287. package/dist/tools/search.d.ts.map +1 -1
  288. package/dist/tools/search.js +2 -0
  289. package/dist/tools/search.js.map +1 -1
  290. package/dist/tools/tree.d.ts +12 -0
  291. package/dist/tools/tree.d.ts.map +1 -0
  292. package/dist/tools/tree.js +87 -0
  293. package/dist/tools/tree.js.map +1 -0
  294. package/dist/tools/types.d.ts +12 -0
  295. package/dist/tools/types.d.ts.map +1 -1
  296. package/dist/tools/web/fetch.d.ts +3 -0
  297. package/dist/tools/web/fetch.d.ts.map +1 -0
  298. package/dist/tools/web/fetch.js +49 -0
  299. package/dist/tools/web/fetch.js.map +1 -0
  300. package/dist/tools/web/search.d.ts +3 -0
  301. package/dist/tools/web/search.d.ts.map +1 -0
  302. package/dist/tools/web/search.js +134 -0
  303. package/dist/tools/web/search.js.map +1 -0
  304. package/dist/tools/write_plan.d.ts.map +1 -1
  305. package/dist/tools/write_plan.js +2 -0
  306. package/dist/tools/write_plan.js.map +1 -1
  307. package/dist/tui/commands.d.ts +4 -0
  308. package/dist/tui/commands.d.ts.map +1 -0
  309. package/dist/tui/commands.js +118 -0
  310. package/dist/tui/commands.js.map +1 -0
  311. package/dist/tui/components/colors.d.ts +36 -0
  312. package/dist/tui/components/colors.d.ts.map +1 -0
  313. package/dist/tui/components/colors.js +48 -0
  314. package/dist/tui/components/colors.js.map +1 -0
  315. package/dist/tui/components/header-bar.d.ts +26 -0
  316. package/dist/tui/components/header-bar.d.ts.map +1 -0
  317. package/dist/tui/components/header-bar.js +78 -0
  318. package/dist/tui/components/header-bar.js.map +1 -0
  319. package/dist/tui/components/index.d.ts +9 -0
  320. package/dist/tui/components/index.d.ts.map +1 -0
  321. package/dist/tui/components/index.js +9 -0
  322. package/dist/tui/components/index.js.map +1 -0
  323. package/dist/tui/components/landing-screen.d.ts +12 -0
  324. package/dist/tui/components/landing-screen.d.ts.map +1 -0
  325. package/dist/tui/components/landing-screen.js +53 -0
  326. package/dist/tui/components/landing-screen.js.map +1 -0
  327. package/dist/tui/components/pixel-logo.d.ts +5 -0
  328. package/dist/tui/components/pixel-logo.d.ts.map +1 -0
  329. package/dist/tui/components/pixel-logo.js +27 -0
  330. package/dist/tui/components/pixel-logo.js.map +1 -0
  331. package/dist/tui/components/plan-utils.d.ts +11 -0
  332. package/dist/tui/components/plan-utils.d.ts.map +1 -0
  333. package/dist/tui/components/plan-utils.js +62 -0
  334. package/dist/tui/components/plan-utils.js.map +1 -0
  335. package/dist/tui/components/plans-list.d.ts +18 -0
  336. package/dist/tui/components/plans-list.d.ts.map +1 -0
  337. package/dist/tui/components/plans-list.js +46 -0
  338. package/dist/tui/components/plans-list.js.map +1 -0
  339. package/dist/tui/components/rich-footer.d.ts +29 -0
  340. package/dist/tui/components/rich-footer.d.ts.map +1 -0
  341. package/dist/tui/components/rich-footer.js +124 -0
  342. package/dist/tui/components/rich-footer.js.map +1 -0
  343. package/dist/tui/components/todo-panel.d.ts +14 -0
  344. package/dist/tui/components/todo-panel.d.ts.map +1 -0
  345. package/dist/tui/components/todo-panel.js +83 -0
  346. package/dist/tui/components/todo-panel.js.map +1 -0
  347. package/dist/tui/components.d.ts.map +1 -1
  348. package/dist/tui/components.js +14 -7
  349. package/dist/tui/components.js.map +1 -1
  350. package/dist/tui/index.d.ts +2 -1
  351. package/dist/tui/index.d.ts.map +1 -1
  352. package/dist/tui/index.js +99 -505
  353. package/dist/tui/index.js.map +1 -1
  354. package/dist/tui/overlays.d.ts +28 -0
  355. package/dist/tui/overlays.d.ts.map +1 -0
  356. package/dist/tui/overlays.js +154 -0
  357. package/dist/tui/overlays.js.map +1 -0
  358. package/dist/tui/themes.d.ts +5 -0
  359. package/dist/tui/themes.d.ts.map +1 -0
  360. package/dist/tui/themes.js +38 -0
  361. package/dist/tui/themes.js.map +1 -0
  362. package/dist/web/index.d.ts.map +1 -1
  363. package/dist/web/index.js +60 -122
  364. package/dist/web/index.js.map +1 -1
  365. package/dist/web/public/index.html +1 -1
  366. package/dist/web/public/messages.js +41 -25
  367. package/dist/web/public/state.js +72 -72
  368. package/dist/web/public/style.css +1126 -996
  369. package/dist/web/public/websocket.js +267 -267
  370. package/dist/web/session-bridge.d.ts.map +1 -1
  371. package/dist/web/session-bridge.js +82 -3
  372. package/dist/web/session-bridge.js.map +1 -1
  373. package/docs/ast-tools.md +117 -0
  374. package/package.json +60 -55
  375. package/scripts/check-line-count.mjs +53 -0
  376. package/scripts/copy-ast-wasm.mjs +32 -0
  377. package/src/agent/__tests__/session-restore.test.ts +284 -0
  378. package/src/agent/commands.ts +274 -0
  379. package/src/agent/compaction.ts +9 -2
  380. package/src/agent/index.ts +30 -25
  381. package/src/agent/memory.ts +60 -0
  382. package/src/agent/prompt-builder.ts +100 -26
  383. package/src/agent/providers/anthropic.ts +179 -179
  384. package/src/agent/providers/google.ts +210 -210
  385. package/src/agent/providers/ollama.ts +186 -186
  386. package/src/agent/providers/openai.ts +18 -3
  387. package/src/agent/session-chat.ts +480 -0
  388. package/src/agent/session-display.ts +195 -0
  389. package/src/agent/session-persistence.ts +146 -0
  390. package/src/agent/session-utils.ts +54 -0
  391. package/src/agent/session.ts +261 -718
  392. package/src/cli/index.ts +73 -4
  393. package/src/config/index.ts +342 -342
  394. package/src/index.ts +30 -3
  395. package/src/tools/__tests__/bash.test.ts +187 -1
  396. package/src/tools/__tests__/edit.test.ts +275 -11
  397. package/src/tools/__tests__/fetch.test.ts +1 -1
  398. package/src/tools/__tests__/glob.test.ts +1 -1
  399. package/src/tools/__tests__/grep.test.ts +1 -1
  400. package/src/tools/__tests__/ls.test.ts +1 -1
  401. package/src/tools/__tests__/read.test.ts +1 -1
  402. package/src/tools/__tests__/registry.test.ts +332 -0
  403. package/src/tools/__tests__/write_plan.test.ts +1 -1
  404. package/src/tools/codebase/ast/__tests__/integration.test.ts +452 -0
  405. package/src/tools/codebase/ast/__tests__/tree-sitter.test.ts +466 -0
  406. package/src/tools/codebase/ast/adapter.ts +44 -0
  407. package/src/tools/codebase/ast/tools.ts +322 -0
  408. package/src/tools/codebase/ast/tree-sitter-adapter.ts +468 -0
  409. package/src/tools/codebase/ast/tree-sitter-converters.ts +480 -0
  410. package/src/tools/codebase/ast/types.ts +102 -0
  411. package/src/tools/codebase/ast/wasm/tree-sitter-python.wasm +0 -0
  412. package/src/tools/codebase/ast/wasm/tree-sitter-tsx.wasm +0 -0
  413. package/src/tools/codebase/ast/wasm/tree-sitter-typescript.wasm +0 -0
  414. package/src/tools/codebase/ast/wasm/tree-sitter.wasm +0 -0
  415. package/src/tools/codebase/ast/wasm/web-tree-sitter.wasm +0 -0
  416. package/src/tools/{find.ts → codebase/find.ts} +4 -2
  417. package/src/tools/{glob.ts → codebase/glob.ts} +4 -2
  418. package/src/tools/{grep.ts → codebase/grep.ts} +4 -2
  419. package/src/tools/{ls.ts → codebase/ls.ts} +4 -2
  420. package/src/tools/{read.ts → codebase/read.ts} +5 -3
  421. package/src/tools/edit/diff-compute.ts +21 -0
  422. package/src/tools/edit/diff-render.ts +145 -0
  423. package/src/tools/edit/edit.ts +468 -0
  424. package/src/tools/edit/matcher.ts +70 -0
  425. package/src/tools/edit/parser.ts +131 -0
  426. package/src/tools/edit/types.ts +19 -0
  427. package/src/tools/{write_plan.ts → edit/write_plan.ts} +4 -2
  428. package/src/tools/execute/bash/constants.ts +93 -0
  429. package/src/tools/execute/bash/errors.ts +304 -0
  430. package/src/tools/execute/bash/execution.ts +211 -0
  431. package/src/tools/execute/bash/index.ts +131 -0
  432. package/src/tools/execute/bash/platform.ts +65 -0
  433. package/src/tools/execute/bash/security.ts +28 -0
  434. package/src/tools/execute/bash/validation.ts +78 -0
  435. package/src/tools/execute/git.ts +209 -0
  436. package/src/tools/execute/task_complete.ts +40 -0
  437. package/src/tools/install/clawhub.ts +222 -0
  438. package/src/tools/install/constants.ts +4 -0
  439. package/src/tools/install/install_skill.ts +150 -0
  440. package/src/tools/install/npm.ts +60 -0
  441. package/src/tools/install/skill-content.ts +108 -0
  442. package/src/tools/memory/delete_memory.ts +46 -0
  443. package/src/tools/memory/list_memory.ts +53 -0
  444. package/src/tools/memory/save_memory.ts +45 -0
  445. package/src/tools/registry.ts +119 -19
  446. package/src/tools/tree.ts +103 -0
  447. package/src/tools/types.ts +13 -0
  448. package/src/tools/{fetch.ts → web/fetch.ts} +4 -2
  449. package/src/tools/{search.ts → web/search.ts} +4 -2
  450. package/src/tui/commands.ts +135 -0
  451. package/src/tui/components/colors.ts +52 -0
  452. package/src/tui/components/header-bar.ts +88 -0
  453. package/src/tui/components/index.ts +8 -0
  454. package/src/tui/components/landing-screen.ts +67 -0
  455. package/src/tui/components/pixel-logo.ts +33 -0
  456. package/src/tui/components/plan-utils.ts +69 -0
  457. package/src/tui/components/plans-list.ts +55 -0
  458. package/src/tui/components/rich-footer.ts +146 -0
  459. package/src/tui/components/todo-panel.ts +95 -0
  460. package/src/tui/index.ts +335 -786
  461. package/src/tui/overlays.ts +203 -0
  462. package/src/tui/themes.ts +41 -0
  463. package/src/web/index.ts +64 -127
  464. package/src/web/public/index.html +1 -1
  465. package/src/web/public/messages.js +41 -25
  466. package/src/web/public/state.js +72 -72
  467. package/src/web/public/style.css +1126 -996
  468. package/src/web/public/websocket.js +267 -267
  469. package/src/web/session-bridge.ts +272 -193
  470. package/AGENT.md +0 -99
  471. package/src/tools/bash.ts +0 -125
  472. package/src/tools/edit.ts +0 -747
  473. package/src/tools/git.ts +0 -76
  474. package/src/tools/install_skill.ts +0 -539
  475. package/src/tui/components.ts +0 -635
@@ -1,996 +1,1126 @@
1
- /* ── Reset & Base ─────────────────────────────────────────────── */
2
- *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
3
-
4
- :root {
5
- --bg-primary: #1a1a2e;
6
- --bg-secondary: #16213e;
7
- --bg-tertiary: #0f3460;
8
- --text-primary: #e0e0e0;
9
- --text-secondary: #8888aa;
10
- --text-dim: #666688;
11
- --accent: #00aaff;
12
- --accent-dim: #0088cc;
13
- --success: #44cc88;
14
- --warning: #ffb030;
15
- --error: #ff4466;
16
- --border: #2a2a4a;
17
- --input-bg: #0d1117;
18
- --msg-user-bg: #1a3a5c;
19
- --msg-assistant-bg: transparent;
20
- --font-mono: 'Cascadia Code', 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
21
- --font-ui: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
22
- }
23
-
24
- html, body {
25
- height: 100%;
26
- background: var(--bg-primary);
27
- color: var(--text-primary);
28
- font-family: var(--font-ui);
29
- font-size: 14px;
30
- line-height: 1.6;
31
- overflow: hidden;
32
- }
33
-
34
- /* ── Status Bar ──────────────────────────────────────────────── */
35
- #status-bar {
36
- display: flex;
37
- justify-content: space-between;
38
- align-items: center;
39
- height: 32px;
40
- padding: 0 12px;
41
- background: var(--bg-secondary);
42
- border-bottom: 1px solid var(--border);
43
- font-size: 13px;
44
- user-select: none;
45
- flex-shrink: 0;
46
- }
47
-
48
- .status-left, .status-right {
49
- display: flex;
50
- align-items: center;
51
- gap: 8px;
52
- }
53
-
54
- .logo {
55
- color: var(--accent);
56
- font-weight: bold;
57
- font-family: var(--font-mono);
58
- }
59
-
60
- .separator {
61
- color: var(--text-dim);
62
- }
63
-
64
- .status-idle { color: var(--text-secondary); }
65
- .status-running { color: var(--success); }
66
-
67
- .mode-badge {
68
- padding: 1px 6px;
69
- border-radius: 3px;
70
- font-size: 11px;
71
- font-weight: 600;
72
- text-transform: uppercase;
73
- background: var(--bg-tertiary);
74
- color: var(--accent);
75
- }
76
-
77
- .model-name { color: var(--text-secondary); font-size: 12px; }
78
- .token-stats { color: var(--text-dim); font-size: 12px; display: flex; align-items: center; gap: 2px; }
79
- .token-in { color: var(--accent-dim); }
80
- .token-out { color: var(--success); }
81
- .token-sep { color: var(--text-dim); margin: 0 1px; }
82
- .token-calls { color: var(--text-secondary); margin-left: 4px; }
83
- .token-cache { color: var(--accent-dim); font-size: 12px; margin-left: 4px; }
84
-
85
- .balance-display {
86
- color: var(--warning);
87
- font-size: 12px;
88
- display: flex;
89
- align-items: center;
90
- gap: 2px;
91
- }
92
-
93
- .cwd-text {
94
- color: var(--text-dim);
95
- font-size: 12px;
96
- max-width: 300px;
97
- overflow: hidden;
98
- text-overflow: ellipsis;
99
- white-space: nowrap;
100
- vertical-align: middle;
101
- font-family: var(--font-mono);
102
- }
103
-
104
- /* ── Chat Container ──────────────────────────────────────────── */
105
- #chat-container {
106
- flex: 1;
107
- overflow-y: auto;
108
- padding: 16px;
109
- scroll-behavior: smooth;
110
- min-height: 0;
111
- }
112
-
113
- #chat-container::-webkit-scrollbar {
114
- width: 6px;
115
- }
116
- #chat-container::-webkit-scrollbar-track {
117
- background: transparent;
118
- }
119
- #chat-container::-webkit-scrollbar-thumb {
120
- background: var(--border);
121
- border-radius: 3px;
122
- }
123
-
124
- body {
125
- display: flex;
126
- flex-direction: column;
127
- height: 100vh;
128
- }
129
-
130
- /* ── App Content Layout ───────────────────────────────────────── */
131
- #app-content {
132
- display: flex;
133
- flex-direction: row;
134
- flex: 1;
135
- overflow: hidden;
136
- min-height: 0;
137
- }
138
-
139
- #chat-panel {
140
- display: flex;
141
- flex-direction: column;
142
- flex: 1;
143
- min-width: 0;
144
- overflow: hidden;
145
- }
146
-
147
- /* ── Messages ────────────────────────────────────────────────── */
148
- #messages {
149
- max-width: 1200px;
150
- margin: 0 auto;
151
- }
152
-
153
- .message {
154
- margin-bottom: 16px;
155
- animation: fadeIn 0.2s ease-out;
156
- }
157
-
158
- @keyframes fadeIn {
159
- from { opacity: 0; transform: translateY(4px); }
160
- to { opacity: 1; transform: translateY(0); }
161
- }
162
-
163
- .message-header {
164
- display: flex;
165
- align-items: center;
166
- gap: 8px;
167
- margin-bottom: 4px;
168
- font-size: 12px;
169
- color: var(--text-secondary);
170
- }
171
-
172
- .message-header .label {
173
- font-weight: 600;
174
- font-family: var(--font-mono);
175
- }
176
-
177
- .message-header .label.user { color: var(--accent); }
178
- .message-header .label.assistant { color: var(--success); }
179
- .message-header .label.system { color: var(--warning); }
180
- .message-header .label.error { color: var(--error); }
181
-
182
- .message-body {
183
- padding: 8px 12px;
184
- border-radius: 8px;
185
- font-family: var(--font-ui);
186
- line-height: 1.1;
187
- white-space: pre-wrap;
188
- word-break: break-word;
189
- }
190
-
191
- .message-body.user {
192
- background: var(--msg-user-bg);
193
- border: 1px solid var(--border);
194
- }
195
-
196
- .message-body.assistant {
197
- background: var(--msg-assistant-bg);
198
- }
199
-
200
- .message-body.system {
201
- background: transparent;
202
- color: var(--text-secondary);
203
- font-style: italic;
204
- }
205
-
206
- .message-body.error {
207
- color: var(--error);
208
- background: rgba(255, 68, 102, 0.08);
209
- border: 1px solid rgba(255, 68, 102, 0.2);
210
- }
211
-
212
- /* Streaming cursor */
213
- .message-body.assistant.streaming::after {
214
- content: '▋';
215
- animation: blink 0.8s step-end infinite;
216
- color: var(--success);
217
- }
218
-
219
- @keyframes blink {
220
- 50% { opacity: 0; }
221
- }
222
-
223
- /* ── Markdown Content ────────────────────────────────────────── */
224
- .message-body :first-child { margin-top: 0; }
225
- .message-body :last-child { margin-bottom: 0; }
226
-
227
- .message-body p {
228
- margin: 0.25em 0;
229
- }
230
-
231
- .message-body ul, .message-body ol {
232
- margin: 0.15em 0;
233
- padding-left: 1.5em;
234
- }
235
-
236
- .message-body li {
237
- margin: 0;
238
- line-height: 1.2;
239
- }
240
-
241
- /* Neutralize <p> inside <li> (marked wraps list items in <p> when there are blank lines) */
242
- .message-body li > p {
243
- margin: 0;
244
- display: inline;
245
- }
246
-
247
- /* Neutralize ALL block-level children inside li (marked can nest multiple p, div, etc.) */
248
- .message-body li > * {
249
- margin-top: 0;
250
- margin-bottom: 0;
251
- }
252
-
253
- /* Remove <br> spacing inside list items (from breaks:true option) */
254
- .message-body li br {
255
- display: none;
256
- }
257
-
258
- .message-body blockquote {
259
- margin: 0.3em 0;
260
- padding: 3px 10px;
261
- border-left: 3px solid var(--accent-dim);
262
- color: var(--text-secondary);
263
- background: rgba(0, 170, 255, 0.04);
264
- border-radius: 0 4px 4px 0;
265
- }
266
-
267
- .message-body pre {
268
- margin: 0.35em 0;
269
- padding: 8px 12px;
270
- background: var(--input-bg);
271
- border: 1px solid var(--border);
272
- border-radius: 6px;
273
- overflow-x: auto;
274
- font-family: var(--font-mono);
275
- font-size: 13px;
276
- line-height: 1.2;
277
- color: var(--text-primary);
278
- }
279
-
280
- .message-body code {
281
- font-family: var(--font-mono);
282
- font-size: 0.9em;
283
- padding: 1px 4px;
284
- background: rgba(255,255,255,0.06);
285
- border-radius: 3px;
286
- color: var(--warning);
287
- }
288
-
289
- .message-body pre code {
290
- padding: 0;
291
- background: none;
292
- color: inherit;
293
- font-size: inherit;
294
- }
295
-
296
- .message-body table {
297
- margin: 0.35em 0;
298
- border-collapse: collapse;
299
- width: 100%;
300
- font-size: 13px;
301
- }
302
-
303
- .message-body th, .message-body td {
304
- padding: 4px 8px;
305
- border: 1px solid var(--border);
306
- text-align: left;
307
- }
308
-
309
- .message-body th {
310
- background: var(--bg-secondary);
311
- font-weight: 600;
312
- color: var(--text-secondary);
313
- }
314
-
315
- .message-body hr {
316
- margin: 0.5em 0;
317
- border: none;
318
- border-top: 1px solid var(--border);
319
- }
320
-
321
- .message-body h1, .message-body h2, .message-body h3,
322
- .message-body h4, .message-body h5, .message-body h6 {
323
- margin: 0.4em 0 0.2em;
324
- color: var(--text-primary);
325
- font-weight: 600;
326
- line-height: 1.3;
327
- }
328
-
329
- .message-body h1 { font-size: 1.2em; }
330
- .message-body h2 { font-size: 1.15em; }
331
- .message-body h3 { font-size: 1.05em; }
332
- .message-body h4 { font-size: 1em; }
333
-
334
- .message-body a {
335
- color: var(--accent);
336
- text-decoration: none;
337
- }
338
-
339
- .message-body a:hover {
340
- text-decoration: underline;
341
- }
342
-
343
- .message-body img {
344
- max-width: 100%;
345
- border-radius: 6px;
346
- margin: 0.35em 0;
347
- }
348
-
349
- /* ── Tool Calls & Results ───────────────────────────────────── */
350
- .tool-call,
351
- .tool-result {
352
- margin: 2px 0 2px 12px;
353
- padding: 3px 8px;
354
- border-left: 2px solid var(--border);
355
- font-size: 13px;
356
- font-family: var(--font-mono);
357
- color: var(--text-secondary);
358
- line-height: 1.5;
359
- }
360
-
361
- .tool-call .tool-name { color: var(--accent-dim); }
362
- .tool-call .tool-name.tool-name-edit { color: var(--warning); }
363
- .tool-call .tool-input { color: var(--text-dim); }
364
- .tool-call .tool-input.tool-input-edit { font-family: var(--font-mono); font-size: 0.85em; }
365
-
366
- .tool-change-badge {
367
- display: inline-block;
368
- font-size: 10px;
369
- font-weight: 700;
370
- text-transform: uppercase;
371
- padding: 0 5px;
372
- border-radius: 3px;
373
- margin-left: 4px;
374
- letter-spacing: 0.3px;
375
- vertical-align: middle;
376
- line-height: 1.6;
377
- }
378
- .tool-change-edit {
379
- color: var(--accent);
380
- background: rgba(0, 170, 255, 0.12);
381
- }
382
- .tool-change-create {
383
- color: var(--success);
384
- background: rgba(68, 204, 136, 0.12);
385
- }
386
- .tool-call.completed { opacity: 0.6; }
387
- .tool-call.completed .tool-name::before { display: none; }
388
-
389
- .tool-result .tool-result-success { color: var(--success); }
390
- .tool-result .tool-result-error { color: var(--error); }
391
- .tool-result .tool-result-summary {
392
- display: block;
393
- color: var(--text-secondary);
394
- font-size: 0.85em;
395
- margin-top: 2px;
396
- line-height: 1.3;
397
- }
398
-
399
- /* ── Edit Diff Display ─────────────────────────────────────────── */
400
- .tool-result .tool-result-diff {
401
- display: block;
402
- margin-top: 2px;
403
- }
404
-
405
- .tool-result .tool-result-diff pre {
406
- max-height: 300px;
407
- max-width: 100%;
408
- overflow-y: auto;
409
- overflow-x: auto;
410
- background: var(--input-bg);
411
- border: 1px solid var(--border);
412
- border-radius: 6px;
413
- padding: 8px 12px;
414
- margin: 4px 0;
415
- font-size: 12px;
416
- line-height: 1.4;
417
- white-space: pre;
418
- word-break: break-all;
419
- }
420
-
421
- .tool-result .tool-result-diff code {
422
- font-family: var(--font-mono);
423
- font-size: inherit;
424
- color: inherit;
425
- background: none;
426
- padding: 0;
427
- }
428
-
429
- .tool-result .diff-added {
430
- color: var(--success);
431
- }
432
-
433
- .tool-result .diff-removed {
434
- color: var(--error);
435
- }
436
-
437
- /* ── Tool Error Display ──────────────────────────────────────────── */
438
- .tool-result .tool-error-detail {
439
- display: block;
440
- margin-top: 4px;
441
- padding: 6px 10px;
442
- background: rgba(255, 68, 102, 0.06);
443
- border: 1px solid rgba(255, 68, 102, 0.15);
444
- border-radius: 4px;
445
- font-size: 12px;
446
- line-height: 1.4;
447
- color: var(--text-secondary);
448
- max-height: 120px;
449
- overflow-y: auto;
450
- word-break: break-all;
451
- white-space: pre-wrap;
452
- }
453
-
454
- .tool-result .tool-error-files {
455
- display: block;
456
- margin-top: 2px;
457
- font-size: 12px;
458
- color: var(--error);
459
- font-weight: 600;
460
- }
461
-
462
- /* ── Thinking Block ──────────────────────────────────────────── */
463
- .thinking-block {
464
- margin: 4px 0 4px 12px;
465
- padding: 6px 10px;
466
- border-left: 2px solid var(--warning);
467
- background: rgba(255, 176, 48, 0.05);
468
- border-radius: 4px;
469
- font-size: 13px;
470
- color: var(--text-dim);
471
- font-family: var(--font-mono);
472
- }
473
-
474
- .thinking-block .thinking-label {
475
- color: var(--warning);
476
- font-size: 11px;
477
- font-weight: 600;
478
- text-transform: uppercase;
479
- margin-bottom: 2px;
480
- }
481
-
482
- .thinking-block .thinking-content {
483
- white-space: pre-wrap;
484
- word-break: break-word;
485
- line-height: 1.5;
486
- }
487
-
488
- /* Markdown styles for thinking content */
489
- .thinking-content :first-child { margin-top: 0; }
490
- .thinking-content :last-child { margin-bottom: 0; }
491
- .thinking-content p { margin: 0.2em 0; }
492
- .thinking-content ul, .thinking-content ol { margin: 0.15em 0; padding-left: 1.5em; }
493
- .thinking-content li { margin: 0; line-height: 1.2; }
494
- .thinking-content li > p { margin: 0; display: inline; }
495
- .thinking-content li > * { margin-top: 0; margin-bottom: 0; }
496
- .thinking-content code {
497
- font-family: var(--font-mono);
498
- font-size: 0.9em;
499
- padding: 1px 4px;
500
- background: rgba(255,255,255,0.08);
501
- border-radius: 3px;
502
- color: var(--warning);
503
- }
504
- .thinking-content pre {
505
- margin: 0.4em 0;
506
- padding: 8px 12px;
507
- background: var(--input-bg);
508
- border: 1px solid var(--border);
509
- border-radius: 4px;
510
- overflow-x: auto;
511
- font-size: 12px;
512
- line-height: 1.5;
513
- }
514
- .thinking-content pre code { padding: 0; background: none; color: inherit; font-size: inherit; }
515
-
516
- .thinking-block.thinking-done {
517
- opacity: 0.7;
518
- border-left-color: var(--text-dim);
519
- }
520
-
521
- .thinking-block.thinking-done .thinking-label {
522
- color: var(--text-dim);
523
- }
524
-
525
- /* ── Token Stats ─────────────────────────────────────────────── */
526
- .token-stats-bar {
527
- margin: 8px 0 12px 12px;
528
- padding: 4px 8px;
529
- font-size: 12px;
530
- color: var(--text-dim);
531
- font-family: var(--font-mono);
532
- border-left: 2px solid var(--border);
533
- }
534
-
535
- /* ── System Messages ─────────────────────────────────────────── */
536
- .system-message {
537
- text-align: center;
538
- color: var(--text-dim);
539
- font-size: 13px;
540
- margin: 8px 0;
541
- padding: 4px 8px;
542
- }
543
-
544
- /* ── Input Area ──────────────────────────────────────────────── */
545
- #input-area {
546
- flex-shrink: 0;
547
- border-top: 1px solid var(--border);
548
- background: var(--bg-secondary);
549
- padding: 8px 16px;
550
- }
551
-
552
- .input-wrapper {
553
- display: flex;
554
- gap: 8px;
555
- max-width: 800px;
556
- margin: 0 auto;
557
- align-items: flex-end;
558
- }
559
-
560
- .input-container {
561
- flex: 1;
562
- position: relative;
563
- }
564
-
565
- /* ── Slash Command Hint ─────────────────────────────────────── */
566
- .slash-hint {
567
- position: absolute;
568
- bottom: 100%;
569
- left: 0;
570
- right: 0;
571
- margin-bottom: 4px;
572
- background: var(--bg-tertiary);
573
- border: 1px solid var(--border);
574
- border-radius: 8px;
575
- padding: 6px 0;
576
- font-size: 13px;
577
- z-index: 100;
578
- box-shadow: 0 -4px 16px rgba(0,0,0,0.3);
579
- }
580
-
581
- .slash-hint-header {
582
- padding: 4px 12px 6px;
583
- font-size: 11px;
584
- font-weight: 600;
585
- text-transform: uppercase;
586
- color: var(--text-dim);
587
- letter-spacing: 0.5px;
588
- }
589
-
590
- .slash-hint-item {
591
- padding: 6px 12px;
592
- cursor: pointer;
593
- color: var(--text-primary);
594
- font-family: var(--font-mono);
595
- font-size: 13px;
596
- transition: background 0.15s;
597
- }
598
-
599
- .slash-hint-item:hover,
600
- .slash-hint-item.selected {
601
- background: rgba(0, 170, 255, 0.12);
602
- }
603
-
604
- .slash-hint-item .hint-arg {
605
- color: var(--warning);
606
- }
607
-
608
- .slash-hint-item .hint-desc {
609
- color: var(--text-dim);
610
- font-family: var(--font-ui);
611
- font-size: 12px;
612
- margin-left: 6px;
613
- }
614
-
615
- #chat-input {
616
- flex: 1;
617
- background: var(--input-bg);
618
- border: 1px solid var(--border);
619
- border-radius: 8px;
620
- color: var(--text-primary);
621
- font-family: var(--font-mono);
622
- font-size: 14px;
623
- padding: 10px 14px;
624
- resize: none;
625
- outline: none;
626
- line-height: 1.5;
627
- transition: border-color 0.2s;
628
- width: 100%;
629
- }
630
-
631
- #chat-input:focus {
632
- border-color: var(--accent);
633
- }
634
-
635
- #chat-input::placeholder {
636
- color: var(--text-dim);
637
- }
638
-
639
- #send-btn {
640
- background: var(--accent);
641
- border: none;
642
- border-radius: 8px;
643
- width: 40px;
644
- height: 40px;
645
- display: flex;
646
- align-items: center;
647
- justify-content: center;
648
- cursor: pointer;
649
- color: white;
650
- transition: background 0.2s, opacity 0.2s;
651
- flex-shrink: 0;
652
- }
653
-
654
- #send-btn:hover { background: var(--accent-dim); }
655
- #send-btn:disabled {
656
- opacity: 0.4;
657
- cursor: not-allowed;
658
- }
659
-
660
- /* ── Stop Button ────────────────────────────────────────────── */
661
- #stop-btn {
662
- background: var(--error);
663
- border: none;
664
- border-radius: 8px;
665
- width: 40px;
666
- height: 40px;
667
- display: flex;
668
- align-items: center;
669
- justify-content: center;
670
- cursor: pointer;
671
- color: white;
672
- transition: background 0.2s, opacity 0.2s;
673
- flex-shrink: 0;
674
- }
675
-
676
- #stop-btn:hover { background: #cc2244; }
677
- #stop-btn:disabled {
678
- opacity: 0.4;
679
- cursor: not-allowed;
680
- }
681
-
682
- /* ── Tool Running State ──────────────────────────────────────── */
683
- .tool-call.executing .tool-name {
684
- color: var(--warning);
685
- }
686
- .tool-call.executing .tool-name::before {
687
- content: '';
688
- display: inline-block;
689
- width: 12px;
690
- height: 12px;
691
- margin-right: 4px;
692
- border: 2px solid var(--warning);
693
- border-top-color: transparent;
694
- border-radius: 50%;
695
- animation: spin 0.6s linear infinite;
696
- vertical-align: middle;
697
- }
698
-
699
- /* ── Confirm Dialog ──────────────────────────────────────────── */
700
- .confirm-dialog {
701
- background: var(--bg-secondary);
702
- border: 1px solid var(--border);
703
- border-radius: 12px;
704
- padding: 20px;
705
- min-width: 360px;
706
- max-width: 480px;
707
- box-shadow: 0 8px 32px rgba(0,0,0,0.4);
708
- }
709
-
710
- .confirm-header {
711
- font-size: 15px;
712
- font-weight: 600;
713
- color: var(--text-primary);
714
- margin-bottom: 12px;
715
- }
716
-
717
- .confirm-tool-list {
718
- margin-bottom: 16px;
719
- }
720
-
721
- .confirm-tool-item {
722
- padding: 6px 10px;
723
- margin-bottom: 4px;
724
- background: rgba(255,255,255,0.03);
725
- border-radius: 6px;
726
- font-family: var(--font-mono);
727
- font-size: 13px;
728
- color: var(--text-secondary);
729
- line-height: 1.4;
730
- }
731
-
732
- .confirm-tool-item .confirm-tool-name {
733
- color: var(--accent-dim);
734
- font-weight: 600;
735
- }
736
-
737
- .confirm-tool-item .confirm-tool-input {
738
- color: var(--text-dim);
739
- word-break: break-all;
740
- }
741
-
742
- .confirm-actions {
743
- display: flex;
744
- gap: 8px;
745
- justify-content: flex-end;
746
- }
747
-
748
- .confirm-btn {
749
- padding: 8px 20px;
750
- border: none;
751
- border-radius: 6px;
752
- font-family: var(--font-ui);
753
- font-size: 14px;
754
- font-weight: 600;
755
- cursor: pointer;
756
- transition: background 0.15s, opacity 0.15s;
757
- }
758
-
759
- .confirm-btn-allow {
760
- background: var(--success);
761
- color: white;
762
- }
763
-
764
- .confirm-btn-allow:hover {
765
- opacity: 0.85;
766
- }
767
-
768
- .confirm-btn-reject {
769
- background: transparent;
770
- color: var(--text-secondary);
771
- border: 1px solid var(--border);
772
- }
773
-
774
- .confirm-btn-reject:hover {
775
- background: rgba(255,255,255,0.06);
776
- color: var(--text-primary);
777
- }
778
-
779
- /* ── Connection Overlay ──────────────────────────────────────── */
780
- .overlay {
781
- position: fixed;
782
- inset: 0;
783
- background: rgba(0, 0, 0, 0.6);
784
- display: flex;
785
- align-items: center;
786
- justify-content: center;
787
- z-index: 1000;
788
- }
789
-
790
- .overlay.hidden {
791
- display: none;
792
- }
793
-
794
- .overlay-content {
795
- text-align: center;
796
- color: var(--text-primary);
797
- }
798
-
799
- .overlay-content p {
800
- margin-top: 16px;
801
- color: var(--text-secondary);
802
- }
803
-
804
- .spinner {
805
- width: 40px;
806
- height: 40px;
807
- margin: 0 auto;
808
- border: 3px solid var(--border);
809
- border-top-color: var(--accent);
810
- border-radius: 50%;
811
- animation: spin 0.8s linear infinite;
812
- }
813
-
814
- @keyframes spin {
815
- to { transform: rotate(360deg); }
816
- }
817
-
818
- /* ── Scrollbar for chat ──────────────────────────────────────── */
819
- #chat-container::-webkit-scrollbar { width: 8px; }
820
- #chat-container::-webkit-scrollbar-track { background: transparent; }
821
- #chat-container::-webkit-scrollbar-thumb {
822
- background: var(--text-dim);
823
- border-radius: 4px;
824
- }
825
- #chat-container::-webkit-scrollbar-thumb:hover {
826
- background: var(--text-secondary);
827
- }
828
-
829
- /* ── Right Sidebar ────────────────────────────────────────────── */
830
- #sidebar {
831
- width: 280px;
832
- flex-shrink: 0;
833
- background: var(--bg-secondary);
834
- border-left: 1px solid var(--border);
835
- display: flex;
836
- flex-direction: column;
837
- overflow: hidden;
838
- }
839
-
840
- .sidebar-tabs {
841
- display: flex;
842
- border-bottom: 1px solid var(--border);
843
- flex-shrink: 0;
844
- }
845
-
846
- .sidebar-tab {
847
- flex: 1;
848
- padding: 8px 4px;
849
- background: transparent;
850
- border: none;
851
- color: var(--text-dim);
852
- font-family: var(--font-ui);
853
- font-size: 12px;
854
- font-weight: 600;
855
- cursor: pointer;
856
- transition: color 0.15s, background 0.15s;
857
- text-transform: uppercase;
858
- letter-spacing: 0.5px;
859
- }
860
-
861
- .sidebar-tab:hover {
862
- color: var(--text-secondary);
863
- background: rgba(255,255,255,0.03);
864
- }
865
-
866
- .sidebar-tab.active {
867
- color: var(--accent);
868
- background: rgba(0,170,255,0.06);
869
- border-bottom: 2px solid var(--accent);
870
- }
871
-
872
- .sidebar-content {
873
- flex: 1;
874
- overflow-y: auto;
875
- min-height: 0;
876
- }
877
-
878
- .sidebar-content::-webkit-scrollbar {
879
- width: 6px;
880
- }
881
- .sidebar-content::-webkit-scrollbar-track {
882
- background: transparent;
883
- }
884
- .sidebar-content::-webkit-scrollbar-thumb {
885
- background: var(--text-dim);
886
- border-radius: 3px;
887
- }
888
- .sidebar-content::-webkit-scrollbar-thumb:hover {
889
- background: var(--text-secondary);
890
- }
891
-
892
- .sidebar-pane {
893
- display: none;
894
- padding: 8px;
895
- }
896
-
897
- .sidebar-pane.active {
898
- display: block;
899
- }
900
-
901
- .sidebar-placeholder {
902
- color: var(--text-dim);
903
- font-size: 13px;
904
- text-align: center;
905
- padding: 20px 8px;
906
- font-style: italic;
907
- }
908
-
909
- /* ── Plan List Items ─────────────────────────────────────────── */
910
- .plan-item {
911
- padding: 8px 10px;
912
- margin-bottom: 4px;
913
- border-radius: 6px;
914
- cursor: pointer;
915
- transition: background 0.15s;
916
- border: 1px solid transparent;
917
- }
918
-
919
- .plan-item:hover {
920
- background: rgba(0,170,255,0.06);
921
- border-color: var(--border);
922
- }
923
-
924
- .plan-item.active {
925
- background: rgba(0,170,255,0.1);
926
- border-color: var(--accent-dim);
927
- }
928
-
929
- .plan-item .plan-name {
930
- color: var(--text-primary);
931
- font-size: 13px;
932
- font-weight: 600;
933
- font-family: var(--font-mono);
934
- word-break: break-all;
935
- }
936
-
937
- .plan-item .plan-time {
938
- color: var(--text-dim);
939
- font-size: 11px;
940
- margin-top: 2px;
941
- }
942
-
943
- /* ── Todo Items ──────────────────────────────────────────────── */
944
- .todo-item {
945
- display: flex;
946
- align-items: flex-start;
947
- gap: 6px;
948
- padding: 5px 8px;
949
- margin-bottom: 2px;
950
- border-radius: 4px;
951
- font-size: 13px;
952
- line-height: 1.4;
953
- transition: background 0.15s;
954
- }
955
-
956
- .todo-item:hover {
957
- background: rgba(255,255,255,0.03);
958
- }
959
-
960
- .todo-item .todo-check {
961
- flex-shrink: 0;
962
- margin-top: 1px;
963
- font-size: 14px;
964
- }
965
-
966
- .todo-item .todo-check.done {
967
- color: var(--success);
968
- }
969
-
970
- .todo-item .todo-check.pending {
971
- color: var(--text-dim);
972
- }
973
-
974
- .todo-item .todo-text {
975
- color: var(--text-primary);
976
- word-break: break-word;
977
- }
978
-
979
- .todo-item .todo-text.done {
980
- color: var(--text-dim);
981
- text-decoration: line-through;
982
- }
983
-
984
- .todo-header-text {
985
- color: var(--text-secondary);
986
- font-size: 11px;
987
- font-weight: 600;
988
- padding: 4px 8px 6px;
989
- text-transform: uppercase;
990
- letter-spacing: 0.5px;
991
- border-bottom: 1px solid var(--border);
992
- margin-bottom: 4px;
993
- }
994
-
995
- /* ── Utility ─────────────────────────────────────────────────── */
996
- .hidden { display: none !important; }
1
+ /* ── Reset & Base ─────────────────────────────────────────────── */
2
+ *,
3
+ *::before,
4
+ *::after {
5
+ box-sizing: border-box;
6
+ margin: 0;
7
+ padding: 0;
8
+ }
9
+
10
+ :root {
11
+ --bg-primary: #1a1a2e;
12
+ --bg-secondary: #16213e;
13
+ --bg-tertiary: #0f3460;
14
+ --text-primary: #e0e0e0;
15
+ --text-secondary: #8888aa;
16
+ --text-dim: #666688;
17
+ --accent: #00aaff;
18
+ --accent-dim: #0088cc;
19
+ --success: #44cc88;
20
+ --warning: #ffb030;
21
+ --error: #ff4466;
22
+ --border: #2a2a4a;
23
+ --input-bg: #0d1117;
24
+ --msg-user-bg: #1a3a5c;
25
+ --msg-assistant-bg: transparent;
26
+ --font-mono: "Cascadia Code", "Fira Code", "JetBrains Mono", "Consolas", monospace;
27
+ --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
28
+ }
29
+
30
+ html,
31
+ body {
32
+ height: 100%;
33
+ background: var(--bg-primary);
34
+ color: var(--text-primary);
35
+ font-family: var(--font-ui);
36
+ font-size: 14px;
37
+ line-height: 1.6;
38
+ overflow: hidden;
39
+ }
40
+
41
+ /* ── Status Bar ──────────────────────────────────────────────── */
42
+ #status-bar {
43
+ display: flex;
44
+ justify-content: space-between;
45
+ align-items: center;
46
+ height: 32px;
47
+ padding: 0 12px;
48
+ background: var(--bg-secondary);
49
+ border-bottom: 1px solid var(--border);
50
+ font-size: 13px;
51
+ user-select: none;
52
+ flex-shrink: 0;
53
+ }
54
+
55
+ .status-left,
56
+ .status-right {
57
+ display: flex;
58
+ align-items: center;
59
+ gap: 8px;
60
+ }
61
+
62
+ .logo {
63
+ color: var(--accent);
64
+ font-weight: bold;
65
+ font-family: var(--font-mono);
66
+ }
67
+
68
+ .separator {
69
+ color: var(--text-dim);
70
+ }
71
+
72
+ .status-idle {
73
+ color: var(--text-secondary);
74
+ }
75
+ .status-running {
76
+ color: var(--success);
77
+ }
78
+
79
+ .mode-badge {
80
+ padding: 1px 6px;
81
+ border-radius: 3px;
82
+ font-size: 11px;
83
+ font-weight: 600;
84
+ text-transform: uppercase;
85
+ background: var(--bg-tertiary);
86
+ color: var(--accent);
87
+ }
88
+
89
+ .model-name {
90
+ color: var(--text-secondary);
91
+ font-size: 12px;
92
+ }
93
+ .token-stats {
94
+ color: var(--text-dim);
95
+ font-size: 12px;
96
+ display: flex;
97
+ align-items: center;
98
+ gap: 2px;
99
+ }
100
+ .token-in {
101
+ color: var(--accent-dim);
102
+ }
103
+ .token-out {
104
+ color: var(--success);
105
+ }
106
+ .token-sep {
107
+ color: var(--text-dim);
108
+ margin: 0 1px;
109
+ }
110
+ .token-calls {
111
+ color: var(--text-secondary);
112
+ margin-left: 4px;
113
+ }
114
+ .token-cache {
115
+ color: var(--accent-dim);
116
+ font-size: 12px;
117
+ margin-left: 4px;
118
+ }
119
+
120
+ .balance-display {
121
+ color: var(--warning);
122
+ font-size: 12px;
123
+ display: flex;
124
+ align-items: center;
125
+ gap: 2px;
126
+ }
127
+
128
+ .cwd-text {
129
+ color: var(--text-dim);
130
+ font-size: 12px;
131
+ max-width: 300px;
132
+ overflow: hidden;
133
+ text-overflow: ellipsis;
134
+ white-space: nowrap;
135
+ vertical-align: middle;
136
+ font-family: var(--font-mono);
137
+ }
138
+
139
+ /* ── Chat Container ──────────────────────────────────────────── */
140
+ #chat-container {
141
+ flex: 1;
142
+ overflow-y: auto;
143
+ padding: 16px;
144
+ scroll-behavior: smooth;
145
+ min-height: 0;
146
+ }
147
+
148
+ #chat-container::-webkit-scrollbar {
149
+ width: 6px;
150
+ }
151
+ #chat-container::-webkit-scrollbar-track {
152
+ background: transparent;
153
+ }
154
+ #chat-container::-webkit-scrollbar-thumb {
155
+ background: var(--border);
156
+ border-radius: 3px;
157
+ }
158
+
159
+ body {
160
+ display: flex;
161
+ flex-direction: column;
162
+ height: 100vh;
163
+ }
164
+
165
+ /* ── App Content Layout ───────────────────────────────────────── */
166
+ #app-content {
167
+ display: flex;
168
+ flex-direction: row;
169
+ flex: 1;
170
+ overflow: hidden;
171
+ min-height: 0;
172
+ }
173
+
174
+ #chat-panel {
175
+ display: flex;
176
+ flex-direction: column;
177
+ flex: 1;
178
+ min-width: 0;
179
+ overflow: hidden;
180
+ }
181
+
182
+ /* ── Messages ────────────────────────────────────────────────── */
183
+ #messages {
184
+ max-width: 1200px;
185
+ margin: 0 auto;
186
+ }
187
+
188
+ .message {
189
+ margin-bottom: 16px;
190
+ animation: fadeIn 0.2s ease-out;
191
+ }
192
+
193
+ @keyframes fadeIn {
194
+ from {
195
+ opacity: 0;
196
+ transform: translateY(4px);
197
+ }
198
+ to {
199
+ opacity: 1;
200
+ transform: translateY(0);
201
+ }
202
+ }
203
+
204
+ .message-header {
205
+ display: flex;
206
+ align-items: center;
207
+ gap: 8px;
208
+ margin-bottom: 4px;
209
+ font-size: 12px;
210
+ color: var(--text-secondary);
211
+ }
212
+
213
+ .message-header .label {
214
+ font-weight: 600;
215
+ font-family: var(--font-mono);
216
+ }
217
+
218
+ .message-header .label.user {
219
+ color: var(--accent);
220
+ }
221
+ .message-header .label.assistant {
222
+ color: var(--success);
223
+ }
224
+ .message-header .label.system {
225
+ color: var(--warning);
226
+ }
227
+ .message-header .label.error {
228
+ color: var(--error);
229
+ }
230
+
231
+ .message-body {
232
+ padding: 8px 12px;
233
+ border-radius: 8px;
234
+ font-family: var(--font-ui);
235
+ line-height: 1.1;
236
+ white-space: pre-wrap;
237
+ word-break: break-word;
238
+ }
239
+
240
+ .message-body.user {
241
+ background: var(--msg-user-bg);
242
+ border: 1px solid var(--border);
243
+ }
244
+
245
+ .message-body.assistant {
246
+ background: var(--msg-assistant-bg);
247
+ }
248
+
249
+ .message-body.system {
250
+ background: transparent;
251
+ color: var(--text-secondary);
252
+ font-style: italic;
253
+ }
254
+
255
+ .message-body.error {
256
+ color: var(--error);
257
+ background: rgba(255, 68, 102, 0.08);
258
+ border: 1px solid rgba(255, 68, 102, 0.2);
259
+ }
260
+
261
+ /* Streaming cursor */
262
+ .message-body.assistant.streaming::after {
263
+ content: "▋";
264
+ animation: blink 0.8s step-end infinite;
265
+ color: var(--success);
266
+ }
267
+
268
+ @keyframes blink {
269
+ 50% {
270
+ opacity: 0;
271
+ }
272
+ }
273
+
274
+ /* ── Markdown Content ────────────────────────────────────────── */
275
+ .message-body :first-child {
276
+ margin-top: 0;
277
+ }
278
+ .message-body :last-child {
279
+ margin-bottom: 0;
280
+ }
281
+
282
+ .message-body p {
283
+ margin: 0.25em 0;
284
+ }
285
+
286
+ .message-body ul,
287
+ .message-body ol {
288
+ margin: 0.15em 0;
289
+ padding-left: 1.5em;
290
+ }
291
+
292
+ .message-body li {
293
+ margin: 0;
294
+ line-height: 1.2;
295
+ }
296
+
297
+ /* Neutralize <p> inside <li> (marked wraps list items in <p> when there are blank lines) */
298
+ .message-body li > p {
299
+ margin: 0;
300
+ display: inline;
301
+ }
302
+
303
+ /* Neutralize ALL block-level children inside li (marked can nest multiple p, div, etc.) */
304
+ .message-body li > * {
305
+ margin-top: 0;
306
+ margin-bottom: 0;
307
+ }
308
+
309
+ /* Remove <br> spacing inside list items (from breaks:true option) */
310
+ .message-body li br {
311
+ display: none;
312
+ }
313
+
314
+ .message-body blockquote {
315
+ margin: 0.3em 0;
316
+ padding: 3px 10px;
317
+ border-left: 3px solid var(--accent-dim);
318
+ color: var(--text-secondary);
319
+ background: rgba(0, 170, 255, 0.04);
320
+ border-radius: 0 4px 4px 0;
321
+ }
322
+
323
+ .message-body pre {
324
+ margin: 0.35em 0;
325
+ padding: 8px 12px;
326
+ background: var(--input-bg);
327
+ border: 1px solid var(--border);
328
+ border-radius: 6px;
329
+ overflow-x: auto;
330
+ font-family: var(--font-mono);
331
+ font-size: 13px;
332
+ line-height: 1.2;
333
+ color: var(--text-primary);
334
+ }
335
+
336
+ .message-body code {
337
+ font-family: var(--font-mono);
338
+ font-size: 0.9em;
339
+ padding: 1px 4px;
340
+ background: rgba(255, 255, 255, 0.06);
341
+ border-radius: 3px;
342
+ color: var(--warning);
343
+ }
344
+
345
+ .message-body pre code {
346
+ padding: 0;
347
+ background: none;
348
+ color: inherit;
349
+ font-size: inherit;
350
+ }
351
+
352
+ .message-body table {
353
+ margin: 0.35em 0;
354
+ border-collapse: collapse;
355
+ width: 100%;
356
+ font-size: 13px;
357
+ }
358
+
359
+ .message-body th,
360
+ .message-body td {
361
+ padding: 4px 8px;
362
+ border: 1px solid var(--border);
363
+ text-align: left;
364
+ }
365
+
366
+ .message-body th {
367
+ background: var(--bg-secondary);
368
+ font-weight: 600;
369
+ color: var(--text-secondary);
370
+ }
371
+
372
+ .message-body hr {
373
+ margin: 0.5em 0;
374
+ border: none;
375
+ border-top: 1px solid var(--border);
376
+ }
377
+
378
+ .message-body h1,
379
+ .message-body h2,
380
+ .message-body h3,
381
+ .message-body h4,
382
+ .message-body h5,
383
+ .message-body h6 {
384
+ margin: 0.4em 0 0.2em;
385
+ color: var(--text-primary);
386
+ font-weight: 600;
387
+ line-height: 1.3;
388
+ }
389
+
390
+ .message-body h1 {
391
+ font-size: 1.2em;
392
+ }
393
+ .message-body h2 {
394
+ font-size: 1.15em;
395
+ }
396
+ .message-body h3 {
397
+ font-size: 1.05em;
398
+ }
399
+ .message-body h4 {
400
+ font-size: 1em;
401
+ }
402
+
403
+ .message-body a {
404
+ color: var(--accent);
405
+ text-decoration: none;
406
+ }
407
+
408
+ .message-body a:hover {
409
+ text-decoration: underline;
410
+ }
411
+
412
+ .message-body img {
413
+ max-width: 100%;
414
+ border-radius: 6px;
415
+ margin: 0.35em 0;
416
+ }
417
+
418
+ /* ── Tool Calls & Results ───────────────────────────────────── */
419
+ .tool-call,
420
+ .tool-result {
421
+ margin: 2px 0 2px 12px;
422
+ padding: 3px 8px;
423
+ border-left: 2px solid var(--border);
424
+ font-size: 13px;
425
+ font-family: var(--font-mono);
426
+ color: var(--text-secondary);
427
+ line-height: 1.5;
428
+ }
429
+
430
+ .tool-call .tool-name {
431
+ color: var(--accent-dim);
432
+ }
433
+ .tool-call .tool-name.tool-name-edit {
434
+ color: var(--warning);
435
+ }
436
+ .tool-call .tool-input {
437
+ color: var(--text-dim);
438
+ }
439
+ .tool-call .tool-input.tool-input-edit {
440
+ font-family: var(--font-mono);
441
+ font-size: 0.85em;
442
+ }
443
+
444
+ .tool-change-badge {
445
+ display: inline-block;
446
+ font-size: 10px;
447
+ font-weight: 700;
448
+ text-transform: uppercase;
449
+ padding: 0 5px;
450
+ border-radius: 3px;
451
+ margin-left: 4px;
452
+ letter-spacing: 0.3px;
453
+ vertical-align: middle;
454
+ line-height: 1.6;
455
+ }
456
+ .tool-change-edit {
457
+ color: var(--accent);
458
+ background: rgba(0, 170, 255, 0.12);
459
+ }
460
+ .tool-change-create {
461
+ color: var(--success);
462
+ background: rgba(68, 204, 136, 0.12);
463
+ }
464
+ .tool-call.completed {
465
+ opacity: 0.6;
466
+ }
467
+ .tool-call.completed .tool-name::before {
468
+ display: none;
469
+ }
470
+
471
+ .tool-result .tool-result-success {
472
+ color: var(--success);
473
+ }
474
+ .tool-result .tool-result-error {
475
+ color: var(--error);
476
+ }
477
+ .tool-result .tool-result-summary {
478
+ display: block;
479
+ color: var(--text-secondary);
480
+ font-size: 0.85em;
481
+ margin-top: 2px;
482
+ line-height: 1.3;
483
+ }
484
+
485
+ /* ── Edit Diff Display ─────────────────────────────────────────── */
486
+ .tool-result .tool-result-diff {
487
+ display: block;
488
+ margin-top: 2px;
489
+ }
490
+
491
+ .tool-result .tool-result-diff pre {
492
+ max-height: 300px;
493
+ max-width: 100%;
494
+ overflow-y: auto;
495
+ overflow-x: auto;
496
+ background: var(--input-bg);
497
+ border: 1px solid var(--border);
498
+ border-radius: 6px;
499
+ padding: 8px 12px;
500
+ margin: 4px 0;
501
+ font-size: 12px;
502
+ line-height: 1.4;
503
+ white-space: pre;
504
+ word-break: break-all;
505
+ }
506
+
507
+ .tool-result .tool-result-diff code {
508
+ font-family: var(--font-mono);
509
+ font-size: inherit;
510
+ color: inherit;
511
+ background: none;
512
+ padding: 0;
513
+ }
514
+
515
+ .tool-result .diff-added {
516
+ color: var(--success);
517
+ }
518
+
519
+ .tool-result .diff-removed {
520
+ color: var(--error);
521
+ }
522
+
523
+ /* ── Tool Error Display ──────────────────────────────────────────── */
524
+ .tool-result .tool-error-detail {
525
+ display: block;
526
+ margin-top: 4px;
527
+ padding: 6px 10px;
528
+ background: rgba(255, 68, 102, 0.06);
529
+ border: 1px solid rgba(255, 68, 102, 0.15);
530
+ border-radius: 4px;
531
+ font-size: 12px;
532
+ line-height: 1.4;
533
+ color: var(--text-secondary);
534
+ max-height: 120px;
535
+ overflow-y: auto;
536
+ word-break: break-all;
537
+ white-space: pre-wrap;
538
+ }
539
+
540
+ .tool-result .tool-error-files {
541
+ display: block;
542
+ margin-top: 2px;
543
+ font-size: 12px;
544
+ color: var(--error);
545
+ font-weight: 600;
546
+ }
547
+
548
+ /* ── Thinking Block ──────────────────────────────────────────── */
549
+ .thinking-block {
550
+ margin: 4px 0 4px 12px;
551
+ padding: 6px 10px;
552
+ border-left: 2px solid var(--warning);
553
+ background: rgba(255, 176, 48, 0.05);
554
+ border-radius: 4px;
555
+ font-size: 13px;
556
+ color: var(--text-dim);
557
+ font-family: var(--font-mono);
558
+ }
559
+
560
+ .thinking-block .thinking-label {
561
+ color: var(--warning);
562
+ font-size: 11px;
563
+ font-weight: 600;
564
+ text-transform: uppercase;
565
+ margin-bottom: 2px;
566
+ }
567
+
568
+ .thinking-block .thinking-content {
569
+ white-space: pre-wrap;
570
+ word-break: break-word;
571
+ line-height: 1.5;
572
+ }
573
+
574
+ /* Markdown styles for thinking content */
575
+ .thinking-content :first-child {
576
+ margin-top: 0;
577
+ }
578
+ .thinking-content :last-child {
579
+ margin-bottom: 0;
580
+ }
581
+ .thinking-content p {
582
+ margin: 0.2em 0;
583
+ }
584
+ .thinking-content ul,
585
+ .thinking-content ol {
586
+ margin: 0.15em 0;
587
+ padding-left: 1.5em;
588
+ }
589
+ .thinking-content li {
590
+ margin: 0;
591
+ line-height: 1.2;
592
+ }
593
+ .thinking-content li > p {
594
+ margin: 0;
595
+ display: inline;
596
+ }
597
+ .thinking-content li > * {
598
+ margin-top: 0;
599
+ margin-bottom: 0;
600
+ }
601
+ .thinking-content code {
602
+ font-family: var(--font-mono);
603
+ font-size: 0.9em;
604
+ padding: 1px 4px;
605
+ background: rgba(255, 255, 255, 0.08);
606
+ border-radius: 3px;
607
+ color: var(--warning);
608
+ }
609
+ .thinking-content pre {
610
+ margin: 0.4em 0;
611
+ padding: 8px 12px;
612
+ background: var(--input-bg);
613
+ border: 1px solid var(--border);
614
+ border-radius: 4px;
615
+ overflow-x: auto;
616
+ font-size: 12px;
617
+ line-height: 1.5;
618
+ }
619
+ .thinking-content pre code {
620
+ padding: 0;
621
+ background: none;
622
+ color: inherit;
623
+ font-size: inherit;
624
+ }
625
+
626
+ .thinking-block.thinking-done {
627
+ opacity: 0.7;
628
+ border-left-color: var(--text-dim);
629
+ }
630
+
631
+ .thinking-block.thinking-done .thinking-label {
632
+ color: var(--text-dim);
633
+ }
634
+
635
+ /* ── Token Stats ─────────────────────────────────────────────── */
636
+ .token-stats-bar {
637
+ margin: 8px 0 12px 12px;
638
+ padding: 4px 8px;
639
+ font-size: 12px;
640
+ color: var(--text-dim);
641
+ font-family: var(--font-mono);
642
+ border-left: 2px solid var(--border);
643
+ }
644
+
645
+ /* ── System Messages ─────────────────────────────────────────── */
646
+ .system-message {
647
+ text-align: center;
648
+ color: var(--text-dim);
649
+ font-size: 13px;
650
+ margin: 8px 0;
651
+ padding: 4px 8px;
652
+ }
653
+
654
+ /* ── Input Area ──────────────────────────────────────────────── */
655
+ #input-area {
656
+ flex-shrink: 0;
657
+ border-top: 1px solid var(--border);
658
+ background: var(--bg-secondary);
659
+ padding: 8px 16px;
660
+ }
661
+
662
+ .input-wrapper {
663
+ display: flex;
664
+ gap: 8px;
665
+ max-width: 800px;
666
+ margin: 0 auto;
667
+ align-items: flex-end;
668
+ }
669
+
670
+ .input-container {
671
+ flex: 1;
672
+ position: relative;
673
+ }
674
+
675
+ /* ── Slash Command Hint ─────────────────────────────────────── */
676
+ .slash-hint {
677
+ position: absolute;
678
+ bottom: 100%;
679
+ left: 0;
680
+ right: 0;
681
+ margin-bottom: 4px;
682
+ background: var(--bg-tertiary);
683
+ border: 1px solid var(--border);
684
+ border-radius: 8px;
685
+ padding: 6px 0;
686
+ font-size: 13px;
687
+ z-index: 100;
688
+ box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.3);
689
+ }
690
+
691
+ .slash-hint-header {
692
+ padding: 4px 12px 6px;
693
+ font-size: 11px;
694
+ font-weight: 600;
695
+ text-transform: uppercase;
696
+ color: var(--text-dim);
697
+ letter-spacing: 0.5px;
698
+ }
699
+
700
+ .slash-hint-item {
701
+ padding: 6px 12px;
702
+ cursor: pointer;
703
+ color: var(--text-primary);
704
+ font-family: var(--font-mono);
705
+ font-size: 13px;
706
+ transition: background 0.15s;
707
+ }
708
+
709
+ .slash-hint-item:hover,
710
+ .slash-hint-item.selected {
711
+ background: rgba(0, 170, 255, 0.12);
712
+ }
713
+
714
+ .slash-hint-item .hint-arg {
715
+ color: var(--warning);
716
+ }
717
+
718
+ .slash-hint-item .hint-desc {
719
+ color: var(--text-dim);
720
+ font-family: var(--font-ui);
721
+ font-size: 12px;
722
+ margin-left: 6px;
723
+ }
724
+
725
+ #chat-input {
726
+ flex: 1;
727
+ background: var(--input-bg);
728
+ border: 1px solid var(--border);
729
+ border-radius: 8px;
730
+ color: var(--text-primary);
731
+ font-family: var(--font-mono);
732
+ font-size: 14px;
733
+ padding: 10px 14px;
734
+ resize: none;
735
+ outline: none;
736
+ line-height: 1.5;
737
+ transition: border-color 0.2s;
738
+ width: 100%;
739
+ }
740
+
741
+ #chat-input:focus {
742
+ border-color: var(--accent);
743
+ }
744
+
745
+ #chat-input::placeholder {
746
+ color: var(--text-dim);
747
+ }
748
+
749
+ #send-btn {
750
+ background: var(--accent);
751
+ border: none;
752
+ border-radius: 8px;
753
+ width: 40px;
754
+ height: 40px;
755
+ display: flex;
756
+ align-items: center;
757
+ justify-content: center;
758
+ cursor: pointer;
759
+ color: white;
760
+ transition:
761
+ background 0.2s,
762
+ opacity 0.2s;
763
+ flex-shrink: 0;
764
+ }
765
+
766
+ #send-btn:hover {
767
+ background: var(--accent-dim);
768
+ }
769
+ #send-btn:disabled {
770
+ opacity: 0.4;
771
+ cursor: not-allowed;
772
+ }
773
+
774
+ /* ── Stop Button ────────────────────────────────────────────── */
775
+ #stop-btn {
776
+ background: var(--error);
777
+ border: none;
778
+ border-radius: 8px;
779
+ width: 40px;
780
+ height: 40px;
781
+ display: flex;
782
+ align-items: center;
783
+ justify-content: center;
784
+ cursor: pointer;
785
+ color: white;
786
+ transition:
787
+ background 0.2s,
788
+ opacity 0.2s;
789
+ flex-shrink: 0;
790
+ }
791
+
792
+ #stop-btn:hover {
793
+ background: #cc2244;
794
+ }
795
+ #stop-btn:disabled {
796
+ opacity: 0.4;
797
+ cursor: not-allowed;
798
+ }
799
+
800
+ /* ── Tool Running State ──────────────────────────────────────── */
801
+ .tool-call.executing .tool-name {
802
+ color: var(--warning);
803
+ }
804
+ .tool-call.executing .tool-name::before {
805
+ content: "";
806
+ display: inline-block;
807
+ width: 12px;
808
+ height: 12px;
809
+ margin-right: 4px;
810
+ border: 2px solid var(--warning);
811
+ border-top-color: transparent;
812
+ border-radius: 50%;
813
+ animation: spin 0.6s linear infinite;
814
+ vertical-align: middle;
815
+ }
816
+
817
+ /* ── Confirm Dialog ──────────────────────────────────────────── */
818
+ .confirm-dialog {
819
+ background: var(--bg-secondary);
820
+ border: 1px solid var(--border);
821
+ border-radius: 12px;
822
+ padding: 20px;
823
+ min-width: 360px;
824
+ max-width: 480px;
825
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
826
+ }
827
+
828
+ .confirm-header {
829
+ font-size: 15px;
830
+ font-weight: 600;
831
+ color: var(--text-primary);
832
+ margin-bottom: 12px;
833
+ }
834
+
835
+ .confirm-tool-list {
836
+ margin-bottom: 16px;
837
+ }
838
+
839
+ .confirm-tool-item {
840
+ padding: 6px 10px;
841
+ margin-bottom: 4px;
842
+ background: rgba(255, 255, 255, 0.03);
843
+ border-radius: 6px;
844
+ font-family: var(--font-mono);
845
+ font-size: 13px;
846
+ color: var(--text-secondary);
847
+ line-height: 1.4;
848
+ }
849
+
850
+ .confirm-tool-item .confirm-tool-name {
851
+ color: var(--accent-dim);
852
+ font-weight: 600;
853
+ }
854
+
855
+ .confirm-tool-item .confirm-tool-input {
856
+ color: var(--text-dim);
857
+ word-break: break-all;
858
+ }
859
+
860
+ .confirm-actions {
861
+ display: flex;
862
+ gap: 8px;
863
+ justify-content: flex-end;
864
+ }
865
+
866
+ .confirm-btn {
867
+ padding: 8px 20px;
868
+ border: none;
869
+ border-radius: 6px;
870
+ font-family: var(--font-ui);
871
+ font-size: 14px;
872
+ font-weight: 600;
873
+ cursor: pointer;
874
+ transition:
875
+ background 0.15s,
876
+ opacity 0.15s;
877
+ }
878
+
879
+ .confirm-btn-allow {
880
+ background: var(--success);
881
+ color: white;
882
+ }
883
+
884
+ .confirm-btn-allow:hover {
885
+ opacity: 0.85;
886
+ }
887
+
888
+ .confirm-btn-reject {
889
+ background: transparent;
890
+ color: var(--text-secondary);
891
+ border: 1px solid var(--border);
892
+ }
893
+
894
+ .confirm-btn-reject:hover {
895
+ background: rgba(255, 255, 255, 0.06);
896
+ color: var(--text-primary);
897
+ }
898
+
899
+ /* ── Connection Overlay ──────────────────────────────────────── */
900
+ .overlay {
901
+ position: fixed;
902
+ inset: 0;
903
+ background: rgba(0, 0, 0, 0.6);
904
+ display: flex;
905
+ align-items: center;
906
+ justify-content: center;
907
+ z-index: 1000;
908
+ }
909
+
910
+ .overlay.hidden {
911
+ display: none;
912
+ }
913
+
914
+ .overlay-content {
915
+ text-align: center;
916
+ color: var(--text-primary);
917
+ }
918
+
919
+ .overlay-content p {
920
+ margin-top: 16px;
921
+ color: var(--text-secondary);
922
+ }
923
+
924
+ .spinner {
925
+ width: 40px;
926
+ height: 40px;
927
+ margin: 0 auto;
928
+ border: 3px solid var(--border);
929
+ border-top-color: var(--accent);
930
+ border-radius: 50%;
931
+ animation: spin 0.8s linear infinite;
932
+ }
933
+
934
+ @keyframes spin {
935
+ to {
936
+ transform: rotate(360deg);
937
+ }
938
+ }
939
+
940
+ /* ── Scrollbar for chat ──────────────────────────────────────── */
941
+ #chat-container::-webkit-scrollbar {
942
+ width: 8px;
943
+ }
944
+ #chat-container::-webkit-scrollbar-track {
945
+ background: transparent;
946
+ }
947
+ #chat-container::-webkit-scrollbar-thumb {
948
+ background: var(--text-dim);
949
+ border-radius: 4px;
950
+ }
951
+ #chat-container::-webkit-scrollbar-thumb:hover {
952
+ background: var(--text-secondary);
953
+ }
954
+
955
+ /* ── Right Sidebar ────────────────────────────────────────────── */
956
+ #sidebar {
957
+ width: 280px;
958
+ flex-shrink: 0;
959
+ background: var(--bg-secondary);
960
+ border-left: 1px solid var(--border);
961
+ display: flex;
962
+ flex-direction: column;
963
+ overflow: hidden;
964
+ }
965
+
966
+ .sidebar-tabs {
967
+ display: flex;
968
+ border-bottom: 1px solid var(--border);
969
+ flex-shrink: 0;
970
+ }
971
+
972
+ .sidebar-tab {
973
+ flex: 1;
974
+ padding: 8px 4px;
975
+ background: transparent;
976
+ border: none;
977
+ color: var(--text-dim);
978
+ font-family: var(--font-ui);
979
+ font-size: 12px;
980
+ font-weight: 600;
981
+ cursor: pointer;
982
+ transition:
983
+ color 0.15s,
984
+ background 0.15s;
985
+ text-transform: uppercase;
986
+ letter-spacing: 0.5px;
987
+ }
988
+
989
+ .sidebar-tab:hover {
990
+ color: var(--text-secondary);
991
+ background: rgba(255, 255, 255, 0.03);
992
+ }
993
+
994
+ .sidebar-tab.active {
995
+ color: var(--accent);
996
+ background: rgba(0, 170, 255, 0.06);
997
+ border-bottom: 2px solid var(--accent);
998
+ }
999
+
1000
+ .sidebar-content {
1001
+ flex: 1;
1002
+ overflow-y: auto;
1003
+ min-height: 0;
1004
+ }
1005
+
1006
+ .sidebar-content::-webkit-scrollbar {
1007
+ width: 6px;
1008
+ }
1009
+ .sidebar-content::-webkit-scrollbar-track {
1010
+ background: transparent;
1011
+ }
1012
+ .sidebar-content::-webkit-scrollbar-thumb {
1013
+ background: var(--text-dim);
1014
+ border-radius: 3px;
1015
+ }
1016
+ .sidebar-content::-webkit-scrollbar-thumb:hover {
1017
+ background: var(--text-secondary);
1018
+ }
1019
+
1020
+ .sidebar-pane {
1021
+ display: none;
1022
+ padding: 8px;
1023
+ }
1024
+
1025
+ .sidebar-pane.active {
1026
+ display: block;
1027
+ }
1028
+
1029
+ .sidebar-placeholder {
1030
+ color: var(--text-dim);
1031
+ font-size: 13px;
1032
+ text-align: center;
1033
+ padding: 20px 8px;
1034
+ font-style: italic;
1035
+ }
1036
+
1037
+ /* ── Plan List Items ─────────────────────────────────────────── */
1038
+ .plan-item {
1039
+ padding: 8px 10px;
1040
+ margin-bottom: 4px;
1041
+ border-radius: 6px;
1042
+ cursor: pointer;
1043
+ transition: background 0.15s;
1044
+ border: 1px solid transparent;
1045
+ }
1046
+
1047
+ .plan-item:hover {
1048
+ background: rgba(0, 170, 255, 0.06);
1049
+ border-color: var(--border);
1050
+ }
1051
+
1052
+ .plan-item.active {
1053
+ background: rgba(0, 170, 255, 0.1);
1054
+ border-color: var(--accent-dim);
1055
+ }
1056
+
1057
+ .plan-item .plan-name {
1058
+ color: var(--text-primary);
1059
+ font-size: 13px;
1060
+ font-weight: 600;
1061
+ font-family: var(--font-mono);
1062
+ word-break: break-all;
1063
+ }
1064
+
1065
+ .plan-item .plan-time {
1066
+ color: var(--text-dim);
1067
+ font-size: 11px;
1068
+ margin-top: 2px;
1069
+ }
1070
+
1071
+ /* ── Todo Items ──────────────────────────────────────────────── */
1072
+ .todo-item {
1073
+ display: flex;
1074
+ align-items: flex-start;
1075
+ gap: 6px;
1076
+ padding: 5px 8px;
1077
+ margin-bottom: 2px;
1078
+ border-radius: 4px;
1079
+ font-size: 13px;
1080
+ line-height: 1.4;
1081
+ transition: background 0.15s;
1082
+ }
1083
+
1084
+ .todo-item:hover {
1085
+ background: rgba(255, 255, 255, 0.03);
1086
+ }
1087
+
1088
+ .todo-item .todo-check {
1089
+ flex-shrink: 0;
1090
+ margin-top: 1px;
1091
+ font-size: 14px;
1092
+ }
1093
+
1094
+ .todo-item .todo-check.done {
1095
+ color: var(--success);
1096
+ }
1097
+
1098
+ .todo-item .todo-check.pending {
1099
+ color: var(--text-dim);
1100
+ }
1101
+
1102
+ .todo-item .todo-text {
1103
+ color: var(--text-primary);
1104
+ word-break: break-word;
1105
+ }
1106
+
1107
+ .todo-item .todo-text.done {
1108
+ color: var(--text-dim);
1109
+ text-decoration: line-through;
1110
+ }
1111
+
1112
+ .todo-header-text {
1113
+ color: var(--text-secondary);
1114
+ font-size: 11px;
1115
+ font-weight: 600;
1116
+ padding: 4px 8px 6px;
1117
+ text-transform: uppercase;
1118
+ letter-spacing: 0.5px;
1119
+ border-bottom: 1px solid var(--border);
1120
+ margin-bottom: 4px;
1121
+ }
1122
+
1123
+ /* ── Utility ─────────────────────────────────────────────────── */
1124
+ .hidden {
1125
+ display: none !important;
1126
+ }