@jobshimo/browser-link 0.1.0 → 0.2.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.
@@ -0,0 +1,7 @@
1
+ import type { Language } from '../commands/welcome.js';
2
+ interface AppProps {
3
+ initialLanguage: Language;
4
+ skipWelcome: boolean;
5
+ }
6
+ export declare function App({ initialLanguage, skipWelcome }: AppProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
package/dist/ui/app.js ADDED
@@ -0,0 +1,62 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useApp, useInput } from 'ink';
3
+ import { useState } from 'react';
4
+ import { AboutView, ClientPicker, DoctorView, ExtensionView, InstallResultView, MainMenu, UpdatesView, WelcomeScreen, } from './screens.js';
5
+ import { saveConfig } from '../config.js';
6
+ import { installFor } from '../commands/install.js';
7
+ import { openUrl } from '../utils/open-url.js';
8
+ const REPO_URL = 'https://github.com/jobshimo/browser-link';
9
+ export function App({ initialLanguage, skipWelcome }) {
10
+ const { exit } = useApp();
11
+ const [language, setLanguage] = useState(initialLanguage);
12
+ const [screen, setScreen] = useState(skipWelcome ? { kind: 'menu' } : { kind: 'welcome', hideDismiss: false });
13
+ // Global Ctrl+C kill. Ink already handles SIGINT but we explicitly exit so
14
+ // any in-flight cleanup runs through the React lifecycle.
15
+ useInput((_input, key) => {
16
+ if (key.ctrl && _input === 'c')
17
+ exit();
18
+ });
19
+ const swapLang = () => setLanguage((l) => (l === 'en' ? 'es' : 'en'));
20
+ const backToMenu = () => setScreen({ kind: 'menu' });
21
+ switch (screen.kind) {
22
+ case 'welcome':
23
+ return (_jsx(WelcomeScreen, { language: language, hideDismiss: screen.hideDismiss, onAccept: () => backToMenu(), onDismiss: () => {
24
+ saveConfig({ skipWelcome: true, language });
25
+ backToMenu();
26
+ }, onSwapLang: swapLang, onQuit: exit }));
27
+ case 'menu':
28
+ return (_jsx(MainMenu, { language: language, onSelect: (action) => {
29
+ if (action === 'register')
30
+ setScreen({ kind: 'pick-client' });
31
+ else if (action === 'extension')
32
+ setScreen({ kind: 'extension' });
33
+ else if (action === 'doctor')
34
+ setScreen({ kind: 'doctor' });
35
+ else if (action === 'updates')
36
+ setScreen({ kind: 'updates' });
37
+ else if (action === 'about')
38
+ setScreen({ kind: 'about' });
39
+ else if (action === 'welcome')
40
+ setScreen({ kind: 'welcome', hideDismiss: true });
41
+ else if (action === 'repo')
42
+ openUrl(REPO_URL);
43
+ // 'quit' is handled by onQuit instead.
44
+ }, onSwapLang: swapLang, onQuit: exit }));
45
+ case 'pick-client':
46
+ return (_jsx(ClientPicker, { language: language, onPick: (id) => {
47
+ const report = installFor(id);
48
+ setScreen({ kind: 'install-result', report });
49
+ }, onBack: backToMenu }));
50
+ case 'install-result':
51
+ return _jsx(InstallResultView, { language: language, report: screen.report, onBack: backToMenu });
52
+ case 'extension':
53
+ return _jsx(ExtensionView, { language: language, onBack: backToMenu });
54
+ case 'doctor':
55
+ return _jsx(DoctorView, { language: language, onBack: backToMenu });
56
+ case 'updates':
57
+ return _jsx(UpdatesView, { language: language, onBack: backToMenu });
58
+ case 'about':
59
+ return _jsx(AboutView, { language: language, onBack: backToMenu });
60
+ }
61
+ }
62
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/ui/app.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EACL,SAAS,EACT,YAAY,EACZ,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,aAAa,GAEd,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAsB,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAG/C,MAAM,QAAQ,GAAG,0CAA0C,CAAC;AAiB5D,MAAM,UAAU,GAAG,CAAC,EAAE,eAAe,EAAE,WAAW,EAAY;IAC5D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAW,eAAe,CAAC,CAAC;IACpE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAClC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,CACzE,CAAC;IAEF,2EAA2E;IAC3E,0DAA0D;IAC1D,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACvB,IAAI,GAAG,CAAC,IAAI,IAAI,MAAM,KAAK,GAAG;YAAE,IAAI,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAErD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,SAAS;YACZ,OAAO,CACL,KAAC,aAAa,IACZ,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,MAAM,CAAC,WAAW,EAC/B,QAAQ,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,EAC5B,SAAS,EAAE,GAAG,EAAE;oBACd,UAAU,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;oBAC5C,UAAU,EAAE,CAAC;gBACf,CAAC,EACD,UAAU,EAAE,QAAQ,EACpB,MAAM,EAAE,IAAI,GACZ,CACH,CAAC;QAEJ,KAAK,MAAM;YACT,OAAO,CACL,KAAC,QAAQ,IACP,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,CAAC,MAAkB,EAAE,EAAE;oBAC/B,IAAI,MAAM,KAAK,UAAU;wBAAE,SAAS,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;yBACzD,IAAI,MAAM,KAAK,WAAW;wBAAE,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;yBAC7D,IAAI,MAAM,KAAK,QAAQ;wBAAE,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;yBACvD,IAAI,MAAM,KAAK,SAAS;wBAAE,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;yBACzD,IAAI,MAAM,KAAK,OAAO;wBAAE,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;yBACrD,IAAI,MAAM,KAAK,SAAS;wBAAE,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;yBAC5E,IAAI,MAAM,KAAK,MAAM;wBAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;oBAC9C,uCAAuC;gBACzC,CAAC,EACD,UAAU,EAAE,QAAQ,EACpB,MAAM,EAAE,IAAI,GACZ,CACH,CAAC;QAEJ,KAAK,aAAa;YAChB,OAAO,CACL,KAAC,YAAY,IACX,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,CAAC,EAAY,EAAE,EAAE;oBACvB,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;oBAC9B,SAAS,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC;gBAChD,CAAC,EACD,MAAM,EAAE,UAAU,GAClB,CACH,CAAC;QAEJ,KAAK,gBAAgB;YACnB,OAAO,KAAC,iBAAiB,IAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,GAAI,CAAC;QAE9F,KAAK,WAAW;YACd,OAAO,KAAC,aAAa,IAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAI,CAAC;QAEnE,KAAK,QAAQ;YACX,OAAO,KAAC,UAAU,IAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAI,CAAC;QAEhE,KAAK,SAAS;YACZ,OAAO,KAAC,WAAW,IAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAI,CAAC;QAEjE,KAAK,OAAO;YACV,OAAO,KAAC,SAAS,IAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAI,CAAC;IACjE,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from 'react';
2
+ interface FrameProps {
3
+ title: string;
4
+ footer: string;
5
+ children: ReactNode;
6
+ }
7
+ export declare function Frame({ title, footer, children }: FrameProps): import("react/jsx-runtime").JSX.Element;
8
+ interface MenuItem<V extends string> {
9
+ value: V;
10
+ label: string;
11
+ hint?: string;
12
+ }
13
+ interface MenuProps<V extends string> {
14
+ items: MenuItem<V>[];
15
+ selectedIndex: number;
16
+ }
17
+ export declare function Menu<V extends string>({ items, selectedIndex }: MenuProps<V>): import("react/jsx-runtime").JSX.Element;
18
+ export type { MenuItem };
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { INSTALLERS } from '../installers/index.js';
4
+ export function Frame({ title, footer, children }) {
5
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: title }), _jsx(StatusBar, {})] }), _jsx(Box, { flexDirection: "column", children: children }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, children: footer }) })] }));
6
+ }
7
+ function StatusBar() {
8
+ return (_jsx(Box, { children: INSTALLERS.map((inst, i) => {
9
+ const d = inst.detect();
10
+ const { color, label } = !d.installed
11
+ ? { color: 'gray', label: 'not detected' }
12
+ : d.registered
13
+ ? { color: 'green', label: 'registered' }
14
+ : { color: 'yellow', label: 'not registered' };
15
+ return (_jsx(Box, { marginRight: i === INSTALLERS.length - 1 ? 0 : 3, children: _jsxs(Text, { children: [_jsx(Text, { bold: true, children: inst.displayName }), _jsx(Text, { color: "gray", children: " \u00B7 " }), _jsx(Text, { color: color, children: label })] }) }, inst.id));
16
+ }) }));
17
+ }
18
+ /* Pure render of a vertical menu — the App owns the selectedIndex state and
19
+ * the key handling (we don't pull in ink-select-input so we can colour and
20
+ * format hints exactly the way we want). */
21
+ export function Menu({ items, selectedIndex }) {
22
+ return (_jsx(Box, { flexDirection: "column", children: items.map((item, i) => {
23
+ const isSel = i === selectedIndex;
24
+ return (_jsxs(Box, { children: [_jsx(Text, { color: isSel ? 'cyan' : 'gray', children: isSel ? '❯ ' : ' ' }), _jsx(Text, { color: isSel ? 'white' : 'gray', bold: isSel, children: item.label }), item.hint && (_jsxs(Text, { color: "gray", dimColor: true, children: [' ', item.hint] }))] }, item.value));
25
+ }) }));
26
+ }
27
+ //# sourceMappingURL=components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.js","sourceRoot":"","sources":["../../src/ui/components.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { type Language } from '../commands/welcome.js';
2
+ import { type ClientId } from '../installers/index.js';
3
+ import { type InstallReport } from '../commands/install.js';
4
+ interface CommonProps {
5
+ language: Language;
6
+ }
7
+ interface WelcomeProps extends CommonProps {
8
+ hideDismiss: boolean;
9
+ onAccept: () => void;
10
+ onDismiss: () => void;
11
+ onSwapLang: () => void;
12
+ onQuit: () => void;
13
+ }
14
+ export declare function WelcomeScreen({ language, hideDismiss, onAccept, onDismiss, onSwapLang, onQuit, }: WelcomeProps): import("react/jsx-runtime").JSX.Element;
15
+ export type MenuAction = 'register' | 'extension' | 'doctor' | 'updates' | 'welcome' | 'about' | 'repo' | 'quit';
16
+ interface MainMenuProps extends CommonProps {
17
+ onSelect: (action: MenuAction) => void;
18
+ onSwapLang: () => void;
19
+ onQuit: () => void;
20
+ }
21
+ export declare function MainMenu({ language, onSelect, onSwapLang, onQuit }: MainMenuProps): import("react/jsx-runtime").JSX.Element;
22
+ interface ClientPickerProps extends CommonProps {
23
+ onPick: (id: ClientId) => void;
24
+ onBack: () => void;
25
+ }
26
+ export declare function ClientPicker({ language, onPick, onBack }: ClientPickerProps): import("react/jsx-runtime").JSX.Element;
27
+ interface InstallResultProps extends CommonProps {
28
+ report: InstallReport;
29
+ onBack: () => void;
30
+ }
31
+ export declare function InstallResultView({ language, report, onBack }: InstallResultProps): import("react/jsx-runtime").JSX.Element;
32
+ interface ExtensionViewProps extends CommonProps {
33
+ onBack: () => void;
34
+ }
35
+ export declare function ExtensionView({ language, onBack }: ExtensionViewProps): import("react/jsx-runtime").JSX.Element;
36
+ interface DoctorViewProps extends CommonProps {
37
+ onBack: () => void;
38
+ }
39
+ export declare function DoctorView({ language, onBack }: DoctorViewProps): import("react/jsx-runtime").JSX.Element;
40
+ interface AboutViewProps extends CommonProps {
41
+ onBack: () => void;
42
+ }
43
+ export declare function AboutView({ language, onBack }: AboutViewProps): import("react/jsx-runtime").JSX.Element;
44
+ interface UpdatesViewProps extends CommonProps {
45
+ onBack: () => void;
46
+ }
47
+ export declare function UpdatesView({ language, onBack }: UpdatesViewProps): import("react/jsx-runtime").JSX.Element;
48
+ export {};
@@ -0,0 +1,291 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from 'ink';
3
+ import { useEffect, useState } from 'react';
4
+ import { Frame, Menu } from './components.js';
5
+ import { I18N_WELCOME } from '../commands/welcome.js';
6
+ import { I18N_ABOUT } from '../commands/about.js';
7
+ import { INSTALLERS } from '../installers/index.js';
8
+ import { runDoctor, formatDoctor } from '../commands/doctor.js';
9
+ import { getExtensionInfo } from '../commands/extension.js';
10
+ import { checkUpdates } from '../commands/updates.js';
11
+ import { PACKAGE_NAME } from '../version.js';
12
+ export function WelcomeScreen({ language, hideDismiss, onAccept, onDismiss, onSwapLang, onQuit, }) {
13
+ const t = I18N_WELCOME[language];
14
+ const items = [
15
+ { value: 'accept', label: t.options.accept },
16
+ ];
17
+ if (!hideDismiss)
18
+ items.push({ value: 'dismiss', label: t.options.dismiss });
19
+ items.push({ value: 'swap', label: t.options.swap }, { value: 'quit', label: t.options.quit });
20
+ const [idx, setIdx] = useState(0);
21
+ useInput((input, key) => {
22
+ if (key.upArrow)
23
+ setIdx((i) => (i - 1 + items.length) % items.length);
24
+ else if (key.downArrow)
25
+ setIdx((i) => (i + 1) % items.length);
26
+ else if (key.return) {
27
+ const v = items[idx].value;
28
+ if (v === 'accept')
29
+ onAccept();
30
+ else if (v === 'dismiss')
31
+ onDismiss();
32
+ else if (v === 'swap')
33
+ onSwapLang();
34
+ else
35
+ onQuit();
36
+ }
37
+ else if (input === 'q' || key.escape)
38
+ onQuit();
39
+ else if (input === 'l')
40
+ onSwapLang();
41
+ });
42
+ const footer = language === 'es'
43
+ ? '↑↓ moverse · ↵ elegir · l idioma · q salir'
44
+ : '↑↓ navigate · ↵ select · l language · q quit';
45
+ return (_jsxs(Frame, { title: t.title, footer: footer, children: [_jsx(Section, { title: t.aboutTitle, body: t.about }), _jsx(Section, { title: t.capabilitiesTitle, body: t.capabilities }), _jsx(Section, { title: t.warningTitle, body: t.warning, warn: true }), _jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", italic: true, children: t.responsibility }), _jsx(Text, { color: "gray", italic: true, children: t.extensionNote })] }), _jsx(Text, { color: "white", bold: true, children: t.prompt }), _jsx(Box, { marginTop: 1, children: _jsx(Menu, { items: items, selectedIndex: idx }) })] }));
46
+ }
47
+ function Section({ title, body, warn }) {
48
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: warn ? 'yellow' : 'cyan', bold: true, children: [warn ? '⚠ ' : '', title] }), _jsx(Text, { children: body })] }));
49
+ }
50
+ const MENU_I18N = {
51
+ en: {
52
+ title: 'browser-link — setup',
53
+ prompt: 'Pick an action',
54
+ footer: '↑↓ navigate · ↵ select · l language · q quit',
55
+ options: {
56
+ register: 'Register browser-link with an MCP client',
57
+ extension: 'Show Chrome extension install steps',
58
+ doctor: 'Run doctor (diagnose current setup)',
59
+ updates: 'Check for updates on npm',
60
+ welcome: 'Show the welcome screen',
61
+ about: 'About / Help — what is this and how it works',
62
+ repo: 'Open the GitHub repository',
63
+ quit: 'Quit',
64
+ },
65
+ },
66
+ es: {
67
+ title: 'browser-link — configuración',
68
+ prompt: 'Elegí una acción',
69
+ footer: '↑↓ moverse · ↵ elegir · l idioma · q salir',
70
+ options: {
71
+ register: 'Registrar browser-link en un cliente MCP',
72
+ extension: 'Ver pasos para instalar la extensión de Chrome',
73
+ doctor: 'Diagnóstico (estado actual de la instalación)',
74
+ updates: 'Buscar actualizaciones en npm',
75
+ welcome: 'Mostrar la pantalla de bienvenida',
76
+ about: 'Información / ayuda — qué es esto y cómo funciona',
77
+ repo: 'Abrir el repositorio en GitHub',
78
+ quit: 'Salir',
79
+ },
80
+ },
81
+ };
82
+ export function MainMenu({ language, onSelect, onSwapLang, onQuit }) {
83
+ const t = MENU_I18N[language];
84
+ const items = ['register', 'extension', 'doctor', 'updates', 'welcome', 'about', 'repo', 'quit'].map((a) => ({ value: a, label: t.options[a] }));
85
+ const [idx, setIdx] = useState(0);
86
+ useInput((input, key) => {
87
+ if (key.upArrow)
88
+ setIdx((i) => (i - 1 + items.length) % items.length);
89
+ else if (key.downArrow)
90
+ setIdx((i) => (i + 1) % items.length);
91
+ else if (key.return) {
92
+ const v = items[idx].value;
93
+ if (v === 'quit')
94
+ onQuit();
95
+ else
96
+ onSelect(v);
97
+ }
98
+ else if (input === 'q' || key.escape)
99
+ onQuit();
100
+ else if (input === 'l')
101
+ onSwapLang();
102
+ });
103
+ return (_jsxs(Frame, { title: t.title, footer: t.footer, children: [_jsx(Text, { color: "white", bold: true, children: t.prompt }), _jsx(Box, { marginTop: 1, children: _jsx(Menu, { items: items, selectedIndex: idx }) })] }));
104
+ }
105
+ const PICKER_I18N = {
106
+ en: {
107
+ title: 'Register browser-link in…',
108
+ prompt: 'Which MCP client?',
109
+ footer: '↑↓ navigate · ↵ register · Esc back',
110
+ },
111
+ es: {
112
+ title: 'Registrar browser-link en…',
113
+ prompt: '¿Qué cliente MCP?',
114
+ footer: '↑↓ moverse · ↵ registrar · Esc volver',
115
+ },
116
+ };
117
+ export function ClientPicker({ language, onPick, onBack }) {
118
+ const t = PICKER_I18N[language];
119
+ const STATUS = {
120
+ en: { registered: 'registered', notRegistered: 'not registered', notDetected: 'not detected' },
121
+ es: { registered: 'registrado', notRegistered: 'no registrado', notDetected: 'no detectado' },
122
+ };
123
+ const s = STATUS[language];
124
+ const items = INSTALLERS.map((inst) => {
125
+ const d = inst.detect();
126
+ const hint = !d.installed ? s.notDetected : d.registered ? s.registered : s.notRegistered;
127
+ return { value: inst.id, label: inst.displayName, hint };
128
+ });
129
+ const [idx, setIdx] = useState(0);
130
+ useInput((input, key) => {
131
+ if (key.upArrow)
132
+ setIdx((i) => (i - 1 + items.length) % items.length);
133
+ else if (key.downArrow)
134
+ setIdx((i) => (i + 1) % items.length);
135
+ else if (key.return)
136
+ onPick(items[idx].value);
137
+ else if (input === 'q' || key.escape)
138
+ onBack();
139
+ });
140
+ return (_jsxs(Frame, { title: t.title, footer: t.footer, children: [_jsx(Text, { color: "white", bold: true, children: t.prompt }), _jsx(Box, { marginTop: 1, children: _jsx(Menu, { items: items, selectedIndex: idx }) })] }));
141
+ }
142
+ const RESULT_I18N = {
143
+ en: {
144
+ ok: 'Registered',
145
+ warn: 'Not registered',
146
+ hint: 'Restart the MCP client so it picks up the new entry.',
147
+ footer: '↵ / Esc back to menu',
148
+ },
149
+ es: {
150
+ ok: 'Registrado',
151
+ warn: 'No registrado',
152
+ hint: 'Reiniciá el cliente MCP para que tome la nueva entrada.',
153
+ footer: '↵ / Esc volver al menú',
154
+ },
155
+ };
156
+ export function InstallResultView({ language, report, onBack }) {
157
+ const t = RESULT_I18N[language];
158
+ useInput((_input, key) => {
159
+ if (key.return || key.escape)
160
+ onBack();
161
+ });
162
+ const ok = report.installedClient;
163
+ return (_jsxs(Frame, { title: `${report.displayName} — ${ok ? t.ok : t.warn}`, footer: t.footer, children: [_jsxs(Text, { color: ok ? 'green' : 'yellow', children: [ok ? '✓ ' : '⚠ ', report.message] }), ok && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "cyan", children: ["\u2192 ", t.hint] }) }))] }));
164
+ }
165
+ /* ── Extension info ────────────────────────────────────────────────────── */
166
+ const EXT_I18N = {
167
+ en: {
168
+ title: 'Chrome extension — install steps',
169
+ pathLabel: 'Extension assets are at:',
170
+ stepsLabel: 'Install steps:',
171
+ afterLoading: 'After loading, open the extension popup on any tab and click "Conectar" to bridge it.',
172
+ notFound: 'Extension assets not found. Run `npm run build:extension` (dev) or reinstall the package.',
173
+ footer: '↵ / Esc back to menu',
174
+ },
175
+ es: {
176
+ title: 'Extensión de Chrome — pasos de instalación',
177
+ pathLabel: 'Los assets de la extensión están en:',
178
+ stepsLabel: 'Pasos:',
179
+ afterLoading: 'Después de cargarla, abrí el popup de la extensión en cualquier pestaña y hacé click en "Conectar" para puentearla.',
180
+ notFound: 'No se encontraron los assets. Corré `npm run build:extension` (dev) o reinstalá el paquete.',
181
+ footer: '↵ / Esc volver al menú',
182
+ },
183
+ };
184
+ export function ExtensionView({ language, onBack }) {
185
+ const t = EXT_I18N[language];
186
+ const info = getExtensionInfo();
187
+ useInput((_input, key) => {
188
+ if (key.return || key.escape)
189
+ onBack();
190
+ });
191
+ return (_jsx(Frame, { title: t.title, footer: t.footer, children: info.path ? (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, children: t.pathLabel }), _jsx(Text, { color: "cyan", children: info.path }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, children: t.stepsLabel }), _jsx(Text, { children: info.hints })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", italic: true, children: t.afterLoading }) })] })) : (_jsx(Text, { color: "yellow", children: t.notFound })) }));
192
+ }
193
+ /* ── Doctor ────────────────────────────────────────────────────────────── */
194
+ const DOCTOR_I18N = {
195
+ en: {
196
+ title: 'Doctor — diagnose current setup',
197
+ loading: 'Diagnosing…',
198
+ refresh: 'r refresh · ↵ / Esc back to menu',
199
+ footer: '↵ / Esc back to menu',
200
+ },
201
+ es: {
202
+ title: 'Diagnóstico — estado actual de la instalación',
203
+ loading: 'Diagnosticando…',
204
+ refresh: 'r refrescar · ↵ / Esc volver al menú',
205
+ footer: '↵ / Esc volver al menú',
206
+ },
207
+ };
208
+ export function DoctorView({ language, onBack }) {
209
+ const t = DOCTOR_I18N[language];
210
+ const [output, setOutput] = useState(null);
211
+ const [refreshKey, setRefreshKey] = useState(0);
212
+ useEffect(() => {
213
+ let cancelled = false;
214
+ setOutput(null);
215
+ runDoctor().then((r) => {
216
+ if (!cancelled)
217
+ setOutput(formatDoctor(r));
218
+ });
219
+ return () => {
220
+ cancelled = true;
221
+ };
222
+ }, [refreshKey]);
223
+ useInput((input, key) => {
224
+ if (key.return || key.escape)
225
+ onBack();
226
+ else if (input === 'r')
227
+ setRefreshKey((k) => k + 1);
228
+ });
229
+ return (_jsx(Frame, { title: t.title, footer: t.refresh, children: output === null ? _jsx(Text, { color: "gray", children: t.loading }) : _jsx(Text, { children: output }) }));
230
+ }
231
+ export function AboutView({ language, onBack }) {
232
+ const t = I18N_ABOUT[language];
233
+ useInput((_input, key) => {
234
+ if (key.return || key.escape)
235
+ onBack();
236
+ });
237
+ const footer = language === 'es' ? '↵ / Esc volver al menú' : '↵ / Esc back to menu';
238
+ return (_jsxs(Frame, { title: t.title, footer: footer, children: [_jsx(AboutSection, { title: t.whatTitle, body: t.what }), _jsx(AboutSection, { title: t.howTitle, body: t.how }), _jsx(AboutSection, { title: t.bindingTitle, body: t.binding }), _jsx(AboutSection, { title: t.bridgeToolsTitle, body: t.bridgeTools }), _jsx(AboutSection, { title: t.mapToolsTitle, body: t.mapTools }), _jsx(AboutSection, { title: t.privacyTitle, body: t.privacy }), _jsx(AboutSection, { title: t.helpTitle, body: t.help })] }));
239
+ }
240
+ function AboutSection({ title, body }) {
241
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: title }), _jsx(Text, { children: body })] }));
242
+ }
243
+ /* ── Updates ───────────────────────────────────────────────────────────── */
244
+ const UPDATES_I18N = {
245
+ en: {
246
+ title: 'Check for updates',
247
+ checking: 'Checking the npm registry…',
248
+ current: 'Current version',
249
+ latest: 'Latest on npm ',
250
+ upToDate: '✓ You are on the latest published version.',
251
+ available: '⚠ A newer version is available.',
252
+ upgradeCmd: 'To upgrade, run:',
253
+ error: 'Could not check the registry',
254
+ footer: 'r retry · ↵ / Esc back to menu',
255
+ },
256
+ es: {
257
+ title: 'Buscar actualizaciones',
258
+ checking: 'Consultando el registry de npm…',
259
+ current: 'Versión instalada',
260
+ latest: 'Última en npm ',
261
+ upToDate: '✓ Estás en la última versión publicada.',
262
+ available: '⚠ Hay una versión más nueva disponible.',
263
+ upgradeCmd: 'Para actualizar, corré:',
264
+ error: 'No se pudo consultar el registry',
265
+ footer: 'r reintentar · ↵ / Esc volver al menú',
266
+ },
267
+ };
268
+ export function UpdatesView({ language, onBack }) {
269
+ const t = UPDATES_I18N[language];
270
+ const [info, setInfo] = useState(null);
271
+ const [refreshKey, setRefreshKey] = useState(0);
272
+ useEffect(() => {
273
+ let cancelled = false;
274
+ setInfo(null);
275
+ checkUpdates().then((r) => {
276
+ if (!cancelled)
277
+ setInfo(r);
278
+ });
279
+ return () => {
280
+ cancelled = true;
281
+ };
282
+ }, [refreshKey]);
283
+ useInput((input, key) => {
284
+ if (key.return || key.escape)
285
+ onBack();
286
+ else if (input === 'r')
287
+ setRefreshKey((k) => k + 1);
288
+ });
289
+ return (_jsx(Frame, { title: t.title, footer: t.footer, children: info === null ? (_jsx(Text, { color: "gray", children: t.checking })) : info.error || info.latest === null ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsxs(Text, { color: "white", children: [t.current, ": "] }), _jsx(Text, { bold: true, children: info.current })] }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: [t.error, ": ", info.error ?? 'unknown error'] }) })] })) : (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsxs(Text, { color: "white", children: [t.current, ": "] }), _jsx(Text, { bold: true, children: info.current })] }), _jsxs(Text, { children: [_jsxs(Text, { color: "white", children: [t.latest, ": "] }), _jsx(Text, { bold: true, color: info.newer ? 'yellow' : 'green', children: info.latest })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: info.newer ? 'yellow' : 'green', children: info.newer ? t.available : t.upToDate }) }), info.newer && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "gray", children: t.upgradeCmd }), _jsx(Text, { color: "cyan", children: `npm install -g ${PACKAGE_NAME}@latest` })] }))] })) }));
290
+ }
291
+ //# sourceMappingURL=screens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screens.js","sourceRoot":"","sources":["../../src/ui/screens.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAiB,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAiB,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAiB,MAAM,wBAAwB,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAmB,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAoB7C,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,SAAS,EACT,UAAU,EACV,MAAM,GACO;IACb,MAAM,CAAC,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,KAAK,GAAuD;QAChE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE;KAC7C,CAAC;IACF,IAAI,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAE/F,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAElC,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,OAAO;YAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;aACjE,IAAI,GAAG,CAAC,SAAS;YAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;aACzD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAE,CAAC,KAAK,CAAC;YAC5B,IAAI,CAAC,KAAK,QAAQ;gBAAE,QAAQ,EAAE,CAAC;iBAC1B,IAAI,CAAC,KAAK,SAAS;gBAAE,SAAS,EAAE,CAAC;iBACjC,IAAI,CAAC,KAAK,MAAM;gBAAE,UAAU,EAAE,CAAC;;gBAC/B,MAAM,EAAE,CAAC;QAChB,CAAC;aAAM,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;aAC5C,IAAI,KAAK,KAAK,GAAG;YAAE,UAAU,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GACV,QAAQ,KAAK,IAAI;QACf,CAAC,CAAC,4CAA4C;QAC9C,CAAC,CAAC,8CAA8C,CAAC;IAErD,OAAO,CACL,MAAC,KAAK,IAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,aACnC,KAAC,OAAO,IAAC,KAAK,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,GAAI,EAC/C,KAAC,OAAO,IAAC,KAAK,EAAE,CAAC,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,YAAY,GAAI,EAC7D,KAAC,OAAO,IAAC,KAAK,EAAE,CAAC,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,SAAG,EACxD,MAAC,GAAG,IAAC,YAAY,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aAC1C,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,MAAM,kBACtB,CAAC,CAAC,cAAc,GACZ,EACP,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,MAAM,kBACtB,CAAC,CAAC,aAAa,GACX,IACH,EACN,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,kBACrB,CAAC,CAAC,MAAM,GACJ,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,GAAI,GACtC,IACA,CACT,CAAC;AACJ,CAAC;AAOD,SAAS,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAgB;IAClD,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC,aACzC,MAAC,IAAI,IAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,mBACxC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EACjB,KAAK,IACD,EACP,KAAC,IAAI,cAAE,IAAI,GAAQ,IACf,CACP,CAAC;AACJ,CAAC;AAqBD,MAAM,SAAS,GAA+B;IAC5C,EAAE,EAAE;QACF,KAAK,EAAE,sBAAsB;QAC7B,MAAM,EAAE,gBAAgB;QACxB,MAAM,EAAE,8CAA8C;QACtD,OAAO,EAAE;YACP,QAAQ,EAAE,0CAA0C;YACpD,SAAS,EAAE,qCAAqC;YAChD,MAAM,EAAE,qCAAqC;YAC7C,OAAO,EAAE,0BAA0B;YACnC,OAAO,EAAE,yBAAyB;YAClC,KAAK,EAAE,8CAA8C;YACrD,IAAI,EAAE,4BAA4B;YAClC,IAAI,EAAE,MAAM;SACb;KACF;IACD,EAAE,EAAE;QACF,KAAK,EAAE,8BAA8B;QACrC,MAAM,EAAE,kBAAkB;QAC1B,MAAM,EAAE,4CAA4C;QACpD,OAAO,EAAE;YACP,QAAQ,EAAE,0CAA0C;YACpD,SAAS,EAAE,gDAAgD;YAC3D,MAAM,EAAE,+CAA+C;YACvD,OAAO,EAAE,+BAA+B;YACxC,OAAO,EAAE,mCAAmC;YAC5C,KAAK,EAAE,mDAAmD;YAC1D,IAAI,EAAE,gCAAgC;YACtC,IAAI,EAAE,OAAO;SACd;KACF;CACF,CAAC;AAQF,MAAM,UAAU,QAAQ,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAiB;IAChF,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,KAAK,GACT,CAAC,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAClF,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAElD,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAElC,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,OAAO;YAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;aACjE,IAAI,GAAG,CAAC,SAAS;YAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;aACzD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAE,CAAC,KAAK,CAAC;YAC5B,IAAI,CAAC,KAAK,MAAM;gBAAE,MAAM,EAAE,CAAC;;gBACtB,QAAQ,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;aAAM,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;aAC5C,IAAI,KAAK,KAAK,GAAG;YAAE,UAAU,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,KAAK,IAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,aACrC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,kBACrB,CAAC,CAAC,MAAM,GACJ,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,GAAI,GACtC,IACA,CACT,CAAC;AACJ,CAAC;AASD,MAAM,WAAW,GAAwE;IACvF,EAAE,EAAE;QACF,KAAK,EAAE,2BAA2B;QAClC,MAAM,EAAE,mBAAmB;QAC3B,MAAM,EAAE,qCAAqC;KAC9C;IACD,EAAE,EAAE;QACF,KAAK,EAAE,4BAA4B;QACnC,MAAM,EAAE,mBAAmB;QAC3B,MAAM,EAAE,uCAAuC;KAChD;CACF,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAqB;IAC1E,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,MAAM,GAGR;QACF,EAAE,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE;QAC9F,EAAE,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE;KAC9F,CAAC;IACF,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAyB,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC1D,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;QAC1F,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAElC,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,OAAO;YAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;aACjE,IAAI,GAAG,CAAC,SAAS;YAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;aACzD,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAE,CAAC,KAAK,CAAC,CAAC;aAC1C,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,KAAK,IAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,aACrC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,kBACrB,CAAC,CAAC,MAAM,GACJ,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,GAAI,GACtC,IACA,CACT,CAAC;AACJ,CAAC;AASD,MAAM,WAAW,GAAiF;IAChG,EAAE,EAAE;QACF,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,gBAAgB;QACtB,IAAI,EAAE,sDAAsD;QAC5D,MAAM,EAAE,sBAAsB;KAC/B;IACD,EAAE,EAAE;QACF,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,yDAAyD;QAC/D,MAAM,EAAE,wBAAwB;KACjC;CACF,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAsB;IAChF,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAChC,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACvB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IACH,MAAM,EAAE,GAAG,MAAM,CAAC,eAAe,CAAC;IAClC,OAAO,CACL,MAAC,KAAK,IAAC,KAAK,EAAE,GAAG,MAAM,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,aAC7E,MAAC,IAAI,IAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,aACjC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAChB,MAAM,CAAC,OAAO,IACV,EACN,EAAE,IAAI,CACL,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,wBAAI,CAAC,CAAC,IAAI,IAAQ,GAChC,CACP,IACK,CACT,CAAC;AACJ,CAAC;AAED,8EAA8E;AAE9E,MAAM,QAAQ,GAUV;IACF,EAAE,EAAE;QACF,KAAK,EAAE,kCAAkC;QACzC,SAAS,EAAE,0BAA0B;QACrC,UAAU,EAAE,gBAAgB;QAC5B,YAAY,EACV,uFAAuF;QACzF,QAAQ,EACN,2FAA2F;QAC7F,MAAM,EAAE,sBAAsB;KAC/B;IACD,EAAE,EAAE;QACF,KAAK,EAAE,4CAA4C;QACnD,SAAS,EAAE,sCAAsC;QACjD,UAAU,EAAE,QAAQ;QACpB,YAAY,EACV,qHAAqH;QACvH,QAAQ,EACN,6FAA6F;QAC/F,MAAM,EAAE,wBAAwB;KACjC;CACF,CAAC;AAMF,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAsB;IACpE,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACvB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IACH,OAAO,CACL,KAAC,KAAK,IAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,YACpC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CACX,8BACE,KAAC,IAAI,IAAC,IAAI,kBAAE,CAAC,CAAC,SAAS,GAAQ,EAC/B,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,IAAI,CAAC,IAAI,GAAQ,EACrC,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aACvC,KAAC,IAAI,IAAC,IAAI,kBAAE,CAAC,CAAC,UAAU,GAAQ,EAChC,KAAC,IAAI,cAAE,IAAI,CAAC,KAAK,GAAQ,IACrB,EACN,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,MAAM,kBACtB,CAAC,CAAC,YAAY,GACV,GACH,IACL,CACJ,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,YAAE,CAAC,CAAC,QAAQ,GAAQ,CACzC,GACK,CACT,CAAC;AACJ,CAAC;AAED,8EAA8E;AAE9E,MAAM,WAAW,GAGb;IACF,EAAE,EAAE;QACF,KAAK,EAAE,iCAAiC;QACxC,OAAO,EAAE,aAAa;QACtB,OAAO,EAAE,kCAAkC;QAC3C,MAAM,EAAE,sBAAsB;KAC/B;IACD,EAAE,EAAE;QACF,KAAK,EAAE,+CAA+C;QACtD,OAAO,EAAE,iBAAiB;QAC1B,OAAO,EAAE,sCAAsC;QAC/C,MAAM,EAAE,wBAAwB;KACjC;CACF,CAAC;AAMF,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAmB;IAC9D,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YACrB,IAAI,CAAC,SAAS;gBAAE,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;aAClC,IAAI,KAAK,KAAK,GAAG;YAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,KAAK,IAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,YACrC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,CAAC,CAAC,OAAO,GAAQ,CAAC,CAAC,CAAC,KAAC,IAAI,cAAE,MAAM,GAAQ,GAC1E,CACT,CAAC;AACJ,CAAC;AAQD,MAAM,UAAU,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAkB;IAC5D,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/B,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACvB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,sBAAsB,CAAC;IACrF,OAAO,CACL,MAAC,KAAK,IAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,aACnC,KAAC,YAAY,IAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,GAAI,EAClD,KAAC,YAAY,IAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,GAAI,EAChD,KAAC,YAAY,IAAC,KAAK,EAAE,CAAC,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,GAAI,EACxD,KAAC,YAAY,IAAC,KAAK,EAAE,CAAC,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,GAAI,EAChE,KAAC,YAAY,IAAC,KAAK,EAAE,CAAC,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,GAAI,EAC1D,KAAC,YAAY,IAAC,KAAK,EAAE,CAAC,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,GAAI,EACxD,KAAC,YAAY,IAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,GAAI,IAC5C,CACT,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAmC;IACpE,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC,aACzC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,kBACpB,KAAK,GACD,EACP,KAAC,IAAI,cAAE,IAAI,GAAQ,IACf,CACP,CAAC;AACJ,CAAC;AAED,8EAA8E;AAE9E,MAAM,YAAY,GAad;IACF,EAAE,EAAE;QACF,KAAK,EAAE,mBAAmB;QAC1B,QAAQ,EAAE,4BAA4B;QACtC,OAAO,EAAE,iBAAiB;QAC1B,MAAM,EAAE,iBAAiB;QACzB,QAAQ,EAAE,4CAA4C;QACtD,SAAS,EAAE,iCAAiC;QAC5C,UAAU,EAAE,kBAAkB;QAC9B,KAAK,EAAE,8BAA8B;QACrC,MAAM,EAAE,gCAAgC;KACzC;IACD,EAAE,EAAE;QACF,KAAK,EAAE,wBAAwB;QAC/B,QAAQ,EAAE,iCAAiC;QAC3C,OAAO,EAAE,mBAAmB;QAC5B,MAAM,EAAE,mBAAmB;QAC3B,QAAQ,EAAE,yCAAyC;QACnD,SAAS,EAAE,yCAAyC;QACpD,UAAU,EAAE,yBAAyB;QACrC,KAAK,EAAE,kCAAkC;QACzC,MAAM,EAAE,uCAAuC;KAChD;CACF,CAAC;AAMF,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAoB;IAChE,MAAM,CAAC,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAoB,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YACxB,IAAI,CAAC,SAAS;gBAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;aAClC,IAAI,KAAK,KAAK,GAAG;YAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,KAAK,IAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,YACpC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,CAAC,CAAC,QAAQ,GAAQ,CACvC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CACvC,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,IAAI,eACH,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,aAAE,CAAC,CAAC,OAAO,UAAU,EACxC,KAAC,IAAI,IAAC,IAAI,kBAAE,IAAI,CAAC,OAAO,GAAQ,IAC3B,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,aACd,CAAC,CAAC,KAAK,QAAI,IAAI,CAAC,KAAK,IAAI,eAAe,IACpC,GACH,IACF,CACP,CAAC,CAAC,CAAC,CACF,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,IAAI,eACH,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,aAAE,CAAC,CAAC,OAAO,UAAU,EACxC,KAAC,IAAI,IAAC,IAAI,kBAAE,IAAI,CAAC,OAAO,GAAQ,IAC3B,EACP,MAAC,IAAI,eACH,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,aAAE,CAAC,CAAC,MAAM,UAAU,EACvC,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,YAC9C,IAAI,CAAC,MAAM,GACP,IACF,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,YACzC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GACjC,GACH,EACL,IAAI,CAAC,KAAK,IAAI,CACb,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,aACtC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,CAAC,CAAC,UAAU,GAAQ,EACxC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,kBAAkB,YAAY,SAAS,GAAQ,IAC/D,CACP,IACG,CACP,GACK,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Mount the Ink UI and return a promise that resolves when the user quits.
3
+ * cli.ts calls this when stdin/stdout are TTYs (i.e. a human is at the
4
+ * terminal). The MCP-server path never reaches here.
5
+ */
6
+ export declare function startUI(): Promise<void>;
@@ -0,0 +1,19 @@
1
+ import { createElement } from 'react';
2
+ import { render } from 'ink';
3
+ import { loadConfig } from '../config.js';
4
+ import { App } from './app.js';
5
+ /**
6
+ * Mount the Ink UI and return a promise that resolves when the user quits.
7
+ * cli.ts calls this when stdin/stdout are TTYs (i.e. a human is at the
8
+ * terminal). The MCP-server path never reaches here.
9
+ */
10
+ export async function startUI() {
11
+ const cfg = loadConfig();
12
+ const initialLanguage = cfg.language ?? 'en';
13
+ const skipWelcome = cfg.skipWelcome === true;
14
+ const instance = render(createElement(App, { initialLanguage, skipWelcome }), {
15
+ exitOnCtrlC: true,
16
+ });
17
+ await instance.waitUntilExit();
18
+ }
19
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/ui/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,eAAe,GAAG,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC;IAC7C,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC,EAAE;QAC5E,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IACH,MAAM,QAAQ,CAAC,aAAa,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const PACKAGE_NAME: string;
2
+ export declare const VERSION: string;
@@ -0,0 +1,15 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ /**
5
+ * Package identity + version, resolved at runtime by reading the shipped
6
+ * package.json. Works in both dev (`tsx src/cli.ts`) and installed
7
+ * (`node_modules/@jobshimo/browser-link/dist/version.js`) layouts because
8
+ * `package.json` always sits one directory above this module's parent in
9
+ * either source tree (src/ or dist/).
10
+ */
11
+ const here = dirname(fileURLToPath(import.meta.url));
12
+ const pkg = JSON.parse(readFileSync(join(here, '..', 'package.json'), 'utf8'));
13
+ export const PACKAGE_NAME = pkg.name;
14
+ export const VERSION = pkg.version;
15
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAG5E,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAW,GAAG,CAAC,IAAI,CAAC;AAC7C,MAAM,CAAC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC"}
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@jobshimo/browser-link",
3
- "version": "0.1.0",
4
- "description": "MCP server that bridges Claude Code, OpenCode and other MCP clients to a Chrome tab, with a persistent UI map of selectors, flows and gotchas across sessions.",
3
+ "version": "0.2.0",
4
+ "description": "MCP server that bridges Claude Code, OpenCode, GitHub Copilot CLI and other MCP clients to a Chrome tab, with a persistent UI map of selectors, flows and gotchas across sessions.",
5
5
  "keywords": [
6
6
  "mcp",
7
7
  "model-context-protocol",
8
8
  "claude",
9
9
  "claude-code",
10
10
  "opencode",
11
+ "github-copilot",
12
+ "copilot-cli",
11
13
  "chrome",
12
14
  "browser-automation",
13
15
  "ai-tools"
@@ -39,6 +41,7 @@
39
41
  "scripts": {
40
42
  "build": "tsc",
41
43
  "dev": "tsx watch src/cli.ts",
44
+ "try": "tsx src/cli.ts",
42
45
  "start": "node dist/cli.js",
43
46
  "typecheck": "tsc --noEmit",
44
47
  "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
@@ -47,15 +50,17 @@
47
50
  "prepublishOnly": "npm run clean && npm run build && node ./scripts/prepare-publish.mjs"
48
51
  },
49
52
  "dependencies": {
50
- "@clack/prompts": "^1.3.0",
51
53
  "@modelcontextprotocol/sdk": "^1.0.0",
52
54
  "better-sqlite3": "^11.5.0",
53
55
  "env-paths": "^3.0.0",
56
+ "ink": "^5.2.1",
57
+ "react": "^18.3.1",
54
58
  "ws": "^8.18.0"
55
59
  },
56
60
  "devDependencies": {
57
61
  "@types/better-sqlite3": "^7.6.11",
58
62
  "@types/node": "^22.0.0",
63
+ "@types/react": "^18.3.28",
59
64
  "@types/ws": "^8.5.13",
60
65
  "tsx": "^4.19.0",
61
66
  "typescript": "^5.6.0",
@@ -1,25 +0,0 @@
1
- import { type Language } from './welcome.js';
2
- interface MenuI18n {
3
- title: string;
4
- outro: string;
5
- prompt: string;
6
- options: {
7
- register: string;
8
- extension: string;
9
- doctor: string;
10
- welcome: string;
11
- about: string;
12
- repo: string;
13
- quit: string;
14
- };
15
- statusRegistered: string;
16
- statusNotRegistered: string;
17
- statusClientMissing: string;
18
- registerSuccessHint: string;
19
- repoOpened: string;
20
- repoFallback: string;
21
- pickClient: string;
22
- }
23
- export declare const I18N_MENU: Record<Language, MenuI18n>;
24
- export declare function runMenu(initialLanguage?: Language): Promise<void>;
25
- export {};