@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.
- package/README.en.md +90 -0
- package/README.md +13 -7
- package/esm/browser/chat/chat-protocol.d.ts +4 -0
- package/esm/browser/chat/chat-view.js +4 -1
- package/esm/browser/chat/chat-view.js.map +1 -1
- package/esm/browser/chat/chat.d.ts +8 -1
- package/esm/browser/chat/chat.js +34 -15
- package/esm/browser/chat/chat.js.map +1 -1
- package/esm/browser/chat/draft-model.d.ts +15 -0
- package/esm/browser/chat/draft-model.js +53 -0
- package/esm/browser/chat/draft-model.js.map +1 -0
- package/esm/browser/components/account-menu.d.ts +3 -2
- package/esm/browser/components/account-menu.js +21 -16
- package/esm/browser/components/account-menu.js.map +1 -1
- package/esm/browser/components/app-view.js +13 -4
- package/esm/browser/components/app-view.js.map +1 -1
- package/esm/browser/components/chat-list.d.ts +3 -1
- package/esm/browser/components/chat-list.js +6 -1
- package/esm/browser/components/chat-list.js.map +1 -1
- package/esm/browser/components/composer-box.d.ts +6 -0
- package/esm/browser/components/composer-box.js +50 -13
- package/esm/browser/components/composer-box.js.map +1 -1
- package/esm/browser/components/composer.js +1 -1
- package/esm/browser/components/composer.js.map +1 -1
- package/esm/browser/components/dialog-view.d.ts +4 -1
- package/esm/browser/components/dialog-view.js +11 -7
- package/esm/browser/components/dialog-view.js.map +1 -1
- package/esm/browser/components/folder-picker.d.ts +37 -6
- package/esm/browser/components/folder-picker.js +155 -33
- package/esm/browser/components/folder-picker.js.map +1 -1
- package/esm/browser/components/notice-center.js +3 -1
- package/esm/browser/components/notice-center.js.map +1 -1
- package/esm/browser/components/remote-hosts.d.ts +7 -0
- package/esm/browser/components/remote-hosts.js +94 -0
- package/esm/browser/components/remote-hosts.js.map +1 -0
- package/esm/browser/components/remote-prompts.d.ts +7 -0
- package/esm/browser/components/remote-prompts.js +72 -0
- package/esm/browser/components/remote-prompts.js.map +1 -0
- package/esm/browser/components/session-view.js +48 -4
- package/esm/browser/components/session-view.js.map +1 -1
- package/esm/browser/components/settings-view.js +8 -1
- package/esm/browser/components/settings-view.js.map +1 -1
- package/esm/browser/components/terminal-art.d.ts +7 -0
- package/esm/browser/components/terminal-art.js +12 -0
- package/esm/browser/components/terminal-art.js.map +1 -0
- package/esm/browser/components/tool-view.js +1 -1
- package/esm/browser/components/tool-view.js.map +1 -1
- package/esm/browser/components/web-composer.d.ts +4 -1
- package/esm/browser/components/web-composer.js +2 -2
- package/esm/browser/components/web-composer.js.map +1 -1
- package/esm/browser/components/working-directory.js +1 -1
- package/esm/browser/components/working-directory.js.map +1 -1
- package/esm/browser/extension/icons.js +6 -1
- package/esm/browser/extension/icons.js.map +1 -1
- package/esm/browser/extension/web-extension-api.d.ts +120 -2
- package/esm/browser/extension/web-extensions.d.ts +3 -0
- package/esm/browser/extension/web-extensions.js +33 -1
- package/esm/browser/extension/web-extensions.js.map +1 -1
- package/esm/browser/i18n/locales.d.ts +44 -1
- package/esm/browser/i18n/messages.d.ts +43 -0
- package/esm/browser/i18n/messages.js +99 -13
- package/esm/browser/i18n/messages.js.map +1 -1
- package/esm/browser/notices/notices-protocol.d.ts +3 -0
- package/esm/browser/notices/notices.d.ts +3 -0
- package/esm/browser/notices/notices.js +15 -0
- package/esm/browser/notices/notices.js.map +1 -1
- package/esm/browser/style/base.d.ts +1 -1
- package/esm/browser/style/base.js +6 -1
- package/esm/browser/style/base.js.map +1 -1
- package/esm/browser/style/conversation.d.ts +1 -1
- package/esm/browser/style/conversation.js +16 -1
- package/esm/browser/style/conversation.js.map +1 -1
- package/esm/browser/style/layout.d.ts +1 -1
- package/esm/browser/style/layout.js +53 -15
- package/esm/browser/style/layout.js.map +1 -1
- package/esm/browser/style/shell.d.ts +1 -1
- package/esm/browser/style/shell.js +1 -0
- package/esm/browser/style/shell.js.map +1 -1
- package/esm/browser/terminal/canvas-font.d.ts +10 -0
- package/esm/browser/terminal/canvas-font.js +34 -0
- package/esm/browser/terminal/canvas-font.js.map +1 -0
- package/esm/browser/terminal/terminal-links.d.ts +18 -0
- package/esm/browser/terminal/terminal-links.js +72 -0
- package/esm/browser/terminal/terminal-links.js.map +1 -0
- package/esm/browser/terminal/terminal-theme.d.ts +8 -0
- package/esm/browser/terminal/terminal-theme.js +65 -0
- package/esm/browser/terminal/terminal-theme.js.map +1 -0
- package/esm/browser/terminal/web-terminal.d.ts +74 -0
- package/esm/browser/terminal/web-terminal.js +300 -0
- package/esm/browser/terminal/web-terminal.js.map +1 -0
- package/esm/browser/terminal/xterm.d.ts +5 -0
- package/esm/browser/terminal/xterm.js +9 -0
- package/esm/browser/terminal/xterm.js.map +1 -0
- package/esm/browser/util/desktop.d.ts +43 -0
- package/esm/browser/util/desktop.js +55 -0
- package/esm/browser/util/desktop.js.map +1 -0
- package/esm/browser/util/file-drag.d.ts +26 -0
- package/esm/browser/util/file-drag.js +73 -0
- package/esm/browser/util/file-drag.js.map +1 -0
- package/esm/browser/util/message.d.ts +1 -0
- package/esm/browser/util/message.js +7 -5
- package/esm/browser/util/message.js.map +1 -1
- package/esm/browser/util/terminal-text.d.ts +33 -0
- package/esm/browser/util/terminal-text.js +209 -0
- package/esm/browser/util/terminal-text.js.map +1 -0
- package/esm/browser/util/tool.js +16 -0
- package/esm/browser/util/tool.js.map +1 -1
- package/esm/browser/workbench-protocol.d.ts +7 -1
- package/esm/browser/workbench-protocol.js.map +1 -1
- package/esm/browser/workbench.d.ts +7 -1
- package/esm/browser/workbench.js +23 -0
- package/esm/browser/workbench.js.map +1 -1
- package/lib/browser/chat/chat-protocol.d.ts +4 -0
- package/lib/browser/chat/chat-protocol.d.ts.map +1 -1
- package/lib/browser/chat/chat-view.d.ts.map +1 -1
- package/lib/browser/chat/chat-view.js +4 -1
- package/lib/browser/chat/chat-view.js.map +1 -1
- package/lib/browser/chat/chat.d.ts +8 -1
- package/lib/browser/chat/chat.d.ts.map +1 -1
- package/lib/browser/chat/chat.js +34 -15
- package/lib/browser/chat/chat.js.map +1 -1
- package/lib/browser/chat/chat.spec.js +30 -0
- package/lib/browser/chat/chat.spec.js.map +1 -1
- package/lib/browser/chat/draft-model.d.ts +16 -0
- package/lib/browser/chat/draft-model.d.ts.map +1 -0
- package/lib/browser/chat/draft-model.js +90 -0
- package/lib/browser/chat/draft-model.js.map +1 -0
- package/lib/browser/chat/draft-model.spec.d.ts +2 -0
- package/lib/browser/chat/draft-model.spec.d.ts.map +1 -0
- package/lib/browser/chat/draft-model.spec.js +31 -0
- package/lib/browser/chat/draft-model.spec.js.map +1 -0
- package/lib/browser/components/account-menu.d.ts +3 -2
- package/lib/browser/components/account-menu.d.ts.map +1 -1
- package/lib/browser/components/account-menu.js +21 -16
- package/lib/browser/components/account-menu.js.map +1 -1
- package/lib/browser/components/app-view.d.ts.map +1 -1
- package/lib/browser/components/app-view.js +13 -4
- package/lib/browser/components/app-view.js.map +1 -1
- package/lib/browser/components/chat-list.d.ts +3 -1
- package/lib/browser/components/chat-list.d.ts.map +1 -1
- package/lib/browser/components/chat-list.js +6 -1
- package/lib/browser/components/chat-list.js.map +1 -1
- package/lib/browser/components/composer-box.d.ts +6 -0
- package/lib/browser/components/composer-box.d.ts.map +1 -1
- package/lib/browser/components/composer-box.js +51 -14
- package/lib/browser/components/composer-box.js.map +1 -1
- package/lib/browser/components/composer.d.ts.map +1 -1
- package/lib/browser/components/composer.js +1 -1
- package/lib/browser/components/composer.js.map +1 -1
- package/lib/browser/components/dialog-view.d.ts +4 -1
- package/lib/browser/components/dialog-view.d.ts.map +1 -1
- package/lib/browser/components/dialog-view.js +11 -7
- package/lib/browser/components/dialog-view.js.map +1 -1
- package/lib/browser/components/folder-picker.d.ts +37 -6
- package/lib/browser/components/folder-picker.d.ts.map +1 -1
- package/lib/browser/components/folder-picker.js +156 -33
- package/lib/browser/components/folder-picker.js.map +1 -1
- package/lib/browser/components/folder-picker.spec.js +15 -0
- package/lib/browser/components/folder-picker.spec.js.map +1 -1
- package/lib/browser/components/notice-center.d.ts.map +1 -1
- package/lib/browser/components/notice-center.js +3 -1
- package/lib/browser/components/notice-center.js.map +1 -1
- package/lib/browser/components/plus-menu.spec.d.ts +2 -0
- package/lib/browser/components/plus-menu.spec.d.ts.map +1 -0
- package/lib/browser/components/plus-menu.spec.js +18 -0
- package/lib/browser/components/plus-menu.spec.js.map +1 -0
- package/lib/browser/components/remote-hosts.d.ts +8 -0
- package/lib/browser/components/remote-hosts.d.ts.map +1 -0
- package/lib/browser/components/remote-hosts.js +130 -0
- package/lib/browser/components/remote-hosts.js.map +1 -0
- package/lib/browser/components/remote-prompts.d.ts +8 -0
- package/lib/browser/components/remote-prompts.d.ts.map +1 -0
- package/lib/browser/components/remote-prompts.js +108 -0
- package/lib/browser/components/remote-prompts.js.map +1 -0
- package/lib/browser/components/session-view.d.ts.map +1 -1
- package/lib/browser/components/session-view.js +48 -4
- package/lib/browser/components/session-view.js.map +1 -1
- package/lib/browser/components/settings-view.d.ts.map +1 -1
- package/lib/browser/components/settings-view.js +7 -0
- package/lib/browser/components/settings-view.js.map +1 -1
- package/lib/browser/components/terminal-art.d.ts +8 -0
- package/lib/browser/components/terminal-art.d.ts.map +1 -0
- package/lib/browser/components/terminal-art.js +48 -0
- package/lib/browser/components/terminal-art.js.map +1 -0
- package/lib/browser/components/tool-view.js +1 -1
- package/lib/browser/components/tool-view.js.map +1 -1
- package/lib/browser/components/web-composer.d.ts +4 -1
- package/lib/browser/components/web-composer.d.ts.map +1 -1
- package/lib/browser/components/web-composer.js +2 -2
- package/lib/browser/components/web-composer.js.map +1 -1
- package/lib/browser/components/working-directory.js +1 -1
- package/lib/browser/components/working-directory.js.map +1 -1
- package/lib/browser/extension/icons.d.ts.map +1 -1
- package/lib/browser/extension/icons.js +5 -0
- package/lib/browser/extension/icons.js.map +1 -1
- package/lib/browser/extension/web-extension-api.d.ts +120 -2
- package/lib/browser/extension/web-extension-api.d.ts.map +1 -1
- package/lib/browser/extension/web-extensions.d.ts +3 -0
- package/lib/browser/extension/web-extensions.d.ts.map +1 -1
- package/lib/browser/extension/web-extensions.js +33 -1
- package/lib/browser/extension/web-extensions.js.map +1 -1
- package/lib/browser/i18n/locales.d.ts +44 -1
- package/lib/browser/i18n/locales.d.ts.map +1 -1
- package/lib/browser/i18n/messages.d.ts +43 -0
- package/lib/browser/i18n/messages.d.ts.map +1 -1
- package/lib/browser/i18n/messages.js +99 -13
- package/lib/browser/i18n/messages.js.map +1 -1
- package/lib/browser/notices/notices-protocol.d.ts +3 -0
- package/lib/browser/notices/notices-protocol.d.ts.map +1 -1
- package/lib/browser/notices/notices.d.ts +3 -0
- package/lib/browser/notices/notices.d.ts.map +1 -1
- package/lib/browser/notices/notices.js +15 -0
- package/lib/browser/notices/notices.js.map +1 -1
- package/lib/browser/notices/notices.spec.js +8 -3
- package/lib/browser/notices/notices.spec.js.map +1 -1
- package/lib/browser/style/base.d.ts +1 -1
- package/lib/browser/style/base.d.ts.map +1 -1
- package/lib/browser/style/base.js +6 -1
- package/lib/browser/style/base.js.map +1 -1
- package/lib/browser/style/conversation.d.ts +1 -1
- package/lib/browser/style/conversation.d.ts.map +1 -1
- package/lib/browser/style/conversation.js +16 -1
- package/lib/browser/style/conversation.js.map +1 -1
- package/lib/browser/style/layout.d.ts +1 -1
- package/lib/browser/style/layout.d.ts.map +1 -1
- package/lib/browser/style/layout.js +53 -15
- package/lib/browser/style/layout.js.map +1 -1
- package/lib/browser/style/shell.d.ts +1 -1
- package/lib/browser/style/shell.d.ts.map +1 -1
- package/lib/browser/style/shell.js +1 -0
- package/lib/browser/style/shell.js.map +1 -1
- package/lib/browser/terminal/canvas-font.d.ts +11 -0
- package/lib/browser/terminal/canvas-font.d.ts.map +1 -0
- package/lib/browser/terminal/canvas-font.js +37 -0
- package/lib/browser/terminal/canvas-font.js.map +1 -0
- package/lib/browser/terminal/canvas-font.spec.d.ts +2 -0
- package/lib/browser/terminal/canvas-font.spec.d.ts.map +1 -0
- package/lib/browser/terminal/canvas-font.spec.js +32 -0
- package/lib/browser/terminal/canvas-font.spec.js.map +1 -0
- package/lib/browser/terminal/terminal-links.d.ts +19 -0
- package/lib/browser/terminal/terminal-links.d.ts.map +1 -0
- package/lib/browser/terminal/terminal-links.js +75 -0
- package/lib/browser/terminal/terminal-links.js.map +1 -0
- package/lib/browser/terminal/terminal-links.spec.d.ts +2 -0
- package/lib/browser/terminal/terminal-links.spec.d.ts.map +1 -0
- package/lib/browser/terminal/terminal-links.spec.js +30 -0
- package/lib/browser/terminal/terminal-links.spec.js.map +1 -0
- package/lib/browser/terminal/terminal-theme.d.ts +9 -0
- package/lib/browser/terminal/terminal-theme.d.ts.map +1 -0
- package/lib/browser/terminal/terminal-theme.js +68 -0
- package/lib/browser/terminal/terminal-theme.js.map +1 -0
- package/lib/browser/terminal/terminal-theme.spec.d.ts +2 -0
- package/lib/browser/terminal/terminal-theme.spec.d.ts.map +1 -0
- package/lib/browser/terminal/terminal-theme.spec.js +24 -0
- package/lib/browser/terminal/terminal-theme.spec.js.map +1 -0
- package/lib/browser/terminal/web-terminal.d.ts +75 -0
- package/lib/browser/terminal/web-terminal.d.ts.map +1 -0
- package/lib/browser/terminal/web-terminal.js +304 -0
- package/lib/browser/terminal/web-terminal.js.map +1 -0
- package/lib/browser/terminal/xterm.d.ts +6 -0
- package/lib/browser/terminal/xterm.d.ts.map +1 -0
- package/lib/browser/terminal/xterm.js +16 -0
- package/lib/browser/terminal/xterm.js.map +1 -0
- package/lib/browser/util/desktop.d.ts +44 -0
- package/lib/browser/util/desktop.d.ts.map +1 -0
- package/lib/browser/util/desktop.js +58 -0
- package/lib/browser/util/desktop.js.map +1 -0
- package/lib/browser/util/desktop.spec.d.ts +2 -0
- package/lib/browser/util/desktop.spec.d.ts.map +1 -0
- package/lib/browser/util/desktop.spec.js +67 -0
- package/lib/browser/util/desktop.spec.js.map +1 -0
- package/lib/browser/util/file-drag.d.ts +27 -0
- package/lib/browser/util/file-drag.d.ts.map +1 -0
- package/lib/browser/util/file-drag.js +76 -0
- package/lib/browser/util/file-drag.js.map +1 -0
- package/lib/browser/util/file-drag.spec.d.ts +2 -0
- package/lib/browser/util/file-drag.spec.d.ts.map +1 -0
- package/lib/browser/util/file-drag.spec.js +46 -0
- package/lib/browser/util/file-drag.spec.js.map +1 -0
- package/lib/browser/util/message.d.ts +1 -0
- package/lib/browser/util/message.d.ts.map +1 -1
- package/lib/browser/util/message.js +7 -5
- package/lib/browser/util/message.js.map +1 -1
- package/lib/browser/util/message.spec.js +2 -0
- package/lib/browser/util/message.spec.js.map +1 -1
- package/lib/browser/util/terminal-text.d.ts +34 -0
- package/lib/browser/util/terminal-text.d.ts.map +1 -0
- package/lib/browser/util/terminal-text.js +212 -0
- package/lib/browser/util/terminal-text.js.map +1 -0
- package/lib/browser/util/terminal-text.spec.d.ts +2 -0
- package/lib/browser/util/terminal-text.spec.d.ts.map +1 -0
- package/lib/browser/util/terminal-text.spec.js +54 -0
- package/lib/browser/util/terminal-text.spec.js.map +1 -0
- package/lib/browser/util/tool.d.ts.map +1 -1
- package/lib/browser/util/tool.js +16 -0
- package/lib/browser/util/tool.js.map +1 -1
- package/lib/browser/util/tool.spec.js +12 -0
- package/lib/browser/util/tool.spec.js.map +1 -1
- package/lib/browser/workbench-protocol.d.ts +7 -1
- package/lib/browser/workbench-protocol.d.ts.map +1 -1
- package/lib/browser/workbench-protocol.js.map +1 -1
- package/lib/browser/workbench.d.ts +7 -1
- package/lib/browser/workbench.d.ts.map +1 -1
- package/lib/browser/workbench.js +23 -0
- package/lib/browser/workbench.js.map +1 -1
- package/package.json +11 -7
- package/src/browser/chat/chat-protocol.ts +4 -0
- package/src/browser/chat/chat-view.tsx +5 -1
- package/src/browser/chat/chat.spec.ts +31 -0
- package/src/browser/chat/chat.ts +36 -14
- package/src/browser/chat/draft-model.spec.tsx +31 -0
- package/src/browser/chat/draft-model.tsx +63 -0
- package/src/browser/components/account-menu.tsx +23 -20
- package/src/browser/components/app-view.tsx +12 -3
- package/src/browser/components/chat-list.tsx +9 -2
- package/src/browser/components/composer-box.tsx +52 -6
- package/src/browser/components/composer.tsx +1 -0
- package/src/browser/components/dialog-view.tsx +16 -7
- package/src/browser/components/folder-picker.spec.ts +17 -0
- package/src/browser/components/folder-picker.tsx +221 -39
- package/src/browser/components/notice-center.tsx +7 -1
- package/src/browser/components/plus-menu.spec.ts +16 -0
- package/src/browser/components/remote-hosts.tsx +149 -0
- package/src/browser/components/remote-prompts.tsx +111 -0
- package/src/browser/components/session-view.tsx +65 -4
- package/src/browser/components/settings-view.tsx +8 -0
- package/src/browser/components/terminal-art.tsx +21 -0
- package/src/browser/components/tool-view.tsx +1 -1
- package/src/browser/components/web-composer.tsx +18 -3
- package/src/browser/components/working-directory.tsx +1 -1
- package/src/browser/extension/icons.ts +10 -0
- package/src/browser/extension/web-extension-api.ts +134 -2
- package/src/browser/extension/web-extensions.ts +47 -2
- package/src/browser/i18n/messages.ts +99 -13
- package/src/browser/notices/notices-protocol.ts +3 -0
- package/src/browser/notices/notices.spec.ts +9 -3
- package/src/browser/notices/notices.ts +17 -1
- package/src/browser/style/base.ts +6 -1
- package/src/browser/style/conversation.ts +16 -1
- package/src/browser/style/layout.ts +53 -15
- package/src/browser/style/shell.ts +1 -0
- package/src/browser/terminal/canvas-font.spec.ts +29 -0
- package/src/browser/terminal/canvas-font.ts +32 -0
- package/src/browser/terminal/terminal-links.spec.ts +32 -0
- package/src/browser/terminal/terminal-links.ts +75 -0
- package/src/browser/terminal/terminal-theme.spec.ts +23 -0
- package/src/browser/terminal/terminal-theme.ts +66 -0
- package/src/browser/terminal/web-terminal.ts +330 -0
- package/src/browser/terminal/xterm.ts +10 -0
- package/src/browser/util/desktop.spec.ts +68 -0
- package/src/browser/util/desktop.ts +96 -0
- package/src/browser/util/file-drag.spec.ts +48 -0
- package/src/browser/util/file-drag.ts +78 -0
- package/src/browser/util/message.spec.ts +2 -0
- package/src/browser/util/message.ts +7 -4
- package/src/browser/util/terminal-text.spec.ts +60 -0
- package/src/browser/util/terminal-text.ts +223 -0
- package/src/browser/util/tool.spec.ts +12 -0
- package/src/browser/util/tool.ts +17 -0
- package/src/browser/workbench-protocol.ts +8 -0
- 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
|
-
/**
|
|
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
|
-
|
|
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.
|
|
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
|
-
{
|
|
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({
|
|
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 {
|
|
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;
|