Skip to main content

debug-store

Developer-only skill for poking at vibe-seller stores from outside the task system — inspect the SQLite DB, drive a store's browser-use wrapper directly via the CDP proxy, manage VIBE_TASK_ID for stable sessions, recover wedged daemons, find seller SKUs, and authenticate without the JWT cookie path. Load when the user says 'debug a store', 'why is store X broken', 'check the wrapper for store X', 'I need to drive Ziniao directly without creating a task', or anything that touches the runtime store layer outside the normal task → agent flow.

Aller à l'installation

Informations de source

Dépôt
zpoint/vibe-seller
Dernière activité de la source
12 août 2026 à 03:15
Langue détectée de SKILL.md
anglais
Étoiles
68
Forks
14

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
debug-store
description
Developer-only skill for poking at vibe-seller stores from outside the task system — inspect the SQLite DB, drive a store's browser-use wrapper directly via the CDP proxy, manage VIBE_TASK_ID for stable sessions, recover wedged daemons, find seller SKUs, and authenticate without the JWT cookie path. Load when the user says 'debug a store', 'why is store X broken', 'check the wrapper for store X', 'I need to drive Ziniao directly without creating a task', or anything that touches the runtime store layer outside the normal task → agent flow.
# Debug Store Infrastructure (developer-only) This is the inside-out view of vibe-seller stores: how to inspect and drive the runtime — the database, the browser-use wrapper, the CDP proxy, the per-store Ziniao session — *without* going through the task system, the web UI, or the JWT-cookie auth wall. This is for the platform builder, not for end-user agents running tasks. For end-user/agent flows (running campaigns, etc.), see `amazon-ads` and `new-product-launch`. ## What you can do without a task The vibe-seller per-store wrapper is just a shell script that talks to a long-running CDP-mux proxy. The wrapper auto-starts the proxy and the browser via an internal API call (with a baked-in `ai_bot` JWT, so you don't need user creds). All you need is: 1. A fresh `VIBE_TASK_ID` env var (lowercase UUID; first 8 chars must be hex). 2. The store slug (look it up in `~/.vibe-seller/data/vibe_seller.db` — `stores.name`, then slugify; or just list `~/.vibe-seller/bin/` for the directories that actually exist). Then `~/.vibe-seller/bin/<slug>/browser-use open <url>` works. ## DB cheatsheet ```bash DB=~/.vibe-seller/data/vibe_seller.db sqlite3 "$DB" .tables sqlite3 "$DB" "SELECT id, name, browser_backend, platforms, countries FROM stores;" sqlite3 "$DB" ".schema stores" sqlite3 "$DB" "SELECT id, username, email, role FROM users;" sqlite3 "$DB" "SELECT store_id, status, current_platform, current_country, active_tab_count, cdp_port, chrome_pid FROM browser_sessions;" sqlite3 "$DB" "SELECT id, status, substr(result,1,120), substr(error,1,120) FROM tasks WHERE created_at > datetime('now','-1 hour') ORDER BY created_at DESC LIMIT 10;" ``` The `stores` table has no `slug` column — the wrapper directory (`~/.vibe-seller/bin/<slug>/`) is where the actual usable name lives. `name` in DB is the user-facing label and may differ from the slug when names contain spaces / non-ascii. Match by ID when scripting. The user table is seeded on first boot with two entries: - a human admin whose username/email/password come from the `ADMIN_USERNAME` / `ADMIN_EMAIL` / `ADMIN_PASSWORD` env vars (defaults: `admin` / `admin@vibe-seller.local` / `admin`). After the first login the user can change these, so don't assume the seeded values are still current — read them from the DB. - `ai_bot` (id `00000000-0000-0000-0000-000000000002`, email `ai@vibe-seller.local`, `password_hash='disabled'`) — its JWT is baked into the wrapper for `browser/start` API calls. **Interactive login for `role='ai_bot'` is rejected by `auth.py`**, so don't try to use this account for HTTP API calls. Use it only as the internal-token subject (which the wrapper already does for you) or follow Option A below to create your own admin user. User-created accounts may also exist alongside these two seeds. `password_hash` is bcrypt; the literal `disabled` means the account cannot log in regardless of role. ## Wrapper architecture in 30 seconds Each store has a generated wrapper at `~/.vibe-seller/bin/<slug>/browser-use`. The wrapper: 1. Resolves `SESSION` from `VIBE_TASK_ID`: - With `VIBE_TASK_ID` set → `<slug>-<first 8 hex>` - Without → `<slug>` (the global session) 2. Validates the session name against `^<slug>(-aux|-[0-9a-fA-F]{8})?$`. 3. Auto-starts the CDP proxy + Ziniao Chrome by calling `POST http://127.0.0.1:7777/api/stores/<store_id>/browser/start` with a hardcoded `ai_bot` JWT. Polls until **that store's** proxy port responds — ports are allocated per store from `_BASE_PROXY_PORT` (9222), so real stores sit on 9223, 9226, 9227… Read the actual port out of the wrapper (`grep -o '127\.0\.0\.1:9[0-9]\{3\}'`) or the `browser_sessions` row; never assume 9222. 4. Exports `BU_CDP_WS=ws://127.0.0.1:<proxy_port>/client-<VIBE_TASK_ID>` so the browser-use daemon connects through the mux proxy as a unique client. (browser-use 0.13 dropped `--cdp-url` for this env var — the wrapper *rejects* `--cdp-url`, see the blocked-flags list above.) 5. Execs the real `browser-use` binary with the rest of the args. The wrapper blocks `--profile`, `--cdp-url`, and `--connect` flags because those break the mux. `--headed` is also blocked (managed by the wrapper). For non-seller-center pages, use `--session <slug>-aux`. **Behavior depends on backend:** - **Wrapper format v4** — every session carries an EXPLICIT `BU_CDP_WS` (an endpoint-less daemon ambiently attached to a DIFFERENT store's browser — observed live; that class is now unrepresentable). Ziniao stores: `-aux` is the store's DEDICATED login-less Chromium, lazily started via `POST /api/stores/{id}/browser/aux/start` (own CDPMuxProxy, own `downloads/{slug}-aux/` dir, NO seller login — never use it for seller central). Chrome stores: aux is a stable `client-aux` on the main proxy. If an aux session shows another store's account, the wrapper predates v3/v4 — restart the server to regenerate. ## VIBE_TASK_ID — the recurring footgun A fresh `VIBE_TASK_ID` per real task is what the runtime gives every task agent. Outside the task system, **rotate it manually after**: - Every long pause (> 15 min idle, especially if the user resumed after sleeping for hours). - Any time you see `Error: Session '<slug>-<8hex>' is already running with different config.` — means the daemon for that ID has stale CDP config. - Any time `browser-use sessions` shows the daemon for your ID with `CONFIG=?` (TTY-detection failure mode). - Any time eval calls return `TimeoutError: timed out` or `Client is stopping` — daemon has wedged. Rotate: ```bash NEW="$(uuidgen | tr '[:upper:]' '[:lower:]')" echo "export VIBE_TASK_ID='$NEW'" > /tmp/vs_session_env.sh . /tmp/vs_session_env.sh ~/.vibe-seller/bin/<slug>/browser-use sessions ~/.vibe-seller/bin/<slug>/browser-use open <some-url> ``` > **A rotated `VIBE_TASK_ID` gets REAPED within 5 minutes — do not use > one for manual driving.** `VIBE_TASK_ID=<uuid>` resolves the session to > `<slug>-<8hex>`, which is exactly the shape > `daemon_reaper.task_prefix_for_bu_name()` reads as *"owned by a task"*. > There is no task row for a hand-made UUID, so the 5-minute sweep > classifies the daemon as orphaned and kills it. The next `js()` in your > heredoc then dies with a bare, undiagnosable traceback — > `FileNotFoundError: [Errno 2] No such file or directory` out of > `_ipc.connect` — because `ensure_daemon()` runs **once** before > `exec(code)` and nothing re-checks the socket mid-script. Confirm with: > `grep -i reaped logs/backend_7777.log` > → `Reaped 1 orphaned browser-use daemon(s): [(<pid>, '<8hex>')]`. > > For manual driving use a session the reaper **skips** — one with no > task suffix: unset `VIBE_TASK_ID` entirely (session `<slug>`, the > global one) or pass `--session <slug>-aux`. Rotation advice above > applies to a *wedged* daemon inside a real task, not to your shell. ## Reviving a wedged daemon ```bash # 1. List daemons to find the wedged one ~/.vibe-seller/bin/<slug>/browser-use sessions # 2. Force-kill (the wrapper's `close` subcommand may itself hang) pkill -9 -f "skill_cli.daemon.*<slug>-<8hex>" # 3. Rotate VIBE_TASK_ID and re-open NEW="$(uuidgen | tr '[:upper:]' '[:lower:]')" export VIBE_TASK_ID="$NEW" ~/.vibe-seller/bin/<slug>/browser-use open about:blank ``` The Ziniao Chrome process and the CDP mux proxy survive daemon kills — they're per-store, not per-task. Don't kill them unless you've tried everything else. To verify the CDP proxy is actually responding: ```bash # This store's mux port — NOT a fixed 9222 (allocated per store). PORT=$(grep -oE '127\.0\.0\.1:9[0-9]{3}' ~/.vibe-seller/bin/<slug>/browser-use | head -1 | cut -d: -f2) curl -sf -m 2 --noproxy '*' "http://127.0.0.1:$PORT/json/version" ps aux | grep -E "ziniaobrowser" | grep -v grep ``` `--noproxy '*'` matters: with ClashX/etc. exported, curl sends the loopback request to the proxy and you get an empty body instead of a connection error — which reads as "the browser is up but broken". The mux proxy is an asyncio server **inside** the FastAPI process, so `grep cdp_mux_proxy` in `ps` finds nothing even when it is running. **Wedge signature:** the port accepts the TCP connection and then never answers (curl hangs to `-m` timeout, HTTP 000). Distinct from a clean "connection refused" — see [docs/ziniao-concurrency.md](../../../docs/ziniao-concurrency.md) runbook. ## Skipping JWT-cookie auth The vibe-seller HTTP API (`/api/tasks`, `/api/stores`, etc.) gates everything on a JWT cookie. From a Claude Code shell, you don't have that cookie. Two ways to work around without touching the user's admin password: ### Option A — reusable `taskbot_debug` account, login via API, then deactivate Use the single stable `taskbot_debug` account for every debug session. The flow below is idempotent: it creates the account on first use, reactivates + rotates the password on every later use, and deactivates it when you're done. ```bash # 1. Generate password + bcrypt hash PW=$(python3 -c "import secrets;print('tmp_'+secrets.token_hex(8))") HASH=$(./.venv/bin/python3 -c "from app.password import hash_password;print(hash_password('$PW'))") # run from repo root # 2. Upsert the stable debug user (admin role, fixed id + username) DBG_UID="taskbot-debug" NOW="$(date -u +%Y-%m-%dT%H:%M:%SZ)" sqlite3 ~/.vibe-seller/data/vibe_seller.db \ "INSERT INTO users (id, username, email, password_hash, role, is_active, plan_mode_default, debug_mode, default_profile_id, created_at, updated_at) VALUES ('$DBG_UID','taskbot_debug',NULL,'$HASH','admin',1,1,0,'default', '$NOW','$NOW') ON CONFLICT(id) DO UPDATE SET password_hash='$HASH', is_active=1, updated_at='$NOW';" # 3. Login → cookie curl -s -c /tmp/vs_cookie.txt -H 'Content-Type: application/json' \ -X POST http://localhost:7777/api/auth/login \ -d "{\"identifier\":\"taskbot_debug\",\"password\":\"$PW\"}" # 4. Use the cookie for any API call curl -s -b /tmp/vs_cookie.txt http://localhost:7777/api/stores # 5. Cleanup before ending the session sqlite3 ~/.vibe-seller/data/vibe_seller.db \ "UPDATE users SET is_active=0 WHERE id='$DBG_UID';" ``` `is_active=0` blocks future logins for this account. The `tasks.created_by` column uses FK = restrict, so the row itself can never be deleted once it owns tasks — that's fine, it's one stable row across all sessions. If you forget step 5 the account stays dormant with a throwaway password; the next session rotates it. ### Option B — drive the wrapper directly (no API auth needed) If your only goal is to drive a store's browser, you don't need the HTTP API at all. The wrapper itself authenticates the `browser/start` call with the `ai_bot` JWT baked into the script. Just rotate `VIBE_TASK_ID` and call `browser-use open <url>`. This is the right choice when: - You're inspecting a single store from outside (debugging, verifying a workflow before turning it into a task). - You don't need the per-task workspace isolation. - You're OK with sharing the global `<slug>` session (or pinning a per-shell `<slug>-<8hex>` session via `VIBE_TASK_ID`). This is the WRONG choice when: - You want isolation across concurrent runs (use real tasks). - You need the agent's MCP tools (`vibe_seller_write_workspace_file`, catalog injection, etc.) — those only exist inside a real task. ## Calling the HTTP API Once you have a cookie file (Option A) — assume `COOKIE=/tmp/vs_cookie.txt` and `BASE=http://localhost:7777` below — every authenticated route is just `curl -b "$COOKIE" "$BASE/<path>"`. Use `-c "$COOKIE"` on the login call (writes), `-b` everywhere else (reads). The API surface (full list in `docs/api.md`) breaks into a few groups: | Group | Common routes | Use for | |---|---|---| | Auth | `POST /api/auth/login`, `GET /api/auth/me`, `POST /api/auth/logout` | Cookie lifecycle | | Stores | `GET /api/stores`, `GET /api/stores/<id>`, `POST /api/stores/<id>/browser/start` (`?force=1`), `POST /api/stores/<id>/browser/aux/start` | Store metadata + per-store browser lifecycle | | Tasks | `POST /api/tasks`, `GET /api/tasks`, `GET /api/tasks/<id>`, `POST /api/tasks/<id>/messages`, `POST /api/tasks/<id>/stop` | Create / list / inspect / message / stop tasks | | Schedules | `GET /api/schedules`, `POST /api/schedules`, `POST /api/schedules/<id>/run` | Cron-style routines | | Events | `GET /api/events/stream` (SSE), `GET /api/events/recent` | Live + historical event feed | > **There is no `browser/stop` route** — stopping is internal only > (`BrowserManager.stop_session` / `aux_browser.stop_aux`, called by store > deletion and the idle sweeper). To stop one store's env by hand, send > Ziniao's own per-store `stopBrowser` with that store's `browser_oauth`; > never kill the shared Ziniao client, which would destroy every other > store's live browser (see
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub