From 1267be4c5dd55dd37d0a1899c73fd2bb10eeebf2 Mon Sep 17 00:00:00 2001 From: leemour Date: Sat, 10 Oct 2026 21:47:49 +0200 Subject: [PATCH] Explain messenger installation and personal login step by step --- app/[lang]/docs/[[...slug]]/page.tsx | 8 +- components/install-tool.tsx | 14 +- components/tool-installation-intro.tsx | 94 +++++----- lib/source.ts | 6 +- lib/tool-installation.ts | 239 +++++++++++++++++++++++++ lib/words.ts | 2 +- tests/mobile-delivery.spec.ts | 2 +- tests/onboarding-merge.spec.ts | 20 +++ 8 files changed, 326 insertions(+), 59 deletions(-) create mode 100644 lib/tool-installation.ts diff --git a/app/[lang]/docs/[[...slug]]/page.tsx b/app/[lang]/docs/[[...slug]]/page.tsx index 76941657..432f8c0f 100644 --- a/app/[lang]/docs/[[...slug]]/page.tsx +++ b/app/[lang]/docs/[[...slug]]/page.tsx @@ -32,6 +32,7 @@ import { import { appName, getPageMarkdownUrl, toolOf } from "@/lib/shared" import { homePath } from "@/lib/site-routes" import { source } from "@/lib/source" +import { toolInstallationGuide } from "@/lib/tool-installation" import { wordsFor } from "@/lib/words" import "@/lib/docs-usability.css" @@ -92,6 +93,11 @@ export default async function Page(props: Props) { : guide === "installation" ? [ { title: ui.installGuide, url: "#agent-installation", depth: 2 }, + ...toolInstallationGuide(tool?.name ?? "tg", lang).sections.map((section) => ({ + title: section.title, + url: `#${section.id}`, + depth: 3, + })), { title: installationReferenceTitle(lang), url: "#installation-reference", depth: 2 }, ...page.data.toc, ] @@ -150,7 +156,7 @@ export default async function Page(props: Props) { )} - {!taskGuide && guideOrientation(page.slugs, lang) && ( + {!taskGuide && guide !== "installation" && guideOrientation(page.slugs, lang) && (

{guideOrientation(page.slugs, lang)}

diff --git a/components/install-tool.tsx b/components/install-tool.tsx index 1387f2cb..a17dc74b 100644 --- a/components/install-tool.tsx +++ b/components/install-tool.tsx @@ -7,7 +7,17 @@ import { CopyText } from "@/components/text-snippet" import type { Tool } from "@/lib/shared" import { wordsFor } from "@/lib/words" -export function InstallTool({ tool, lang, terminal = true }: { tool: Tool; lang: string; terminal?: boolean }) { +export function InstallTool({ + tool, + lang, + terminal = true, + request, +}: { + tool: Tool + lang: string + terminal?: boolean + request?: string +}) { const words = wordsFor(lang) const ui = words.onboarding const [open, setOpen] = useState(false) @@ -34,7 +44,7 @@ export function InstallTool({ tool, lang, terminal = true }: { tool: Tool; lang: diff --git a/components/tool-installation-intro.tsx b/components/tool-installation-intro.tsx index b06383c5..4dd69212 100644 --- a/components/tool-installation-intro.tsx +++ b/components/tool-installation-intro.tsx @@ -1,66 +1,54 @@ import Link from "next/link" -import { DocTerm } from "@/components/doc-term" import { InstallTool } from "@/components/install-tool" +import { CopyText } from "@/components/text-snippet" import type { Tool } from "@/lib/shared" -import { wordsFor } from "@/lib/words" - -const copy = { - en: { - prefix: "Install with your", - agent: "local agent", - intro: - "or in a terminal. The cli is an npm package for Windows, macOS and Linux. Your agent can install it and help you log in.", - steps: - "Open the block below and copy the request to your agent. After login, verify your account and a few chats. Downloading older history is a separate step.", - tasks: "Try your first tasks", - requests: "How to phrase requests", - reference: "Manual setup and technical details", - }, - ru: { - prefix: "Установите cli с помощью", - agent: "локального агента", - intro: "или в терминале. Это npm-пакет для Windows, macOS и Linux. Агент поможет установить cli и войти в аккаунт.", - steps: - "Раскройте блок ниже и скопируйте запрос агенту. После входа проверьте свой аккаунт и несколько чатов. Загрузка старой истории — отдельный шаг.", - tasks: "Попробовать первые задачи", - requests: "Как формулировать запросы", - reference: "Самостоятельная установка и технические детали", - }, - es: { - prefix: "Instala el cli con tu", - agent: "agente local", - intro: - "o en la terminal. Es un paquete npm para Windows, macOS y Linux. El agente puede instalarlo y ayudarte a iniciar sesión.", - steps: - "Abre el bloque de abajo y copia la petición en tu agente. Después de iniciar sesión, comprueba tu cuenta y algunos chats. Descargar el historial antiguo es un paso aparte.", - tasks: "Probar las primeras tareas", - requests: "Cómo formular peticiones", - reference: "Instalación manual y detalles técnicos", - }, -} +import { toolInstallationGuide } from "@/lib/tool-installation" export function installationReferenceTitle(lang: string) { - return (copy[lang as keyof typeof copy] ?? copy.en).reference + return toolInstallationGuide("tg", lang).reference } export function ToolInstallationIntro({ tool, lang }: { tool: Tool; lang: string }) { - const text = copy[lang as keyof typeof copy] ?? copy.en + const guide = toolInstallationGuide(tool.name, lang) return ( <> -

- {text.prefix} {text.intro} -

-

{wordsFor(lang).navigation.installGuide}

-

{text.steps}

-
- -
-

- {text.tasks} → - {" · "} - {text.requests} -

-

{text.reference}

+

{guide.intro}

+

{guide.title}

+ {guide.sections.map((section) => ( +
+

{section.title}

+ {section.paragraphs.map((paragraph) => ( +

{paragraph}

+ ))} + {section.command && } + {section.request && ( +
+ +
+ )} + {section.steps && ( +
    + {section.steps.map((step) => ( +
  1. {step}
  2. + ))} +
+ )} + {section.fallback && ( + <> +

{section.fallback.title}

+ {section.fallback.paragraphs.map((paragraph) => ( +

{paragraph}

+ ))} + + )} + {section.links.map((link) => ( +

+ {link.label} → +

+ ))} +
+ ))} +

{guide.reference}

) } diff --git a/lib/source.ts b/lib/source.ts index 6f9b3d16..f5a2c688 100644 --- a/lib/source.ts +++ b/lib/source.ts @@ -15,6 +15,7 @@ import { remarkAnchorAliases } from "./remark-anchor-aliases" import { remarkDocUsability } from "./remark-doc-usability" import { remarkMermaid } from "./remark-mermaid" import { docsRoute, getPageMarkdownUrl, siteUrl, toolOf } from "./shared" +import { toolInstallationMarkdown } from "./tool-installation" const docs = defineDocs({ dir: "content/docs", @@ -65,9 +66,12 @@ export const docsLlms = llms(source, { (page.slugs.length === 1 && ["installation", "memo", "email"].includes(page.slugs[0])) ? raw : dedentDocComponents(await page.data.getText("processed")) + const installationIntro = toolInstallationMarkdown(page.slugs, page.locale ?? i18n.defaultLanguage) const body = + installationIntro + readerGuideMarkdown(page.slugs, page.locale ?? i18n.defaultLanguage) + - (!readerGuideMarkdown(page.slugs, page.locale ?? i18n.defaultLanguage) && + (!installationIntro && + !readerGuideMarkdown(page.slugs, page.locale ?? i18n.defaultLanguage) && guideOrientation(page.slugs, page.locale ?? i18n.defaultLanguage) ? `${guideOrientation(page.slugs, page.locale ?? i18n.defaultLanguage)}\n\n` : "") + diff --git a/lib/tool-installation.ts b/lib/tool-installation.ts new file mode 100644 index 00000000..c196970e --- /dev/null +++ b/lib/tool-installation.ts @@ -0,0 +1,239 @@ +import { wordsFor } from "./words" + +const copy = { + en: { + intro: (name: string) => + `Connect your ${name} account to an AI agent on your computer. After setup, you can ask it to read chats, find messages and prepare replies.`, + titles: [ + "1. Open your agent on the computer", + "2. Ask it to help with installation", + "3. Confirm the login yourself", + "4. Check that it works", + ], + agent: + "Use an agent such as Codex, Claude Code or Cursor that can run programs on this computer. Have your phone ready, with your account already signed in to the messaging app.", + browser: + "If you only use an agent chat in a browser or on your phone, follow the web and mobile connection guide instead.", + browserLink: "Connect from the web or your phone", + install: (name: string) => + `The ${name} tool is a program that gives your agent access to your account. Open the installation block below and copy the request into your agent chat. The agent will check the programs your computer needs and help install the tool.`, + request: (name: string, tool: string) => + `Help connect my ${name} account to my AI agent on this computer. +Follow https://wirecat.dev/en/docs/${tool}/installation: check the required programs and help install the tool. +Show me the login steps so I can confirm account access myself. +Connect the tool's instructions to my agent. Then show my account and a few chats. Do not send any messages.`, + login: + "The agent starts setup; you complete the account confirmation. Enter login codes and passwords in the setup terminal or the messenger's login page, rather than in the agent chat. The terminal is the command window where setup is running; ask the agent to show you that window if you cannot find it.", + manualLogin: + "If the agent cannot provide an interactive login prompt, open Terminal on macOS/Linux or PowerShell on Windows yourself and run the setup command below. Follow its prompts; keep the window open until the account check finishes.", + tgSteps: [ + "When setup asks for your phone number, enter it with the country code, for example +44… . This first confirmation lets the tool prepare the connection details that Telegram requires for your account.", + "Open Telegram on your phone and find the service message from Telegram with the code for my.telegram.org. Enter that code at the setup prompt. The tool reads your existing connection details or creates them for you; you do not need to write a program.", + "Next, wait for the account-login QR code on your computer. These are separate confirmations: the earlier code prepares the connection, while this QR code signs the tool in to your account.", + "In Telegram on your phone, open Settings → Devices and choose Link Desktop Device or Add Device. Allow camera access if asked, then point the scanner at the QR code shown by setup on your computer.", + "If setup asks for your additional Telegram password, enter the password you previously set in Telegram. This is different from the one-time code. Password input is hidden; type it and press Enter.", + "Wait for setup to confirm the login and check your account and chats. This computer will appear among the connected devices in Telegram. If you interrupted setup, ask the agent to resume it; a completed login can be reused.", + ], + tgFallback: + "If automatic connection setup fails, ask the agent to use browser registration. Open my.telegram.org/apps, sign in with your phone number and the code sent to Telegram, then open API development tools. For a new application, choose a name and short name, select Desktop, and create it. Enter App api_id and App api_hash when the setup terminal asks, then continue to QR login. These values identify the connection; they are not a bot token.", + tgPhone: + "If you cannot scan the QR code, ask the agent to choose phone-number login. Enter your number and the new login code at the setup prompts, followed by your additional Telegram password if requested. Use the delivery method shown by setup; the code may arrive in Telegram rather than by SMS.", + maxSteps: [ + "Wait for setup to show a login QR code on your computer. It appears in the terminal; if the window is too narrow, setup opens the code in your browser.", + "Open MAX on the phone where you are already signed in. Open Settings → Devices and choose QR scanning. Allow access to the camera if asked.", + "Point the scanner at the code shown by setup on your computer. Use the login code from setup, rather than your profile's QR code for sharing contacts. Complete any confirmation shown in MAX.", + "If setup asks for your additional account password, enter the password you previously set in MAX. The terminal hides what you type; enter it and press Enter.", + "Wait for setup to confirm the login and check your account and up to five chats. The new device appears in MAX's device list. If setup was interrupted or the code expired, ask the agent to restart setup and scan the new code.", + ], + maxFallback: + "If scanning does not work, ask the agent to open browser login. On web.max.ru you can scan its QR code or choose phone-number login and complete the steps on the page, including any CAPTCHA. This opens a separate browser window for the connection.", + fallback: "If the usual login does not work", + sessions: "Login methods and connection help", + check: + "Ask your agent to show your account and a few chats. Check that the name and chats belong to the account you intended to connect. If they do, the connection is ready. Finding older messages may require a separate history download; setup does not download your entire history.", + archive: "Download the history you need", + tasks: "Try your first task", + reference: "Manual setup and technical details", + }, + ru: { + intro: (name: string) => + `Подключите свой аккаунт ${name} к ИИ-агенту на компьютере. После настройки можно просить его читать чаты, искать сообщения и готовить ответы.`, + titles: [ + "1. Откройте агента на компьютере", + "2. Попросите помочь с установкой", + "3. Подтвердите вход самостоятельно", + "4. Проверьте, что всё работает", + ], + agent: + "Подойдёт, например, Codex, Claude Code или Cursor с доступом к запуску программ на этом компьютере. Держите рядом телефон, на котором вы уже вошли в нужный аккаунт мессенджера.", + browser: + "Если вы пользуетесь только чатом с агентом в браузере или на телефоне, начните с руководства по подключению для веба и телефона.", + browserLink: "Подключить из веба или с телефона", + install: (name: string) => + `Инструмент ${name} — программа, которая даёт агенту доступ к вашему аккаунту. Раскройте блок установки ниже и скопируйте запрос в чат с агентом. Он проверит, какие программы нужны вашему компьютеру, и поможет установить инструмент.`, + request: (name: string, tool: string) => + `Помоги подключить мой аккаунт ${name} к моему ИИ-агенту на этом компьютере. +Следуй https://wirecat.dev/ru/docs/${tool}/installation: проверь нужные программы и помоги с установкой. +Покажи мне шаги входа, чтобы я сам подтвердил доступ к аккаунту. +Подключи инструкции инструмента к моему агенту. В конце покажи мой аккаунт и несколько чатов. Ничего не отправляй.`, + login: + "Агент запускает настройку, а доступ к аккаунту подтверждаете вы. Коды и пароли вводите в терминал настройки или на страницу входа мессенджера, а не в чат с агентом. Терминал — окно команд, в котором идёт настройка; если вы его не видите, попросите агента показать это окно.", + manualLogin: + "Если агент не может открыть ввод для подтверждения входа, откройте сами «Терминал» в macOS/Linux или PowerShell в Windows и запустите настройку командой ниже. Следуйте вопросам настройки и не закрывайте окно до проверки аккаунта.", + tgSteps: [ + "Когда настройка попросит номер телефона, введите его с кодом страны, например +7… . Это первое подтверждение нужно, чтобы инструмент подготовил данные подключения, которые Telegram требует для вашего аккаунта.", + "Откройте Telegram на телефоне и найдите служебное сообщение Telegram с кодом для my.telegram.org. Введите этот код в запросе настройки. Инструмент получит уже созданные данные подключения или создаст их за вас — писать программу не нужно.", + "Затем дождитесь QR-кода для входа в аккаунт на экране компьютера. Это два отдельных подтверждения: предыдущий код нужен для настройки подключения, а QR-код — для входа инструмента в ваш аккаунт.", + "В Telegram на телефоне откройте «Настройки» → «Устройства» и выберите «Подключить устройство» или «Привязать настольное устройство». Разрешите доступ к камере, если приложение попросит, и наведите сканер на QR-код, который настройка показала на компьютере.", + "Если настройка попросит дополнительный пароль Telegram, введите пароль, который вы ранее задали в Telegram. Это не одноразовый код. При вводе пароль не отображается — наберите его и нажмите Enter.", + "Дождитесь подтверждения входа и проверки аккаунта и чатов. Компьютер появится в списке подключённых устройств Telegram. Если настройка прервалась, попросите агента продолжить её; уже выполненный вход можно использовать повторно.", + ], + tgFallback: + "Если автоматическая настройка подключения не получилась, попросите агента выбрать регистрацию через браузер. Откройте my.telegram.org/apps, войдите по номеру телефона и коду из Telegram и выберите API development tools. Для нового приложения укажите название и краткое имя, выберите Desktop и создайте приложение. Введите App api_id и App api_hash, когда терминал настройки попросит их, затем продолжите вход по QR-коду. Эти значения обозначают подключение, а не токен бота.", + tgPhone: + "Если не получается отсканировать QR-код, попросите агента выбрать вход по номеру телефона. Введите номер и новый код для входа в запросах настройки, затем дополнительный пароль Telegram, если его попросят. Способ доставки кода покажет настройка: он может прийти в Telegram, а не по SMS.", + maxSteps: [ + "Дождитесь QR-кода для входа на компьютере. Он появится в терминале; если окно слишком узкое, настройка откроет код в браузере.", + "Откройте MAX на телефоне, где вы уже вошли в свой аккаунт. Перейдите в «Настройки» → «Устройства» и выберите сканирование QR-кода. Разрешите доступ к камере, если приложение попросит.", + "Наведите сканер на код, который настройка показала на компьютере. Нужен код для входа из настройки, а не QR-код вашего профиля для обмена контактами. Выполните подтверждение, если MAX покажет его на телефоне.", + "Если настройка попросит дополнительный пароль аккаунта, введите пароль, который вы ранее задали в MAX. В терминале ввод скрыт — наберите пароль и нажмите Enter.", + "Дождитесь подтверждения входа и проверки аккаунта и до пяти чатов. Новое устройство появится в списке устройств MAX. Если настройка прервалась или код устарел, попросите агента запустить настройку заново и отсканируйте новый код.", + ], + maxFallback: + "Если сканирование не работает, попросите агента открыть вход через браузер. На web.max.ru можно отсканировать QR-код или выбрать вход по номеру телефона и выполнить шаги на странице, включая проверку CAPTCHA, если она появится. Для подключения откроется отдельное окно браузера.", + fallback: "Если обычный вход не получается", + sessions: "Способы входа и помощь с подключением", + check: + "Попросите агента показать ваш аккаунт и несколько чатов. Проверьте, что имя и чаты относятся к тому аккаунту, который вы хотели подключить. Если всё верно, подключение готово. Для поиска в старых сообщениях может понадобиться отдельно скачать нужный период; настройка не скачивает всю историю.", + archive: "Скачать нужную историю", + tasks: "Попробовать первую задачу", + reference: "Самостоятельная установка и технические детали", + }, + es: { + intro: (name: string) => + `Conecta tu cuenta de ${name} a un agente de IA en tu ordenador. Después podrás pedirle que lea chats, busque mensajes y prepare respuestas.`, + titles: [ + "1. Abre el agente en tu ordenador", + "2. Pídele ayuda con la instalación", + "3. Confirma tú el inicio de sesión", + "4. Comprueba que funciona", + ], + agent: + "Puedes usar, por ejemplo, Codex, Claude Code o Cursor con acceso para ejecutar programas en este ordenador. Ten a mano el teléfono donde ya has iniciado sesión en tu cuenta de mensajería.", + browser: + "Si solo usas un chat con el agente en el navegador o en el teléfono, empieza con la guía de conexión para web y móvil.", + browserLink: "Conectar desde la web o el móvil", + install: (name: string) => + `La herramienta de ${name} es un programa que permite al agente acceder a tu cuenta. Abre el bloque de instalación de abajo y copia la petición en el chat con tu agente. Comprobará los programas necesarios en tu ordenador y te ayudará a instalar la herramienta.`, + request: (name: string, tool: string) => + `Ayúdame a conectar mi cuenta de ${name} a mi agente de IA en este ordenador. +Sigue https://wirecat.dev/es/docs/${tool}/installation: comprueba los programas necesarios y ayúdame a instalar la herramienta. +Muéstrame los pasos de inicio de sesión para que yo confirme el acceso a mi cuenta. +Conecta las instrucciones de la herramienta a mi agente. Al final muestra mi cuenta y algunos chats. No envíes mensajes.`, + login: + "El agente inicia la configuración; tú confirmas el acceso a la cuenta. Introduce los códigos y contraseñas en el terminal de configuración o en la página de inicio de sesión, en lugar del chat con el agente. El terminal es la ventana de comandos donde se ejecuta la configuración; pide al agente que te muestre esa ventana si no la encuentras.", + manualLogin: + "Si el agente no puede ofrecer un campo interactivo para confirmar el acceso, abre Terminal en macOS/Linux o PowerShell en Windows y ejecuta el comando de configuración de abajo. Sigue sus preguntas y mantén la ventana abierta hasta que termine la comprobación de la cuenta.", + tgSteps: [ + "Cuando la configuración pida tu número de teléfono, introdúcelo con el prefijo del país, por ejemplo +34… . Esta primera confirmación permite preparar los datos de conexión que Telegram requiere para tu cuenta.", + "Abre Telegram en el teléfono y busca el mensaje de servicio de Telegram con el código para my.telegram.org. Introduce el código cuando lo pida la configuración. La herramienta obtiene los datos de conexión existentes o los crea por ti; no necesitas programar.", + "Después espera a que aparezca el código QR de inicio de sesión en el ordenador. Son dos confirmaciones distintas: el primer código prepara la conexión y el QR conecta la herramienta a tu cuenta.", + "En Telegram en el teléfono, abre Configuración → Dispositivos y elige Vincular dispositivo o Vincular dispositivo de escritorio. Permite el acceso a la cámara si se solicita y apunta el escáner al QR que muestra la configuración en el ordenador.", + "Si la configuración pide la contraseña adicional de Telegram, introduce la que habías establecido en Telegram. Es distinta del código de un solo uso. La contraseña no se muestra al escribir; introdúcela y pulsa Enter.", + "Espera a la confirmación del inicio de sesión y a la comprobación de la cuenta y los chats. El ordenador aparecerá entre los dispositivos conectados en Telegram. Si interrumpiste la configuración, pide al agente que la continúe; puede reutilizar el acceso ya confirmado.", + ], + tgFallback: + "Si falla la preparación automática de la conexión, pide al agente que elija el registro en el navegador. Abre my.telegram.org/apps, inicia sesión con tu número y el código recibido en Telegram y entra en API development tools. Para una aplicación nueva, elige un nombre y un nombre corto, selecciona Desktop y créala. Introduce App api_id y App api_hash cuando el terminal de configuración los pida y continúa con el QR. Estos valores identifican la conexión; no son un token de bot.", + tgPhone: + "Si no puedes escanear el QR, pide al agente que elija el inicio de sesión por número de teléfono. Introduce el número y el nuevo código cuando lo pida la configuración, seguido de la contraseña adicional de Telegram si se solicita. Sigue el método de entrega que indique la configuración: el código puede llegar a Telegram en lugar de por SMS.", + maxSteps: [ + "Espera a que la configuración muestre un QR de inicio de sesión en el ordenador. Aparece en el terminal; si la ventana es demasiado estrecha, la configuración abre el código en el navegador.", + "Abre MAX en el teléfono donde ya has iniciado sesión. Entra en Ajustes → Dispositivos y elige escanear el QR. Permite el acceso a la cámara si se solicita.", + "Apunta el escáner al código que muestra la configuración en el ordenador. Usa el QR de inicio de sesión de la configuración, en lugar del QR de tu perfil para compartir contactos. Completa cualquier confirmación que MAX muestre en el teléfono.", + "Si la configuración pide la contraseña adicional de la cuenta, introduce la que habías establecido en MAX. El terminal oculta lo que escribes; introduce la contraseña y pulsa Enter.", + "Espera a la confirmación del inicio de sesión y a la comprobación de tu cuenta y hasta cinco chats. El nuevo dispositivo aparece en la lista de dispositivos de MAX. Si la configuración se interrumpe o el código caduca, pide al agente que la reinicie y escanea el nuevo código.", + ], + maxFallback: + "Si el escaneo no funciona, pide al agente que abra el inicio de sesión en el navegador. En web.max.ru puedes escanear el QR o elegir el acceso por número de teléfono y completar los pasos de la página, incluido el CAPTCHA si aparece. La conexión abre una ventana de navegador separada.", + fallback: "Si el inicio de sesión habitual no funciona", + sessions: "Métodos de acceso y ayuda con la conexión", + check: + "Pide al agente que muestre tu cuenta y algunos chats. Comprueba que el nombre y los chats pertenecen a la cuenta que querías conectar. Si es así, la conexión está lista. Para buscar mensajes antiguos puede ser necesario descargar ese período por separado; la configuración no descarga todo el historial.", + archive: "Descargar el historial que necesitas", + tasks: "Probar la primera tarea", + reference: "Instalación manual y detalles técnicos", + }, +} + +export function toolInstallationGuide(tool: string, lang: string) { + const text = copy[lang === "ru" || lang === "es" ? lang : "en"] + const name = tool === "tg" ? "Telegram" : "MAX" + const root = `/${lang}/docs` + return { + intro: text.intro(name), + title: wordsFor(lang).navigation.installGuide, + reference: text.reference, + sections: [ + { + id: "install-open-agent", + title: text.titles[0], + paragraphs: [text.agent, text.browser], + links: [{ label: text.browserLink, href: `${root}/browser-apps` }], + }, + { + id: "install-request", + title: text.titles[1], + paragraphs: [text.install(name)], + request: text.request(name, tool), + links: [], + }, + { + id: "install-login", + title: text.titles[2], + paragraphs: [text.login, text.manualLogin], + command: `${tool} setup`, + steps: tool === "tg" ? text.tgSteps : text.maxSteps, + fallback: { + title: text.fallback, + paragraphs: tool === "tg" ? [text.tgFallback, text.tgPhone] : [text.maxFallback], + }, + links: [ + { + label: tool === "tg" ? "my.telegram.org/apps" : "web.max.ru", + href: tool === "tg" ? "https://my.telegram.org/apps" : "https://web.max.ru", + }, + { label: text.sessions, href: `${root}/${tool}/sessions` }, + ], + }, + { + id: "install-check", + title: text.titles[3], + paragraphs: [text.check], + links: [ + { label: text.tasks, href: `${root}/first-tasks` }, + { label: text.archive, href: `${root}/${tool}/archive` }, + ], + }, + ], + } +} + +/** Same reader steps and request as HTML, ahead of the unchanged native reference. */ +export function toolInstallationMarkdown(slugs: string[], lang: string) { + if (slugs.length !== 2 || !["tg", "max"].includes(slugs[0]) || slugs[1] !== "installation") return "" + const guide = toolInstallationGuide(slugs[0], lang) + const sections = guide.sections + .map((section) => + [ + `### ${section.title} [#${section.id}]`, + ...section.paragraphs, + ...(section.command ? [`\`\`\`sh\n${section.command}\n\`\`\``] : []), + ...(section.request ? [`\`\`\`text\n${section.request}\n\`\`\``] : []), + ...(section.steps ? [section.steps.map((step, i) => `${i + 1}. ${step}`).join("\n")] : []), + ...(section.fallback ? [`#### ${section.fallback.title}`, ...section.fallback.paragraphs] : []), + ...section.links.map((link) => `[${link.label}](${link.href})`), + ].join("\n\n"), + ) + .join("\n\n") + return `${guide.intro}\n\n## ${guide.title} [#agent-installation]\n\n${sections}\n\n## ${guide.reference} [#installation-reference]\n\n` +} diff --git a/lib/words.ts b/lib/words.ts index afcfb5c4..fa83742f 100644 --- a/lib/words.ts +++ b/lib/words.ts @@ -114,7 +114,7 @@ At the end, offer to install the ${tool} skill for my agent.`, }, onboarding: { terminal: "Установить в терминале", - paste: "Скопируйте запрос своему агенту. Он поможет установить CLI и войти в аккаунт на вашем компьютере.", + paste: "Скопируйте запрос своему агенту. Он поможет установить инструмент и войти в аккаунт на вашем компьютере.", copy: "Скопировать", copied: "Скопировано", copyFailed: "Не удалось скопировать. Выделите и скопируйте текст ниже.", diff --git a/tests/mobile-delivery.spec.ts b/tests/mobile-delivery.spec.ts index e559c595..2f843720 100644 --- a/tests/mobile-delivery.spec.ts +++ b/tests/mobile-delivery.spec.ts @@ -176,7 +176,7 @@ for (const lang of ["en", "ru", "es"]) { await page.locator(`main a[href="/${lang}/docs/tg/installation"]`).first().click() await expect(page).toHaveURL(`https://wirecat.dev/${lang}/docs/tg/installation`) await page.locator("main details#tg > summary").click() - const install = page.locator("main .docs-prompt").filter({ hasText: "@wirecat/tg-cli" }) + const install = page.locator("section[aria-labelledby=install-request] .docs-prompt") await install.locator("button.docs-copy").click() expect((await events()).ga[guideIndex + 1]).toEqual([ "event", diff --git a/tests/onboarding-merge.spec.ts b/tests/onboarding-merge.spec.ts index 5fb6450e..3f612add 100644 --- a/tests/onboarding-merge.spec.ts +++ b/tests/onboarding-merge.spec.ts @@ -46,6 +46,26 @@ for (const lang of ["en", "ru", "es"]) { await guide.click() await expect(page).toHaveURL(new RegExp(`/${lang}/docs/${tool}/installation$`)) await expect(page.locator("main")).toContainText(`@wirecat/${tool}-cli`) + const login = page.locator("section[aria-labelledby=install-login]") + await expect(login.locator("ol")).toBeVisible() + await expect(login.locator("code")).toHaveText(`${tool} setup`) + }) + + test(`${lang}/${tool}: login instructions and request match the Markdown guide`, async ({ page }) => { + await page.goto(`/${lang}/docs/${tool}/installation`) + const login = page.locator("section[aria-labelledby=install-login]") + const md = await page.request.get( + `/llms.mdx/docs/${lang === "en" ? "" : `${lang}/`}${tool}/installation/content.md`, + ) + expect(md.status()).toBe(200) + const markdown = await md.text() + for (const paragraph of await login.locator("p, li").allTextContents()) { + expect(markdown).toContain(paragraph.replace(/ →$/, "")) + } + expect(markdown).toContain( + await page.locator("section[aria-labelledby=install-request] .docs-prompt code").textContent(), + ) + expect(markdown.indexOf("[#install-login]")).toBeLessThan(markdown.indexOf("[#installation-reference]")) }) }