@celljs/ta-web 4.6.1 → 4.8.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 (361) hide show
  1. package/README.en.md +90 -0
  2. package/README.md +13 -7
  3. package/esm/browser/chat/chat-protocol.d.ts +4 -0
  4. package/esm/browser/chat/chat-view.js +4 -1
  5. package/esm/browser/chat/chat-view.js.map +1 -1
  6. package/esm/browser/chat/chat.d.ts +8 -1
  7. package/esm/browser/chat/chat.js +34 -15
  8. package/esm/browser/chat/chat.js.map +1 -1
  9. package/esm/browser/chat/draft-model.d.ts +15 -0
  10. package/esm/browser/chat/draft-model.js +53 -0
  11. package/esm/browser/chat/draft-model.js.map +1 -0
  12. package/esm/browser/components/account-menu.d.ts +3 -2
  13. package/esm/browser/components/account-menu.js +21 -16
  14. package/esm/browser/components/account-menu.js.map +1 -1
  15. package/esm/browser/components/app-view.js +13 -4
  16. package/esm/browser/components/app-view.js.map +1 -1
  17. package/esm/browser/components/chat-list.d.ts +3 -1
  18. package/esm/browser/components/chat-list.js +6 -1
  19. package/esm/browser/components/chat-list.js.map +1 -1
  20. package/esm/browser/components/composer-box.d.ts +6 -0
  21. package/esm/browser/components/composer-box.js +50 -13
  22. package/esm/browser/components/composer-box.js.map +1 -1
  23. package/esm/browser/components/composer.js +1 -1
  24. package/esm/browser/components/composer.js.map +1 -1
  25. package/esm/browser/components/dialog-view.d.ts +4 -1
  26. package/esm/browser/components/dialog-view.js +11 -7
  27. package/esm/browser/components/dialog-view.js.map +1 -1
  28. package/esm/browser/components/folder-picker.d.ts +37 -6
  29. package/esm/browser/components/folder-picker.js +155 -33
  30. package/esm/browser/components/folder-picker.js.map +1 -1
  31. package/esm/browser/components/notice-center.js +3 -1
  32. package/esm/browser/components/notice-center.js.map +1 -1
  33. package/esm/browser/components/remote-hosts.d.ts +7 -0
  34. package/esm/browser/components/remote-hosts.js +94 -0
  35. package/esm/browser/components/remote-hosts.js.map +1 -0
  36. package/esm/browser/components/remote-prompts.d.ts +7 -0
  37. package/esm/browser/components/remote-prompts.js +72 -0
  38. package/esm/browser/components/remote-prompts.js.map +1 -0
  39. package/esm/browser/components/session-view.js +48 -4
  40. package/esm/browser/components/session-view.js.map +1 -1
  41. package/esm/browser/components/settings-view.js +8 -1
  42. package/esm/browser/components/settings-view.js.map +1 -1
  43. package/esm/browser/components/terminal-art.d.ts +7 -0
  44. package/esm/browser/components/terminal-art.js +12 -0
  45. package/esm/browser/components/terminal-art.js.map +1 -0
  46. package/esm/browser/components/tool-view.js +1 -1
  47. package/esm/browser/components/tool-view.js.map +1 -1
  48. package/esm/browser/components/web-composer.d.ts +4 -1
  49. package/esm/browser/components/web-composer.js +2 -2
  50. package/esm/browser/components/web-composer.js.map +1 -1
  51. package/esm/browser/components/working-directory.js +1 -1
  52. package/esm/browser/components/working-directory.js.map +1 -1
  53. package/esm/browser/extension/icons.js +6 -1
  54. package/esm/browser/extension/icons.js.map +1 -1
  55. package/esm/browser/extension/web-extension-api.d.ts +120 -2
  56. package/esm/browser/extension/web-extensions.d.ts +3 -0
  57. package/esm/browser/extension/web-extensions.js +33 -1
  58. package/esm/browser/extension/web-extensions.js.map +1 -1
  59. package/esm/browser/i18n/locales.d.ts +44 -1
  60. package/esm/browser/i18n/messages.d.ts +43 -0
  61. package/esm/browser/i18n/messages.js +99 -13
  62. package/esm/browser/i18n/messages.js.map +1 -1
  63. package/esm/browser/notices/notices-protocol.d.ts +3 -0
  64. package/esm/browser/notices/notices.d.ts +3 -0
  65. package/esm/browser/notices/notices.js +15 -0
  66. package/esm/browser/notices/notices.js.map +1 -1
  67. package/esm/browser/style/base.d.ts +1 -1
  68. package/esm/browser/style/base.js +6 -1
  69. package/esm/browser/style/base.js.map +1 -1
  70. package/esm/browser/style/conversation.d.ts +1 -1
  71. package/esm/browser/style/conversation.js +16 -1
  72. package/esm/browser/style/conversation.js.map +1 -1
  73. package/esm/browser/style/layout.d.ts +1 -1
  74. package/esm/browser/style/layout.js +53 -15
  75. package/esm/browser/style/layout.js.map +1 -1
  76. package/esm/browser/style/shell.d.ts +1 -1
  77. package/esm/browser/style/shell.js +1 -0
  78. package/esm/browser/style/shell.js.map +1 -1
  79. package/esm/browser/terminal/canvas-font.d.ts +10 -0
  80. package/esm/browser/terminal/canvas-font.js +34 -0
  81. package/esm/browser/terminal/canvas-font.js.map +1 -0
  82. package/esm/browser/terminal/terminal-links.d.ts +18 -0
  83. package/esm/browser/terminal/terminal-links.js +72 -0
  84. package/esm/browser/terminal/terminal-links.js.map +1 -0
  85. package/esm/browser/terminal/terminal-theme.d.ts +8 -0
  86. package/esm/browser/terminal/terminal-theme.js +65 -0
  87. package/esm/browser/terminal/terminal-theme.js.map +1 -0
  88. package/esm/browser/terminal/web-terminal.d.ts +74 -0
  89. package/esm/browser/terminal/web-terminal.js +300 -0
  90. package/esm/browser/terminal/web-terminal.js.map +1 -0
  91. package/esm/browser/terminal/xterm.d.ts +5 -0
  92. package/esm/browser/terminal/xterm.js +9 -0
  93. package/esm/browser/terminal/xterm.js.map +1 -0
  94. package/esm/browser/util/desktop.d.ts +43 -0
  95. package/esm/browser/util/desktop.js +55 -0
  96. package/esm/browser/util/desktop.js.map +1 -0
  97. package/esm/browser/util/file-drag.d.ts +26 -0
  98. package/esm/browser/util/file-drag.js +73 -0
  99. package/esm/browser/util/file-drag.js.map +1 -0
  100. package/esm/browser/util/message.d.ts +1 -0
  101. package/esm/browser/util/message.js +7 -5
  102. package/esm/browser/util/message.js.map +1 -1
  103. package/esm/browser/util/terminal-text.d.ts +33 -0
  104. package/esm/browser/util/terminal-text.js +209 -0
  105. package/esm/browser/util/terminal-text.js.map +1 -0
  106. package/esm/browser/util/tool.js +16 -0
  107. package/esm/browser/util/tool.js.map +1 -1
  108. package/esm/browser/workbench-protocol.d.ts +7 -1
  109. package/esm/browser/workbench-protocol.js.map +1 -1
  110. package/esm/browser/workbench.d.ts +7 -1
  111. package/esm/browser/workbench.js +23 -0
  112. package/esm/browser/workbench.js.map +1 -1
  113. package/lib/browser/chat/chat-protocol.d.ts +4 -0
  114. package/lib/browser/chat/chat-protocol.d.ts.map +1 -1
  115. package/lib/browser/chat/chat-view.d.ts.map +1 -1
  116. package/lib/browser/chat/chat-view.js +4 -1
  117. package/lib/browser/chat/chat-view.js.map +1 -1
  118. package/lib/browser/chat/chat.d.ts +8 -1
  119. package/lib/browser/chat/chat.d.ts.map +1 -1
  120. package/lib/browser/chat/chat.js +34 -15
  121. package/lib/browser/chat/chat.js.map +1 -1
  122. package/lib/browser/chat/chat.spec.js +30 -0
  123. package/lib/browser/chat/chat.spec.js.map +1 -1
  124. package/lib/browser/chat/draft-model.d.ts +16 -0
  125. package/lib/browser/chat/draft-model.d.ts.map +1 -0
  126. package/lib/browser/chat/draft-model.js +90 -0
  127. package/lib/browser/chat/draft-model.js.map +1 -0
  128. package/lib/browser/chat/draft-model.spec.d.ts +2 -0
  129. package/lib/browser/chat/draft-model.spec.d.ts.map +1 -0
  130. package/lib/browser/chat/draft-model.spec.js +31 -0
  131. package/lib/browser/chat/draft-model.spec.js.map +1 -0
  132. package/lib/browser/components/account-menu.d.ts +3 -2
  133. package/lib/browser/components/account-menu.d.ts.map +1 -1
  134. package/lib/browser/components/account-menu.js +21 -16
  135. package/lib/browser/components/account-menu.js.map +1 -1
  136. package/lib/browser/components/app-view.d.ts.map +1 -1
  137. package/lib/browser/components/app-view.js +13 -4
  138. package/lib/browser/components/app-view.js.map +1 -1
  139. package/lib/browser/components/chat-list.d.ts +3 -1
  140. package/lib/browser/components/chat-list.d.ts.map +1 -1
  141. package/lib/browser/components/chat-list.js +6 -1
  142. package/lib/browser/components/chat-list.js.map +1 -1
  143. package/lib/browser/components/composer-box.d.ts +6 -0
  144. package/lib/browser/components/composer-box.d.ts.map +1 -1
  145. package/lib/browser/components/composer-box.js +51 -14
  146. package/lib/browser/components/composer-box.js.map +1 -1
  147. package/lib/browser/components/composer.d.ts.map +1 -1
  148. package/lib/browser/components/composer.js +1 -1
  149. package/lib/browser/components/composer.js.map +1 -1
  150. package/lib/browser/components/dialog-view.d.ts +4 -1
  151. package/lib/browser/components/dialog-view.d.ts.map +1 -1
  152. package/lib/browser/components/dialog-view.js +11 -7
  153. package/lib/browser/components/dialog-view.js.map +1 -1
  154. package/lib/browser/components/folder-picker.d.ts +37 -6
  155. package/lib/browser/components/folder-picker.d.ts.map +1 -1
  156. package/lib/browser/components/folder-picker.js +156 -33
  157. package/lib/browser/components/folder-picker.js.map +1 -1
  158. package/lib/browser/components/folder-picker.spec.js +15 -0
  159. package/lib/browser/components/folder-picker.spec.js.map +1 -1
  160. package/lib/browser/components/notice-center.d.ts.map +1 -1
  161. package/lib/browser/components/notice-center.js +3 -1
  162. package/lib/browser/components/notice-center.js.map +1 -1
  163. package/lib/browser/components/plus-menu.spec.d.ts +2 -0
  164. package/lib/browser/components/plus-menu.spec.d.ts.map +1 -0
  165. package/lib/browser/components/plus-menu.spec.js +18 -0
  166. package/lib/browser/components/plus-menu.spec.js.map +1 -0
  167. package/lib/browser/components/remote-hosts.d.ts +8 -0
  168. package/lib/browser/components/remote-hosts.d.ts.map +1 -0
  169. package/lib/browser/components/remote-hosts.js +130 -0
  170. package/lib/browser/components/remote-hosts.js.map +1 -0
  171. package/lib/browser/components/remote-prompts.d.ts +8 -0
  172. package/lib/browser/components/remote-prompts.d.ts.map +1 -0
  173. package/lib/browser/components/remote-prompts.js +108 -0
  174. package/lib/browser/components/remote-prompts.js.map +1 -0
  175. package/lib/browser/components/session-view.d.ts.map +1 -1
  176. package/lib/browser/components/session-view.js +48 -4
  177. package/lib/browser/components/session-view.js.map +1 -1
  178. package/lib/browser/components/settings-view.d.ts.map +1 -1
  179. package/lib/browser/components/settings-view.js +7 -0
  180. package/lib/browser/components/settings-view.js.map +1 -1
  181. package/lib/browser/components/terminal-art.d.ts +8 -0
  182. package/lib/browser/components/terminal-art.d.ts.map +1 -0
  183. package/lib/browser/components/terminal-art.js +48 -0
  184. package/lib/browser/components/terminal-art.js.map +1 -0
  185. package/lib/browser/components/tool-view.js +1 -1
  186. package/lib/browser/components/tool-view.js.map +1 -1
  187. package/lib/browser/components/web-composer.d.ts +4 -1
  188. package/lib/browser/components/web-composer.d.ts.map +1 -1
  189. package/lib/browser/components/web-composer.js +2 -2
  190. package/lib/browser/components/web-composer.js.map +1 -1
  191. package/lib/browser/components/working-directory.js +1 -1
  192. package/lib/browser/components/working-directory.js.map +1 -1
  193. package/lib/browser/extension/icons.d.ts.map +1 -1
  194. package/lib/browser/extension/icons.js +5 -0
  195. package/lib/browser/extension/icons.js.map +1 -1
  196. package/lib/browser/extension/web-extension-api.d.ts +120 -2
  197. package/lib/browser/extension/web-extension-api.d.ts.map +1 -1
  198. package/lib/browser/extension/web-extensions.d.ts +3 -0
  199. package/lib/browser/extension/web-extensions.d.ts.map +1 -1
  200. package/lib/browser/extension/web-extensions.js +33 -1
  201. package/lib/browser/extension/web-extensions.js.map +1 -1
  202. package/lib/browser/i18n/locales.d.ts +44 -1
  203. package/lib/browser/i18n/locales.d.ts.map +1 -1
  204. package/lib/browser/i18n/messages.d.ts +43 -0
  205. package/lib/browser/i18n/messages.d.ts.map +1 -1
  206. package/lib/browser/i18n/messages.js +99 -13
  207. package/lib/browser/i18n/messages.js.map +1 -1
  208. package/lib/browser/notices/notices-protocol.d.ts +3 -0
  209. package/lib/browser/notices/notices-protocol.d.ts.map +1 -1
  210. package/lib/browser/notices/notices.d.ts +3 -0
  211. package/lib/browser/notices/notices.d.ts.map +1 -1
  212. package/lib/browser/notices/notices.js +15 -0
  213. package/lib/browser/notices/notices.js.map +1 -1
  214. package/lib/browser/notices/notices.spec.js +8 -3
  215. package/lib/browser/notices/notices.spec.js.map +1 -1
  216. package/lib/browser/style/base.d.ts +1 -1
  217. package/lib/browser/style/base.d.ts.map +1 -1
  218. package/lib/browser/style/base.js +6 -1
  219. package/lib/browser/style/base.js.map +1 -1
  220. package/lib/browser/style/conversation.d.ts +1 -1
  221. package/lib/browser/style/conversation.d.ts.map +1 -1
  222. package/lib/browser/style/conversation.js +16 -1
  223. package/lib/browser/style/conversation.js.map +1 -1
  224. package/lib/browser/style/layout.d.ts +1 -1
  225. package/lib/browser/style/layout.d.ts.map +1 -1
  226. package/lib/browser/style/layout.js +53 -15
  227. package/lib/browser/style/layout.js.map +1 -1
  228. package/lib/browser/style/shell.d.ts +1 -1
  229. package/lib/browser/style/shell.d.ts.map +1 -1
  230. package/lib/browser/style/shell.js +1 -0
  231. package/lib/browser/style/shell.js.map +1 -1
  232. package/lib/browser/terminal/canvas-font.d.ts +11 -0
  233. package/lib/browser/terminal/canvas-font.d.ts.map +1 -0
  234. package/lib/browser/terminal/canvas-font.js +37 -0
  235. package/lib/browser/terminal/canvas-font.js.map +1 -0
  236. package/lib/browser/terminal/canvas-font.spec.d.ts +2 -0
  237. package/lib/browser/terminal/canvas-font.spec.d.ts.map +1 -0
  238. package/lib/browser/terminal/canvas-font.spec.js +32 -0
  239. package/lib/browser/terminal/canvas-font.spec.js.map +1 -0
  240. package/lib/browser/terminal/terminal-links.d.ts +19 -0
  241. package/lib/browser/terminal/terminal-links.d.ts.map +1 -0
  242. package/lib/browser/terminal/terminal-links.js +75 -0
  243. package/lib/browser/terminal/terminal-links.js.map +1 -0
  244. package/lib/browser/terminal/terminal-links.spec.d.ts +2 -0
  245. package/lib/browser/terminal/terminal-links.spec.d.ts.map +1 -0
  246. package/lib/browser/terminal/terminal-links.spec.js +30 -0
  247. package/lib/browser/terminal/terminal-links.spec.js.map +1 -0
  248. package/lib/browser/terminal/terminal-theme.d.ts +9 -0
  249. package/lib/browser/terminal/terminal-theme.d.ts.map +1 -0
  250. package/lib/browser/terminal/terminal-theme.js +68 -0
  251. package/lib/browser/terminal/terminal-theme.js.map +1 -0
  252. package/lib/browser/terminal/terminal-theme.spec.d.ts +2 -0
  253. package/lib/browser/terminal/terminal-theme.spec.d.ts.map +1 -0
  254. package/lib/browser/terminal/terminal-theme.spec.js +24 -0
  255. package/lib/browser/terminal/terminal-theme.spec.js.map +1 -0
  256. package/lib/browser/terminal/web-terminal.d.ts +75 -0
  257. package/lib/browser/terminal/web-terminal.d.ts.map +1 -0
  258. package/lib/browser/terminal/web-terminal.js +304 -0
  259. package/lib/browser/terminal/web-terminal.js.map +1 -0
  260. package/lib/browser/terminal/xterm.d.ts +6 -0
  261. package/lib/browser/terminal/xterm.d.ts.map +1 -0
  262. package/lib/browser/terminal/xterm.js +16 -0
  263. package/lib/browser/terminal/xterm.js.map +1 -0
  264. package/lib/browser/util/desktop.d.ts +44 -0
  265. package/lib/browser/util/desktop.d.ts.map +1 -0
  266. package/lib/browser/util/desktop.js +58 -0
  267. package/lib/browser/util/desktop.js.map +1 -0
  268. package/lib/browser/util/desktop.spec.d.ts +2 -0
  269. package/lib/browser/util/desktop.spec.d.ts.map +1 -0
  270. package/lib/browser/util/desktop.spec.js +67 -0
  271. package/lib/browser/util/desktop.spec.js.map +1 -0
  272. package/lib/browser/util/file-drag.d.ts +27 -0
  273. package/lib/browser/util/file-drag.d.ts.map +1 -0
  274. package/lib/browser/util/file-drag.js +76 -0
  275. package/lib/browser/util/file-drag.js.map +1 -0
  276. package/lib/browser/util/file-drag.spec.d.ts +2 -0
  277. package/lib/browser/util/file-drag.spec.d.ts.map +1 -0
  278. package/lib/browser/util/file-drag.spec.js +46 -0
  279. package/lib/browser/util/file-drag.spec.js.map +1 -0
  280. package/lib/browser/util/message.d.ts +1 -0
  281. package/lib/browser/util/message.d.ts.map +1 -1
  282. package/lib/browser/util/message.js +7 -5
  283. package/lib/browser/util/message.js.map +1 -1
  284. package/lib/browser/util/message.spec.js +2 -0
  285. package/lib/browser/util/message.spec.js.map +1 -1
  286. package/lib/browser/util/terminal-text.d.ts +34 -0
  287. package/lib/browser/util/terminal-text.d.ts.map +1 -0
  288. package/lib/browser/util/terminal-text.js +212 -0
  289. package/lib/browser/util/terminal-text.js.map +1 -0
  290. package/lib/browser/util/terminal-text.spec.d.ts +2 -0
  291. package/lib/browser/util/terminal-text.spec.d.ts.map +1 -0
  292. package/lib/browser/util/terminal-text.spec.js +54 -0
  293. package/lib/browser/util/terminal-text.spec.js.map +1 -0
  294. package/lib/browser/util/tool.d.ts.map +1 -1
  295. package/lib/browser/util/tool.js +16 -0
  296. package/lib/browser/util/tool.js.map +1 -1
  297. package/lib/browser/util/tool.spec.js +12 -0
  298. package/lib/browser/util/tool.spec.js.map +1 -1
  299. package/lib/browser/workbench-protocol.d.ts +7 -1
  300. package/lib/browser/workbench-protocol.d.ts.map +1 -1
  301. package/lib/browser/workbench-protocol.js.map +1 -1
  302. package/lib/browser/workbench.d.ts +7 -1
  303. package/lib/browser/workbench.d.ts.map +1 -1
  304. package/lib/browser/workbench.js +23 -0
  305. package/lib/browser/workbench.js.map +1 -1
  306. package/package.json +11 -7
  307. package/src/browser/chat/chat-protocol.ts +4 -0
  308. package/src/browser/chat/chat-view.tsx +5 -1
  309. package/src/browser/chat/chat.spec.ts +31 -0
  310. package/src/browser/chat/chat.ts +36 -14
  311. package/src/browser/chat/draft-model.spec.tsx +31 -0
  312. package/src/browser/chat/draft-model.tsx +63 -0
  313. package/src/browser/components/account-menu.tsx +23 -20
  314. package/src/browser/components/app-view.tsx +12 -3
  315. package/src/browser/components/chat-list.tsx +9 -2
  316. package/src/browser/components/composer-box.tsx +52 -6
  317. package/src/browser/components/composer.tsx +1 -0
  318. package/src/browser/components/dialog-view.tsx +16 -7
  319. package/src/browser/components/folder-picker.spec.ts +17 -0
  320. package/src/browser/components/folder-picker.tsx +221 -39
  321. package/src/browser/components/notice-center.tsx +7 -1
  322. package/src/browser/components/plus-menu.spec.ts +16 -0
  323. package/src/browser/components/remote-hosts.tsx +149 -0
  324. package/src/browser/components/remote-prompts.tsx +111 -0
  325. package/src/browser/components/session-view.tsx +65 -4
  326. package/src/browser/components/settings-view.tsx +8 -0
  327. package/src/browser/components/terminal-art.tsx +21 -0
  328. package/src/browser/components/tool-view.tsx +1 -1
  329. package/src/browser/components/web-composer.tsx +18 -3
  330. package/src/browser/components/working-directory.tsx +1 -1
  331. package/src/browser/extension/icons.ts +10 -0
  332. package/src/browser/extension/web-extension-api.ts +134 -2
  333. package/src/browser/extension/web-extensions.ts +47 -2
  334. package/src/browser/i18n/messages.ts +99 -13
  335. package/src/browser/notices/notices-protocol.ts +3 -0
  336. package/src/browser/notices/notices.spec.ts +9 -3
  337. package/src/browser/notices/notices.ts +17 -1
  338. package/src/browser/style/base.ts +6 -1
  339. package/src/browser/style/conversation.ts +16 -1
  340. package/src/browser/style/layout.ts +53 -15
  341. package/src/browser/style/shell.ts +1 -0
  342. package/src/browser/terminal/canvas-font.spec.ts +29 -0
  343. package/src/browser/terminal/canvas-font.ts +32 -0
  344. package/src/browser/terminal/terminal-links.spec.ts +32 -0
  345. package/src/browser/terminal/terminal-links.ts +75 -0
  346. package/src/browser/terminal/terminal-theme.spec.ts +23 -0
  347. package/src/browser/terminal/terminal-theme.ts +66 -0
  348. package/src/browser/terminal/web-terminal.ts +330 -0
  349. package/src/browser/terminal/xterm.ts +10 -0
  350. package/src/browser/util/desktop.spec.ts +68 -0
  351. package/src/browser/util/desktop.ts +96 -0
  352. package/src/browser/util/file-drag.spec.ts +48 -0
  353. package/src/browser/util/file-drag.ts +78 -0
  354. package/src/browser/util/message.spec.ts +2 -0
  355. package/src/browser/util/message.ts +7 -4
  356. package/src/browser/util/terminal-text.spec.ts +60 -0
  357. package/src/browser/util/terminal-text.ts +223 -0
  358. package/src/browser/util/tool.spec.ts +12 -0
  359. package/src/browser/util/tool.ts +17 -0
  360. package/src/browser/workbench-protocol.ts +8 -0
  361. package/src/browser/workbench.ts +29 -0
@@ -0,0 +1,111 @@
1
+ import type { TaRemoteEvent, TaRemotePrompt } from '@celljs/ta-protocol';
2
+ import { KeyRound, Server, ShieldQuestion } from 'lucide-react';
3
+ import * as React from 'react';
4
+ import { createPortal } from 'react-dom';
5
+ import { useNotices, useWorkbench } from '../hooks';
6
+ import { useT } from '../i18n/use-t';
7
+ import { Icon } from './icon';
8
+
9
+ /** Asks what ssh asks: a password or a passphrase (not shown), whether to trust a new host, or a line of text. */
10
+ function PromptDialog({ prompt, onAnswer }: { prompt: TaRemotePrompt; onAnswer(value: string | null): void }) {
11
+ const t = useT();
12
+ const [value, setValue] = React.useState('');
13
+ const confirm = prompt.kind === 'confirm';
14
+ return createPortal(
15
+ <div className="ta-modal-scrim">
16
+ <button type="button" className="ta-overlay-close" aria-label={t('ta.cancel')} tabIndex={-1} onClick={() => onAnswer(null)} />
17
+ <form
18
+ className="ta-modal ta-confirm ta-remote-prompt"
19
+ role="alertdialog"
20
+ aria-modal="true"
21
+ aria-label={t('ta.remote.prompt.title', { host: prompt.host })}
22
+ onKeyDown={event => event.key === 'Escape' && onAnswer(null)}
23
+ onSubmit={event => {
24
+ event.preventDefault();
25
+ onAnswer(confirm ? 'yes' : value);
26
+ }}
27
+ >
28
+ <div className="ta-confirm-title">
29
+ <Icon icon={confirm ? ShieldQuestion : prompt.kind === 'secret' ? KeyRound : Server} size={16} />
30
+ {t('ta.remote.prompt.title', { host: prompt.host })}
31
+ </div>
32
+ <pre className="ta-remote-message">{prompt.message}</pre>
33
+ {!confirm && (
34
+ <label className="ta-field">
35
+ <input
36
+ autoFocus
37
+ type={prompt.kind === 'secret' ? 'password' : 'text'}
38
+ autoComplete="off"
39
+ spellCheck={false}
40
+ value={value}
41
+ aria-label={prompt.message}
42
+ onChange={event => setValue(event.target.value)}
43
+ />
44
+ </label>
45
+ )}
46
+ <div className="ta-dialog-actions">
47
+ <button type="button" className="ta-button" onClick={() => onAnswer(confirm ? 'no' : null)}>
48
+ {t('ta.cancel')}
49
+ </button>
50
+ <button type="submit" className="ta-button ta-primary" autoFocus={confirm}>
51
+ {t(confirm ? 'ta.remote.prompt.trust' : 'ta.remote.prompt.continue')}
52
+ </button>
53
+ </div>
54
+ </form>
55
+ </div>,
56
+ document.body,
57
+ );
58
+ }
59
+
60
+ /**
61
+ * What ssh asks while ta serve connects to a host, one question at a time, in every page that is open (the
62
+ * first answer counts); a line at the bottom while a host connects, which may take a while the first
63
+ * time (it installs Node.js there); and a notice when a connection is lost.
64
+ */
65
+ export function RemotePrompts() {
66
+ const t = useT();
67
+ const [, bench] = useWorkbench();
68
+ const [, notices] = useNotices();
69
+ const [prompts, setPrompts] = React.useState<TaRemotePrompt[]>([]);
70
+ const [steps, setSteps] = React.useState<Record<string, string>>({});
71
+ const connected = React.useRef(new Set<string>());
72
+ React.useEffect(
73
+ () =>
74
+ bench.onRemoteEvent((event: TaRemoteEvent) => {
75
+ if (event.type === 'prompt') {
76
+ setPrompts(shown => (shown.some(prompt => prompt.promptId === event.prompt.promptId) ? shown : [...shown, event.prompt]));
77
+ } else if (event.type === 'prompt_closed') {
78
+ setPrompts(shown => shown.filter(prompt => prompt.promptId !== event.promptId));
79
+ } else if (event.type === 'progress') {
80
+ setSteps(shown => ({ ...shown, [event.host]: t(`ta.remote.step.${event.step}`, { host: event.host, detail: event.detail ?? '' }) }));
81
+ } else {
82
+ setSteps(({ [event.host]: _gone, ...rest }) => rest);
83
+ // Lost, not closed on purpose; a connection that failed is the caller's to tell.
84
+ if (!event.connected && event.error && connected.current.has(event.host)) {
85
+ notices.notify(t('ta.remote.lost', { host: event.host }), { level: 'warning', detail: event.error });
86
+ }
87
+ connected.current[event.connected ? 'add' : 'delete'](event.host);
88
+ }
89
+ }),
90
+ [bench, notices, t],
91
+ );
92
+ const [prompt] = prompts;
93
+ const answer = (value: string | null) => {
94
+ setPrompts(shown => shown.slice(1));
95
+ void bench.remote.answer(prompt.promptId, value).catch(() => undefined);
96
+ };
97
+ const lines = Object.values(steps);
98
+ return (
99
+ <>
100
+ {prompt && <PromptDialog key={prompt.promptId} prompt={prompt} onAnswer={answer} />}
101
+ {lines.length > 0 &&
102
+ createPortal(
103
+ <div className="ta-remote-status" role="status">
104
+ <span className="ta-spinner" />
105
+ {lines.join(' · ')}
106
+ </div>,
107
+ document.body,
108
+ )}
109
+ </>
110
+ );
111
+ }
@@ -4,6 +4,7 @@ import * as React from 'react';
4
4
  import { useNotices, useOpenLink, useSessionState } from '../hooks';
5
5
  import { useT } from '../i18n/use-t';
6
6
  import { MessageUtil } from '../util/message';
7
+ import { TerminalText } from '../util/terminal-text';
7
8
  import { Composer } from './composer';
8
9
  import type { ComposerBoxHandle } from './composer-box';
9
10
  import { useConversationScroll } from './conversation-scroll';
@@ -14,11 +15,17 @@ import { useMessageActions } from './message-actions';
14
15
  import { MessageActions } from './message-footer';
15
16
  import { ConversationSession, MessageList } from './message-list';
16
17
  import { useSessionSettings } from './session-settings';
18
+ import { TerminalArt } from './terminal-art';
17
19
 
18
- /** What the extensions of the session say with `notify` goes to the notices of the page; what was said before it opened stays quiet. */
20
+ /**
21
+ * What the extensions of the session say with `notify` goes to the notices of the page; what was said before it
22
+ * opened stays quiet. A picture in it (a QR code to sign in) is drawn, and stays until the next notice of the
23
+ * session, which says how it went or brings a new code.
24
+ */
19
25
  function useSessionNotices(notices: Notice[]) {
20
26
  const [, center] = useNotices();
21
27
  const seen = React.useRef<Set<string> | undefined>(undefined);
28
+ const picture = React.useRef<number>(undefined);
22
29
  React.useEffect(() => {
23
30
  if (!seen.current) {
24
31
  seen.current = new Set(notices.map(notice => notice.id));
@@ -27,12 +34,46 @@ function useSessionNotices(notices: Notice[]) {
27
34
  for (const notice of notices) {
28
35
  if (!seen.current.has(notice.id)) {
29
36
  seen.current.add(notice.id);
30
- center.notify(notice.message, { level: notice.type });
37
+ if (picture.current !== undefined) {
38
+ center.dismiss(picture.current);
39
+ picture.current = undefined;
40
+ }
41
+ const { text, art } = TerminalText.art(notice.message);
42
+ const id = center.notify(text, { level: notice.type, art, sticky: art !== undefined });
43
+ picture.current = art ? id : undefined;
31
44
  }
32
45
  }
33
46
  }, [notices, center]);
34
47
  }
35
48
 
49
+ /** What an extension shows above or below the message box (`setWidget`): its lines as a terminal draws them, a picture in them drawn. */
50
+ function WidgetView({ lines }: { lines: string[] }) {
51
+ const t = useT();
52
+ const { text, art } = React.useMemo(() => TerminalText.art(lines.join('\n')), [lines]);
53
+ return (
54
+ <div className="ta-widget">
55
+ {text && <pre className="ta-widget-text">{text}</pre>}
56
+ {art && <TerminalArt art={art} className="ta-widget-art" label={t('ta.notice.picture')} />}
57
+ </div>
58
+ );
59
+ }
60
+
61
+ /** The status of an extension, as a chip: its label, then each part, with a dot for the sign of its state. */
62
+ function StatusChip({ text }: { text: string }) {
63
+ const { label, segments } = React.useMemo(() => TerminalText.status(text), [text]);
64
+ return (
65
+ <span className="ta-statusline-item" title={text}>
66
+ {label && <span className="ta-statusline-label">{label}</span>}
67
+ {segments.map((segment, index) => (
68
+ <span key={index} className={`ta-statusline-part${segment.tone ? ` ta-tone-${segment.tone}` : ''}`}>
69
+ {segment.tone && <span className={`ta-status ta-status-${segment.tone}`} />}
70
+ {segment.text}
71
+ </span>
72
+ ))}
73
+ </span>
74
+ );
75
+ }
76
+
36
77
  export interface SessionViewProps {
37
78
  store: SessionStore;
38
79
  server: TaServer;
@@ -80,6 +121,15 @@ export function SessionView({
80
121
  const composer = React.useRef<ComposerBoxHandle>(null);
81
122
  const cwd = info?.cwd;
82
123
  const messageActions = useMessageActions(store, server, state.working, cwd, composer, onActivity);
124
+ // An extension puts text in the message box, as in pi's terminal.
125
+ const editorText = state.editorText;
126
+ const takenText = React.useRef(editorText?.id);
127
+ React.useEffect(() => {
128
+ if (editorText && editorText.id !== takenText.current) {
129
+ takenText.current = editorText.id;
130
+ composer.current?.setText(TerminalText.plain(editorText.text));
131
+ }
132
+ }, [editorText]);
83
133
  React.useEffect(() => {
84
134
  if (draftText) {
85
135
  composer.current?.setText(draftText);
@@ -97,7 +147,10 @@ export function SessionView({
97
147
  }
98
148
  }, [state.closed, onClosed]);
99
149
 
100
- const statuses = Object.values(state.status);
150
+ const statuses = Object.entries(state.status).filter(([, text]) => TerminalText.plain(text).trim());
151
+ const widgets = Object.entries(state.widgets);
152
+ const widgetsAt = (placement: 'aboveEditor' | 'belowEditor') =>
153
+ widgets.filter(([, widget]) => widget.placement === placement).map(([key, widget]) => <WidgetView key={key} lines={widget.lines} />);
101
154
  const dialog = state.pendingUi[0];
102
155
  const title = info?.sessionName || (info ? MessageUtil.basename(info.cwd) : t('ta.session.title'));
103
156
 
@@ -134,6 +187,7 @@ export function SessionView({
134
187
  <div className="ta-bottom">
135
188
  {dialog && <DialogView key={dialog.id} request={dialog} respond={response => store.respondUi(response).catch(fail)} />}
136
189
  {aboveComposer}
190
+ {widgetsAt('aboveEditor')}
137
191
  <Composer
138
192
  ref={composer}
139
193
  store={store}
@@ -146,7 +200,14 @@ export function SessionView({
146
200
  onError={fail}
147
201
  />
148
202
  {belowComposer}
149
- {statuses.length > 0 && <div className="ta-statusline">{statuses.join(' · ')}</div>}
203
+ {widgetsAt('belowEditor')}
204
+ {statuses.length > 0 && (
205
+ <div className="ta-statusline">
206
+ {statuses.map(([key, text]) => (
207
+ <StatusChip key={key} text={text} />
208
+ ))}
209
+ </div>
210
+ )}
150
211
  </div>
151
212
  </section>
152
213
  );
@@ -19,6 +19,7 @@ import {
19
19
  Puzzle,
20
20
  RefreshCw,
21
21
  Search,
22
+ Server,
22
23
  Smartphone,
23
24
  Sparkles,
24
25
  Sun,
@@ -37,6 +38,7 @@ import { AgentControl, ScopeBar, useAgentSettings } from './agent-settings-view'
37
38
  import { AuthDialog } from './auth-view';
38
39
  import { Icon, IconButton } from './icon';
39
40
  import { RelayDialog } from './relay-view';
41
+ import { RemoteHosts } from './remote-hosts';
40
42
  import { type Choice, Keys, Row, type RowEntry, row, Segmented, Switch } from './settings-controls';
41
43
  import { TrustedDomains } from './trusted-domains';
42
44
  import { WorkingDirectoryPicker } from './working-directory';
@@ -336,6 +338,12 @@ function useParts(scope: TaSettingsScope, onScope: (scope: TaSettingsScope) => v
336
338
  ),
337
339
  ],
338
340
  },
341
+ {
342
+ id: 'remote',
343
+ title: t('ta.remote.title'),
344
+ icon: Server,
345
+ rows: [row('remote', [t('ta.remote.title'), t('ta.remote.description'), 'ssh'], <RemoteHosts />)],
346
+ },
339
347
  {
340
348
  id: 'shortcuts',
341
349
  title: t('ta.settings.shortcuts'),
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ import { TerminalText } from '../util/terminal-text';
3
+
4
+ /** A picture of cells, as a QR code to scan: black on white whatever the theme, with a margin of white. */
5
+ export function TerminalArt({ art, className, label }: { art: boolean[][]; className: string; label: string }) {
6
+ const path = React.useMemo(() => TerminalText.path(art), [art]);
7
+ const width = Math.max(...art.map(row => row.length));
8
+ const margin = 2;
9
+ return (
10
+ <svg
11
+ className={className}
12
+ viewBox={`${-margin} ${-margin} ${width + margin * 2} ${art.length + margin * 2}`}
13
+ role="img"
14
+ aria-label={label}
15
+ shapeRendering="crispEdges"
16
+ >
17
+ <rect x={-margin} y={-margin} width={width + margin * 2} height={art.length + margin * 2} fill="#fff" />
18
+ <path d={path} fill="#111" />
19
+ </svg>
20
+ );
21
+ }
@@ -63,7 +63,7 @@ function ToolRow({ name, args, status, trailing, details }: ToolRowProps) {
63
63
  const line = (
64
64
  <>
65
65
  <StatusDot status={status} />
66
- <span className="ta-tool-verb">{summary.verb ? t(summary.verb) : name}</span>
66
+ <span className="ta-tool-verb">{summary.verb ? t(summary.verb) : summary.name}</span>
67
67
  {summary.target && <span className={`ta-tool-target ${summary.code ? 'ta-mono' : ''}`}>{summary.target}</span>}
68
68
  {details ? <Icon icon={ChevronRight} size={13} className="ta-tool-chevron" /> : <span className="ta-tool-chevron" />}
69
69
  </>
@@ -5,7 +5,7 @@ import { useT } from '../i18n/use-t';
5
5
  import type { TaNotices } from '../notices/notices-protocol';
6
6
  import { ComposerUtil } from '../util/composer';
7
7
  import { ComposerBox } from './composer-box';
8
- import { DirectoryButton } from './folder-picker';
8
+ import { DirectoryButton, type FolderPickerRemote } from './folder-picker';
9
9
 
10
10
  export interface WebComposerHostProps extends WebComposerProps {
11
11
  /** Where a failure to send goes. */
@@ -14,10 +14,24 @@ export interface WebComposerHostProps extends WebComposerProps {
14
14
  listDirectory?(directory: string): Promise<TaDirEntry[]>;
15
15
  /** The directory of ta serve: that of a `cwd` left empty. */
16
16
  serverCwd?: string;
17
+ /** The hosts of ssh, which the button offers too. */
18
+ remote?: FolderPickerRemote;
17
19
  }
18
20
 
19
21
  /** The message box as web extensions get it (`pi.ui.Composer`): text only, `@` for the names they give; a failure is a notice of the page. */
20
- export function WebComposer({ notices, placeholder, onSend, mentions, mentionLabel, actions, cwd, onPickCwd, listDirectory, serverCwd }: WebComposerHostProps) {
22
+ export function WebComposer({
23
+ notices,
24
+ placeholder,
25
+ onSend,
26
+ mentions,
27
+ mentionLabel,
28
+ actions,
29
+ cwd,
30
+ onPickCwd,
31
+ listDirectory,
32
+ serverCwd,
33
+ remote,
34
+ }: WebComposerHostProps) {
21
35
  const t = useT();
22
36
  const [query, setQuery] = React.useState<string>();
23
37
  return (
@@ -40,7 +54,8 @@ export function WebComposer({ notices, placeholder, onSend, mentions, mentionLab
40
54
  }
41
55
  mentionLabel={mentions ? mentionLabel : undefined}
42
56
  actions={actions}
43
- beside={onPickCwd && listDirectory && <DirectoryButton cwd={cwd || serverCwd || ''} list={listDirectory} onPick={onPickCwd} />}
57
+ beside={onPickCwd && listDirectory && <DirectoryButton cwd={cwd || serverCwd || ''} list={listDirectory} remote={remote} onPick={onPickCwd} />}
58
+ cwd={cwd || serverCwd}
44
59
  onError={cause => notices.error(cause)}
45
60
  />
46
61
  );
@@ -18,5 +18,5 @@ export function WorkingDirectoryPicker({ onClose }: { onClose(): void }) {
18
18
  notices.error(error);
19
19
  }
20
20
  };
21
- return <FolderPicker list={list} initial={workbench.server?.cwd ?? '.'} onPick={pick} onClose={onClose} />;
21
+ return <FolderPicker list={list} initial={workbench.server?.cwd ?? '.'} remote={bench} onPick={pick} onClose={onClose} />;
22
22
  }
@@ -1,4 +1,5 @@
1
1
  import {
2
+ AlarmClock,
2
3
  ArrowDown,
3
4
  ArrowLeft,
4
5
  ArrowRight,
@@ -12,6 +13,7 @@ import {
12
13
  ChevronRight,
13
14
  ChevronsDownUp,
14
15
  ChevronsUpDown,
16
+ CircleAlert,
15
17
  Clipboard,
16
18
  Code,
17
19
  Columns2,
@@ -51,6 +53,7 @@ import {
51
53
  Pencil,
52
54
  Pin,
53
55
  PinOff,
56
+ Play,
54
57
  Plus,
55
58
  Puzzle,
56
59
  RefreshCw,
@@ -62,11 +65,13 @@ import {
62
65
  Save,
63
66
  ScrollText,
64
67
  Search,
68
+ Server,
65
69
  Sparkles,
66
70
  Square,
67
71
  SquareMinus,
68
72
  SquarePlus,
69
73
  SquareTerminal,
74
+ Store,
70
75
  Text,
71
76
  Trash2,
72
77
  Undo2,
@@ -81,6 +86,7 @@ import type { WebIcon } from './web-extension-api';
81
86
 
82
87
  /** The icons a web extension gets as `pi.ui.icons`; names are lucide's. Only add: removing one breaks extensions. */
83
88
  export const WEB_ICONS: Readonly<Record<string, WebIcon>> = Object.freeze({
89
+ AlarmClock,
84
90
  ArrowDown,
85
91
  ArrowLeft,
86
92
  ArrowRight,
@@ -94,6 +100,7 @@ export const WEB_ICONS: Readonly<Record<string, WebIcon>> = Object.freeze({
94
100
  ChevronRight,
95
101
  ChevronsDownUp,
96
102
  ChevronsUpDown,
103
+ CircleAlert,
97
104
  Clipboard,
98
105
  Code,
99
106
  Columns2,
@@ -132,6 +139,7 @@ export const WEB_ICONS: Readonly<Record<string, WebIcon>> = Object.freeze({
132
139
  PackageOpen,
133
140
  Pencil,
134
141
  Pin,
142
+ Play,
135
143
  PinOff,
136
144
  Plus,
137
145
  Puzzle,
@@ -144,11 +152,13 @@ export const WEB_ICONS: Readonly<Record<string, WebIcon>> = Object.freeze({
144
152
  Save,
145
153
  ScrollText,
146
154
  Search,
155
+ Server,
147
156
  Sparkles,
148
157
  Square,
149
158
  SquareMinus,
150
159
  SquarePlus,
151
160
  SquareTerminal,
161
+ Store,
152
162
  Text,
153
163
  Trash2,
154
164
  Undo2,
@@ -1,4 +1,13 @@
1
- import type { TaEvent, TaPackageServer, TaServer, TaSessionInfo, TaTerminalServer, TaWorkspaceServer } from '@celljs/ta-protocol';
1
+ import type {
2
+ TaEvent,
3
+ TaPackageServer,
4
+ TaRemoteServer,
5
+ TaServer,
6
+ TaSessionInfo,
7
+ TaSettingsServer,
8
+ TaTerminalServer,
9
+ TaWorkspaceServer,
10
+ } from '@celljs/ta-protocol';
2
11
  import type * as React from 'react';
3
12
  import type { Mood } from '../avatar/dino-avatar';
4
13
  import type { Language, Theme } from '../settings/settings-protocol';
@@ -13,12 +22,16 @@ export interface WebExtensionAPI {
13
22
  readonly React: typeof React;
14
23
  /** The sessions of ta serve, for what the rest of the API does not do: the commands of pi's RPC mode. */
15
24
  readonly server: TaServer;
16
- /** The files and programs of a directory on the machine of ta serve. */
25
+ /** The files and programs of a directory, on the machine of ta serve or of an `ssh://` directory. */
17
26
  readonly workspace: TaWorkspaceServer;
18
27
  /** Shells; their output comes by {@link onTerminalData}. */
19
28
  readonly terminals: TaTerminalServer;
20
29
  /** The packages pi loads; for the data of the extension's own package, {@link storage}. */
21
30
  readonly packages: TaPackageServer;
31
+ /** The other machines of `ssh://` directories (TaLocation): their ports, for a page served there. */
32
+ readonly remote: TaRemoteServer;
33
+ /** pi's settings of ta (`settings.json`): `getSettings(cwd)` also lists the models with credentials, for a model picker. */
34
+ readonly settings: TaSettingsServer;
22
35
  readonly ui: WebExtensionUI;
23
36
  /** A view of its own: a page or a sidebar view, in the navigation on the left, or a tool of the workbench on the right. */
24
37
  registerView(name: string, view: WebView): void;
@@ -127,6 +140,31 @@ export interface WebExtensionUI {
127
140
  editor(title: string, prefill?: string): Promise<string | undefined>;
128
141
  readonly theme: Theme;
129
142
  readonly language: Language;
143
+ /**
144
+ * Whether a view can show a site in a `<webview>` element, as in Ta Desktop: a page of its own rather
145
+ * than a frame, which sites cannot refuse, where signing in works and stays, with the history, title and
146
+ * icon of the page as events and methods of the element (Electron's). Elsewhere, an iframe.
147
+ */
148
+ readonly supportsWebview: boolean;
149
+ /**
150
+ * Ta Desktop's way to the file manager of the system (Finder, File Explorer, that of Linux), for paths of
151
+ * this machine; undefined in a browser and the mobile app. A directory of `ssh://` is not of this machine.
152
+ */
153
+ readonly desktop?: WebDesktop;
154
+ /**
155
+ * Files dragged between views, as the explorer drags them: `set` them in `dragstart`. Dropped on the
156
+ * message box of a conversation they become `@` references (relative to its directory when they are in
157
+ * it); a terminal takes their `paths`; anywhere else they are their paths as text.
158
+ */
159
+ readonly fileDrag: WebFileDrag;
160
+ /**
161
+ * Ta Desktop: sends a command of the Chrome DevTools Protocol to the page of a `<webview>` of this page
162
+ * (its `getWebContentsId()`), as that page's debugger, and resolves with its result; `undefined`
163
+ * elsewhere. Only commands on the page itself: Accessibility, CSS, DOM, DOMSnapshot, Emulation, Input,
164
+ * Log, Overlay, Page and Runtime, without those that touch files, downloads or navigate (use the
165
+ * element's `loadURL`); the app refuses the rest.
166
+ */
167
+ readonly debugWebview?: (webContentsId: number, method: string, params?: Record<string, unknown>) => Promise<unknown>;
130
168
  /**
131
169
  * A tab in the editor area beside the conversation (a file, a diff, a browser); an open id is shown
132
170
  * again. With `preserveFocus`, it opens behind the tab shown, and the workbench is not revealed: for
@@ -164,6 +202,11 @@ export interface WebExtensionUI {
164
202
  readonly CodeEditor: React.ComponentType<CodeEditorProps>;
165
203
  /** Monaco's diff editor on two texts of a file, side by side or inline; the right side can be edited. */
166
204
  readonly DiffEditor: React.ComponentType<DiffEditorProps>;
205
+ /**
206
+ * A terminal as VS Code's: xterm.js drawn on the GPU, in the theme of the page. It loads the first
207
+ * time one is made; what it shows stays while no view shows it (`attach` it to the next one).
208
+ */
209
+ createTerminal(options?: WebTerminalOptions): WebTerminal;
167
210
  /** The message box of the conversations of the page, with its + menu: one look for every conversation. */
168
211
  readonly Composer: React.ComponentType<WebComposerProps>;
169
212
  /** Markdown as the conversations show it. */
@@ -174,6 +217,95 @@ export interface WebExtensionUI {
174
217
  readonly FolderPicker: React.ComponentType<WebFolderPickerProps>;
175
218
  }
176
219
 
220
+ export interface WebDesktop {
221
+ /** Node's `process.platform` of the machine (`darwin`, `win32`, `linux`): what its file manager is called. */
222
+ readonly platform: string;
223
+ /** Opens the folder of an absolute path of this machine in the file manager, the item selected. */
224
+ showItemInFolder(path: string): Promise<void>;
225
+ /** The sign-ins of the user's browsers taken into the browser of Ta; macOS and Windows only. */
226
+ readonly browserData?: WebBrowserData;
227
+ }
228
+
229
+ /** A profile of the user's Chrome, Edge, Brave, Arc, Vivaldi or Chromium. */
230
+ export interface WebBrowserProfile {
231
+ /** What `import` takes. */
232
+ id: string;
233
+ /** The name of the browser, `Google Chrome`. */
234
+ browser: string;
235
+ /** The name of the profile, as the browser shows it. */
236
+ name: string;
237
+ }
238
+
239
+ /** The cookies an import took into the browser of Ta. */
240
+ export interface WebBrowserImport {
241
+ imported: number;
242
+ /** Those that could not be read or set. */
243
+ skipped: number;
244
+ /** Windows: those under Chrome's app-bound encryption, which only Chrome can read: sign in again. */
245
+ appBound: number;
246
+ }
247
+
248
+ /**
249
+ * Ta Desktop's browser of the workbench keeps its own sign-ins. These take those of the user's browser:
250
+ * its cookies, never its passwords or history, once the user said yes in a dialog of the app (on macOS,
251
+ * the Keychain asks too).
252
+ */
253
+ export interface WebBrowserData {
254
+ /** The profiles with cookies of the browsers installed. */
255
+ profiles(): Promise<WebBrowserProfile[]>;
256
+ /** Takes the cookies of a profile; `undefined` when the user said no. */
257
+ import(profileId: string): Promise<WebBrowserImport | undefined>;
258
+ /** Forgets the cookies, storage and cache of the browser of Ta. */
259
+ clear(): Promise<void>;
260
+ }
261
+
262
+ /** Files of a directory on a drag. */
263
+ export interface WebDraggedFiles {
264
+ /** The directory they are of (`ui.useCwd()` or another): a path of the machine of ta serve, or `ssh://`. */
265
+ cwd: string;
266
+ /** Relative to `cwd`, with `/`. */
267
+ paths: string[];
268
+ }
269
+
270
+ export interface WebFileDrag {
271
+ set(dataTransfer: DataTransfer, files: WebDraggedFiles): void;
272
+ /** Whether a drag holds files: what `dragover` can tell, before the drop. */
273
+ has(dataTransfer: DataTransfer): boolean;
274
+ /** The files of a drop; undefined when it holds none. */
275
+ get(dataTransfer: DataTransfer): WebDraggedFiles | undefined;
276
+ /** Their absolute paths inside their machine. */
277
+ paths(files: WebDraggedFiles): string[];
278
+ }
279
+
280
+ export interface WebTerminalOptions {
281
+ /** Its size until a view fits it: the size the program started with. Default: 80 × 24. */
282
+ cols?: number;
283
+ rows?: number;
284
+ /**
285
+ * The directory of the program: paths of its output (`src/a.ts:10`) are read from there, and from the
286
+ * one a shell reports (OSC 7) once it does. URLs and paths are links, opened with Cmd or Ctrl + click
287
+ * as the links of a reply are (with Shift, a page in the browser of the system).
288
+ */
289
+ cwd?: string;
290
+ }
291
+
292
+ /** A terminal screen; the program behind it is the extension's (`pi.terminals` for a shell of the server). */
293
+ export interface WebTerminal {
294
+ /** Its size in characters. */
295
+ readonly cols: number;
296
+ readonly rows: number;
297
+ /** Output of the program, with its control sequences. */
298
+ write(data: string): void;
299
+ /** What the user types or pastes, and the mouse reports the program asked for, as a terminal sends them. */
300
+ onData(listener: (data: string) => void): () => void;
301
+ /** It fitted a view of another size: the program should know it (`resizeTerminal`). */
302
+ onResize(listener: (size: { cols: number; rows: number }) => void): () => void;
303
+ /** Shows it in `element`, which it fills and follows in size; the function returned takes it out again. */
304
+ attach(element: HTMLElement): () => void;
305
+ focus(): void;
306
+ dispose(): void;
307
+ }
308
+
177
309
  export interface WebFolderPickerProps {
178
310
  /** Where it opens; default: the directory of ta serve. */
179
311
  initial?: string;