zerg-ztc 0.1.0

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 (411) hide show
  1. package/README.md +361 -0
  2. package/dist/App.d.ts +4 -0
  3. package/dist/App.d.ts.map +1 -0
  4. package/dist/App.js +499 -0
  5. package/dist/App.js.map +1 -0
  6. package/dist/agent/agent.d.ts +54 -0
  7. package/dist/agent/agent.d.ts.map +1 -0
  8. package/dist/agent/agent.js +347 -0
  9. package/dist/agent/agent.js.map +1 -0
  10. package/dist/agent/backends/anthropic.d.ts +13 -0
  11. package/dist/agent/backends/anthropic.d.ts.map +1 -0
  12. package/dist/agent/backends/anthropic.js +54 -0
  13. package/dist/agent/backends/anthropic.js.map +1 -0
  14. package/dist/agent/backends/gemini.d.ts +13 -0
  15. package/dist/agent/backends/gemini.d.ts.map +1 -0
  16. package/dist/agent/backends/gemini.js +71 -0
  17. package/dist/agent/backends/gemini.js.map +1 -0
  18. package/dist/agent/backends/inception.d.ts +12 -0
  19. package/dist/agent/backends/inception.d.ts.map +1 -0
  20. package/dist/agent/backends/inception.js +15 -0
  21. package/dist/agent/backends/inception.js.map +1 -0
  22. package/dist/agent/backends/index.d.ts +7 -0
  23. package/dist/agent/backends/index.d.ts.map +1 -0
  24. package/dist/agent/backends/index.js +6 -0
  25. package/dist/agent/backends/index.js.map +1 -0
  26. package/dist/agent/backends/openai.d.ts +12 -0
  27. package/dist/agent/backends/openai.d.ts.map +1 -0
  28. package/dist/agent/backends/openai.js +15 -0
  29. package/dist/agent/backends/openai.js.map +1 -0
  30. package/dist/agent/backends/openai_compatible.d.ts +17 -0
  31. package/dist/agent/backends/openai_compatible.d.ts.map +1 -0
  32. package/dist/agent/backends/openai_compatible.js +95 -0
  33. package/dist/agent/backends/openai_compatible.js.map +1 -0
  34. package/dist/agent/backends/types.d.ts +49 -0
  35. package/dist/agent/backends/types.d.ts.map +1 -0
  36. package/dist/agent/backends/types.js +2 -0
  37. package/dist/agent/backends/types.js.map +1 -0
  38. package/dist/agent/commands/clipboard.d.ts +3 -0
  39. package/dist/agent/commands/clipboard.d.ts.map +1 -0
  40. package/dist/agent/commands/clipboard.js +72 -0
  41. package/dist/agent/commands/clipboard.js.map +1 -0
  42. package/dist/agent/commands/config.d.ts +3 -0
  43. package/dist/agent/commands/config.d.ts.map +1 -0
  44. package/dist/agent/commands/config.js +120 -0
  45. package/dist/agent/commands/config.js.map +1 -0
  46. package/dist/agent/commands/debug.d.ts +3 -0
  47. package/dist/agent/commands/debug.d.ts.map +1 -0
  48. package/dist/agent/commands/debug.js +23 -0
  49. package/dist/agent/commands/debug.js.map +1 -0
  50. package/dist/agent/commands/emulation.d.ts +3 -0
  51. package/dist/agent/commands/emulation.d.ts.map +1 -0
  52. package/dist/agent/commands/emulation.js +78 -0
  53. package/dist/agent/commands/emulation.js.map +1 -0
  54. package/dist/agent/commands/execution.d.ts +3 -0
  55. package/dist/agent/commands/execution.d.ts.map +1 -0
  56. package/dist/agent/commands/execution.js +8 -0
  57. package/dist/agent/commands/execution.js.map +1 -0
  58. package/dist/agent/commands/help.d.ts +3 -0
  59. package/dist/agent/commands/help.d.ts.map +1 -0
  60. package/dist/agent/commands/help.js +19 -0
  61. package/dist/agent/commands/help.js.map +1 -0
  62. package/dist/agent/commands/history.d.ts +3 -0
  63. package/dist/agent/commands/history.d.ts.map +1 -0
  64. package/dist/agent/commands/history.js +12 -0
  65. package/dist/agent/commands/history.js.map +1 -0
  66. package/dist/agent/commands/index.d.ts +4 -0
  67. package/dist/agent/commands/index.d.ts.map +1 -0
  68. package/dist/agent/commands/index.js +19 -0
  69. package/dist/agent/commands/index.js.map +1 -0
  70. package/dist/agent/commands/model.d.ts +3 -0
  71. package/dist/agent/commands/model.d.ts.map +1 -0
  72. package/dist/agent/commands/model.js +10 -0
  73. package/dist/agent/commands/model.js.map +1 -0
  74. package/dist/agent/commands/models.d.ts +3 -0
  75. package/dist/agent/commands/models.d.ts.map +1 -0
  76. package/dist/agent/commands/models.js +110 -0
  77. package/dist/agent/commands/models.js.map +1 -0
  78. package/dist/agent/commands/permissions.d.ts +3 -0
  79. package/dist/agent/commands/permissions.d.ts.map +1 -0
  80. package/dist/agent/commands/permissions.js +58 -0
  81. package/dist/agent/commands/permissions.js.map +1 -0
  82. package/dist/agent/commands/retry.d.ts +3 -0
  83. package/dist/agent/commands/retry.d.ts.map +1 -0
  84. package/dist/agent/commands/retry.js +8 -0
  85. package/dist/agent/commands/retry.js.map +1 -0
  86. package/dist/agent/commands/shell.d.ts +4 -0
  87. package/dist/agent/commands/shell.d.ts.map +1 -0
  88. package/dist/agent/commands/shell.js +66 -0
  89. package/dist/agent/commands/shell.js.map +1 -0
  90. package/dist/agent/commands/skills.d.ts +3 -0
  91. package/dist/agent/commands/skills.d.ts.map +1 -0
  92. package/dist/agent/commands/skills.js +50 -0
  93. package/dist/agent/commands/skills.js.map +1 -0
  94. package/dist/agent/commands/status.d.ts +3 -0
  95. package/dist/agent/commands/status.d.ts.map +1 -0
  96. package/dist/agent/commands/status.js +18 -0
  97. package/dist/agent/commands/status.js.map +1 -0
  98. package/dist/agent/commands/types.d.ts +70 -0
  99. package/dist/agent/commands/types.d.ts.map +1 -0
  100. package/dist/agent/commands/types.js +2 -0
  101. package/dist/agent/commands/types.js.map +1 -0
  102. package/dist/agent/factory.d.ts +13 -0
  103. package/dist/agent/factory.d.ts.map +1 -0
  104. package/dist/agent/factory.js +46 -0
  105. package/dist/agent/factory.js.map +1 -0
  106. package/dist/agent/index.d.ts +14 -0
  107. package/dist/agent/index.d.ts.map +1 -0
  108. package/dist/agent/index.js +10 -0
  109. package/dist/agent/index.js.map +1 -0
  110. package/dist/agent/runtime/capabilities.d.ts +7 -0
  111. package/dist/agent/runtime/capabilities.d.ts.map +1 -0
  112. package/dist/agent/runtime/capabilities.js +8 -0
  113. package/dist/agent/runtime/capabilities.js.map +1 -0
  114. package/dist/agent/runtime/memory.d.ts +13 -0
  115. package/dist/agent/runtime/memory.d.ts.map +1 -0
  116. package/dist/agent/runtime/memory.js +13 -0
  117. package/dist/agent/runtime/memory.js.map +1 -0
  118. package/dist/agent/runtime/policy.d.ts +22 -0
  119. package/dist/agent/runtime/policy.d.ts.map +1 -0
  120. package/dist/agent/runtime/policy.js +29 -0
  121. package/dist/agent/runtime/policy.js.map +1 -0
  122. package/dist/agent/runtime/session.d.ts +11 -0
  123. package/dist/agent/runtime/session.d.ts.map +1 -0
  124. package/dist/agent/runtime/session.js +10 -0
  125. package/dist/agent/runtime/session.js.map +1 -0
  126. package/dist/agent/runtime/tracing.d.ts +13 -0
  127. package/dist/agent/runtime/tracing.d.ts.map +1 -0
  128. package/dist/agent/runtime/tracing.js +6 -0
  129. package/dist/agent/runtime/tracing.js.map +1 -0
  130. package/dist/agent/tools/file.d.ts +5 -0
  131. package/dist/agent/tools/file.d.ts.map +1 -0
  132. package/dist/agent/tools/file.js +162 -0
  133. package/dist/agent/tools/file.js.map +1 -0
  134. package/dist/agent/tools/index.d.ts +13 -0
  135. package/dist/agent/tools/index.d.ts.map +1 -0
  136. package/dist/agent/tools/index.js +34 -0
  137. package/dist/agent/tools/index.js.map +1 -0
  138. package/dist/agent/tools/search.d.ts +3 -0
  139. package/dist/agent/tools/search.d.ts.map +1 -0
  140. package/dist/agent/tools/search.js +124 -0
  141. package/dist/agent/tools/search.js.map +1 -0
  142. package/dist/agent/tools/shell.d.ts +3 -0
  143. package/dist/agent/tools/shell.d.ts.map +1 -0
  144. package/dist/agent/tools/shell.js +60 -0
  145. package/dist/agent/tools/shell.js.map +1 -0
  146. package/dist/agent/tools/skills.d.ts +3 -0
  147. package/dist/agent/tools/skills.d.ts.map +1 -0
  148. package/dist/agent/tools/skills.js +27 -0
  149. package/dist/agent/tools/skills.js.map +1 -0
  150. package/dist/agent/tools/types.d.ts +8 -0
  151. package/dist/agent/tools/types.d.ts.map +1 -0
  152. package/dist/agent/tools/types.js +2 -0
  153. package/dist/agent/tools/types.js.map +1 -0
  154. package/dist/agent/tools/zerg.d.ts +3 -0
  155. package/dist/agent/tools/zerg.d.ts.map +1 -0
  156. package/dist/agent/tools/zerg.js +47 -0
  157. package/dist/agent/tools/zerg.js.map +1 -0
  158. package/dist/cli.d.ts +3 -0
  159. package/dist/cli.d.ts.map +1 -0
  160. package/dist/cli.js +75 -0
  161. package/dist/cli.js.map +1 -0
  162. package/dist/components/FullScreen.d.ts +28 -0
  163. package/dist/components/FullScreen.d.ts.map +1 -0
  164. package/dist/components/FullScreen.js +40 -0
  165. package/dist/components/FullScreen.js.map +1 -0
  166. package/dist/components/Header.d.ts +10 -0
  167. package/dist/components/Header.d.ts.map +1 -0
  168. package/dist/components/Header.js +14 -0
  169. package/dist/components/Header.js.map +1 -0
  170. package/dist/components/InputArea.d.ts +24 -0
  171. package/dist/components/InputArea.d.ts.map +1 -0
  172. package/dist/components/InputArea.js +476 -0
  173. package/dist/components/InputArea.js.map +1 -0
  174. package/dist/components/MessageList.d.ts +12 -0
  175. package/dist/components/MessageList.d.ts.map +1 -0
  176. package/dist/components/MessageList.js +9 -0
  177. package/dist/components/MessageList.js.map +1 -0
  178. package/dist/components/StatusBar.d.ts +18 -0
  179. package/dist/components/StatusBar.d.ts.map +1 -0
  180. package/dist/components/StatusBar.js +21 -0
  181. package/dist/components/StatusBar.js.map +1 -0
  182. package/dist/components/index.d.ts +6 -0
  183. package/dist/components/index.d.ts.map +1 -0
  184. package/dist/components/index.js +7 -0
  185. package/dist/components/index.js.map +1 -0
  186. package/dist/config/types.d.ts +12 -0
  187. package/dist/config/types.d.ts.map +1 -0
  188. package/dist/config/types.js +2 -0
  189. package/dist/config/types.js.map +1 -0
  190. package/dist/config.d.ts +28 -0
  191. package/dist/config.d.ts.map +1 -0
  192. package/dist/config.js +155 -0
  193. package/dist/config.js.map +1 -0
  194. package/dist/debug/logger.d.ts +2 -0
  195. package/dist/debug/logger.d.ts.map +1 -0
  196. package/dist/debug/logger.js +15 -0
  197. package/dist/debug/logger.js.map +1 -0
  198. package/dist/emulation/catalog.d.ts +4 -0
  199. package/dist/emulation/catalog.d.ts.map +1 -0
  200. package/dist/emulation/catalog.js +68 -0
  201. package/dist/emulation/catalog.js.map +1 -0
  202. package/dist/emulation/trace_style.d.ts +3 -0
  203. package/dist/emulation/trace_style.d.ts.map +1 -0
  204. package/dist/emulation/trace_style.js +10 -0
  205. package/dist/emulation/trace_style.js.map +1 -0
  206. package/dist/emulation/types.d.ts +8 -0
  207. package/dist/emulation/types.d.ts.map +1 -0
  208. package/dist/emulation/types.js +2 -0
  209. package/dist/emulation/types.js.map +1 -0
  210. package/dist/skills/index.d.ts +5 -0
  211. package/dist/skills/index.d.ts.map +1 -0
  212. package/dist/skills/index.js +36 -0
  213. package/dist/skills/index.js.map +1 -0
  214. package/dist/skills/loader.d.ts +3 -0
  215. package/dist/skills/loader.d.ts.map +1 -0
  216. package/dist/skills/loader.js +137 -0
  217. package/dist/skills/loader.js.map +1 -0
  218. package/dist/skills/registry.d.ts +3 -0
  219. package/dist/skills/registry.d.ts.map +1 -0
  220. package/dist/skills/registry.js +5 -0
  221. package/dist/skills/registry.js.map +1 -0
  222. package/dist/skills/types.d.ts +11 -0
  223. package/dist/skills/types.d.ts.map +1 -0
  224. package/dist/skills/types.js +2 -0
  225. package/dist/skills/types.js.map +1 -0
  226. package/dist/types.d.ts +93 -0
  227. package/dist/types.d.ts.map +1 -0
  228. package/dist/types.js +5 -0
  229. package/dist/types.js.map +1 -0
  230. package/dist/ui/core/factory.d.ts +4 -0
  231. package/dist/ui/core/factory.d.ts.map +1 -0
  232. package/dist/ui/core/factory.js +7 -0
  233. package/dist/ui/core/factory.js.map +1 -0
  234. package/dist/ui/core/index.d.ts +5 -0
  235. package/dist/ui/core/index.d.ts.map +1 -0
  236. package/dist/ui/core/index.js +4 -0
  237. package/dist/ui/core/index.js.map +1 -0
  238. package/dist/ui/core/input.d.ts +22 -0
  239. package/dist/ui/core/input.d.ts.map +1 -0
  240. package/dist/ui/core/input.js +15 -0
  241. package/dist/ui/core/input.js.map +1 -0
  242. package/dist/ui/core/input_segments.d.ts +19 -0
  243. package/dist/ui/core/input_segments.d.ts.map +1 -0
  244. package/dist/ui/core/input_segments.js +367 -0
  245. package/dist/ui/core/input_segments.js.map +1 -0
  246. package/dist/ui/core/input_state.d.ts +24 -0
  247. package/dist/ui/core/input_state.d.ts.map +1 -0
  248. package/dist/ui/core/input_state.js +2 -0
  249. package/dist/ui/core/input_state.js.map +1 -0
  250. package/dist/ui/core/layout_yoga.d.ts +11 -0
  251. package/dist/ui/core/layout_yoga.d.ts.map +1 -0
  252. package/dist/ui/core/layout_yoga.js +102 -0
  253. package/dist/ui/core/layout_yoga.js.map +1 -0
  254. package/dist/ui/core/style.d.ts +3 -0
  255. package/dist/ui/core/style.d.ts.map +1 -0
  256. package/dist/ui/core/style.js +37 -0
  257. package/dist/ui/core/style.js.map +1 -0
  258. package/dist/ui/core/types.d.ts +50 -0
  259. package/dist/ui/core/types.d.ts.map +1 -0
  260. package/dist/ui/core/types.js +2 -0
  261. package/dist/ui/core/types.js.map +1 -0
  262. package/dist/ui/ink/index.d.ts +2 -0
  263. package/dist/ui/ink/index.d.ts.map +1 -0
  264. package/dist/ui/ink/index.js +2 -0
  265. package/dist/ui/ink/index.js.map +1 -0
  266. package/dist/ui/ink/render.d.ts +6 -0
  267. package/dist/ui/ink/render.d.ts.map +1 -0
  268. package/dist/ui/ink/render.js +14 -0
  269. package/dist/ui/ink/render.js.map +1 -0
  270. package/dist/ui/views/app.d.ts +28 -0
  271. package/dist/ui/views/app.d.ts.map +1 -0
  272. package/dist/ui/views/app.js +59 -0
  273. package/dist/ui/views/app.js.map +1 -0
  274. package/dist/ui/views/header.d.ts +11 -0
  275. package/dist/ui/views/header.d.ts.map +1 -0
  276. package/dist/ui/views/header.js +28 -0
  277. package/dist/ui/views/header.js.map +1 -0
  278. package/dist/ui/views/input_area.d.ts +45 -0
  279. package/dist/ui/views/input_area.d.ts.map +1 -0
  280. package/dist/ui/views/input_area.js +183 -0
  281. package/dist/ui/views/input_area.js.map +1 -0
  282. package/dist/ui/views/message_list.d.ts +12 -0
  283. package/dist/ui/views/message_list.d.ts.map +1 -0
  284. package/dist/ui/views/message_list.js +381 -0
  285. package/dist/ui/views/message_list.js.map +1 -0
  286. package/dist/ui/views/status_bar.d.ts +18 -0
  287. package/dist/ui/views/status_bar.d.ts.map +1 -0
  288. package/dist/ui/views/status_bar.js +72 -0
  289. package/dist/ui/views/status_bar.js.map +1 -0
  290. package/dist/ui/vue/index.d.ts +5 -0
  291. package/dist/ui/vue/index.d.ts.map +1 -0
  292. package/dist/ui/vue/index.js +50 -0
  293. package/dist/ui/vue/index.js.map +1 -0
  294. package/dist/utils/clipboard.d.ts +2 -0
  295. package/dist/utils/clipboard.d.ts.map +1 -0
  296. package/dist/utils/clipboard.js +39 -0
  297. package/dist/utils/clipboard.js.map +1 -0
  298. package/dist/utils/clipboard_image.d.ts +2 -0
  299. package/dist/utils/clipboard_image.d.ts.map +1 -0
  300. package/dist/utils/clipboard_image.js +37 -0
  301. package/dist/utils/clipboard_image.js.map +1 -0
  302. package/dist/utils/diff.d.ts +2 -0
  303. package/dist/utils/diff.d.ts.map +1 -0
  304. package/dist/utils/diff.js +49 -0
  305. package/dist/utils/diff.js.map +1 -0
  306. package/dist/utils/image_preview.d.ts +2 -0
  307. package/dist/utils/image_preview.d.ts.map +1 -0
  308. package/dist/utils/image_preview.js +37 -0
  309. package/dist/utils/image_preview.js.map +1 -0
  310. package/dist/utils/models.d.ts +8 -0
  311. package/dist/utils/models.d.ts.map +1 -0
  312. package/dist/utils/models.js +85 -0
  313. package/dist/utils/models.js.map +1 -0
  314. package/dist/utils/shell.d.ts +4 -0
  315. package/dist/utils/shell.d.ts.map +1 -0
  316. package/dist/utils/shell.js +57 -0
  317. package/dist/utils/shell.js.map +1 -0
  318. package/dist/utils/tool_summary.d.ts +3 -0
  319. package/dist/utils/tool_summary.d.ts.map +1 -0
  320. package/dist/utils/tool_summary.js +54 -0
  321. package/dist/utils/tool_summary.js.map +1 -0
  322. package/dist/utils/tool_trace.d.ts +9 -0
  323. package/dist/utils/tool_trace.d.ts.map +1 -0
  324. package/dist/utils/tool_trace.js +183 -0
  325. package/dist/utils/tool_trace.js.map +1 -0
  326. package/package.json +41 -0
  327. package/src/App.tsx +576 -0
  328. package/src/agent/agent.ts +407 -0
  329. package/src/agent/backends/anthropic.ts +76 -0
  330. package/src/agent/backends/gemini.ts +107 -0
  331. package/src/agent/backends/inception.ts +23 -0
  332. package/src/agent/backends/index.ts +16 -0
  333. package/src/agent/backends/openai.ts +23 -0
  334. package/src/agent/backends/openai_compatible.ts +131 -0
  335. package/src/agent/backends/types.ts +59 -0
  336. package/src/agent/commands/clipboard.ts +77 -0
  337. package/src/agent/commands/config.ts +130 -0
  338. package/src/agent/commands/debug.ts +23 -0
  339. package/src/agent/commands/emulation.ts +80 -0
  340. package/src/agent/commands/execution.ts +9 -0
  341. package/src/agent/commands/help.ts +20 -0
  342. package/src/agent/commands/history.ts +13 -0
  343. package/src/agent/commands/index.ts +40 -0
  344. package/src/agent/commands/model.ts +11 -0
  345. package/src/agent/commands/models.ts +116 -0
  346. package/src/agent/commands/permissions.ts +64 -0
  347. package/src/agent/commands/retry.ts +9 -0
  348. package/src/agent/commands/shell.ts +68 -0
  349. package/src/agent/commands/skills.ts +54 -0
  350. package/src/agent/commands/status.ts +19 -0
  351. package/src/agent/commands/types.ts +78 -0
  352. package/src/agent/factory.ts +60 -0
  353. package/src/agent/index.ts +20 -0
  354. package/src/agent/runtime/capabilities.ts +6 -0
  355. package/src/agent/runtime/memory.ts +23 -0
  356. package/src/agent/runtime/policy.ts +48 -0
  357. package/src/agent/runtime/session.ts +18 -0
  358. package/src/agent/runtime/tracing.ts +23 -0
  359. package/src/agent/tools/file.ts +173 -0
  360. package/src/agent/tools/index.ts +46 -0
  361. package/src/agent/tools/search.ts +137 -0
  362. package/src/agent/tools/shell.ts +65 -0
  363. package/src/agent/tools/skills.ts +28 -0
  364. package/src/agent/tools/types.ts +10 -0
  365. package/src/agent/tools/zerg.ts +50 -0
  366. package/src/cli.tsx +80 -0
  367. package/src/components/FullScreen.tsx +73 -0
  368. package/src/components/Header.tsx +27 -0
  369. package/src/components/InputArea.tsx +551 -0
  370. package/src/components/MessageList.tsx +25 -0
  371. package/src/components/StatusBar.tsx +49 -0
  372. package/src/components/index.tsx +6 -0
  373. package/src/config/types.ts +11 -0
  374. package/src/config.ts +178 -0
  375. package/src/debug/logger.ts +14 -0
  376. package/src/emulation/README.md +24 -0
  377. package/src/emulation/catalog.ts +82 -0
  378. package/src/emulation/trace_style.ts +8 -0
  379. package/src/emulation/types.ts +7 -0
  380. package/src/skills/index.ts +36 -0
  381. package/src/skills/loader.ts +135 -0
  382. package/src/skills/registry.ts +6 -0
  383. package/src/skills/types.ts +10 -0
  384. package/src/types.ts +83 -0
  385. package/src/ui/README.md +44 -0
  386. package/src/ui/core/factory.ts +9 -0
  387. package/src/ui/core/index.ts +4 -0
  388. package/src/ui/core/input.ts +38 -0
  389. package/src/ui/core/input_segments.ts +375 -0
  390. package/src/ui/core/input_state.ts +17 -0
  391. package/src/ui/core/layout_yoga.ts +122 -0
  392. package/src/ui/core/style.ts +38 -0
  393. package/src/ui/core/types.ts +53 -0
  394. package/src/ui/ink/index.tsx +1 -0
  395. package/src/ui/ink/render.tsx +49 -0
  396. package/src/ui/views/app.ts +99 -0
  397. package/src/ui/views/header.ts +42 -0
  398. package/src/ui/views/input_area.ts +244 -0
  399. package/src/ui/views/message_list.ts +427 -0
  400. package/src/ui/views/status_bar.ts +104 -0
  401. package/src/ui/vue/index.ts +53 -0
  402. package/src/utils/clipboard.ts +39 -0
  403. package/src/utils/clipboard_image.ts +40 -0
  404. package/src/utils/diff.ts +52 -0
  405. package/src/utils/image_preview.ts +36 -0
  406. package/src/utils/models.ts +98 -0
  407. package/src/utils/shell.ts +63 -0
  408. package/src/utils/tool_summary.ts +56 -0
  409. package/src/utils/tool_trace.ts +206 -0
  410. package/tsconfig.json +22 -0
  411. package/vite.config.ts +363 -0
@@ -0,0 +1,551 @@
1
+ import React, { useReducer, useCallback } from 'react';
2
+ import { useInput, useStdout } from 'ink';
3
+ import { InkNode } from '../ui/ink/index.js';
4
+ import { buildInputAreaView, wrapInputSegments } from '../ui/views/input_area.js';
5
+ import { InputBus, InputKey } from '../ui/core/input.js';
6
+ import { InputState, InputSegment } from '../ui/core/input_state.js';
7
+ import { debugLog } from '../debug/logger.js';
8
+ import chalk from 'chalk';
9
+ import { saveClipboardImage } from '../utils/clipboard_image.js';
10
+ import { renderImagePreview } from '../utils/image_preview.js';
11
+ import {
12
+ createEmptyState,
13
+ insertText,
14
+ insertSegment,
15
+ insertBadge,
16
+ backspace,
17
+ deleteForward,
18
+ moveLeft,
19
+ moveRight,
20
+ moveWordLeft,
21
+ moveWordRight,
22
+ getPlainText,
23
+ serializeSegments,
24
+ PASTE_BADGE_THRESHOLD
25
+ } from '../ui/core/input_segments.js';
26
+
27
+ interface InputAreaProps {
28
+ onSubmit: (text: string) => void;
29
+ onCommand?: (command: string, args: string[]) => void;
30
+ commands?: Array<{
31
+ name: string;
32
+ description: string;
33
+ usage?: string;
34
+ }>;
35
+ onStateChange?: (state: InputState) => void;
36
+ onToast?: (message: string) => void;
37
+ cols?: number;
38
+ inputBus?: InputBus;
39
+ disabled?: boolean;
40
+ placeholder?: string;
41
+ historyEnabled?: boolean;
42
+ debug?: boolean;
43
+ }
44
+
45
+ export type { InputState } from '../ui/core/input_state.js';
46
+
47
+ type InputAction =
48
+ | { type: 'apply'; state: Partial<InputState> }
49
+ | { type: 'submit'; historyEnabled: boolean; historyEntry?: string }
50
+ | { type: 'history_nav'; direction: 'up' | 'down'; historyEnabled: boolean };
51
+
52
+ const initialState: InputState = createEmptyState();
53
+
54
+ function reducer(state: InputState, action: InputAction): InputState {
55
+ switch (action.type) {
56
+ case 'apply':
57
+ return { ...state, ...action.state };
58
+ case 'submit': {
59
+ const history = action.historyEnabled && action.historyEntry
60
+ ? [...state.history.slice(-100), action.historyEntry]
61
+ : state.history;
62
+ return {
63
+ ...state,
64
+ segments: [],
65
+ cursor: { index: 0, offset: 0 },
66
+ historyIdx: -1,
67
+ history
68
+ };
69
+ }
70
+ case 'history_nav': {
71
+ if (!action.historyEnabled || state.history.length === 0) return state;
72
+
73
+ let newIdx: number;
74
+ if (action.direction === 'up') {
75
+ newIdx = state.historyIdx === -1
76
+ ? state.history.length - 1
77
+ : Math.max(0, state.historyIdx - 1);
78
+ } else {
79
+ newIdx = state.historyIdx === -1 ? -1 : state.historyIdx + 1;
80
+ if (newIdx >= state.history.length) newIdx = -1;
81
+ }
82
+
83
+ if (newIdx === -1) {
84
+ return { ...state, historyIdx: -1, segments: [], cursor: { index: 0, offset: 0 } };
85
+ }
86
+
87
+ const historyValue = state.history[newIdx];
88
+ const nextSegments: InputSegment[] = historyValue.length > 0
89
+ ? [{ type: 'text', text: historyValue }]
90
+ : [];
91
+ return {
92
+ ...state,
93
+ historyIdx: newIdx,
94
+ segments: nextSegments,
95
+ cursor: { index: nextSegments.length ? 0 : 0, offset: historyValue.length }
96
+ };
97
+ }
98
+ default:
99
+ return state;
100
+ }
101
+ }
102
+
103
+ export const InputArea: React.FC<InputAreaProps> = ({
104
+ onSubmit,
105
+ onCommand,
106
+ commands = [],
107
+ onStateChange,
108
+ onToast,
109
+ cols = process.stdout.columns || 80,
110
+ inputBus,
111
+ disabled = false,
112
+ placeholder = 'Type a message...',
113
+ historyEnabled = true,
114
+ debug = false
115
+ }) => {
116
+ const [state, dispatch] = useReducer(reducer, initialState);
117
+ const stateRef = React.useRef(state);
118
+ const [badgePreview, setBadgePreview] = React.useState<string[] | null>(null);
119
+ React.useEffect(() => {
120
+ stateRef.current = state;
121
+ onStateChange?.(state);
122
+ }, [onStateChange, state]);
123
+
124
+ React.useEffect(() => {
125
+ const segment = state.segments[state.cursor.index];
126
+ if (!segment || segment.type === 'text') {
127
+ setBadgePreview(null);
128
+ return;
129
+ }
130
+ if (segment.type === 'paste') {
131
+ const lines = segment.text.split('\n');
132
+ const preview = lines.slice(0, 3);
133
+ if (lines.length > 3) preview.push('…');
134
+ setBadgePreview(preview);
135
+ return;
136
+ }
137
+ if (segment.type === 'file') {
138
+ setBadgePreview([`[file] ${segment.path}`]);
139
+ return;
140
+ }
141
+ if (segment.type === 'image') {
142
+ renderImagePreview(segment.path, 40, 16).then(result => {
143
+ if (result && result.length > 0) {
144
+ setBadgePreview(result);
145
+ } else {
146
+ setBadgePreview([`[image] ${segment.path}`, 'Install chafa for preview.']);
147
+ }
148
+ }).catch(() => {
149
+ setBadgePreview([`[image] ${segment.path}`]);
150
+ });
151
+ }
152
+ }, [state.cursor.index, state.segments]);
153
+
154
+ const inputRenderCount = React.useRef(0);
155
+ React.useEffect(() => {
156
+ inputRenderCount.current += 1;
157
+ const totalLength = state.segments.reduce((acc, segment) => (
158
+ segment.type === 'text' ? acc + segment.text.length : acc + 0
159
+ ), 0);
160
+ debugLog(`InputArea render #${inputRenderCount.current} (valueLen=${totalLength})`);
161
+ });
162
+
163
+ const handleSubmit = useCallback(() => {
164
+ const serialized = serializeSegments(state.segments).trim();
165
+ if (!serialized) return;
166
+
167
+ const plainText = getPlainText(state.segments).trim();
168
+ const isCommand = state.segments.length === 1 && state.segments[0].type === 'text' && plainText.startsWith('/');
169
+ if (isCommand) {
170
+ const parts = plainText.slice(1).split(/\s+/);
171
+ const cmd = parts[0];
172
+ const args = parts.slice(1);
173
+ onCommand?.(cmd, args);
174
+ } else {
175
+ onSubmit(serialized);
176
+ }
177
+
178
+ dispatch({ type: 'submit', historyEnabled, historyEntry: serialized });
179
+ }, [state.segments, onSubmit, onCommand, historyEnabled]);
180
+
181
+ const navigateHistory = useCallback((direction: 'up' | 'down') => {
182
+ dispatch({ type: 'history_nav', direction, historyEnabled });
183
+ }, [historyEnabled]);
184
+
185
+ const { stdout } = useStdout();
186
+ const overlayEnabled = process.env.ZTC_INPUT_OVERLAY !== '0' && process.env.ZTC_WEB_MIRROR !== '1';
187
+ const overlayStateRef = React.useRef<InputState>(initialState);
188
+ const overlayBusyRef = React.useRef(false);
189
+ const pasteBusyRef = React.useRef(false);
190
+
191
+ const insertTextIntoState = useCallback((text: string) => {
192
+ const current = stateRef.current;
193
+ const next = insertText(current, text);
194
+ dispatch({ type: 'apply', state: { ...next, historyIdx: -1 } });
195
+ }, []);
196
+
197
+ const renderOverlay = useCallback((overlayState: InputState) => {
198
+ if (!stdout || !stdout.isTTY) return;
199
+ if (overlayBusyRef.current) return;
200
+ overlayBusyRef.current = true;
201
+
202
+ const rows = stdout.rows || 24;
203
+ const statusHeight = 1;
204
+ const cols = stdout.columns || 80;
205
+ const wrapped = wrapInputSegments(overlayState.segments, overlayState.cursor, cols);
206
+ const inputLines = Math.max(1, wrapped.lines.length);
207
+ const inputHeight = inputLines + 4;
208
+ const startRow = Math.max(1, rows - (inputHeight + statusHeight) + 1);
209
+
210
+ const prompt = disabled ? chalk.gray('❯ ') : chalk.blue('❯ ');
211
+
212
+ const lines: string[] = [];
213
+ if (disabled) {
214
+ lines.push(prompt + chalk.gray(placeholder));
215
+ } else if (overlayState.segments.length === 0) {
216
+ lines.push(prompt + chalk.inverse(' ') + chalk.gray(placeholder));
217
+ } else {
218
+ wrapped.lines.forEach((lineTokens, index) => {
219
+ const prefix = index === 0 ? prompt : ' ';
220
+ let lineText = prefix;
221
+ lineTokens.forEach((token, tokenIndex) => {
222
+ const isCursor = index === wrapped.cursorLine && tokenIndex === wrapped.cursorCol;
223
+ if (isCursor) {
224
+ lineText += chalk.inverse(token.text || ' ');
225
+ } else if (token.style?.color === 'yellow') {
226
+ lineText += chalk.gray(token.text);
227
+ } else {
228
+ lineText += token.text;
229
+ }
230
+ });
231
+ if (index === wrapped.cursorLine && wrapped.cursorCol === lineTokens.length) {
232
+ lineText += chalk.inverse(' ');
233
+ }
234
+ lines.push(lineText);
235
+ });
236
+ }
237
+
238
+ const plainText = overlayState.segments.length === 1 && overlayState.segments[0].type === 'text'
239
+ ? overlayState.segments[0].text
240
+ : '';
241
+ const isCommandMode = plainText.startsWith('/');
242
+ const commandQuery = isCommandMode ? plainText.slice(1).trim() : '';
243
+ const commandMatches = isCommandMode
244
+ ? commands.filter(c => c.name.startsWith(commandQuery)).slice(0, 4)
245
+ : [];
246
+
247
+ for (let i = 0; i < 4; i += 1) {
248
+ const cmd = commandMatches[i];
249
+ if (!cmd) {
250
+ lines.push(' ');
251
+ continue;
252
+ }
253
+ const usage = cmd.usage ? ` ${cmd.usage}` : '';
254
+ const line = `${chalk.cyan.bold(`/${cmd.name}`)}${chalk.white(usage)}${chalk.gray(` — ${cmd.description}`)}`;
255
+ lines.push(line);
256
+ }
257
+
258
+ stdout.write('\x1b[s');
259
+ for (let i = 0; i < inputHeight; i += 1) {
260
+ const row = startRow + i;
261
+ const raw = lines[i] || '';
262
+ const trimmed = raw.length > cols ? raw.slice(0, cols) : raw;
263
+ stdout.write(`\x1b[${row};1H\x1b[2K${trimmed}`);
264
+ }
265
+ stdout.write('\x1b[u');
266
+ overlayBusyRef.current = false;
267
+ }, [commands, disabled, placeholder, stdout]);
268
+
269
+ const insertTextIntoOverlay = useCallback((text: string) => {
270
+ const current = overlayStateRef.current;
271
+ const next = insertText(current, text);
272
+ overlayStateRef.current = { ...next, historyIdx: -1 };
273
+ renderOverlay(overlayStateRef.current);
274
+ }, [renderOverlay]);
275
+
276
+ const handleClipboardImagePaste = useCallback(async (target: 'state' | 'overlay') => {
277
+ if (pasteBusyRef.current) return;
278
+ pasteBusyRef.current = true;
279
+ try {
280
+ const path = await saveClipboardImage();
281
+ if (!path) return;
282
+ onToast?.(`Image saved to ${path}`);
283
+ if (target === 'overlay') {
284
+ const current = overlayStateRef.current;
285
+ const next = insertBadge(current, { type: 'image', path });
286
+ overlayStateRef.current = { ...next, historyIdx: -1 };
287
+ renderOverlay(overlayStateRef.current);
288
+ } else {
289
+ const current = stateRef.current;
290
+ const next = insertBadge(current, { type: 'image', path });
291
+ dispatch({ type: 'apply', state: { ...next, historyIdx: -1 } });
292
+ }
293
+ } finally {
294
+ pasteBusyRef.current = false;
295
+ }
296
+ }, [insertTextIntoOverlay, insertTextIntoState, onToast, renderOverlay]);
297
+
298
+ const handleInput = useCallback((input: string, key: InputKey) => {
299
+ if (disabled) return;
300
+
301
+ if ((key.ctrl || key.meta) && (input === 'v' || input === '\u0016')) {
302
+ void handleClipboardImagePaste('state');
303
+ return;
304
+ }
305
+
306
+ if (key.return && !key.shift) {
307
+ handleSubmit();
308
+ return;
309
+ }
310
+
311
+ if (key.return && key.shift) {
312
+ const next = insertText(state, '\n');
313
+ dispatch({ type: 'apply', state: { ...next, historyIdx: -1 } });
314
+ return;
315
+ }
316
+
317
+ if (key.upArrow) {
318
+ navigateHistory('up');
319
+ return;
320
+ }
321
+ if (key.downArrow) {
322
+ navigateHistory('down');
323
+ return;
324
+ }
325
+
326
+ if (key.leftArrow) {
327
+ if (key.ctrl) {
328
+ dispatch({ type: 'apply', state: moveWordLeft(state) });
329
+ } else {
330
+ dispatch({ type: 'apply', state: moveLeft(state) });
331
+ }
332
+ return;
333
+ }
334
+ if (key.rightArrow) {
335
+ if (key.ctrl) {
336
+ dispatch({ type: 'apply', state: moveWordRight(state) });
337
+ } else {
338
+ dispatch({ type: 'apply', state: moveRight(state) });
339
+ }
340
+ return;
341
+ }
342
+
343
+ if (key.ctrl && input === 'a') {
344
+ dispatch({ type: 'apply', state: { cursor: { index: 0, offset: 0 } } });
345
+ return;
346
+ }
347
+ if (key.ctrl && input === 'e') {
348
+ dispatch({ type: 'apply', state: { cursor: { index: state.segments.length, offset: 0 } } });
349
+ return;
350
+ }
351
+
352
+ if (key.backspace || key.delete) {
353
+ const next = key.backspace ? backspace(state) : deleteForward(state);
354
+ dispatch({ type: 'apply', state: next });
355
+ return;
356
+ }
357
+
358
+ if (key.ctrl && input === 'u') {
359
+ dispatch({ type: 'apply', state: { segments: [], cursor: { index: 0, offset: 0 } } });
360
+ return;
361
+ }
362
+
363
+ if (key.ctrl && input === 'w') {
364
+ const next = backspace(moveWordLeft(state));
365
+ dispatch({ type: 'apply', state: next });
366
+ return;
367
+ }
368
+
369
+ if (!key.ctrl && !key.meta && input) {
370
+ if (input.includes('\n')) {
371
+ const lineCount = input.split('\n').length;
372
+ if (lineCount >= PASTE_BADGE_THRESHOLD) {
373
+ const next = insertBadge(state, { type: 'paste', text: input });
374
+ dispatch({ type: 'apply', state: { ...next, historyIdx: -1 } });
375
+ return;
376
+ }
377
+ }
378
+ const next = insertText(state, input);
379
+ dispatch({ type: 'apply', state: { ...next, historyIdx: -1 } });
380
+ }
381
+ }, [disabled, handleSubmit, navigateHistory, state]);
382
+
383
+ const handleOverlayInput = useCallback((input: string, key: InputKey) => {
384
+ if (disabled) return;
385
+ const current = overlayStateRef.current;
386
+
387
+ if ((key.ctrl || key.meta) && (input === 'v' || input === '\u0016')) {
388
+ void handleClipboardImagePaste('overlay');
389
+ return;
390
+ }
391
+
392
+ if (key.return && !key.shift) {
393
+ const serialized = serializeSegments(current.segments).trim();
394
+ if (serialized) {
395
+ const plainText = getPlainText(current.segments).trim();
396
+ const isCommand = current.segments.length === 1 && current.segments[0].type === 'text' && plainText.startsWith('/');
397
+ if (isCommand) {
398
+ const parts = plainText.slice(1).split(/\s+/);
399
+ const cmd = parts[0];
400
+ const args = parts.slice(1);
401
+ onCommand?.(cmd, args);
402
+ } else {
403
+ onSubmit(serialized);
404
+ }
405
+ if (historyEnabled) {
406
+ current.history = [...current.history.slice(-100), serialized];
407
+ }
408
+ }
409
+ overlayStateRef.current = { ...createEmptyState(), history: current.history, historyIdx: -1 };
410
+ renderOverlay(overlayStateRef.current);
411
+ return;
412
+ }
413
+
414
+ if (key.return && key.shift) {
415
+ overlayStateRef.current = { ...insertText(current, '\n'), historyIdx: -1 };
416
+ renderOverlay(overlayStateRef.current);
417
+ return;
418
+ }
419
+
420
+ if (key.upArrow || key.downArrow) {
421
+ const direction = key.upArrow ? 'up' : 'down';
422
+ if (historyEnabled && current.history.length > 0) {
423
+ let newIdx: number;
424
+ if (direction === 'up') {
425
+ newIdx = current.historyIdx === -1 ? current.history.length - 1 : Math.max(0, current.historyIdx - 1);
426
+ } else {
427
+ newIdx = current.historyIdx === -1 ? -1 : current.historyIdx + 1;
428
+ if (newIdx >= current.history.length) newIdx = -1;
429
+ }
430
+ if (newIdx === -1) {
431
+ overlayStateRef.current = { ...createEmptyState(), history: current.history, historyIdx: -1 };
432
+ } else {
433
+ const historyValue = current.history[newIdx];
434
+ overlayStateRef.current = {
435
+ ...current,
436
+ historyIdx: newIdx,
437
+ segments: historyValue.length > 0 ? [{ type: 'text', text: historyValue }] : [],
438
+ cursor: { index: historyValue.length > 0 ? 0 : 0, offset: historyValue.length }
439
+ };
440
+ }
441
+ renderOverlay(overlayStateRef.current);
442
+ }
443
+ return;
444
+ }
445
+
446
+ if (key.leftArrow) {
447
+ if (key.ctrl) {
448
+ overlayStateRef.current = moveWordLeft(current);
449
+ } else {
450
+ overlayStateRef.current = moveLeft(current);
451
+ }
452
+ renderOverlay(overlayStateRef.current);
453
+ return;
454
+ }
455
+
456
+ if (key.rightArrow) {
457
+ if (key.ctrl) {
458
+ overlayStateRef.current = moveWordRight(current);
459
+ } else {
460
+ overlayStateRef.current = moveRight(current);
461
+ }
462
+ renderOverlay(overlayStateRef.current);
463
+ return;
464
+ }
465
+
466
+ if (key.ctrl && input === 'a') {
467
+ overlayStateRef.current = { ...current, cursor: { index: 0, offset: 0 } };
468
+ renderOverlay(overlayStateRef.current);
469
+ return;
470
+ }
471
+
472
+ if (key.ctrl && input === 'e') {
473
+ overlayStateRef.current = { ...current, cursor: { index: current.segments.length, offset: 0 } };
474
+ renderOverlay(overlayStateRef.current);
475
+ return;
476
+ }
477
+
478
+ if (key.backspace || key.delete) {
479
+ overlayStateRef.current = key.backspace ? backspace(current) : deleteForward(current);
480
+ renderOverlay(overlayStateRef.current);
481
+ return;
482
+ }
483
+
484
+ if (key.ctrl && input === 'u') {
485
+ overlayStateRef.current = { ...createEmptyState(), history: current.history, historyIdx: -1 };
486
+ renderOverlay(overlayStateRef.current);
487
+ return;
488
+ }
489
+
490
+ if (key.ctrl && input === 'w') {
491
+ overlayStateRef.current = backspace(moveWordLeft(current));
492
+ renderOverlay(overlayStateRef.current);
493
+ return;
494
+ }
495
+
496
+ if (!key.ctrl && !key.meta && input) {
497
+ if (input.includes('\n')) {
498
+ const lineCount = input.split('\n').length;
499
+ if (lineCount >= PASTE_BADGE_THRESHOLD) {
500
+ overlayStateRef.current = insertBadge(current, { type: 'paste', text: input });
501
+ } else {
502
+ overlayStateRef.current = insertText(current, input);
503
+ }
504
+ } else {
505
+ overlayStateRef.current = insertText(current, input);
506
+ }
507
+ overlayStateRef.current = { ...overlayStateRef.current, historyIdx: -1 };
508
+ renderOverlay(overlayStateRef.current);
509
+ }
510
+ }, [disabled, historyEnabled, onCommand, onSubmit, renderOverlay]);
511
+
512
+ useInput((input, key) => {
513
+ if (overlayEnabled) {
514
+ handleOverlayInput(input, key);
515
+ return;
516
+ }
517
+ handleInput(input, key);
518
+ });
519
+
520
+ React.useEffect(() => {
521
+ if (!inputBus) return;
522
+ return inputBus.subscribe(({ input, key }) => {
523
+ if (overlayEnabled) {
524
+ handleOverlayInput(input, key);
525
+ return;
526
+ }
527
+ handleInput(input, key);
528
+ });
529
+ }, [handleInput, handleOverlayInput, inputBus, overlayEnabled]);
530
+
531
+ React.useEffect(() => {
532
+ if (!overlayEnabled) return;
533
+ renderOverlay(overlayStateRef.current);
534
+ }, [overlayEnabled, renderOverlay]);
535
+
536
+ const node = buildInputAreaView({
537
+ state,
538
+ placeholder,
539
+ disabled,
540
+ commands,
541
+ cols,
542
+ badgePreview,
543
+ showBadgePreview: true,
544
+ debug,
545
+ renderContent: !overlayEnabled
546
+ });
547
+
548
+ return <InkNode node={node} />;
549
+ };
550
+
551
+ export default InputArea;
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { Message } from '../types.js';
3
+ import { InkNode } from '../ui/ink/index.js';
4
+ import { buildMessageListView } from '../ui/views/message_list.js';
5
+
6
+ interface MessageListProps {
7
+ messages: Message[];
8
+ height: number;
9
+ maxMessages?: number;
10
+ debug?: boolean;
11
+ expandToolOutputs?: boolean;
12
+ }
13
+
14
+ export const MessageList: React.FC<MessageListProps> = ({
15
+ messages,
16
+ height,
17
+ maxMessages = 50,
18
+ debug = false,
19
+ expandToolOutputs = false
20
+ }) => {
21
+ const node = buildMessageListView({ messages, height, maxMessages, debug, expandToolOutputs });
22
+ return <InkNode node={node} />;
23
+ };
24
+
25
+ export default MessageList;
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import { AgentState } from '../types.js';
3
+ import { InkNode } from '../ui/ink/index.js';
4
+ import { buildStatusBarView } from '../ui/views/status_bar.js';
5
+
6
+ interface StatusBarProps {
7
+ state: AgentState;
8
+ sessionId?: string;
9
+ version?: string;
10
+ connectionStatus?: 'connected' | 'disconnected' | 'connecting';
11
+ contextLength?: number;
12
+ contextEstimated?: boolean;
13
+ provider?: string;
14
+ model?: string;
15
+ emulationId?: string;
16
+ toast?: string | null;
17
+ debug?: boolean;
18
+ }
19
+
20
+ export const StatusBar: React.FC<StatusBarProps> = ({
21
+ state,
22
+ sessionId,
23
+ version = '0.1.0',
24
+ connectionStatus = 'connected',
25
+ contextLength,
26
+ contextEstimated,
27
+ provider,
28
+ model,
29
+ emulationId,
30
+ toast,
31
+ debug = false
32
+ }) => {
33
+ const node = buildStatusBarView({
34
+ state,
35
+ sessionId,
36
+ version,
37
+ connectionStatus,
38
+ contextLength,
39
+ contextEstimated,
40
+ provider,
41
+ model,
42
+ emulationId,
43
+ toast,
44
+ debug
45
+ });
46
+ return <InkNode node={node} />;
47
+ };
48
+
49
+ export default StatusBar;
@@ -0,0 +1,6 @@
1
+ // Component exports
2
+ export { Header } from './Header.js';
3
+ export { MessageList } from './MessageList.js';
4
+ export { InputArea } from './InputArea.js';
5
+ export { StatusBar } from './StatusBar.js';
6
+ export { FullScreen, useScreenSize } from './FullScreen.js';
@@ -0,0 +1,11 @@
1
+ export interface ZTCConfig {
2
+ apiKey?: string;
3
+ apiKeys?: Record<string, string>;
4
+ provider?: string;
5
+ openaiCompatibleBaseUrl?: string;
6
+ model: string;
7
+ maxTokens: number;
8
+ zergEndpoint?: string;
9
+ emulationId?: string;
10
+ toolPermissions?: Partial<Record<'file_read' | 'file_write' | 'shell_exec' | 'network', boolean>>;
11
+ }