# Viktor.com (app.viktor.com) — reverse + РАБОЧИЙ Slack-регер (2026-10) API base: `https://api.viktor.com`. SPA: Vite/React, 380 chunks (dump: `~/tmp/viktor/assets/`, report: `~/tmp/viktor/VIKTOR_API_REVERSE.md`). Репа с инструментом: `gbonnet65923/viktor-autoreg` (`tools/slack_reger.py` — полный флоу, `SETUP.md` — все точки конфигурации). Локальная рабочая копия: `~/tmp/viktor/slack_full.py`. ## Signup doors 1. **email-code** (`POST /api/auth/email-code/request`) — LOGIN-ONLY: новый адрес получает "No Viktor account for this address". 2. **Google OAuth** — HARD-DISABLED серверно (`/signup?error=signup-unavailable`). 3. **Microsoft Teams** — нужен work/school tenant. 4. **Slack** (`/api/coworker/slack/signin`, client_id 5770720430932.10097753943189) — **РАБОЧИЙ ПУТЬ**: создать свой workspace через createnew → OAuth → JWT. Проверено вживую до `GET /api/me` 200. ## РАБОЧИЙ ЧЕЙН (Slack door, проверен end-to-end) Порядок шагов (всё в ОДНОЙ cloakbrowser-сессии — токен капчи должен жить в той же странице, где жмётся Continue; отдельный solve+inject не работает): 1. Почта из пула t-online (`working_mails.txt`, 17895 шт, формат email:password; offset-файл для ротации). Consumer-домены (gmail) Slack режет, work-домены принимает. 2. `app.slack.com/get-started#/createnew` → fill email → submit. 3. **reCAPTCHA v2 решается ЛОКАЛЬНО, $0** — in-process `solve_recaptcha_v2_realpage(classifier='mistral')` из `cs_sidecar` (vision keypool mistral/qwen3-vl через локальный OpenAI-совместимый прокси). Старое утверждение «ONNX-классификатор не решает Slack, нужен платный solver» — НЕВЕРНО: решает vision-классификатор сетки. Критично: - НЕ через sidecar HTTP `/solve` — `_solve_lock` занимают cron-задачи (turnstile-джобы), recaptcha-запрос голодает 400+ сек. Только in-process import. - `image_solve.py`: цикл раундов — `while`, НЕ `for range(rounds)` (range фиксируется на входе, апгрейд rounds внутри тела не расширяет итерации). Динамика детектится по `.rc-imageselect-dynamic-selected`. - Лимит раундов ≥25: Slack Enterprise ре-эскалирует челлендж дольше, чем Google demo (8 мало). - `humanize=0` (frame_locator-цепочки несовместимы с humanize), `.first` после frame_locator при двух reCAPTCHA-iframes. - NO TOKEN после N раундов = Google зациклил challenge на этой почте → перезапуск берёт следующую. 4. Код из письма по IMAP (secureimap.t-online.de:993): формат `XXX-XXX` (НЕ `\d{6}`). UI `#/confirmemail` — **6 отдельных боксов `input[maxlength="1"]`** (aria "digit N of 6"): вбивать по одному символу, без тире; целым куском в одно поле = вечное «Checking your code…». 5. Magic-link из письма (`go.slack.com/get-started...`) — ТУПИК: ведёт в `#/workspaces` join-лист, не в создание. Игнорировать, только код. 6. Авторитет успеха = сетевой ответ `POST app.slack.com/api/signin.confirmCode` → `{"ok":true,"has_workspace":false}`. SPA при этом может остаться висеть на confirmemail — это баг навигации, не отказ: форс-навигация `#/createnew` → multi-step создание workspace (name → your name → password, кнопки Next/Continue). 7. Workspace URL: regex `https://([a-z0-9-]+)\.slack\.com` по странице/ссылкам, фолбэк — поле `domain` из cookie `d`. Куки + state сохранять в JSON. 8. **Viktor OAuth**: `api.viktor.com/api/coworker/slack/signin?app_url=https%3A%2F%2Fapp.viktor.com` в той же сессии с куками → страница выбора аккаунта (`button[type=submit]`) → ВТОРАЯ страница консента «Where do you want to use Viktor?» → ещё один submit → callback `app.viktor.com/signin/callback?exchange_token=...&user_id=...`. 9. **exchange_token ОДНОРАЗОВЫЙ**: ручной urllib-запрос `/api/auth/jwt_token` может словить 429, а повтор с тем же токеном — 400 (сожжён). НЕ дёргать jwt_token руками — вешать `page.on("response")` на `/api/auth/jwt_token` и перехватывать JSON-ответ, который делает сам SPA (`{"jwts":[...]}`). 10. Пруф авторизации: `GET /api/me` с `Authorization: Bearer ` + Cookie `session` → 200 с профилем. `session`-кука `api.viktor.com` снимается с контекста после callback. ## Token flow OAuth callback → `{exchange_token}` (одноразовый) → `GET /api/auth/jwt_token?exchange_token=` → `{jwts:[...]}` → cookie `session` = JWT. `post-signin-state?jwt=` → `{provider:'slack', slack_connected:false}` (не блокирует /api/me). ## Мёртвое (не тратить время) - `jwt_bypass` — серверно задизейблен (production → `?error=bypass-disabled`), роут жив но обхода нет. - `/docs /redoc /openapi.json` — 404, схемы нет, только статика чанков. - Thread-эндпоинты web-chat (`thread-info?thread=`) — 404 на REST; тред живёт в WS-потоке гейтвея (`tools/viktor_gateway.py`, REST `POST /threads` + WS `tok_delta`). ## Кредиты и модели (проверено живым JWT) - **Fresh Slack-workspace = 0 кредитов**: sendMessage → HTTP 402 «This workspace is out of credits». Заданий/тасков за кредиты НЕТ (user-research опросник `eligible:false`). - **Starter credit 16 000** — единственный подтверждённый бесплатный путь: `POST /api/coworker/starter-credit-unlock-session {"return_to":"onboarding"}` (литералы: onboarding|dashboard|billing) → `{outcome:"redirect", credits:16000, destination:"https://pay.viktor.com/c/pay/cs_live_..."}` → верификация карты ($0 auth, VCC). `outcome:"unlocked"` = карта уже верифицирована. - Кредит-статус акка: `GET /api/coworker/getting-started-status` → `starter_credit_amount`, `starter_card_required`, `chat_platform_connect_bonus_credits` (поле живое, сейчас 0 — периодически перепроверять: бонус за Discord/MSTeams connect). `GET /subscription` (null=free), `GET /auto-top-up` (прайс: 10000 cr = $25). - **Google-дверь**: `POST /api/auth/google_one_tap {credential, user_type, ph_session_id, anon_session_id}` → JWT напрямую. По отчётам юзеров Gmail-рега даёт стартовые кредиты БЕЗ карты, но с нашего IP дверь отвечала signup-unavailable — перед массовкой нужен один ручной тест через UI «Continue with Google». - Referral: кредиты = % от revenue платящих рефералов, tiers Connector 15% / Advocate 20% (@$750) / Insider 25% (@$2500). Partner offer `claude_startups` (cookie `vk_partner` или `?partner=`, живёт 720ч) + промокоды `?code=` проходят в checkout через `POST /api/coworker/partner-offers/preflight`. - **Модели**: `GET /api/coworker/model-settings` (200, ~17KB) — весь каталог: пресеты Ultra/Smart/Balanced = Claude Opus 5.5 (high/medium/low), Cheap = GPT-6 Luna; прямые модели GPT-6 Astra/Sol/Luna, GPT-6.1 Sol, GPT-5.6 Terra/Sol/Luna, Claude Fable 5.1, Opus 5.5/5/4.8, Sonnet 5.5/5, Grok 4.7; deprecated: Kimi K3, Gemini Flash 3, Fable 5, Opus 4.7. Default `smart`. Infinity-режим: Opus 5 + GPT-6 Astra. Скрипты-пруфы: репа `tools/credits_probe.py`, `tools/starter_unlock.py`, `docs/CREDITS.md`. ## Gateway → IDE `tools/viktor_gateway.py` (:8700, stdlib+websockets, OpenAI-compat `/v1/chat/completions|/v1/models`, pool accounts.jsonl hot-reload, round-robin, 401/403 авто-дизейбл в gw_pool.json) — проверен вживую: health/models/chat работают, 402 от Viktor пробрасывается текстом в content (не маскировать — клиент должен видеть причину). Проводка в Cursor/Cline/Continue/Claude Code/MCP + Cloudflare Tunnel наружу: репа `docs/IDE-GUIDE.md`. Tool-calls из IDE не работают (Viktor сам агент, function-calling наружу не отдаёт) — только чат-режим. ## Антибот Verisoul (`verisoul_session_id` в email-code body, nulls проходят). PostHog server-side eval. ## Pitfalls - Google cookies v20 (App-Bound Encryption) не расшифровываются DPAPI — только v10; сессию между профилями не перенести. - `cloakbrowser.launch_async()` НЕ принимает `user_data_dir` (TypeError) — профиль эфемерный; куки переносить через `context.add_cookies()`. - Workspace ToS speedbump: кнопка «Понятно»/«I understand» (локализована). - patchright headed обходит Google identifier-блок; headless — нет. - `asyncio.run()` внутри уже работающего event loop (родительский поток) — конфликт; оборачивать solve в `threading.Thread` с результатом в dict. - IMAP-заголовки Slack: `From`/`Subject` декодировать через `email.header.make_header(decode_header(...))`, иначе код не найдётся.