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
package/src/config.ts ADDED
@@ -0,0 +1,178 @@
1
+ import { homedir } from 'os';
2
+ import { join } from 'path';
3
+ import { readFile, writeFile, mkdir } from 'fs/promises';
4
+
5
+ import { ZTCConfig } from './config/types.js';
6
+
7
+ // --- Configuration Store ---
8
+
9
+ const DEFAULT_CONFIG: ZTCConfig = {
10
+ apiKey: process.env.ANTHROPIC_API_KEY,
11
+ apiKeys: undefined,
12
+ provider: 'anthropic',
13
+ openaiCompatibleBaseUrl: undefined,
14
+ model: 'claude-opus-4-20250514',
15
+ maxTokens: 4096,
16
+ zergEndpoint: undefined,
17
+ emulationId: undefined,
18
+ toolPermissions: {
19
+ file_read: true,
20
+ file_write: true,
21
+ shell_exec: true,
22
+ network: true
23
+ }
24
+ };
25
+
26
+ const CONFIG_DIR = join(homedir(), '.ztc');
27
+ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
28
+
29
+ class ConfigStore {
30
+ private config: ZTCConfig = { ...DEFAULT_CONFIG };
31
+ private loaded = false;
32
+
33
+ private applyEnvOverrides(): void {
34
+ if (process.env.ANTHROPIC_API_KEY) {
35
+ this.config.apiKey = process.env.ANTHROPIC_API_KEY;
36
+ }
37
+ }
38
+
39
+ async load(force = false): Promise<ZTCConfig> {
40
+ if (this.loaded && !force) return this.config;
41
+
42
+ try {
43
+ const data = await readFile(CONFIG_FILE, 'utf-8');
44
+ const saved = JSON.parse(data) as Partial<ZTCConfig>;
45
+ this.config = { ...DEFAULT_CONFIG, ...saved };
46
+ if (this.config.model === 'claude-opus-4-5-20250514') {
47
+ this.config.model = 'claude-opus-4-20250514';
48
+ }
49
+ if (!this.config.toolPermissions) {
50
+ this.config.toolPermissions = { ...DEFAULT_CONFIG.toolPermissions };
51
+ }
52
+ this.applyEnvOverrides();
53
+ } catch {
54
+ // File doesn't exist or is invalid, use defaults
55
+ this.config = { ...DEFAULT_CONFIG };
56
+ }
57
+
58
+ this.loaded = true;
59
+ return this.config;
60
+ }
61
+
62
+ async refresh(): Promise<void> {
63
+ await this.load(true);
64
+ }
65
+
66
+ async save(): Promise<void> {
67
+ try {
68
+ await mkdir(CONFIG_DIR, { recursive: true });
69
+
70
+ // Don't persist API key if it came from env
71
+ const toSave: Partial<ZTCConfig> = { ...this.config };
72
+ if (process.env.ANTHROPIC_API_KEY === this.config.apiKey) {
73
+ delete toSave.apiKey;
74
+ }
75
+
76
+ await writeFile(CONFIG_FILE, JSON.stringify(toSave, null, 2), 'utf-8');
77
+ } catch (err) {
78
+ console.error('Failed to save config:', err);
79
+ }
80
+ }
81
+
82
+ get(): ZTCConfig {
83
+ return this.config;
84
+ }
85
+
86
+ set<K extends keyof ZTCConfig>(key: K, value: ZTCConfig[K]): void {
87
+ this.config[key] = value;
88
+ }
89
+
90
+ setAll(next: Partial<ZTCConfig>): void {
91
+ this.config = { ...DEFAULT_CONFIG, ...this.config, ...next };
92
+ if (this.config.model === 'claude-opus-4-5-20250514') {
93
+ this.config.model = 'claude-opus-4-20250514';
94
+ }
95
+ if (!this.config.toolPermissions) {
96
+ this.config.toolPermissions = { ...DEFAULT_CONFIG.toolPermissions };
97
+ }
98
+ this.applyEnvOverrides();
99
+ this.loaded = true;
100
+ }
101
+
102
+ hasApiKey(): boolean {
103
+ const key = this.getApiKey();
104
+ return !!key && key.length > 0;
105
+ }
106
+
107
+ getApiKey(provider?: string): string | undefined {
108
+ const chosen = provider || this.getProvider();
109
+ const envKey = this.getEnvKey(chosen);
110
+ if (envKey) return envKey;
111
+ if (this.config.apiKeys && this.config.apiKeys[chosen]) return this.config.apiKeys[chosen];
112
+ return this.config.apiKey;
113
+ }
114
+
115
+ setApiKey(key: string, provider?: string): void {
116
+ const chosen = provider || this.getProvider();
117
+ if (!this.config.apiKeys) {
118
+ this.config.apiKeys = {};
119
+ }
120
+ this.config.apiKeys[chosen] = key;
121
+ if (chosen === 'anthropic') {
122
+ this.config.apiKey = key;
123
+ }
124
+ }
125
+
126
+ getEmulationId(): string | undefined {
127
+ return this.config.emulationId;
128
+ }
129
+
130
+ setEmulationId(id: string | undefined): void {
131
+ this.config.emulationId = id;
132
+ }
133
+
134
+ getMaskedApiKey(): string {
135
+ const key = this.getApiKey();
136
+ if (!key) return '(not set)';
137
+ if (key.length < 12) return '****';
138
+ return `${key.slice(0, 7)}...${key.slice(-4)}`;
139
+ }
140
+
141
+ getProvider(): string {
142
+ return this.config.provider || 'anthropic';
143
+ }
144
+
145
+ setProvider(provider: string): void {
146
+ this.config.provider = provider;
147
+ }
148
+
149
+ getOpenAICompatibleBaseUrl(): string | undefined {
150
+ return this.config.openaiCompatibleBaseUrl;
151
+ }
152
+
153
+ setOpenAICompatibleBaseUrl(url: string | undefined): void {
154
+ this.config.openaiCompatibleBaseUrl = url;
155
+ }
156
+
157
+ private getEnvKey(provider: string): string | undefined {
158
+ const map: Record<string, string | undefined> = {
159
+ anthropic: process.env.ANTHROPIC_API_KEY,
160
+ openai: process.env.OPENAI_API_KEY,
161
+ gemini: process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY,
162
+ inception: process.env.INCEPTION_API_KEY,
163
+ openai_compatible: process.env.OPENAI_COMPAT_API_KEY
164
+ };
165
+ return map[provider];
166
+ }
167
+
168
+ getConfigPath(): string {
169
+ return CONFIG_FILE;
170
+ }
171
+
172
+ get locationLabel(): string {
173
+ return CONFIG_FILE;
174
+ }
175
+ }
176
+
177
+ export const configStore = new ConfigStore();
178
+ export default configStore;
@@ -0,0 +1,14 @@
1
+ import { appendFileSync } from 'fs';
2
+
3
+ const enabled = process.env.ZTC_DEBUG_RENDER === '1';
4
+ const logPath = process.env.ZTC_DEBUG_RENDER_LOG || '/tmp/ztc_render.log';
5
+
6
+ export function debugLog(message: string): void {
7
+ if (!enabled) return;
8
+ const line = `[${new Date().toISOString()}] ${message}\n`;
9
+ try {
10
+ appendFileSync(logPath, line, 'utf-8');
11
+ } catch {
12
+ // Ignore logging failures
13
+ }
14
+ }
@@ -0,0 +1,24 @@
1
+ ## Emulation Layer
2
+
3
+ This module loads third-party tool prompts (e.g., Claude Code, Codex CLI) and exposes them as selectable emulation profiles.
4
+
5
+ ### Data Source
6
+ The content is extracted from the `x1xhlol/system-prompts-and-models-of-ai-tools` repository and stored locally in:
7
+ `~/.ztc/emulations/x1xhlol/`
8
+
9
+ You can override the base path with `ZTC_EMULATION_DIR` (useful for tests or custom fixtures).
10
+
11
+ ### Fixture Setup
12
+ For tests, point `ZTC_EMULATION_DIR` at `tests/fixtures/emulations/x1xhlol` to use the bundled fixture data.
13
+
14
+ To populate your local emulation cache:
15
+ - `npm run emulation:init`
16
+
17
+ ### Usage
18
+ - `/emulation list` to see available profiles
19
+ - `/emulation set <id>` to activate
20
+ - `/emulation show` to see the current profile
21
+
22
+ ### Notes
23
+ - The emulation layer currently wires the **system prompt** into the agent.
24
+ - Tool schemas are loaded and stored for future use, but not yet mapped to runtime tools.
@@ -0,0 +1,82 @@
1
+ import { readFileSync, existsSync } from 'fs';
2
+ import { resolve, join } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import { homedir } from 'os';
5
+ import { EmulationProfile } from './types.js';
6
+
7
+ interface EmulationSource {
8
+ id: string;
9
+ name: string;
10
+ description: string;
11
+ promptPath: string;
12
+ toolsPath?: string;
13
+ }
14
+
15
+ const sources: EmulationSource[] = [
16
+ {
17
+ id: 'claude-code',
18
+ name: 'Claude Code',
19
+ description: 'Anthropic Claude Code CLI emulation',
20
+ promptPath: 'Anthropic/Claude Code/Prompt.txt',
21
+ toolsPath: 'Anthropic/Claude Code/Tools.json'
22
+ },
23
+ {
24
+ id: 'codex-cli-system',
25
+ name: 'Codex CLI (System Prompt 2025-08-20)',
26
+ description: 'OpenAI Codex CLI system prompt emulation',
27
+ promptPath: 'Open Source prompts/Codex CLI/openai-codex-cli-system-prompt-20250820.txt'
28
+ },
29
+ {
30
+ id: 'codex-cli',
31
+ name: 'Codex CLI (Prompt)',
32
+ description: 'OpenAI Codex CLI prompt emulation',
33
+ promptPath: 'Open Source prompts/Codex CLI/Prompt.txt'
34
+ }
35
+ ];
36
+
37
+ function resolveBaseDir(): string {
38
+ const override = process.env.ZTC_EMULATION_DIR;
39
+ if (override && override.trim().length > 0) {
40
+ return resolve(override);
41
+ }
42
+ const candidates = [
43
+ join(homedir(), '.ztc', 'emulations', 'x1xhlol'),
44
+ resolve(process.cwd(), 'emulations/x1xhlol'),
45
+ resolve(process.cwd(), 'ztc/emulations/x1xhlol'),
46
+ resolve(fileURLToPath(new URL('../../emulations/x1xhlol', import.meta.url)))
47
+ ];
48
+ for (const candidate of candidates) {
49
+ if (existsSync(candidate)) {
50
+ return candidate;
51
+ }
52
+ }
53
+ return candidates[0];
54
+ }
55
+
56
+ export function loadEmulationProfiles(): EmulationProfile[] {
57
+ const baseDir = resolveBaseDir();
58
+
59
+ return sources.flatMap(source => {
60
+ const promptFile = resolve(baseDir, source.promptPath);
61
+ if (!existsSync(promptFile)) {
62
+ return [];
63
+ }
64
+ const prompt = readFileSync(promptFile, 'utf-8');
65
+ const toolsFile = source.toolsPath ? resolve(baseDir, source.toolsPath) : undefined;
66
+ const tools = toolsFile && existsSync(toolsFile)
67
+ ? JSON.parse(readFileSync(toolsFile, 'utf-8'))
68
+ : undefined;
69
+
70
+ return [{
71
+ id: source.id,
72
+ name: source.name,
73
+ description: source.description,
74
+ systemPrompt: prompt,
75
+ tools
76
+ }];
77
+ });
78
+ }
79
+
80
+ export function getEmulationProfile(id: string): EmulationProfile | undefined {
81
+ return loadEmulationProfiles().find(profile => profile.id === id);
82
+ }
@@ -0,0 +1,8 @@
1
+ export type TraceStyle = 'claude_code' | 'codex' | 'plain';
2
+
3
+ export function getTraceStyle(emulationId?: string): TraceStyle {
4
+ if (!emulationId) return 'plain';
5
+ if (emulationId === 'claude-code') return 'claude_code';
6
+ if (emulationId.startsWith('codex')) return 'codex';
7
+ return 'plain';
8
+ }
@@ -0,0 +1,7 @@
1
+ export interface EmulationProfile {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ systemPrompt: string;
6
+ tools?: Record<string, unknown>;
7
+ }
@@ -0,0 +1,36 @@
1
+ import { Skill } from './types.js';
2
+
3
+ export function buildSkillPrompt(skills: Skill[]): string {
4
+ if (skills.length === 0) return '';
5
+ const blocks = skills.map(skill => {
6
+ const header = `Skill: ${skill.name}`;
7
+ const description = skill.description ? `Description: ${skill.description}` : '';
8
+ const instructions = skill.instructions.trim();
9
+ return [header, description, instructions].filter(Boolean).join('\n');
10
+ });
11
+ return ['# Skills', ...blocks].join('\n\n');
12
+ }
13
+
14
+ export function autoActivateSkills(message: string, skills: Skill[]): Skill[] {
15
+ const haystack = message.toLowerCase();
16
+ return skills.filter(skill => {
17
+ const name = skill.name.toLowerCase();
18
+ const id = skill.id.toLowerCase();
19
+ if (haystack.includes(name) || haystack.includes(id)) return true;
20
+ if (skill.keywords) {
21
+ return skill.keywords.some(keyword => haystack.includes(keyword.toLowerCase()));
22
+ }
23
+ return false;
24
+ });
25
+ }
26
+
27
+ export function formatSkillList(skills: Skill[]): string {
28
+ if (skills.length === 0) return 'No skills found.';
29
+ const lines = skills
30
+ .sort((a, b) => a.name.localeCompare(b.name))
31
+ .map(skill => {
32
+ const source = skill.sourceRoot.includes('.claude') ? 'claude' : 'ztc';
33
+ return ` ${skill.id} - ${skill.name}${skill.description ? `: ${skill.description}` : ''} (${source})`;
34
+ });
35
+ return ['Available skills:', ...lines].join('\n');
36
+ }
@@ -0,0 +1,135 @@
1
+ import { homedir } from 'os';
2
+ import { join, resolve, basename } from 'path';
3
+ import { readdir, readFile, stat } from 'fs/promises';
4
+
5
+ import { Skill } from './types.js';
6
+
7
+ const MAX_DEPTH = 4;
8
+
9
+ function defaultRoots(): string[] {
10
+ const home = homedir();
11
+ return [
12
+ join(home, '.ztc', 'skills'),
13
+ join(home, '.claude', 'skills'),
14
+ join(process.cwd(), '.ztc', 'skills'),
15
+ join(process.cwd(), '.claude', 'skills')
16
+ ];
17
+ }
18
+
19
+ async function walk(dir: string, depth = 0): Promise<string[]> {
20
+ if (depth > MAX_DEPTH) return [];
21
+ try {
22
+ const entries = await readdir(dir, { withFileTypes: true });
23
+ const results: string[] = [];
24
+ for (const entry of entries) {
25
+ if (entry.name.startsWith('.')) continue;
26
+ const full = join(dir, entry.name);
27
+ if (entry.isDirectory()) {
28
+ results.push(...await walk(full, depth + 1));
29
+ } else if (entry.isFile() && entry.name.toLowerCase() === 'skill.md') {
30
+ results.push(full);
31
+ }
32
+ }
33
+ return results;
34
+ } catch {
35
+ return [];
36
+ }
37
+ }
38
+
39
+ function parseFrontmatter(content: string): { meta: Record<string, unknown>; body: string } {
40
+ if (!content.startsWith('---')) {
41
+ return { meta: {}, body: content };
42
+ }
43
+ const end = content.indexOf('\n---', 3);
44
+ if (end === -1) return { meta: {}, body: content };
45
+
46
+ const metaBlock = content.slice(3, end).trim();
47
+ const body = content.slice(end + 4).trim();
48
+ const meta: Record<string, unknown> = {};
49
+ let currentKey: string | null = null;
50
+
51
+ for (const line of metaBlock.split('\n')) {
52
+ if (!line.trim()) continue;
53
+ if (line.startsWith(' -') || line.startsWith('- ')) {
54
+ if (!currentKey) continue;
55
+ const value = line.replace(/^(\s*-)\s*/, '').trim();
56
+ const list = Array.isArray(meta[currentKey]) ? meta[currentKey] as string[] : [];
57
+ list.push(value);
58
+ meta[currentKey] = list;
59
+ continue;
60
+ }
61
+ const idx = line.indexOf(':');
62
+ if (idx === -1) continue;
63
+ const key = line.slice(0, idx).trim();
64
+ let value = line.slice(idx + 1).trim();
65
+ if (value.startsWith('[') && value.endsWith(']')) {
66
+ value = value.slice(1, -1);
67
+ meta[key] = value.split(',').map(item => item.trim()).filter(Boolean);
68
+ } else if (value) {
69
+ meta[key] = value;
70
+ } else {
71
+ meta[key] = [];
72
+ currentKey = key;
73
+ continue;
74
+ }
75
+ currentKey = key;
76
+ }
77
+
78
+ return { meta, body };
79
+ }
80
+
81
+ function normalizeList(value?: unknown): string[] | undefined {
82
+ if (!value) return undefined;
83
+ if (Array.isArray(value)) {
84
+ return value.map(item => String(item)).filter(Boolean);
85
+ }
86
+ if (typeof value === 'string') {
87
+ return value.split(',').map(item => item.trim()).filter(Boolean);
88
+ }
89
+ return undefined;
90
+ }
91
+
92
+ function deriveSkillId(path: string, meta: Record<string, unknown>): string {
93
+ const explicit = meta.id ? String(meta.id) : '';
94
+ if (explicit) return explicit;
95
+ const name = meta.name ? String(meta.name) : '';
96
+ if (name) return name.toLowerCase().replace(/\s+/g, '-');
97
+ return basename(resolve(path, '..')) || 'skill';
98
+ }
99
+
100
+ export async function loadSkills(roots: string[] = defaultRoots()): Promise<Skill[]> {
101
+ const files = new Set<string>();
102
+ for (const root of roots) {
103
+ const paths = await walk(root);
104
+ for (const path of paths) files.add(path);
105
+ }
106
+
107
+ const skills: Skill[] = [];
108
+ for (const filePath of files) {
109
+ try {
110
+ const content = await readFile(filePath, 'utf-8');
111
+ const { meta, body } = parseFrontmatter(content);
112
+ const id = deriveSkillId(filePath, meta);
113
+ const name = meta.name ? String(meta.name) : id;
114
+ const description = meta.description ? String(meta.description) : undefined;
115
+ const allowedTools = normalizeList(meta['allowed-tools'] || meta.allowed_tools || meta.allowedTools);
116
+ const keywords = normalizeList(meta.keywords);
117
+ const root = roots.find(r => filePath.startsWith(resolve(r))) || resolve(filePath, '..');
118
+ await stat(filePath);
119
+ skills.push({
120
+ id,
121
+ name,
122
+ description,
123
+ instructions: body.trim(),
124
+ allowedTools,
125
+ keywords,
126
+ sourcePath: filePath,
127
+ sourceRoot: root
128
+ });
129
+ } catch {
130
+ // skip unreadable skills
131
+ }
132
+ }
133
+
134
+ return skills;
135
+ }
@@ -0,0 +1,6 @@
1
+ import { loadSkills } from './loader.js';
2
+ import { Skill } from './types.js';
3
+
4
+ export async function getSkillRegistry(): Promise<Skill[]> {
5
+ return loadSkills();
6
+ }
@@ -0,0 +1,10 @@
1
+ export interface Skill {
2
+ id: string;
3
+ name: string;
4
+ description?: string;
5
+ instructions: string;
6
+ allowedTools?: string[];
7
+ keywords?: string[];
8
+ sourcePath: string;
9
+ sourceRoot: string;
10
+ }
package/src/types.ts ADDED
@@ -0,0 +1,83 @@
1
+ // ==========================================
2
+ // ZTC Type Definitions
3
+ // ==========================================
4
+
5
+ export type MessageRole = 'user' | 'assistant' | 'tool' | 'system';
6
+
7
+ export type ToolStatus = 'pending' | 'running' | 'complete' | 'error';
8
+
9
+ export type AgentStatus = 'idle' | 'thinking' | 'tool_use' | 'streaming' | 'error';
10
+
11
+ export interface ToolCall {
12
+ id: string;
13
+ name: string;
14
+ args: Record<string, unknown>;
15
+ status: ToolStatus;
16
+ result?: string;
17
+ error?: string;
18
+ startedAt?: Date;
19
+ completedAt?: Date;
20
+ }
21
+
22
+ export interface Message {
23
+ id: string;
24
+ role: MessageRole;
25
+ content: string;
26
+ timestamp: Date;
27
+ toolCalls?: ToolCall[];
28
+ isStreaming?: boolean;
29
+ metadata?: Record<string, unknown>;
30
+ }
31
+
32
+ export interface AgentState {
33
+ status: AgentStatus;
34
+ currentTool?: string;
35
+ tokensUsed?: number;
36
+ contextTokens?: number;
37
+ tokensEstimated?: boolean;
38
+ authError?: boolean;
39
+ error?: string;
40
+ startedAt?: Date;
41
+ }
42
+
43
+ export interface Session {
44
+ id: string;
45
+ createdAt: Date;
46
+ messages: Message[];
47
+ metadata?: Record<string, unknown>;
48
+ }
49
+
50
+ export interface ZTCConfig {
51
+ zergEndpoint?: string;
52
+ maxTokens?: number;
53
+ timeout?: number;
54
+ tools?: string[];
55
+ }
56
+
57
+ // Tool definition for the agent
58
+ export interface ToolDefinition {
59
+ name: string;
60
+ description: string;
61
+ parameters: {
62
+ type: 'object';
63
+ properties: Record<string, {
64
+ type: string;
65
+ description: string;
66
+ enum?: string[];
67
+ }>;
68
+ required?: string[];
69
+ };
70
+ }
71
+
72
+ // Events emitted during agent execution
73
+ export type AgentEvent =
74
+ | { type: 'thinking_start' }
75
+ | { type: 'thinking_end' }
76
+ | { type: 'tool_start'; tool: string; args: Record<string, unknown> }
77
+ | { type: 'tool_end'; tool: string; result: string }
78
+ | { type: 'tool_error'; tool: string; error: string }
79
+ | { type: 'stream_start' }
80
+ | { type: 'stream_delta'; content: string }
81
+ | { type: 'stream_end' }
82
+ | { type: 'token_usage'; usage: { inputTokens: number; outputTokens: number; totalTokens: number; estimated?: boolean } }
83
+ | { type: 'error'; error: string };
@@ -0,0 +1,44 @@
1
+ ## UI Architecture (Renderer-Agnostic)
2
+
3
+ This directory defines a shared, renderer-agnostic UI tree for ZTC and thin adapters for Ink (CLI), Web (React DOM), and Vue.
4
+
5
+ ### Goals
6
+ - Single source of truth for layout and UI structure.
7
+ - Pixel-aligned monospace rendering in the browser.
8
+ - Optional Yoga integration for layout parity with Ink.
9
+
10
+ ### Structure
11
+ - `core/`: layout tree types + helpers
12
+ - `ink/`: Ink renderer adapter
13
+ - `web/`: React DOM renderer adapter
14
+ - `vue/`: Vue adapter (no Vue dependency; pass `h()` from your app)
15
+
16
+ ### Core Tree
17
+ The UI is expressed as a `LayoutNode` tree:
18
+ - `box` nodes with flex and spacing styles
19
+ - `text` nodes with basic text styles
20
+
21
+ This keeps the model portable across Ink/DOM/Vue.
22
+
23
+ ### Renderers
24
+ - **Ink** uses `Box`/`Text` directly.
25
+ - **Web** renders to `div`/`span` with strict monospace styles to match terminal layout.
26
+ - **Vue** uses a tiny helper `renderToVue(h, node)` that returns VNodes.
27
+
28
+ ### Nuxt/Vue Integration
29
+ Because `vue/` does not import Vue directly, you can pass Nuxt's `h`:
30
+
31
+ ```ts
32
+ import { renderToVue } from '~/ui/vue';
33
+
34
+ export default {
35
+ render() {
36
+ return renderToVue(this.$createElement, nodeTree);
37
+ }
38
+ };
39
+ ```
40
+
41
+ ### Next Steps
42
+ - Add Yoga-backed layout engine in `core/` for exact Ink parity.
43
+ - Move existing Ink UI components to build `LayoutNode` trees.
44
+ - Create a web mirror route that renders the same tree for debugging.
@@ -0,0 +1,9 @@
1
+ import { BoxNode, LayoutNode, TextNode } from './types.js';
2
+
3
+ export function box(children: LayoutNode[] = [], style?: BoxNode['style']): BoxNode {
4
+ return { type: 'box', children, style };
5
+ }
6
+
7
+ export function text(content: string, style?: TextNode['style']): TextNode {
8
+ return { type: 'text', text: content, style };
9
+ }
@@ -0,0 +1,4 @@
1
+ export type { LayoutNode, BoxNode, TextNode, Style, TextStyle } from './types.js';
2
+ export { box, text } from './factory.js';
3
+ export { toCssStyle } from './style.js';
4
+ export { computeLayout, type LayoutFrame } from './layout_yoga.js';
@@ -0,0 +1,38 @@
1
+ export interface InputKey {
2
+ return?: boolean;
3
+ shift?: boolean;
4
+ upArrow?: boolean;
5
+ downArrow?: boolean;
6
+ leftArrow?: boolean;
7
+ rightArrow?: boolean;
8
+ ctrl?: boolean;
9
+ meta?: boolean;
10
+ backspace?: boolean;
11
+ delete?: boolean;
12
+ }
13
+
14
+ export interface InputEvent {
15
+ input: string;
16
+ key: InputKey;
17
+ }
18
+
19
+ export interface InputBus {
20
+ subscribe(handler: (event: InputEvent) => void): () => void;
21
+ emit(event: InputEvent): void;
22
+ }
23
+
24
+ export function createInputBus(): InputBus {
25
+ const handlers = new Set<(event: InputEvent) => void>();
26
+
27
+ return {
28
+ subscribe(handler) {
29
+ handlers.add(handler);
30
+ return () => handlers.delete(handler);
31
+ },
32
+ emit(event) {
33
+ for (const handler of handlers) {
34
+ handler(event);
35
+ }
36
+ }
37
+ };
38
+ }