@jobshimo/browser-link 0.0.1
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/LICENSE +21 -0
- package/README.md +83 -0
- package/dist/auth/allowlist.d.ts +2 -0
- package/dist/auth/allowlist.js +53 -0
- package/dist/auth/allowlist.js.map +1 -0
- package/dist/auth/process-identity.d.ts +19 -0
- package/dist/auth/process-identity.js +106 -0
- package/dist/auth/process-identity.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +116 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/about.d.ts +23 -0
- package/dist/commands/about.js +248 -0
- package/dist/commands/about.js.map +1 -0
- package/dist/commands/doctor.d.ts +29 -0
- package/dist/commands/doctor.js +110 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/extension.d.ts +12 -0
- package/dist/commands/extension.js +76 -0
- package/dist/commands/extension.js.map +1 -0
- package/dist/commands/install.d.ts +19 -0
- package/dist/commands/install.js +52 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/menu.d.ts +26 -0
- package/dist/commands/menu.js +187 -0
- package/dist/commands/menu.js.map +1 -0
- package/dist/commands/tty.d.ts +51 -0
- package/dist/commands/tty.js +148 -0
- package/dist/commands/tty.js.map +1 -0
- package/dist/commands/uninstall.d.ts +8 -0
- package/dist/commands/uninstall.js +10 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/welcome.d.ts +33 -0
- package/dist/commands/welcome.js +177 -0
- package/dist/commands/welcome.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.js +35 -0
- package/dist/config.js.map +1 -0
- package/dist/entry-info.d.ts +12 -0
- package/dist/entry-info.js +15 -0
- package/dist/entry-info.js.map +1 -0
- package/dist/extension/background.d.ts +1 -0
- package/dist/extension/background.js +490 -0
- package/dist/extension/background.js.map +1 -0
- package/dist/extension/icons/icon-128.png +0 -0
- package/dist/extension/icons/icon-16.png +0 -0
- package/dist/extension/icons/icon-32.png +0 -0
- package/dist/extension/icons/icon-48.png +0 -0
- package/dist/extension/icons/icon.svg +14 -0
- package/dist/extension/manifest.json +28 -0
- package/dist/extension/popup.d.ts +13 -0
- package/dist/extension/popup.html +88 -0
- package/dist/extension/popup.js +78 -0
- package/dist/extension/popup.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/installers/claude.d.ts +2 -0
- package/dist/installers/claude.js +77 -0
- package/dist/installers/claude.js.map +1 -0
- package/dist/installers/index.d.ts +9 -0
- package/dist/installers/index.js +14 -0
- package/dist/installers/index.js.map +1 -0
- package/dist/installers/opencode.d.ts +2 -0
- package/dist/installers/opencode.js +39 -0
- package/dist/installers/opencode.js.map +1 -0
- package/dist/installers/types.d.ts +30 -0
- package/dist/installers/types.js +2 -0
- package/dist/installers/types.js.map +1 -0
- package/dist/map/db.d.ts +3 -0
- package/dist/map/db.js +81 -0
- package/dist/map/db.js.map +1 -0
- package/dist/map/paths.d.ts +12 -0
- package/dist/map/paths.js +22 -0
- package/dist/map/paths.js.map +1 -0
- package/dist/map/queries.d.ts +72 -0
- package/dist/map/queries.js +162 -0
- package/dist/map/queries.js.map +1 -0
- package/dist/map/tools.d.ts +8 -0
- package/dist/map/tools.js +143 -0
- package/dist/map/tools.js.map +1 -0
- package/dist/messages.d.ts +42 -0
- package/dist/messages.js +9 -0
- package/dist/messages.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.js +217 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/browser-definitions.d.ts +7 -0
- package/dist/tools/browser-definitions.js +127 -0
- package/dist/tools/browser-definitions.js.map +1 -0
- package/dist/tools/browser-dispatch.d.ts +20 -0
- package/dist/tools/browser-dispatch.js +75 -0
- package/dist/tools/browser-dispatch.js.map +1 -0
- package/dist/tools/responses.d.ts +19 -0
- package/dist/tools/responses.js +27 -0
- package/dist/tools/responses.js.map +1 -0
- package/dist/tools/server-instructions.d.ts +3 -0
- package/dist/tools/server-instructions.js +50 -0
- package/dist/tools/server-instructions.js.map +1 -0
- package/dist/tools/types.d.ts +6 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/utils/open-url.d.ts +4 -0
- package/dist/utils/open-url.js +37 -0
- package/dist/utils/open-url.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { stdout } from 'node:process';
|
|
2
|
+
import { claudeInstaller } from '../installers/claude.js';
|
|
3
|
+
import { installFor } from './install.js';
|
|
4
|
+
import { formatDoctor, runDoctor } from './doctor.js';
|
|
5
|
+
import { printExtensionInstructions } from './extension.js';
|
|
6
|
+
import { runWelcome } from './welcome.js';
|
|
7
|
+
import { runAbout } from './about.js';
|
|
8
|
+
import { openUrl } from '../utils/open-url.js';
|
|
9
|
+
const REPO_URL = 'https://github.com/jobshimo/browser-link';
|
|
10
|
+
import { ansi, classifyKey, clearScreen, hideCursor, readKey, renderBox, showCursor, } from './tty.js';
|
|
11
|
+
export const I18N_MENU = {
|
|
12
|
+
en: {
|
|
13
|
+
title: 'browser-link — setup',
|
|
14
|
+
prompt: '↑/↓ to move, Enter to select, q to quit',
|
|
15
|
+
pressEnter: 'Press Enter to return to the menu…',
|
|
16
|
+
options: {
|
|
17
|
+
register: 'Register browser-link in Claude Code',
|
|
18
|
+
extension: 'Show Chrome extension install steps',
|
|
19
|
+
doctor: 'Run doctor (diagnose current setup)',
|
|
20
|
+
welcome: 'Show welcome screen',
|
|
21
|
+
about: 'About / Help — what is this and how it works',
|
|
22
|
+
repo: 'Open the GitHub repository (view code, report issues, contribute)',
|
|
23
|
+
quit: 'Quit',
|
|
24
|
+
},
|
|
25
|
+
statusRegistered: 'already registered',
|
|
26
|
+
statusNotRegistered: 'not registered',
|
|
27
|
+
statusClientMissing: 'Claude config not found',
|
|
28
|
+
registerSuccessHint: 'Restart Claude Code so it picks up the new MCP entry.',
|
|
29
|
+
repoOpened: 'Opening the repository in your browser…',
|
|
30
|
+
repoFallback: 'Could not open a browser automatically. Visit:',
|
|
31
|
+
},
|
|
32
|
+
es: {
|
|
33
|
+
title: 'browser-link — configuración',
|
|
34
|
+
prompt: '↑/↓ para moverte, Enter para elegir, q para salir',
|
|
35
|
+
pressEnter: 'Pulsá Enter para volver al menú…',
|
|
36
|
+
options: {
|
|
37
|
+
register: 'Registrar browser-link en Claude Code',
|
|
38
|
+
extension: 'Ver pasos para instalar la extensión de Chrome',
|
|
39
|
+
doctor: 'Diagnóstico (estado actual de la instalación)',
|
|
40
|
+
welcome: 'Mostrar pantalla de bienvenida',
|
|
41
|
+
about: 'Información / ayuda — qué es esto y cómo funciona',
|
|
42
|
+
repo: 'Abrir el repositorio en GitHub (ver código, reportar bugs, contribuir)',
|
|
43
|
+
quit: 'Salir',
|
|
44
|
+
},
|
|
45
|
+
statusRegistered: 'ya registrado',
|
|
46
|
+
statusNotRegistered: 'no registrado',
|
|
47
|
+
statusClientMissing: 'config de Claude no encontrada',
|
|
48
|
+
registerSuccessHint: 'Reiniciá Claude Code para que tome el nuevo MCP.',
|
|
49
|
+
repoOpened: 'Abriendo el repositorio en tu navegador…',
|
|
50
|
+
repoFallback: 'No se pudo abrir el navegador automáticamente. Visitá:',
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
export function claudeStatus(t) {
|
|
54
|
+
const d = claudeInstaller.detect();
|
|
55
|
+
if (!d.installed)
|
|
56
|
+
return t.statusClientMissing;
|
|
57
|
+
return d.registered ? t.statusRegistered : t.statusNotRegistered;
|
|
58
|
+
}
|
|
59
|
+
export function renderMenuScreen(t, selectedIndex, options) {
|
|
60
|
+
const lines = [];
|
|
61
|
+
lines.push(`${ansi.bold}${ansi.cyan}${t.title}${ansi.reset}`);
|
|
62
|
+
lines.push('');
|
|
63
|
+
options.forEach((label, i) => {
|
|
64
|
+
const isSel = i === selectedIndex;
|
|
65
|
+
const cursor = isSel ? `${ansi.cyan}❯${ansi.reset}` : ' ';
|
|
66
|
+
const body = isSel ? `${ansi.bold}${label}${ansi.reset}` : `${ansi.gray}${label}${ansi.reset}`;
|
|
67
|
+
lines.push(` ${cursor} ${body}`);
|
|
68
|
+
});
|
|
69
|
+
lines.push('');
|
|
70
|
+
lines.push(`${ansi.dim}${t.prompt}${ansi.reset}`);
|
|
71
|
+
return renderBox(lines, { borderColor: ansi.gray });
|
|
72
|
+
}
|
|
73
|
+
async function pressEnter(t) {
|
|
74
|
+
stdout.write('\n' + ansi.dim + t.pressEnter + ansi.reset + ' ');
|
|
75
|
+
while (true) {
|
|
76
|
+
const k = classifyKey(await readKey());
|
|
77
|
+
if (k === 'enter' || k === 'ctrl-c' || k === 'esc' || k === 'q')
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function runOption(t, index, language) {
|
|
82
|
+
let lang = language;
|
|
83
|
+
switch (index) {
|
|
84
|
+
case 0: {
|
|
85
|
+
clearScreen();
|
|
86
|
+
const report = installFor('claude');
|
|
87
|
+
const mark = report.installedClient
|
|
88
|
+
? `${ansi.green}✓${ansi.reset}`
|
|
89
|
+
: `${ansi.gray}·${ansi.reset}`;
|
|
90
|
+
console.log(`${mark} ${ansi.bold}${report.displayName}${ansi.reset}: ${report.message}`);
|
|
91
|
+
if (report.installedClient)
|
|
92
|
+
console.log(` ${ansi.cyan}→${ansi.reset} ${t.registerSuccessHint}`);
|
|
93
|
+
await pressEnter(t);
|
|
94
|
+
return { keep: true, language: lang };
|
|
95
|
+
}
|
|
96
|
+
case 1: {
|
|
97
|
+
clearScreen();
|
|
98
|
+
printExtensionInstructions();
|
|
99
|
+
await pressEnter(t);
|
|
100
|
+
return { keep: true, language: lang };
|
|
101
|
+
}
|
|
102
|
+
case 2: {
|
|
103
|
+
clearScreen();
|
|
104
|
+
const r = await runDoctor();
|
|
105
|
+
console.log(formatDoctor(r));
|
|
106
|
+
await pressEnter(t);
|
|
107
|
+
return { keep: true, language: lang };
|
|
108
|
+
}
|
|
109
|
+
case 3: {
|
|
110
|
+
// Show welcome again (forced; hides "Don't show again" because the
|
|
111
|
+
// user explicitly asked to see it).
|
|
112
|
+
const result = await runWelcome({ initial: lang, hideDismiss: true });
|
|
113
|
+
if (result.action === 'quit')
|
|
114
|
+
return { keep: false, language: lang };
|
|
115
|
+
lang = result.language;
|
|
116
|
+
return { keep: true, language: lang };
|
|
117
|
+
}
|
|
118
|
+
case 4: {
|
|
119
|
+
await runAbout(lang);
|
|
120
|
+
return { keep: true, language: lang };
|
|
121
|
+
}
|
|
122
|
+
case 5: {
|
|
123
|
+
clearScreen();
|
|
124
|
+
const ok = openUrl(REPO_URL);
|
|
125
|
+
if (ok) {
|
|
126
|
+
console.log(`${ansi.cyan}→${ansi.reset} ${t.repoOpened}`);
|
|
127
|
+
console.log(` ${ansi.dim}${REPO_URL}${ansi.reset}`);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
console.log(`${ansi.yellow}!${ansi.reset} ${t.repoFallback}`);
|
|
131
|
+
console.log(` ${ansi.cyan}${REPO_URL}${ansi.reset}`);
|
|
132
|
+
}
|
|
133
|
+
await pressEnter(t);
|
|
134
|
+
return { keep: true, language: lang };
|
|
135
|
+
}
|
|
136
|
+
case 6:
|
|
137
|
+
return { keep: false, language: lang };
|
|
138
|
+
default:
|
|
139
|
+
return { keep: true, language: lang };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export async function runMenu(initialLanguage = 'en') {
|
|
143
|
+
let language = initialLanguage;
|
|
144
|
+
let selected = 0;
|
|
145
|
+
hideCursor();
|
|
146
|
+
try {
|
|
147
|
+
while (true) {
|
|
148
|
+
const t = I18N_MENU[language];
|
|
149
|
+
const opts = [
|
|
150
|
+
`${t.options.register} ${ansi.dim}(${claudeStatus(t)})${ansi.reset}`,
|
|
151
|
+
t.options.extension,
|
|
152
|
+
t.options.doctor,
|
|
153
|
+
t.options.welcome,
|
|
154
|
+
t.options.about,
|
|
155
|
+
t.options.repo,
|
|
156
|
+
t.options.quit,
|
|
157
|
+
];
|
|
158
|
+
clearScreen();
|
|
159
|
+
stdout.write(renderMenuScreen(t, selected, opts));
|
|
160
|
+
stdout.write('\n');
|
|
161
|
+
const key = classifyKey(await readKey());
|
|
162
|
+
if (key === 'ctrl-c' || key === 'esc' || key === 'q')
|
|
163
|
+
return;
|
|
164
|
+
if (key === 'up') {
|
|
165
|
+
selected = (selected - 1 + opts.length) % opts.length;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (key === 'down') {
|
|
169
|
+
selected = (selected + 1) % opts.length;
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (key === 'enter') {
|
|
173
|
+
showCursor();
|
|
174
|
+
const result = await runOption(t, selected, language);
|
|
175
|
+
if (!result.keep)
|
|
176
|
+
return;
|
|
177
|
+
language = result.language;
|
|
178
|
+
hideCursor();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
showCursor();
|
|
184
|
+
stdout.write('\n');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/commands/menu.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export declare const ansi: {
|
|
2
|
+
reset: string;
|
|
3
|
+
bold: string;
|
|
4
|
+
dim: string;
|
|
5
|
+
italic: string;
|
|
6
|
+
underline: string;
|
|
7
|
+
black: string;
|
|
8
|
+
red: string;
|
|
9
|
+
green: string;
|
|
10
|
+
yellow: string;
|
|
11
|
+
blue: string;
|
|
12
|
+
magenta: string;
|
|
13
|
+
cyan: string;
|
|
14
|
+
white: string;
|
|
15
|
+
gray: string;
|
|
16
|
+
bgYellow: string;
|
|
17
|
+
bgRed: string;
|
|
18
|
+
clearScreen: string;
|
|
19
|
+
hideCursor: string;
|
|
20
|
+
showCursor: string;
|
|
21
|
+
};
|
|
22
|
+
export declare const KEY: {
|
|
23
|
+
CTRL_C: string;
|
|
24
|
+
ESC: string;
|
|
25
|
+
ENTER_CR: string;
|
|
26
|
+
ENTER_LF: string;
|
|
27
|
+
UP: string;
|
|
28
|
+
DOWN: string;
|
|
29
|
+
RIGHT: string;
|
|
30
|
+
LEFT: string;
|
|
31
|
+
};
|
|
32
|
+
/** Visible width of a string (ignores ANSI escape sequences). Treats every
|
|
33
|
+
* other code point as 1 column — fine for ASCII + the Latin range we use. */
|
|
34
|
+
export declare function visibleWidth(s: string): number;
|
|
35
|
+
export declare function padRight(s: string, width: number): string;
|
|
36
|
+
/** Wrap a line at the given width, preserving simple ANSI runs. */
|
|
37
|
+
export declare function wrap(text: string, width: number): string[];
|
|
38
|
+
export interface BoxOptions {
|
|
39
|
+
width?: number;
|
|
40
|
+
borderColor?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Render an array of lines inside a rounded Unicode box. */
|
|
43
|
+
export declare function renderBox(lines: string[], opts?: BoxOptions): string;
|
|
44
|
+
/** Read a single keypress from stdin without echoing. Returns the raw key
|
|
45
|
+
* (a control sequence for arrows, '\r' for enter, etc.). */
|
|
46
|
+
export declare function readKey(): Promise<string>;
|
|
47
|
+
/** Classify a raw key into a logical name. */
|
|
48
|
+
export declare function classifyKey(raw: string): string;
|
|
49
|
+
export declare function clearScreen(): void;
|
|
50
|
+
export declare function hideCursor(): void;
|
|
51
|
+
export declare function showCursor(): void;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { stdin, stdout } from 'node:process';
|
|
2
|
+
/* ANSI helpers — no dependencies. Modern terminals (macOS Terminal, iTerm,
|
|
3
|
+
* Windows Terminal, PowerShell 7+, every Linux TTY) understand these.
|
|
4
|
+
* Old cmd.exe may render the box characters poorly but the flow still works. */
|
|
5
|
+
const ESC = '\x1b';
|
|
6
|
+
export const ansi = {
|
|
7
|
+
reset: `${ESC}[0m`,
|
|
8
|
+
bold: `${ESC}[1m`,
|
|
9
|
+
dim: `${ESC}[2m`,
|
|
10
|
+
italic: `${ESC}[3m`,
|
|
11
|
+
underline: `${ESC}[4m`,
|
|
12
|
+
black: `${ESC}[30m`,
|
|
13
|
+
red: `${ESC}[31m`,
|
|
14
|
+
green: `${ESC}[32m`,
|
|
15
|
+
yellow: `${ESC}[33m`,
|
|
16
|
+
blue: `${ESC}[34m`,
|
|
17
|
+
magenta: `${ESC}[35m`,
|
|
18
|
+
cyan: `${ESC}[36m`,
|
|
19
|
+
white: `${ESC}[37m`,
|
|
20
|
+
gray: `${ESC}[90m`,
|
|
21
|
+
bgYellow: `${ESC}[43m`,
|
|
22
|
+
bgRed: `${ESC}[41m`,
|
|
23
|
+
clearScreen: `${ESC}[2J${ESC}[H`,
|
|
24
|
+
hideCursor: `${ESC}[?25l`,
|
|
25
|
+
showCursor: `${ESC}[?25h`,
|
|
26
|
+
};
|
|
27
|
+
export const KEY = {
|
|
28
|
+
CTRL_C: '\x03',
|
|
29
|
+
ESC: '\x1b',
|
|
30
|
+
ENTER_CR: '\r',
|
|
31
|
+
ENTER_LF: '\n',
|
|
32
|
+
UP: '\x1b[A',
|
|
33
|
+
DOWN: '\x1b[B',
|
|
34
|
+
RIGHT: '\x1b[C',
|
|
35
|
+
LEFT: '\x1b[D',
|
|
36
|
+
};
|
|
37
|
+
/** Visible width of a string (ignores ANSI escape sequences). Treats every
|
|
38
|
+
* other code point as 1 column — fine for ASCII + the Latin range we use. */
|
|
39
|
+
export function visibleWidth(s) {
|
|
40
|
+
// eslint-disable-next-line no-control-regex
|
|
41
|
+
return s.replace(/\x1b\[[0-9;?]*[a-zA-Z]/g, '').length;
|
|
42
|
+
}
|
|
43
|
+
export function padRight(s, width) {
|
|
44
|
+
const diff = width - visibleWidth(s);
|
|
45
|
+
return diff > 0 ? s + ' '.repeat(diff) : s;
|
|
46
|
+
}
|
|
47
|
+
/** Wrap a line at the given width, preserving simple ANSI runs. */
|
|
48
|
+
export function wrap(text, width) {
|
|
49
|
+
if (width <= 0)
|
|
50
|
+
return [text];
|
|
51
|
+
const lines = [];
|
|
52
|
+
for (const paragraph of text.split('\n')) {
|
|
53
|
+
if (visibleWidth(paragraph) <= width) {
|
|
54
|
+
lines.push(paragraph);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const words = paragraph.split(/\s+/);
|
|
58
|
+
let cur = '';
|
|
59
|
+
for (const w of words) {
|
|
60
|
+
if (cur.length === 0) {
|
|
61
|
+
cur = w;
|
|
62
|
+
}
|
|
63
|
+
else if (visibleWidth(cur) + 1 + visibleWidth(w) > width) {
|
|
64
|
+
lines.push(cur);
|
|
65
|
+
cur = w;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
cur += ' ' + w;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (cur.length > 0)
|
|
72
|
+
lines.push(cur);
|
|
73
|
+
}
|
|
74
|
+
return lines;
|
|
75
|
+
}
|
|
76
|
+
const B = {
|
|
77
|
+
tl: '╭',
|
|
78
|
+
tr: '╮',
|
|
79
|
+
bl: '╰',
|
|
80
|
+
br: '╯',
|
|
81
|
+
h: '─',
|
|
82
|
+
v: '│',
|
|
83
|
+
};
|
|
84
|
+
/** Render an array of lines inside a rounded Unicode box. */
|
|
85
|
+
export function renderBox(lines, opts = {}) {
|
|
86
|
+
const termWidth = stdout.columns ?? 80;
|
|
87
|
+
// 86 cols comfortably fits the longest pre-formatted line in About
|
|
88
|
+
// (tool name + padded description). Smaller terminals still get the cap.
|
|
89
|
+
const width = Math.min(opts.width ?? 86, Math.max(40, termWidth - 2));
|
|
90
|
+
const inner = width - 2; // 2 columns for the vertical borders
|
|
91
|
+
const wrapped = lines.flatMap((l) => wrap(l, inner - 2)); // padding 1 each side
|
|
92
|
+
const color = opts.borderColor ?? '';
|
|
93
|
+
const reset = color ? ansi.reset : '';
|
|
94
|
+
const top = `${color}${B.tl}${B.h.repeat(inner)}${B.tr}${reset}`;
|
|
95
|
+
const bottom = `${color}${B.bl}${B.h.repeat(inner)}${B.br}${reset}`;
|
|
96
|
+
const body = wrapped.map((l) => `${color}${B.v}${reset} ${padRight(l, inner - 2)} ${color}${B.v}${reset}`);
|
|
97
|
+
return [top, ...body, bottom].join('\n');
|
|
98
|
+
}
|
|
99
|
+
/** Read a single keypress from stdin without echoing. Returns the raw key
|
|
100
|
+
* (a control sequence for arrows, '\r' for enter, etc.). */
|
|
101
|
+
export function readKey() {
|
|
102
|
+
return new Promise((resolve) => {
|
|
103
|
+
const wasRaw = stdin.isTTY ? stdin.isRaw : false;
|
|
104
|
+
if (stdin.isTTY)
|
|
105
|
+
stdin.setRawMode(true);
|
|
106
|
+
stdin.resume();
|
|
107
|
+
stdin.setEncoding('utf8');
|
|
108
|
+
const onData = (data) => {
|
|
109
|
+
const key = data.toString();
|
|
110
|
+
stdin.off('data', onData);
|
|
111
|
+
if (stdin.isTTY)
|
|
112
|
+
stdin.setRawMode(wasRaw);
|
|
113
|
+
stdin.pause();
|
|
114
|
+
resolve(key);
|
|
115
|
+
};
|
|
116
|
+
stdin.on('data', onData);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/** Classify a raw key into a logical name. */
|
|
120
|
+
export function classifyKey(raw) {
|
|
121
|
+
if (raw === KEY.CTRL_C)
|
|
122
|
+
return 'ctrl-c';
|
|
123
|
+
if (raw === KEY.ESC)
|
|
124
|
+
return 'esc';
|
|
125
|
+
if (raw === KEY.ENTER_CR || raw === KEY.ENTER_LF)
|
|
126
|
+
return 'enter';
|
|
127
|
+
if (raw === KEY.UP)
|
|
128
|
+
return 'up';
|
|
129
|
+
if (raw === KEY.DOWN)
|
|
130
|
+
return 'down';
|
|
131
|
+
if (raw === KEY.LEFT)
|
|
132
|
+
return 'left';
|
|
133
|
+
if (raw === KEY.RIGHT)
|
|
134
|
+
return 'right';
|
|
135
|
+
if (raw.length === 1)
|
|
136
|
+
return raw.toLowerCase();
|
|
137
|
+
return raw;
|
|
138
|
+
}
|
|
139
|
+
export function clearScreen() {
|
|
140
|
+
stdout.write(ansi.clearScreen);
|
|
141
|
+
}
|
|
142
|
+
export function hideCursor() {
|
|
143
|
+
stdout.write(ansi.hideCursor);
|
|
144
|
+
}
|
|
145
|
+
export function showCursor() {
|
|
146
|
+
stdout.write(ansi.showCursor);
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=tty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tty.js","sourceRoot":"","sources":["../../src/commands/tty.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE7C;;gFAEgF;AAEhF,MAAM,GAAG,GAAG,MAAM,CAAC;AAEnB,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,KAAK,EAAE,GAAG,GAAG,KAAK;IAClB,IAAI,EAAE,GAAG,GAAG,KAAK;IACjB,GAAG,EAAE,GAAG,GAAG,KAAK;IAChB,MAAM,EAAE,GAAG,GAAG,KAAK;IACnB,SAAS,EAAE,GAAG,GAAG,KAAK;IAEtB,KAAK,EAAE,GAAG,GAAG,MAAM;IACnB,GAAG,EAAE,GAAG,GAAG,MAAM;IACjB,KAAK,EAAE,GAAG,GAAG,MAAM;IACnB,MAAM,EAAE,GAAG,GAAG,MAAM;IACpB,IAAI,EAAE,GAAG,GAAG,MAAM;IAClB,OAAO,EAAE,GAAG,GAAG,MAAM;IACrB,IAAI,EAAE,GAAG,GAAG,MAAM;IAClB,KAAK,EAAE,GAAG,GAAG,MAAM;IACnB,IAAI,EAAE,GAAG,GAAG,MAAM;IAElB,QAAQ,EAAE,GAAG,GAAG,MAAM;IACtB,KAAK,EAAE,GAAG,GAAG,MAAM;IAEnB,WAAW,EAAE,GAAG,GAAG,MAAM,GAAG,IAAI;IAChC,UAAU,EAAE,GAAG,GAAG,OAAO;IACzB,UAAU,EAAE,GAAG,GAAG,OAAO;CAC1B,CAAC;AAEF,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,MAAM,EAAE,MAAM;IACd,GAAG,EAAE,MAAM;IACX,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,EAAE,EAAE,QAAQ;IACZ,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,QAAQ;IACf,IAAI,EAAE,QAAQ;CACf,CAAC;AAEF;6EAC6E;AAC7E,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,4CAA4C;IAC5C,OAAO,CAAC,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,CAAS,EAAE,KAAa;IAC/C,MAAM,IAAI,GAAG,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IACrC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,KAAa;IAC9C,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,IAAI,YAAY,CAAC,SAAS,CAAC,IAAI,KAAK,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtB,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrB,GAAG,GAAG,CAAC,CAAC;YACV,CAAC;iBAAM,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;gBAC3D,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAChB,GAAG,GAAG,CAAC,CAAC;YACV,CAAC;iBAAM,CAAC;gBACN,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAOD,MAAM,CAAC,GAAG;IACR,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;CACP,CAAC;AAEF,6DAA6D;AAC7D,MAAM,UAAU,SAAS,CAAC,KAAe,EAAE,OAAmB,EAAE;IAC9D,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IACvC,mEAAmE;IACnE,yEAAyE;IACzE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,qCAAqC;IAC9D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB;IAEhF,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACtC,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;IACjE,MAAM,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CACtB,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,QAAQ,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CACjF,CAAC;IAEF,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED;4DAC4D;AAC5D,MAAM,UAAU,OAAO;IACrB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QACjD,IAAI,KAAK,CAAC,KAAK;YAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACxC,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC1B,MAAM,MAAM,GAAG,CAAC,IAAqB,EAAE,EAAE;YACvC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5B,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC1B,IAAI,KAAK,CAAC,KAAK;gBAAE,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC1C,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC,CAAC;QACF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,GAAG,KAAK,GAAG,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC;IACxC,IAAI,GAAG,KAAK,GAAG,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IAClC,IAAI,GAAG,KAAK,GAAG,CAAC,QAAQ,IAAI,GAAG,KAAK,GAAG,CAAC,QAAQ;QAAE,OAAO,OAAO,CAAC;IACjE,IAAI,GAAG,KAAK,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,GAAG,KAAK,GAAG,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC;IACpC,IAAI,GAAG,KAAK,GAAG,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC;IACpC,IAAI,GAAG,KAAK,GAAG,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC;IACtC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;IAC/C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ClientId } from '../installers/index.js';
|
|
2
|
+
export interface UninstallReport {
|
|
3
|
+
client: ClientId;
|
|
4
|
+
displayName: string;
|
|
5
|
+
message: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function uninstallFor(client: ClientId): UninstallReport;
|
|
8
|
+
export declare function uninstallAll(): UninstallReport[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { INSTALLERS, getInstaller } from '../installers/index.js';
|
|
2
|
+
export function uninstallFor(client) {
|
|
3
|
+
const inst = getInstaller(client);
|
|
4
|
+
const message = inst.uninstall();
|
|
5
|
+
return { client, displayName: inst.displayName, message };
|
|
6
|
+
}
|
|
7
|
+
export function uninstallAll() {
|
|
8
|
+
return INSTALLERS.map((i) => uninstallFor(i.id));
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=uninstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAiB,MAAM,wBAAwB,CAAC;AAQjF,MAAM,UAAU,YAAY,CAAC,MAAgB;IAC3C,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IACjC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type Language = 'en' | 'es';
|
|
2
|
+
export interface WelcomeResult {
|
|
3
|
+
action: 'continue' | 'quit';
|
|
4
|
+
language: Language;
|
|
5
|
+
persisted: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface WelcomeOptions {
|
|
8
|
+
/** Initial language to render. */
|
|
9
|
+
initial?: Language;
|
|
10
|
+
/** When true, hide the "Accept and don't show again" option. Used when
|
|
11
|
+
* the user explicitly asks to see the welcome from the menu. */
|
|
12
|
+
hideDismiss?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface I18n {
|
|
15
|
+
title: string;
|
|
16
|
+
intro: string[];
|
|
17
|
+
capabilities: string[];
|
|
18
|
+
warning: string[];
|
|
19
|
+
responsibility: string;
|
|
20
|
+
extensionNote: string;
|
|
21
|
+
actions: {
|
|
22
|
+
accept: string;
|
|
23
|
+
dismiss: string;
|
|
24
|
+
swap: string;
|
|
25
|
+
quit: string;
|
|
26
|
+
};
|
|
27
|
+
prompt: string;
|
|
28
|
+
promptNoDismiss: string;
|
|
29
|
+
}
|
|
30
|
+
export declare const I18N_WELCOME: Record<Language, I18n>;
|
|
31
|
+
export declare function buildWelcomeScreen(t: I18n, hideDismiss: boolean): string;
|
|
32
|
+
export declare function runWelcome(opts?: WelcomeOptions): Promise<WelcomeResult>;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { stdout } from 'node:process';
|
|
2
|
+
import { saveConfig } from '../config.js';
|
|
3
|
+
import { ansi, classifyKey, clearScreen, hideCursor, readKey, renderBox, showCursor, } from './tty.js';
|
|
4
|
+
export const I18N_WELCOME = {
|
|
5
|
+
en: {
|
|
6
|
+
title: 'browser-link',
|
|
7
|
+
intro: [
|
|
8
|
+
'An MCP server that opens a small WebSocket bridge between Claude Code',
|
|
9
|
+
'and the Google Chrome tabs you explicitly grant access to through a',
|
|
10
|
+
'custom companion extension you load locally.',
|
|
11
|
+
],
|
|
12
|
+
capabilities: [
|
|
13
|
+
'On every tab where you press "Conectar" in the extension popup, the',
|
|
14
|
+
'agent can:',
|
|
15
|
+
' • Navigate that tab to any URL',
|
|
16
|
+
' • Read its DOM, console and network traffic',
|
|
17
|
+
' • Click and type into its elements',
|
|
18
|
+
' • Execute arbitrary JavaScript in the page context',
|
|
19
|
+
'',
|
|
20
|
+
'Tabs you do not connect remain invisible to the agent. You can connect',
|
|
21
|
+
'as many tabs as you want — each one is enabled one by one, by hand.',
|
|
22
|
+
'',
|
|
23
|
+
'And the server remembers what it learns about each app across sessions',
|
|
24
|
+
'in a local SQLite map (selectors, flows, gotchas — never uploaded',
|
|
25
|
+
'anywhere).',
|
|
26
|
+
],
|
|
27
|
+
warning: [
|
|
28
|
+
`${ansi.bold}${ansi.yellow}⚠ Read this before you continue${ansi.reset}`,
|
|
29
|
+
'',
|
|
30
|
+
'Connecting a tab gives the agent access to whatever is on it — any',
|
|
31
|
+
'logged-in session, saved card, wallet, banking page, work console or',
|
|
32
|
+
'admin panel the browser is currently showing on that tab.',
|
|
33
|
+
'',
|
|
34
|
+
'Treat the agent like a junior dev given remote control of those tabs:',
|
|
35
|
+
'it can buy things, submit forms, change configurations, send messages,',
|
|
36
|
+
'or follow instructions it reads on the page that you did not write.',
|
|
37
|
+
'',
|
|
38
|
+
'Only connect tabs where you would be comfortable letting an automated',
|
|
39
|
+
'process act on your behalf. Disconnect a tab from the extension popup',
|
|
40
|
+
'when you are done with it.',
|
|
41
|
+
],
|
|
42
|
+
responsibility: 'You are responsible for every action the agent performs on the tabs ' +
|
|
43
|
+
'you explicitly enable. The extension stays inert on any tab where ' +
|
|
44
|
+
'you have not pressed "Conectar" yourself.',
|
|
45
|
+
extensionNote: 'The Chrome extension is custom and ships inside this package. ' +
|
|
46
|
+
'The setup menu after this screen will tell you where it lives so ' +
|
|
47
|
+
'you can load it via chrome://extensions → Load unpacked.',
|
|
48
|
+
actions: {
|
|
49
|
+
accept: 'I understand, continue',
|
|
50
|
+
dismiss: "Accept and don't show again",
|
|
51
|
+
swap: 'Switch to español',
|
|
52
|
+
quit: 'Quit',
|
|
53
|
+
},
|
|
54
|
+
prompt: 'Press [A] to accept, [D] to accept & hide next time, [L] for español, [Q] to quit.',
|
|
55
|
+
promptNoDismiss: 'Press [A] to continue, [L] for español, [Q] to quit.',
|
|
56
|
+
},
|
|
57
|
+
es: {
|
|
58
|
+
title: 'browser-link',
|
|
59
|
+
intro: [
|
|
60
|
+
'Un servidor MCP que abre un puente WebSocket entre Claude Code y las',
|
|
61
|
+
'pestañas de Google Chrome a las que vos le des acceso explícito a',
|
|
62
|
+
'través de una extensión que cargás vos manualmente.',
|
|
63
|
+
],
|
|
64
|
+
capabilities: [
|
|
65
|
+
'En cada pestaña donde pulsás "Conectar" en el popup de la extensión,',
|
|
66
|
+
'el agente puede:',
|
|
67
|
+
' • Navegar esa pestaña a cualquier URL',
|
|
68
|
+
' • Leer su DOM, su consola y su tráfico de red',
|
|
69
|
+
' • Hacer click y escribir en sus elementos',
|
|
70
|
+
' • Ejecutar JavaScript arbitrario en el contexto de la página',
|
|
71
|
+
'',
|
|
72
|
+
'Las pestañas que NO conectes siguen invisibles para el agente. Podés',
|
|
73
|
+
'conectar todas las pestañas que quieras — cada una se habilita una por',
|
|
74
|
+
'una, a mano.',
|
|
75
|
+
'',
|
|
76
|
+
'Además el servidor guarda lo que aprende de cada app entre sesiones en',
|
|
77
|
+
'un mapa SQLite local (selectores, flujos, gotchas — nunca se sube a',
|
|
78
|
+
'ningún lado).',
|
|
79
|
+
],
|
|
80
|
+
warning: [
|
|
81
|
+
`${ansi.bold}${ansi.yellow}⚠ Leelo antes de continuar${ansi.reset}`,
|
|
82
|
+
'',
|
|
83
|
+
'Conectar una pestaña le da al agente acceso a todo lo que esté en esa',
|
|
84
|
+
'pestaña: sesiones iniciadas, tarjetas guardadas, wallets, banca,',
|
|
85
|
+
'consolas de trabajo, paneles de administración… lo que el navegador',
|
|
86
|
+
'esté mostrando en ella en ese momento.',
|
|
87
|
+
'',
|
|
88
|
+
'Tratá al agente como a un dev junior con control remoto de esas',
|
|
89
|
+
'pestañas: puede comprar cosas, enviar formularios, cambiar',
|
|
90
|
+
'configuraciones, mandar mensajes, o seguir instrucciones que lea en',
|
|
91
|
+
'la página y que vos no escribiste.',
|
|
92
|
+
'',
|
|
93
|
+
'Solo conectá pestañas donde estarías cómodo dejando que un proceso',
|
|
94
|
+
'automatizado actúe en tu nombre. Desconectá la pestaña desde el popup',
|
|
95
|
+
'cuando termines de usarla.',
|
|
96
|
+
],
|
|
97
|
+
responsibility: 'Sos responsable de cada acción que el agente haga en las pestañas que ' +
|
|
98
|
+
'habilitás explícitamente. La extensión se mantiene inerte en cualquier ' +
|
|
99
|
+
'pestaña donde no hayas apretado "Conectar" vos mismo.',
|
|
100
|
+
extensionNote: 'La extensión de Chrome es custom y viene incluida en este paquete. ' +
|
|
101
|
+
'El menú que aparece después de esta pantalla te dice exactamente dónde ' +
|
|
102
|
+
'está para que la cargues vía chrome://extensions → Cargar sin empaquetar.',
|
|
103
|
+
actions: {
|
|
104
|
+
accept: 'Entendido, continuar',
|
|
105
|
+
dismiss: 'Aceptar y no volver a mostrar',
|
|
106
|
+
swap: 'Cambiar a English',
|
|
107
|
+
quit: 'Salir',
|
|
108
|
+
},
|
|
109
|
+
prompt: 'Pulsá [A] para aceptar, [D] para aceptar y ocultar la próxima vez, [L] para English, [Q] para salir.',
|
|
110
|
+
promptNoDismiss: 'Pulsá [A] para continuar, [L] para English, [Q] para salir.',
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
export function buildWelcomeScreen(t, hideDismiss) {
|
|
114
|
+
const lines = [];
|
|
115
|
+
lines.push(`${ansi.bold}${ansi.cyan}${t.title}${ansi.reset}`);
|
|
116
|
+
lines.push('');
|
|
117
|
+
for (const l of t.intro)
|
|
118
|
+
lines.push(l);
|
|
119
|
+
lines.push('');
|
|
120
|
+
for (const l of t.capabilities)
|
|
121
|
+
lines.push(l);
|
|
122
|
+
lines.push('');
|
|
123
|
+
for (const l of t.warning)
|
|
124
|
+
lines.push(l);
|
|
125
|
+
lines.push('');
|
|
126
|
+
lines.push(`${ansi.dim}${t.responsibility}${ansi.reset}`);
|
|
127
|
+
lines.push('');
|
|
128
|
+
lines.push(`${ansi.dim}${t.extensionNote}${ansi.reset}`);
|
|
129
|
+
lines.push('');
|
|
130
|
+
const acceptLine = ` ${ansi.green}[A]${ansi.reset} ${t.actions.accept}`;
|
|
131
|
+
const dismissLine = hideDismiss ? '' : ` ${ansi.green}[D]${ansi.reset} ${t.actions.dismiss}`;
|
|
132
|
+
const langLine = ` ${ansi.cyan}[L]${ansi.reset} ${t.actions.swap}`;
|
|
133
|
+
const quitLine = ` ${ansi.red}[Q]${ansi.reset} ${t.actions.quit}`;
|
|
134
|
+
if (hideDismiss) {
|
|
135
|
+
lines.push(`${acceptLine} ${langLine} ${quitLine}`);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
lines.push(acceptLine);
|
|
139
|
+
lines.push(dismissLine);
|
|
140
|
+
lines.push(`${langLine} ${quitLine}`);
|
|
141
|
+
}
|
|
142
|
+
return renderBox(lines, { borderColor: ansi.gray });
|
|
143
|
+
}
|
|
144
|
+
export async function runWelcome(opts = {}) {
|
|
145
|
+
let lang = opts.initial ?? 'en';
|
|
146
|
+
const hideDismiss = opts.hideDismiss === true;
|
|
147
|
+
hideCursor();
|
|
148
|
+
try {
|
|
149
|
+
while (true) {
|
|
150
|
+
const t = I18N_WELCOME[lang];
|
|
151
|
+
clearScreen();
|
|
152
|
+
stdout.write(buildWelcomeScreen(t, hideDismiss));
|
|
153
|
+
stdout.write('\n\n');
|
|
154
|
+
stdout.write(`${ansi.dim}${hideDismiss ? t.promptNoDismiss : t.prompt}${ansi.reset} `);
|
|
155
|
+
const key = classifyKey(await readKey());
|
|
156
|
+
if (key === 'a')
|
|
157
|
+
return { action: 'continue', language: lang, persisted: false };
|
|
158
|
+
if (key === 'd' && !hideDismiss) {
|
|
159
|
+
saveConfig({ skipWelcome: true, language: lang });
|
|
160
|
+
return { action: 'continue', language: lang, persisted: true };
|
|
161
|
+
}
|
|
162
|
+
if (key === 'l') {
|
|
163
|
+
lang = lang === 'en' ? 'es' : 'en';
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (key === 'q' || key === 'esc' || key === 'ctrl-c') {
|
|
167
|
+
return { action: 'quit', language: lang, persisted: false };
|
|
168
|
+
}
|
|
169
|
+
// ignore other keys
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
showCursor();
|
|
174
|
+
stdout.write('\n');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=welcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"welcome.js","sourceRoot":"","sources":["../../src/commands/welcome.ts"],"names":[],"mappings":"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"}
|