WTStarMark/QAQ--packages-dsh-qaq3

dsh-qaq

QAQ 备份插件:在宿主成功启动并发生首次对话后将配置快照备份至本地

AI 分析

核心用途是在 DSH 成功启动且确认可用后,自动将当前配置备份至本地目录。适合作为 QAQ 守护进程的辅助插件,保障配置安全,不改变 DSH 运行逻辑。

套件
dsh-qaq
版本
0.1.0
授權
MIT
最近更新
2026年8月17日

安裝

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:WTStarMark/QAQ#548e41dacc05ebb375bb22f74ed89f05a4e59e4e&path:packages/dsh-qaq

QAQ — DeepSeek Harness Launch Resilience Guard

简体中文

QAQ is a launch resilience guard for DeepSeek Harness (DSH). When a disrupted profile configuration prevents DSH from starting normally — a crashed host or a red-screened Web UI — QAQ automatically restores the configuration snapshot from the last successful boot and restarts, while preserving the broken config for manual recovery.

Author: WTStarMark

Non-invasive: QAQ never edits DSH source. The guard is a standalone executable that supervises the dsh web process and reads the browser's real DOM over CDP; the backup plugin only reads configuration and never changes behavior.

QAQ interface

QAQ 界面展示

What it solves

DSH's Web surface has a failure mode where the host is alive but the UI red-screens: the host process runs, the port responds, yet the browser renders Failed to load plugins. Such failures are invisible to host-process monitoring and cannot be detected by curl (the server-side HTML ships an empty , rendered client-side). The only reliable non-invasive probe is to open the page in a headless browser and read the actual DOM. QAQ's UI-detection line is exactly that.

Requirements

  • Node.js >= 22
  • A Chrome/Chromium/Edge binary on the machine (used headlessly via CDP; no Playwright/Puppeteer dependency)
  • The dsh command on PATH, or an explicit QAQ_DSH_CMD / --cwd

Install / Quick start

One command: qaq setup installs dependencies + builds, then qaq tui opens the full-screen live guard dashboard.

Or manually:

pnpm install
pnpm build   # bundles dist/qaq.mjs AND regenerates packages/dsh-qaq/lib (the plugin)

bin/qaq.cmd runs the CLI through tsx for development; the global qaq command (from pnpm build) runs the bundled dist/qaq.mjs. Both share the same CLI surface. qaq console / qaq tui opens the full-screen dashboard on a TTY, or a compact menu otherwise.

Take over dsh web from a visible CMD window:

qaq tui --port 3080
# or a single supervised boot without the dashboard:
qaq dsh web --port 3080 --yes

or directly:

qaq dsh web --port 3080 --yes

Which dsh runs? The guard defaults to dsh web (PATH resolution). To run from the DSH source tree instead:

QAQ_DSH_CMD="node --import tsx/esm apps/cli/src/bin.ts web" qaq dsh web --cwd /path/to/dsh-checkout

Pre-launch self-check: qaq dsh web (and the console) auto-discover the dsh command — QAQ_DSH_CMD--cwd → a nearby DSH checkout (ancestors of the current directory, plus a sibling checkout sitting next to it, e.g. QAQ and deepseek-harness side by side) → PATH — pick a Chrome/Chromium/Edge binary for the UI probe, and verify the target port is free. Problems are reported with actionable Chinese hints before anything is spawned.

Commands

CommandPurpose
qaq dsh web [--port N] [--yes]supervised startup: detect host/UI failure -> count -> roll back when triggered -> restart (with anti-loop)
qaq statusprint a summary of ~/.dsh/.qaq/state.json
qaq backup [--profile web]snapshot the current profile into the MANUAL backup set (independent 3-snapshot quota)
qaq restore --to [--profile web]restore a profile from a snapshot directory
qaq reset --profile webzero the failure counters
qaq tui / qaq consoleopen the full-screen live dashboard (or a compact menu on non-TTY)
qaq setupinstall dependencies + build (one command)
qaq install-plugin [--profile web]auto-mount the dsh-qaq backup plugin into a profile

Global: --yes auto-confirms rollbacks.

Dashboard (qaq tui / qaq console)

On a terminal (qaq tui) QAQ shows a full-screen, auto-refreshing dashboard — the all-in-one entry for launching, watching, browsing logs, and managing plugins. It shows guard status, the current operating mode (launcher / sideload / idle), failure counters, last-good snapshot, plugin mount state, a log viewer, and a plugin manager. On a non-TTY it falls back to a one-screen menu (qaq console). The interface is bilingual — press 10 in the TUI to toggle en/zh (a bare qaq console defaults to Chinese; $QAQ_LANG or --lang overrides). The actions available are:

[1]  supervise a dsh web boot (guard)   — fresh preflight each time, rollback + restart (launcher mode)
[2]  refresh state panel                — also auto-refreshes every ~1s
[3]  back up the current profile into the MANUAL backup set
[4]  backup/rollback list               — open the backup manager: auto vs manual groups, pick one to restore
[5]  reset failure counters
[6]  mount the dsh-qaq backup plugin     — idempotent, rollback-safe
[7]  manage plugins                     — install / uninstall / enable / disable
[8]  view logs                           — full-screen log viewer (error/access/host/qaq)
[9]  sideload watch                      — run a continuous sideload guard on an external DSH (toggle)
[10] toggle en / zh
[11] quit

Navigation: / (or j/k) move the selection, Enter/Space run the action, digits 1..N jump straight to an action, q/Esc/Ctrl+C quit.

  • Log viewer ([8]): 14 switch between error.log / access.log / host.log / qaq.log, / scroll, q/Esc/Enter return to the menu.
  • Plugin manager ([7]): manages the real DeepSeek Harness plugins. It auto-discovers the DSH installation (home + source checkout, detected running process via heartbeat), scans the checkout's packages/ for the installable @deepseek-ai/dsh-* bundle packages, lists what's installed/enabled in the active profile, and lets you / select then e enable, d disable, u uninstall, i install. Disabling keeps the module installed but removes it from the profile's boot bundle; uninstalling removes both. It never touches QAQ's own repository.
  • Operating modes: the status line shows which integration mode is active — launcher (QAQ owns a supervised dsh web), sideload (an external DSH is up, or a continuous sideload guard is watching it), or idle.
  • Backup manager ([4]): the backup-list sub-screen, split into auto backups (written by the guard on confirmed health / the plugin after a real conversation; independent 10-snapshot quota) and manual backups (written by [3] / qaq backup; independent 3-snapshot quota). / move the selection, Enter restores the chosen backup, q/Esc returns.
  • Sideload guard ([9]): a toggle. First press resolves the external DSH (the --port you gave qaq tui, else the dsh-qaq plugin heartbeat), pins that port, then keeps probing the real DOM every ~15s — counting host/UI failures and rolling back at threshold (auto-confirm, CLI-owned), exactly like qaq watch. Press [9] again (or quit) to stop. The status line shows the watched URL and the last probe outcome.

The panel auto-refreshes while a supervised dsh web runs; the guard lock is held until it exits (a second launch is refused and a stale port check never misfires). q/Esc/Ctrl+C quit the dashboard; a supervised child is killed so no process is left holding the port.

Operations guide

First-time setup (Windows)

  1. Install — run qaq setup. It checks Node.js >= 22, installs dependencies (pnpm, with an npx fallback), and builds dist/qaq.mjs + the plugin lib.
  2. Mount the backup plugin (recommended) — run qaq tui, press i (mount the dsh-qaq backup plugin). This adds dsh-qaq to the profile's bundle list and links the module into the profile's node_modules. From then on, the plugin snapshots the config once a real user conversation has happened — the strongest proof the boot is actually usable. A host that settles but renders a web red screen never lets the user talk, so it is never recorded as last-good (backup-only; it never changes DSH behavior). The profile's own cordis.patch.yml is intentionally left untouched — DSH auto-loads the plugin's patch from its bundle declaration.
  3. Launch — press 1 (start the guard). The dashboard re-runs the pre-launch self-check (dsh command, browser, port), then supervises dsh web. Once the UI has been healthy for the confirmation window, the config is recorded as last-good and the guard keeps monitoring in the background.
  4. Verifyqaq status: hostFailures / uiFailures should be 0 and lastSuccess / lastGoodSnapshot present.

Everyday use

  • Start DSH the same way every time: qaq tui → press 1. Prefer not to start dsh web directly anymore — the guard owns the supervised process and is the only one that can detect a red screen.
  • If the UI red-screens (or the host crashes) 3 times in a row, QAQ offers a rollback to the last-good config with a diff preview. Accept it — the broken config is preserved under ~/.dsh/.qaq/rolled-back/ for later inspection, and the guard restarts once automatically.
  • After a successful rollback + restart, the counters are zeroed and the anti-loop fence is cleared; the restored profile is the one you had before it broke.

Troubleshooting

SymptomWhat to do
Pre-launch self-check failed — dsh not foundPut dsh on PATH, set QAQ_DSH_CMD, or pass --cwd pointing at the DSH checkout
Port already in use — port busyStop the other process, or pick another port: --port N
UI red-screens again after a rollbackInspect the logs and the preserved bad config: qaq tui (logs are shown in the dashboard) or read, or read ~/.dsh/.qaq/log/ (error.log, access.log, host.log)
Guard says anti-loop fence is activeA rollback already happened within the last 5 minutes. Fix the config manually (see rolled-back/), then qaq reset --profile web to clear the counters
Want to undo a rollbackqaq restore --to --profile web with any directory under ~/.dsh/.qaq/history/auto/ (or history/manual/, rolled-back/)
dsh-qaq not snapshottingThe plugin only writes last-good after a real user conversation — a host that settles but red-screens, or a boot nobody talked to, is never snapshotted. Confirm dsh-qaq is in the profile bundles (the dashboard shows the last snapshot) and that install-plugin reported success

Data locations

  • Guard state, snapshots, and logs: ~/.dsh/.qaq/ (or $DSH_HOME/.qaq/)
  • Profile configs: $DSH_HOME/profiles// (package.json + cordis.patch.yml)
  • qaq status prints the exact paths for your environment.

Supervised dsh web options

OptionMeaningDefault
--confirm-ms stable-healthy confirmation window before snapshotting20000
--ui-timeout max wait for the UI to settle during the L3 probe25000
--threshold consecutive same-kind failures that trigger a rollback3
--cwd working directory for the supervised dsh (set to the checkout for source launch)process cwd

Detection criteria (L3, empirically verified)

  • UI failure: document.body.innerText contains the pinned text Failed to load plugins (stable across builds). The failure detail even names the missing plugin/service (e.g. web boot: 1 entry did not activate dsh-x: pending (waiting for service: s)).
  • Success: a composer business container (``) is present and the failure marker is absent, stable for >= --confirm-ms.
  • No CSS class selectors: the red-screen structural classes are CSS-Module hashes (_boot_) that change between builds.

State & storage (~/.dsh/.qaq/)

  • state.jsonhostFailures, uiFailures, lastSuccess, lastFailure, lastGoodSnapshot, rolledBackAt
  • latest-good/ — the last confirmed-good profile config (package.json + cordis.patch.yml + manifest.json)
  • history/auto// — auto backup set (guard confirm / plugin real conversation; independent 10-snapshot quota)
  • history/manual// — manual backup set (qaq backup / TUI [3]; independent 3-snapshot quota)
  • rolled-back// — the broken config saved before a rollback (for manual recovery)
  • log/ — structured multi-file logs (see below)

Never snapshotted: credentials, sessions, storages, mcp-servers.

Logging (for developer troubleshooting)

Every record is one JSON line ({ ts, level, cat, phase?, msg, ...meta }) so the trail is machine-parseable, split across four files under log/, each rotating by size (256 KB → .1.log, keeping 5 copies):

FileContent
qaq.logeverything (info + warn + error), the canonical record
error.logwarn/error only — grep for trouble fast
access.logcrash-audit trail: boot verdicts, snapshots, rollbacks, resets, plugin mounts, manual restore
host.lograw supervised dsh stdout/stderr (mirrored to the visible window)

Trigger & anti-loop

  • 3 consecutive failures of the same kind (host or UI) trigger a rollback.
  • Exception — definitive host crash: when the child process dies and its output carries a fail-loud boot marker (`plugin tree failed