# ЁЯзк dsh-test-drive - **1024 рд╕реНрдЯреЛрд░ рдЪреИрдирд▓**: рдПрдХ рдмрд╛рд░ `npm i -g dsh1024`, рдлрд┐рд░ `dsh1024 plugin --profile web add dsh-test-drive` ([deepseek1024.com](https://deepseek1024.com) рдЗрдВрд╕реНрдЯреЙрд▓ рд░реИрдВрдХрд┐рдВрдЧ рдореЗрдВ рдЧрд┐рдирд╛ рдЬрд╛рддрд╛ рд╣реИ)ред **DeepSeek Harness рдкреНрд▓рдЧрдЗрди рдХреЗ рд▓рд┐рдП рдкреГрдердХ рдЗрдВрд╕реНрдЯреЙрд▓-рдФрд░-рд╕реНрдореЛрдХ рдкрд░реАрдХреНрд╖рдгред** *рдПрдХ рдбрд┐рд╕реНрдкреЛрдЬрд╝реЗрдмрд▓ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЗрдВрд╕реНрдЯреЙрд▓, рд╕реНрдореЛрдХ, рд╕рддреНрдпрд╛рдкрди рдФрд░ рд╕рдлрд╝рд╛рдИ рдХрд░реЗрдВ тАФ рдЖрдкрдХрд╛ рдЕрд╕рд▓реА `~/.dsh` рдЕрдЫреВрддрд╛ рд░рд╣рддрд╛ рд╣реИред* [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) [![Gitee](https://img.shields.io/badge/Gitee-mirror-c71d23?logo=gitee)](https://gitee.com/perrylink/dsh-test-drive) [![DSH plugin](https://img.shields.io/badge/dsh--plugin-тЬЕ-green)](https://github.com/topics/dsh-plugin) [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-test-drive.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-х╛╜чла) [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-en.svg)](https://dsh.market/) [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#) [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-test-drive/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-test-drive/actions) [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-test-drive?label=version)](https://github.com/PerryLink/dsh-test-drive/releases) [![npm version](https://img.shields.io/npm/v/dsh-test-drive)](https://www.npmjs.com/package/dsh-test-drive) [![npm downloads](https://img.shields.io/npm/dm/dsh-test-drive)](https://www.npmjs.com/package/dsh-test-drive) [English](README.md) ┬╖ [чоАф╜Уф╕нцЦЗ](README-zh.md) ┬╖ [Espa├▒ol](README-es.md) ┬╖ [Portugu├кs](README-pt.md) ┬╖ [рд╣рд┐рдиреНрджреА](README-hi.md) ```sh dsh plugin --profile add dsh-test-drive ```
--- **ЁЯУЦ рдЗрдХреЛрд╕рд┐рд╕реНрдЯрдо рдиреЙрд▓реЗрдЬ рдмреЗрд╕** тАФ рдорд╛рдкреЗ рдЧрдП рдЖрдБрдХрдбрд╝реЗ, рдорд╛рд░реНрдХреЗрдЯрд┐рдВрдЧ рдирд╣реАрдВ: [рдбреЗрд╡рд▓рдкрдореЗрдВрдЯ рдЧрд╛рдЗрдб ┬╖ рдЪрдпрди рдбреЗрдЯрд╛ ┬╖ рд░рдЦрд░рдЦрд╛рд╡ рдорд╛рдирджрдВрдб](https://perrylink.github.io/dsh-plugin-guide/)ред ## Install & uninstall (рдЗрдВрд╕реНрдЯреЙрд▓ рдФрд░ рдЕрдирдЗрдВрд╕реНрдЯреЙрд▓) ```sh dsh plugin --profile web add dsh-test-drive # рдЗрдВрд╕реНрдЯреЙрд▓ (npm) тАФ рдпрд╛ рдКрдкрд░ рд╡рд╛рд▓рд╛ git рд░реВрдк dsh plugin --profile web remove dsh-test-drive # рдЕрдирдЗрдВрд╕реНрдЯреЙрд▓ ``` ## тнР хжВцЮЬхоГх╕охИ░ф║Жф╜а рдпрд╣ рдкреНрд▓рдЧрдЗрди [DSH рдкреНрд▓рдЧрдЗрди рдкрд░рд┐рд╡рд╛рд░](https://github.com/PerryLink) рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ (95 рдкреНрд▓рдЧрдЗрди, рд╕рднреА Apache-2.0)ред рдЕрдЧрд░ рдпрд╣ рдЙрдкрдпреЛрдЧреА рд▓рдЧреЗ, рддреЛ **рдПрдХ рд╕реНрдЯрд╛рд░ рджреЗрдВ** тАФ рдЗрд╕рд╕реЗ рдХреЛрдИ рд╕реБрд╡рд┐рдзрд╛ рдЕрдирд▓реЙрдХ рдирд╣реАрдВ рд╣реЛрддреА, рдкрд░ рдЕрдЧрд▓рд╛ рд╡реНрдпрдХреНрддрд┐ рдЗрд╕реЗ рдЦреЛрдЬ рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдкрд╛ рд▓реЗрддрд╛ рд╣реИред *English:* part of a 95 plugin family for DeepSeek Harness. If it is useful, **a star helps the next person find it** тАФ nothing is gated behind it. ## What is dsh-test-drive? DeepSeek Harness рдкреНрд▓рдЧрдЗрди рдХреЗ рд▓рд┐рдП рдкреГрдердХ рдЗрдВрд╕реНрдЯреЙрд▓-рдФрд░-рд╕реНрдореЛрдХ рдкрд░реАрдХреНрд╖рдгред рдПрдХ рдбрд┐рд╕реНрдкреЛрдЬрд╝реЗрдмрд▓ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЗрдВрд╕реНрдЯреЙрд▓, рд╕реНрдореЛрдХ, рд╕рддреНрдпрд╛рдкрди рдФрд░ рд╕рдлрд╝рд╛рдИ рдХрд░реЗрдВ тАФ рдЖрдкрдХрд╛ рдЕрд╕рд▓реА `~/.dsh` рдЕрдЫреВрддрд╛ рд░рд╣рддрд╛ рд╣реИред ![dsh-test-drive рдХрд╛рд░реНрдпрдкреНрд░рд╡рд╛рд╣ рдЖрд░реЗрдЦ: рдкреНрд░рд╢реНрди тЖТ рд╕реАрд▓рдмрдВрдж рд╕реНрд░реЛрдд тЖТ рд░рд┐рдкреЛрд░реНрдЯред](docs/assets/dsh-test-drive-flow.svg) *рдХрд╛рд░реНрдпрдкреНрд░рд╡рд╛рд╣: рдкреНрд░рд╢реНрди тЖТ рд╕реАрд▓рдмрдВрдж рд╕реНрд░реЛрдд тЖТ рд░рд┐рдкреЛрд░реНрдЯред рдиреАрдЪреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрдорд╛рдВрдб рд╕рддрд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред* *рд╡рд╣реА рд░рди, рдПрдирд┐рдореЗрдЯреЗрдбред* ## Compatibility (рд╕рдВрдЧрддрддрд╛) | рдШрдЯрдХ | рд╕рдВрд╕реНрдХрд░рдг | |---|---| | DeepSeek Harness | **`dsh-v0.2.1-alpha.1`** (GitHub tag, 2026-09-11 рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд: рдкреВрд░реНрдг рдЧреЗрдЯ рд╢реНрд░реГрдВрдЦрд▓рд╛ + рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдЗрдВрд╕реНрдЯреЙрд▓ рд╕реНрдореЛрдХ)ред npm рдирд┐рд░реНрднрд░рддрд╛ рд▓рд╛рдЗрди `0.1.2-rc.1` рдФрд░ `0.1.7-rc.2` (peer рдирд┐рд░реНрднрд░рддрд╛рдПрдБ `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0`)уАВ | | Node.js | `^22.19.0 \|\| >=24.0.0` | | рдкреИрдХреЗрдЬ рдкреНрд░рдмрдВрдзрдХ | `pnpm@11.7.0` | | рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо | Windows / macOS / Linux (рдХреЗрд╡рд▓ host рдкреНрд▓рдЧрдЗрди) | | рдмрд╛рд╣рд░реА рдЙрдкрдХрд░рдг | PATH рдкрд░ `dsh` CLI (рд╕реНрд╡рддрдГ-рдкрд╣рдЪрд╛рди, npm shim рдкрд╛рд░реНрд╕ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ), PATH рдкрд░ `pnpm` | ## What you get (рдЖрдкрдХреЛ рдХреНрдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИ) - `test_drive` рдЙрдкрдХрд░рдг тАФ рдПрдХ рд▓рдХреНрд╖реНрдп рдХреЛ рдкреВрд░реА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рд╕реЗ рдЧреБрдЬрд╝рд╛рд░рддрд╛ рд╣реИ: `dsh plugin add` тЖТ `--dump-config` рдкреИрдЪ рдЬрд╛рдБрдЪ тЖТ рд╣реЗрдбрд▓реЗрд╕ рдмреВрдЯ рд╕реНрдореЛрдХ (FAILED рдорд╛рд░реНрдХрд░ рд╕реНрдХреИрди + рд╡реИрдХрд▓реНрдкрд┐рдХ рдПрдХ-рд╡рд╛рдХреНрдп рдХрд╛рд░реНрдп) тЖТ рд╡реИрдХрд▓реНрдкрд┐рдХ рдХреНрд╖рдорддрд╛-рдкреБрд╖реНрдЯрд┐ тЖТ `dsh plugin remove` тЖТ рдХреНрд╡рд╛рд░рдВрдЯреАрди рд╕рдлрд╝рд╛рдИред рд╕рдВрд░рдЪрд┐рдд рд░рд┐рдХреЙрд░реНрдб рд╕рдордХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдпрд╛ `background: true` рдкрд░ `{ kind: 'background', jobId }`ред - `/testdrive` рдХрдорд╛рдВрдб тАФ рд╕реНрдкреЗрд╕/рдХреЙрдорд╛ рд╕реЗ рдЕрд▓рдЧ рдХрд┐рдП рдЧрдП рд▓рдХреНрд╖реНрдпреЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ `ctx.jobs` рдкрд░ `drive-batch` рдкреГрд╖реНрдарднреВрдорд┐ рдХрд╛рд░реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд▓рд╛рдХрд░ рдореИрдЯреНрд░рд┐рдХреНрд╕ рд░рд┐рдкреЛрд░реНрдЯ (JSON + Markdown) рдмрдирд╛рддрд╛ рд╣реИред - `drive_report` рдЙрдкрдХрд░рдг тАФ рдХрд┐рд╕реА рднреА рд░рди (`tdr_...`), рдореИрдЯреНрд░рд┐рдХреНрд╕ (`tdm_...`) рдпрд╛ рдирд╡реАрдирддрдо рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЛ рд▓рд╛рддрд╛ рд╣реИ; Markdown рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рд╣реЛрддрд╛ рд╣реИред - рдХреНрд╖рдорддрд╛-рдкреБрд╖реНрдЯрд┐ тАФ тАЬрдмреВрдЯ рд╣реБрдЖ рдФрд░ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рд╛тАЭ рд╕реЗ рдЖрдЧреЗ: рд╡реИрдХрд▓реНрдкрд┐рдХ `capability` рдЪрд░рдг рдПрдЬреЗрдВрдЯ рд╕реЗ рдирд╛рдорд┐рдд рдЙрдкрдХрд░рдг рдХреЛ рдмреБрд▓рд╡рд╛рддрд╛ рд╣реИ (рдпрд╛ `/command` рдЪрд▓рд╡рд╛рддрд╛ рд╣реИ) рдФрд░ рдЯрд┐рдХрд╛рдК рд╕рддреНрд░ рд▓реЙрдЧ рдореЗрдВ рдЖрд╣реНрд╡рд╛рди рддрдерд╛ `expect` рд╡рд╛рд▓рд╛ рдкреНрд░реЗрдХреНрд╖рд┐рдд рдЖрдЙрдЯрдкреБрдЯ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реИред рд╕рд╛рдлрд╝ рдмреВрдЯ рдХреЗрд╡рд▓ рд╕реНрдореЛрдХ рдЯреЗрд╕реНрдЯ рд╣реИ; `observed` рд╕рд┐рджреНрдз рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдирд╛рдорд┐рдд рдХреНрд╖рдорддрд╛ рд╕рдЪрдореБрдЪ рдХрд╛рдо рдХрд░рддреА рд╣реИред - рд╕рдВрд░рдЪрд┐рдд рдкрд░рд┐рдгрд╛рдо тАФ рд╣рд░ рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ рд╡рд┐рднреЗрджрдХ `schema: "dsh-test-drive/v1"` рдФрд░ рдкреНрд░рдердо-рд╢реНрд░реЗрдгреА рдлрд╝реАрд▓реНрдб рд╣реЛрддреЗ рд╣реИрдВ: `stages.install.status` (`pass`/`fail`), `stages.smoke.status` (`pass`/`fail`/`boot-ok`/`skipped`), рдкреНрд░рддрд┐-рдЪрд░рдг `durationMs`, рд╕реИрдирд┐рдЯрд╛рдЗрдЬрд╝ рдХрд┐рдП рдЧрдП `summary`/`outputTail`, рдФрд░ рд╕рдордЧреНрд░ `verdict` (`pass`/`fail`/`partial`/`unknown`)ред рдпрд╣реА рдорд╢реАрди-рдкрдардиреАрдп рдЕрдиреБрдмрдВрдз рд╣реИ рдЬрд┐рд╕реЗ рд╕реНрдХреЛрд░рд┐рдВрдЧ рдкрд╛рдЗрдкрд▓рд╛рдЗрдиреЗрдВ (dsh-score) рдЙрдкрднреЛрдЧ рдХрд░рддреА рд╣реИрдВред - рдирд┐рд░реНрдорд╛рдг рд╕реЗ рд╕реБрд░рдХреНрд╖рд╛ тАФ рд╣рд░ рдЕрд╕реНрдерд╛рдпреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдЗрд╕ рдкреНрд▓рдЧрдЗрди рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдкрд┐рдд рдЙрдкрд╕рд░реНрдЧ `dsh-test-drive-` рдХреЗ рддрд╣рдд рдмрдирд╛рдИ рдЬрд╛рддреА рд╣реИ, рдПрдХ рд╕рдХреНрд░рд┐рдп рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдореЗрдВ рджрд░реНрдЬ рд╣реЛрддреА рд╣реИ, рдФрд░ рдХреЗрд╡рд▓ dry-run тЖТ рдХреНрд╡рд╛рд░рдВрдЯреАрди-рдирд╛рдорд╛рдВрддрд░рдг тЖТ рд╣рдЯрд╛рдиреЗ рдХреА рд╕реАрдврд╝реА рд╕реЗ рд╣рдЯрд╛рдИ рдЬрд╛рддреА рд╣реИред рд╣реЛрд╕реНрдЯ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХрднреА рдкрдврд╝реА рдпрд╛ рд▓рд┐рдЦреА рдирд╣реАрдВ рдЬрд╛рддреАред ## Quick start (рддреНрд╡рд░рд┐рдд рд╢реБрд░реБрдЖрдд) ### git рдЪреИрдирд▓ ```sh dsh plugin --profile web add github:PerryLink/dsh-test-drive# ``` рдкрд╣рд▓рд╛ `add` рд╡рд┐рдлрд▓ рд╣реЛрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ pnpm рдкреИрдХреЗрдЬ рдХреА `prepare` рдмрд┐рд▓реНрдб рд░реЛрдХрддрд╛ рд╣реИ; pnpm рджреНрд╡рд╛рд░рд╛ рдЫрд╛рдкреА рдЧрдИ рд╕рдЯреАрдХ рдХреБрдВрдЬреА рдХреЛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ `pnpm-workspace.yaml` рдореЗрдВ рдХреЙрдкреА рдХрд░реЗрдВ рдФрд░ рдлрд┐рд░ рдЪрд▓рд╛рдПрдБ: ```yaml allowBuilds: 'dsh-test-drive': true ``` ### npm рдЪреИрдирд▓ ```sh dsh plugin --profile web add dsh-test-drive ``` рдкрд╣рд▓реЗ рд╕реЗ рдмрдиреЗ рдкреИрдХреЗрдЬреЛрдВ рдХреЛ рдмрд┐рд▓реНрдб рдЕрдиреБрдорддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреАред рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреБрдирдГ рдЖрд░рдВрдн рдХрд░реЗрдВ, рдлрд┐рд░ рд╕рддреНрд░ рд╕реЗ `test_drive` / `/testdrive` рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред ## DSH Desktop рд╕рдорд░реНрдерд┐рдд рдкрд░реАрдХреНрд╖рдг рд╣реЛрд╕реНрдЯ рдирд╣реАрдВ рд╣реИ `test_drive` рдХреЛ рдРрд╕рд╛ `dsh` CLI рдЪрд╛рд╣рд┐рдП рдЬреЛ **рджреВрд╕рд░рд╛** headless DSH рдкреНрд░реЛрд╕реЗрд╕ рд╢реБрд░реВ рдХрд░ рд╕рдХреЗред DSH Desktop рдХрд╛ `dsh.CMD` launcher рдХреЗрд╡рд▓ `dsh plugin тАж`, `--dump-config` рдФрд░ `--version` рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ; рдиреАрддрд┐ рдХреЗ рдХрд╛рд░рдг рд╡рд╣ рджреВрд╕рд░рд╛ headless boot рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред `config.dshBin` рдХреЛ npm/pnpm рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд `dsh` CLI (рдпрд╛ рд╕рд╛рдорд╛рдиреНрдп Node + dsh JS entry) рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВред рдЕрдм рддреНрд░реБрдЯрд┐ тАЬcannot parse npm shimтАЭ рдХреЗ рдмрдЬрд╛рдп рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдХрд╛рд░рдг рдмрддрд╛рддреА рд╣реИред ## Configuration (рд╡рд┐рдиреНрдпрд╛рд╕) рд╕рднреА рдХреБрдВрдЬрд┐рдпрд╛рдБ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИрдВ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рджрд┐рдЦрд╛рдП рдЧрдП); рдЕрдорд╛рдиреНрдп рдорд╛рди рд▓реЛрдб рдХреЗ рд╕рдордп рдЬрд╝реЛрд░ рд╕реЗ рд╡рд┐рдлрд▓ рд╣реЛрддреЗ рд╣реИрдВред | рдХреБрдВрдЬреА | рдбрд┐рдлрд╝реЙрд▓реНрдЯ | рд╡рд┐рд╡рд░рдг | |---|---|---| | `profileName` | `headless` | рд╣рд░ рдбрд┐рд╕реНрдкреЛрдЬрд╝реЗрдмрд▓ DSH_HOME рдореЗрдВ рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдЯреЗрдореНрдкрд▓реЗрдЯ (base + headless рдмрдВрдбрд▓)ред | | `dshBin` | `""` | dsh рдирд┐рд╖реНрдкрд╛рджрдирдпреЛрдЧреНрдп рдХреЗ рд▓рд┐рдП рдирд┐рд░рдкреЗрдХреНрд╖ рдкрде рдУрд╡рд░рд░рд╛рдЗрдб; рдЦрд╛рд▓реА = PATH рдкрд░ `dsh` рд╕реНрд╡рддрдГ-рдкрд╣рдЪрд╛рдиред | | `headlessTask` | `"Reply with exactly: ok"` | рдмреВрдЯ-рд╕реНрдореЛрдХ рдЪрд░рдг рдХрд╛ рдПрдХ-рд╡рд╛рдХреНрдп рдХрд╛рд░реНрдп; рдЦрд╛рд▓реА = рдЪрд░рдг рдЫреЛрдбрд╝реЗрдВред | | `forwardEnv` | `[]` | рдкрд░реАрдХреНрд╖рдг-рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдЙрдк-рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдореЗрдВ рднреЗрдЬреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░реЛрдВ рдХреЗ **рдирд╛рдо** (рдорд╛рди рдХрднреА рдирд╣реАрдВ)ред | | `allowBuilds` | `true` | рдкрд░реАрдХреНрд╖рдг рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЕрд╡рд░реБрджреНрдз git `prepare` рдмрд┐рд▓реНрдб рдХреЛ рдЕрдиреБрдорддрд┐ рджреЗрдВ рдФрд░ рдЗрдВрд╕реНрдЯреЙрд▓ рдПрдХ рдмрд╛рд░ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред | | `installTimeoutMs` | `600000` | `dsh plugin add` рдЪрд░рдг рдХреА рд╕рдордп-рд╕реАрдорд╛ред | | `configTimeoutMs` | `60000` | `--dump-config` рдЪрд░рдг рдХреА рд╕рдордп-рд╕реАрдорд╛ред | | `smokeTimeoutMs` | `300000` | рд╣реЗрдбрд▓реЗрд╕ рдмреВрдЯ-рд╕реНрдореЛрдХ рдЪрд░рдг рдХреА рд╕рдордп-рд╕реАрдорд╛ред | | `capabilityTimeoutMs` | `300000` | рдХреНрд╖рдорддрд╛-рдкреБрд╖реНрдЯрд┐ рдХрд╛рд░реНрдп рдХреА рд╕рдордп-рд╕реАрдорд╛ред | `capability.enabled` | `false` | рдХреНрд╖рдорддрд╛-рдкреБрд╖реНрдЯрд┐ рдЪрд░рдг рдЪрд▓рд╛рдПрдБ (рдкрдВрдЬреАрдХреГрдд тЖТ рдЖрд╣реВрдд тЖТ рдкреНрд░реЗрдХреНрд╖рд┐рдд)ред | `capability.kind` | `tool` | рдХреНрдпрд╛ рдЬрд╛рдБрдЪреЗрдВ: `tool` рдпрд╛ `command`ред | `capability.name` | `""` | рдЙрдкрдХрд░рдг рдпрд╛ рдХрдорд╛рдВрдб рдирд╛рдо (рдЖрдЧреЗ `/` рдХреЗ рдмрд┐рдирд╛)ред | `capability.args` | `""` | рдЖрд╣реНрд╡рд╛рди рдкрд╛рда: рдЙрдкрдХрд░рдг рддрд░реНрдХ (JSON-рд╢реИрд▓реА) рдпрд╛ рдХрдорд╛рдВрдб рд╢рдмреНрджред | `capability.expect` | `""` | рдкреНрд░реЗрдХреНрд╖рд┐рдд рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ рдЕрдкреЗрдХреНрд╖рд┐рдд рдЕрдХреНрд╖рд░ (рдХреЗрд╕-рдЕрд╕рдВрд╡реЗрджреА рдЙрдк-рд╕реНрдЯреНрд░рд┐рдВрдЧ)ред | `uninstallTimeoutMs` | `120000` | `dsh plugin remove` рдЪрд░рдг рдХреА рд╕рдордп-рд╕реАрдорд╛ред | | `outputTailBytes` | `8000` | рдкреНрд░рддрд┐ рдЪрд░рдг рджрд░реНрдЬ рд╕реИрдирд┐рдЯрд╛рдЗрдЬрд╝реНрдб рдЖрдЙрдЯрдкреБрдЯ рдЯреЗрд▓ рдХреА рд╕реАрдорд╛ред | | `keepTempDirs` | `false` | рд╡рд┐рдлрд▓рддрд╛ рдкрд░ рдлрд╝реЙрд░реЗрдВрд╕рд┐рдХ рд╣реЗрддреБ рдЕрд╕реНрдерд╛рдпреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдПрдБ рд░рдЦреЗрдВ (рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдЫреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ; рдЖрдк рд╕рд╛рдлрд╝ рдХрд░реЗрдВ)ред | | `maxBatchTargets` | `20` | `/testdrive` рдмреИрдЪ рд╕реАрдорд╛ред | | `batchConcurrency` | `1` | рдмреИрдЪ рд╕рдорд╛рдирд╛рдВрддрд░рддрд╛ (рдХреНрд░рдорд┐рдХ pnpm-рд╕реНрдЯреЛрд░ рд╡рд┐рд╡рд╛рдж рд╕реЗ рдмрдЪрд╛рддрд╛ рд╣реИ)ред | ## Tools & surfaces (рдЙрдкрдХрд░рдг рдФрд░ рд╕рддрд╣реЗрдВ) ### `test_drive` ``` test_drive(target: string, headlessTask?: string, background?: boolean, capability?: { kind: 'tool' | 'command', name: string, args: string, expect: string }) ``` - `target` тАФ git рд╕реНрдкреЗрдХ (`github:owner/repo#sha`, `git+https://...`), npm рдирд╛рдо, рд╕реНрдерд╛рдиреАрдп рдкрде рдпрд╛ `.tgz` рдЯрд╛рд░рдмреЙрд▓ред - `capability` тАФ рд╕реНрдореЛрдХ рдХреЗ рдмрд╛рдж рдХреА рдкреБрд╖реНрдЯрд┐: рдПрдЬреЗрдВрдЯ `args` рдХреЗ рд╕рд╛рде `name` (рдЙрдкрдХрд░рдг) рдмреБрд▓рд╛рддрд╛ рд╣реИ рдпрд╛ `/name` (рдХрдорд╛рдВрдб) рдЪрд▓рд╛рддрд╛ рд╣реИ; рдЪрд░рдг рдЯрд┐рдХрд╛рдК рд╕рддреНрд░ рд▓реЙрдЧ рдкрдврд╝рдХрд░ `expect` рд╡рд╛рд▓рд╛ рдкреНрд░реЗрдХреНрд╖рд┐рдд рдЖрдЙрдЯрдкреБрдЯ рдорд╛рдБрдЧрддрд╛ рд╣реИред `DEEPSEEK_API_KEY` рдЪрд╛рд╣рд┐рдП (рд╣реЛрд╕реНрдЯ рдкрд░рд┐рд╡реЗрд╢ рдпрд╛ `forwardEnv`); рдмрд┐рдирд╛ рдЙрд╕рдХреЗ рдЪрд░рдг `skipped` рд░рд╣рддрд╛ рд╣реИ, рдХрднреА рд╡рд┐рдлрд▓ рдирд╣реАрдВ рд╣реЛрддрд╛ред - рдкреВрд░рд╛ рд╕рдВрд░рдЪрд┐рдд рд░рд┐рдХреЙрд░реНрдб рд▓реМрдЯрд╛рддрд╛ рд╣реИ; рдирдореВрдирд╛ рдиреАрдЪреЗред - `background: true` рдПрдХ `drive-batch` рдХрд╛рд░реНрдп рдЖрд░рдВрдн рдХрд░ рдЙрд╕рдХрд╛ id рд▓реМрдЯрд╛рддрд╛ рд╣реИред ### `/testdrive <рд▓рдХреНрд╖реНрдп...>` рдПрдХ рдкреГрд╖реНрдарднреВрдорд┐ рдмреИрдЪ рдХрд╛рд░реНрдп рдЖрд░рдВрдн рдХрд░рддрд╛ рд╣реИ; рдкреНрд░рдЧрддрд┐ рдХрд╛рд░реНрдп рдЖрдЙрдЯрдкреБрдЯ рд╕реЗ рдкреНрд░рд╡рд╛рд╣рд┐рдд рд╣реЛрддреА рд╣реИ, рдФрд░ рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ `drive_report` рдХреЗ рд▓рд┐рдП рдореИрдЯреНрд░рд┐рдХреНрд╕ id рдмрддрд╛рддреА рд╣реИред ### `drive_report(id?)` рдПрдХ рд░рди рд░рд┐рдХреЙрд░реНрдб (`tdr_...`), рдореИрдЯреНрд░рд┐рдХреНрд╕ (`tdm_...`), рдпрд╛ тАФ рдмрд┐рдирд╛ id тАФ рдирд╡реАрдирддрдо рдореИрдЯреНрд░рд┐рдХреНрд╕ рд▓реМрдЯрд╛рддрд╛ рд╣реИред ### рд╕рдВрд░рдЪрд┐рдд рдкрд░рд┐рдгрд╛рдо рдирдореВрдирд╛ ```json { "schema": "dsh-test-drive/v1", "run": { "runId": "tdr_9f2c...", "startedAt": "2026-08-16T00:00:00.000Z", "finishedAt": "2026-08-16T00:00:45.120Z", "durationMs": 45120, "harnessVersion": "0.1.7-rc.2", "pluginVersion": "0.3.10", "platform": "win32", "node": "v22.22.3" }, "target": { "kind": "repo", "spec": "github:owner/dsh-click#abc123", "resolved": { "packageName": "dsh-click", "packageVersion": "0.1.0", "hasBundleManifest": true } }, "isolation": { "tempDshHome": true, "tempWorkspace": true, "tempStore": true, "hostHomeTouched": false }, "stages": { "install": { "status": "pass", "exitCode": 0, "durationMs": 30412, "attempts": 2, "summary": "install ok after allowBuilds allowance", "outputTail": "", "allowBuildsNeeded": true }, "config": { "status": "pass", "exitCode": 0, "durationMs": 2310, "attempts": 1, "summary": "dump ok (exit 0)", "outputTail": "", "patchEffective": true, "layers": ["dsh-click"] }, "smoke": { "status": "boot-ok", "exitCode": 1, "durationMs": 4123, "attempts": 1, "summary": "booted without loader failures; headless task did not complete (credentials/model unreachable)", "outputTail": "", "bootFailed": false, "taskCompleted": false }, "capability": { "status": "observed", "exitCode": 0, "durationMs": 8123, "attempts": 1, "summary": "tool \"plugin_vet\" called and its result contains the expectation", "outputTail": "", "capabilityKind": "tool", "name": "plugin_vet", "expectMatched": true, "detail": "tool \"plugin_vet\" called and its result contains the expectation" }, "uninstall": { "status": "pass", "exitCode": 0, "durationMs": 5123, "attempts": 1, "summary": "remove ok (exit 0)", "outputTail": "" }, "cleanup": { "status": "pass", "quarantined": true, "removed": true, "summary": "owned temp root quarantined and removed" } }, "verdict": "pass", "verdictReason": "install, patch, boot, and uninstall verified; headless task inconclusive (see smoke.summary)" } ``` рдирд┐рд░реНрдгрдп рдирд┐рдпрдо: рдЗрдВрд╕реНрдЯреЙрд▓ рд╡рд┐рдлрд▓рддрд╛, рдмреВрдЯ рд╡рд┐рдлрд▓рддрд╛ (`smoke.fail`) рдпрд╛ `not-registered`/`failed` рддрдХ рдкрд╣реБрдБрдЪрд╛ рдХреНрд╖рдорддрд╛ рдЪрд░рдг тЗТ `fail`; рдЗрдВрд╕реНрдЯреЙрд▓ рдкрд╛рд╕ + рдкреИрдЪ рдкреНрд░рднрд╛рд╡реА + рд╕рд╛рдлрд╝ рдмреВрдЯ (`pass`/`boot-ok`) + рдЕрдирдЗрдВрд╕реНрдЯреЙрд▓ рдкрд╛рд╕ тЗТ `pass` (`observed` рдкрд░ рдХреНрд╖рдорддрд╛ рдиреЛрдЯ рдХреЗ рд╕рд╛рде); рдЗрдВрд╕реНрдЯреЙрд▓ рд╣реБрдЖ рдкрд░ рдмрд╛рдж рдХреА рдХреЛрдИ рдкреБрд╖реНрдЯрд┐ рдЕрдзреВрд░реА тЗТ `partial`; рдЕрдиреНрдпрдерд╛ тЗТ `unknown`ред ## CI (GitHub Actions) рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА рдореЗрдВ рдПрдХ composite [`action.yml`](action.yml) рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬрд┐рд╕реЗ рдХрд┐рд╕реА рднреА рдкреНрд▓рдЧрдЗрди рд░рд┐рдкреЙ рдореЗрдВ `uses:` рд╕реЗ рджреЛрдмрд╛рд░рд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рдпрд╣ рд▓рдХреНрд╖реНрдп рдХреЛ рдПрдХ рдЕрд▓рдЧ-рдерд▓рдЧ throwaway profile рдореЗрдВ рдЪрд▓рд╛рддрд╛ рд╣реИ рдФрд░ CI рджреНрд╡рд╛рд░рд╛ рдЙрдкрднреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рд░рд┐рдкреЛрд░реНрдЯ рдЬреЛрдбрд╝рд╛ тАФ Markdown (PR рдХрдореЗрдВрдЯ) рдФрд░ JUnit XML (рд╕реНрдЯреЗрдЯрд╕ рдЪреЗрдХ) тАФ рдЙрддреНрд╕рд░реНрдЬрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрдирдкреБрдЯ `target` (рдЖрд╡рд╢реНрдпрдХ)/`headless-task`/`dsh-version`; рдЖрдЙрдЯрдкреБрдЯ `markdown`/`junit`/`verdict`ред рдбреНрд░рд╛рдЗрд╡ рдХреЛ рдХреБрдВрдЬреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ; рдХреЗрд╡рд▓ capability assertion рдХреЛ `DEEPSEEK_API_KEY` рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрд╕рдХреЗ рдмрд┐рдирд╛ рд╡рд╣ `skipped` (рдХрднреА рдЕрд╕рдлрд▓ рдирд╣реАрдВ) рд░рд╣рддреА рд╣реИред ## Permissions & data (рдЕрдиреБрдорддрд┐рдпрд╛рдБ рдФрд░ рдбреЗрдЯрд╛) - рдХреЗрд╡рд▓ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╕реЗрд╡рд╛рдПрдБ рдЙрдкрднреЛрдЧ рд╣реЛрддреА рд╣реИрдВ: `ctx.subprocess`, `ctx.jobs`, `ctx.storageDomain`, `ctx.tools`, `ctx.commands`ред - рд░рд┐рдкреЛрд░реНрдЯреЗрдВ `test_drive` рд╕реНрдЯреЛрд░реЗрдЬ-рдбреЛрдореЗрди (рддрд╛рд▓рд┐рдХрд╛рдПрдБ `runs`, `matrices`; рдирд╡реАрдирддрдо-рдореИрдЯреНрд░рд┐рдХреНрд╕ рд╕рдВрдХреЗрддрдХ) рдореЗрдВ рд░рд╣рддреА рд╣реИрдВред рдЬрдм рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ `storageDomain` рдирд╣реАрдВ рд╣реИ (рдЬреИрд╕реЗ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╣реЗрдбрд▓реЗрд╕ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓), рдЙрдкрдХрд░рдг рдЪрд▓рддреЗ рд░рд╣рддреЗ рд╣реИрдВ рдФрд░ рд░рд┐рдкреЛрд░реНрдЯ рд╕реНрдерд╛рдпрд┐рддреНрд╡ рдХрд╛рд░рдг рд╕рд╣рд┐рдд рдЕрдХреНрд╖рдо рд╣реЛрддрд╛ рд╣реИред - рдЙрдк-рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ **рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓-рд░рд╣рд┐рдд** рд╡рд╛рддрд╛рд╡рд░рдг рдорд┐рд▓рддрд╛ рд╣реИ: рд╣реЛрд╕реНрдЯ рд░рд╣рд╕реНрдп рддрдм рддрдХ рдкрд░реАрдХреНрд╖рд┐рдд рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдирд╣реАрдВ рдкрд╣реБрдБрдЪрддреЗ рдЬрдм рддрдХ рдЖрдк рдЙрдиреНрд╣реЗрдВ `forwardEnv` рдореЗрдВ рдирд╛рдо рди рджреЗрдВред рдорд╛рди рдХрднреА рд▓реЙрдЧ рдирд╣реАрдВ рд╣реЛрддреЗред - рд╕рднреА рд░рд┐рдкреЛрд░реНрдЯ/рд▓реЙрдЧ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢реБрджреНрдз рд╕реИрдирд┐рдЯрд╛рдЗрдЬрд╝рд░ рд╕реЗ рдЧреБрдЬрд╝рд░рддреА рд╣реИрдВ: рдЯреЛрдХрди рдЕрдХреНрд╖рд░, URL рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓ рдФрд░ bearer рд╣реЗрдбрд░ рд░рд┐рдбреИрдХреНрдЯ рд╣реЛрддреЗ рд╣реИрдВ, рдЕрд╕реНрдерд╛рдпреА рд░реВрдЯ рдкрде `` рд╕реЗ рдмрджрд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рдЯреЗрд▓ рдмрд╛рдЗрдЯ-рд╕реАрдорд┐рдд рд╣реЛрддреА рд╣реИрдВред ## Security boundaries (рд╕реБрд░рдХреНрд╖рд╛ рд╕реАрдорд╛рдПрдБ) - **рдкреГрдердХреНрдХрд░рдгред** рд╣рд░ рдкрд░реАрдХреНрд╖рдг OS рдЕрд╕реНрдерд╛рдпреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЗ рдЕрдВрджрд░ рдирдИ `mkdtemp` рд░реВрдЯ рдореЗрдВ рдЪрд▓рддрд╛ рд╣реИ: рдбрд┐рд╕реНрдкреЛрдЬрд╝реЗрдмрд▓ `DSH_HOME`, рдбрд┐рд╕реНрдкреЛрдЬрд╝реЗрдмрд▓ рдХрд╛рд░реНрдп рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛, рдФрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд pnpm рд╕реНрдЯреЛрд░ред рдкрд░реАрдХреНрд╖рд┐рдд рдкреНрд▓рдЧрдЗрди рдХрд╛ рдХреЛрдб рдХреЗрд╡рд▓ рдЙрд╕реА рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЪрд▓рддрд╛ рд╣реИ; рдЖрдкрдХреА рд╣реЛрд╕реНрдЯ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдЕрдЫреВрддреА рд░рд╣рддреА рд╣реИред - **рд╕реНрд╡рд╛рдорд┐рддреНрд╡ред** рдПрдХ рд╕рдХреНрд░рд┐рдп рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдЗрд╕ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреА рдмрдирд╛рдИ рд╣рд░ рд░реВрдЯ рдХреЛ рджрд░реНрдЬ рдХрд░рддреА рд╣реИред рд╕рдлрд╝рд╛рдИ рдХрд┐рд╕реА рднреА рдРрд╕реЗ рдкрде рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреА рд╣реИ рдЬреЛ `dsh-test-drive-` рдЙрдкрд╕рд░реНрдЧ рдХреЗ рд╕рд╛рде OS рдЕрд╕реНрдерд╛рдпреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХрд╛ рдкрдВрдЬреАрдХреГрдд рдкреНрд░рддреНрдпрдХреНрд╖ рдЙрдк-рдирд┐рд░реНрджреЗрд╢ рди рд╣реЛ тАФ рдХреЛрдИ `%TEMP%` рд╕рдлрд╝рд╛рдИ рдирд╣реАрдВ, рдХреЛрдИ рдкрд░рд╛рдпрд╛ рдЙрдкрд╕рд░реНрдЧ рдирд╣реАрдВ, рдХреЛрдИ рдЕрд╕рд▓реА рд╣реЛрдо рдкрде рдирд╣реАрдВред - **рд╕рдлрд╝рд╛рдИ рдХреА рд╕реАрдврд╝реАред** рдХрд┐рд╕реА рднреА рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдкрд╣рд▓реЗ рдкреВрд░реА dry-run рдпреЛрдЬрдирд╛ рд▓реЙрдЧ рд╣реЛрддреА рд╣реИ (рдирд┐рд░рдкреЗрдХреНрд╖ рдкрде)ред рд╣рдЯрд╛рдирд╛ рдкрд╣рд▓реЗ рд░реВрдЯ рдХреЛ `dsh-test-drive-quarantine-` рдирд╛рдо рд╕реЗ рдХреНрд╡рд╛рд░рдВрдЯреАрди рдХрд░рддрд╛ рд╣реИ, рд╕рддреНрдпрд╛рдкрди рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ рд╣рдЯрд╛рддрд╛ рд╣реИ; рд╡рд┐рдлрд▓рддрд╛ рдкрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреНрд╡рд╛рд░рдВрдЯреАрди рд░рд╣рддреА рд╣реИ рдФрд░ рд╕реВрдЪрд┐рдд рд╣реЛрддреА рд╣реИ тАФ рдХрднреА рдЪреБрдкрдЪрд╛рдк рдирд╣реАрдВ рдЫреЛрдбрд╝реА рдЬрд╛рддреАред рд╕рдлрд╝рд╛рдИ рд╕рдлрд▓рддрд╛, рд╡рд┐рдлрд▓рддрд╛, рд╕рдордп-рд╕рдорд╛рдкреНрддрд┐ рдФрд░ рд░рджреНрджреАрдХрд░рдг рдХреЗ рд╣рд░ рд░рд╛рд╕реНрддреЗ рдореЗрдВ `finally` рдореЗрдВ рдЪрд▓рддреА рд╣реИ, рдФрд░ рдкреНрд▓рдЧрдЗрди рд╣рдЯрдиреЗ рдкрд░ рдлрд┐рд░ рдЪрд▓рддреА рд╣реИред - **`allowBuilds` рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЕрдиреБрдорддрд┐ рд╣реИред** git рдкреИрдХреЗрдЬ рдХреА `prepare` рдмрд┐рд▓реНрдб рдХреА рдЕрдиреБрдорддрд┐ рдЗрдВрд╕реНрдЯреЙрд▓ рдХреЗ рд╕рдордп рдЙрд╕ рдкреИрдХреЗрдЬ рдХрд╛ рдХреЛрдб рдЪрд▓рд╛рдирд╛ рд╣реИред рдЕрдиреБрдорддрд┐ рдХреЗрд╡рд▓ рдбрд┐рд╕реНрдкреЛрдЬрд╝реЗрдмрд▓ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рддрдХ рд╕реАрдорд┐рдд рд╣реИ, рдлрд┐рд░ рднреА рдХреЗрд╡рд▓ рднрд░реЛрд╕реЗрдордВрдж рд▓рдХреНрд╖реНрдпреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВ рдФрд░ commit рдкрд┐рди рдХрд░реЗрдВред - **рд╣реЗрдбрд▓реЗрд╕ рд╕реНрдореЛрдХ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдХреБрдВрдЬреА-рд░рд╣рд┐рдд рд╣реИред** рдмреВрдЯ рдЬрд╛рдБрдЪ рдХреЛ рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓ рдирд╣реАрдВ рдЪрд╛рд╣рд┐рдП; рдПрдХ-рд╡рд╛рдХреНрдп рдХрд╛рд░реНрдп рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЛ рдЪрд╛рд╣рд┐рдПред рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рднреЗрдЬреЗрдВ (`forwardEnv`) рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХрднреА рд▓реЙрдЧ рди рдХрд░реЗрдВред ## Known limitations (рдЬреНрдЮрд╛рдд рд╕реАрдорд╛рдПрдБ) - рд░рдЬрд┐рд╕реНрдЯреНрд░реА/git рд▓рдХреНрд╖реНрдп рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдк-рдкреНрд░рдХреНрд░рд┐рдпрд╛ `dsh`/pnpm рдХреЛ рдиреЗрдЯрд╡рд░реНрдХ рдЪрд╛рд╣рд┐рдПред - рд╕реНрдореЛрдХ рдХрд╛рд░реНрдп рдХреЛ `pass` рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдореЙрдбрд▓ рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓ рдЪрд╛рд╣рд┐рдП; рдмрд┐рдирд╛ рдЙрдирдХреЗ рдпрд╣ рдИрдорд╛рдирджрд╛рд░ `boot-ok` рджрд░реНрдЬ рдХрд░рддрд╛ рд╣реИред - `storageDomain` рд░рд╣рд┐рдд рд╕рдВрд░рдЪрдирд╛рдУрдВ рдореЗрдВ рд░рд┐рдкреЛрд░реНрдЯреЗрдВ рд╕реНрдерд╛рдпреА рдирд╣реАрдВ рд╣реЛрддреАрдВ (`drive_report` рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рд╡рд┐рдлрд▓ рд╣реЛрддрд╛ рд╣реИ)ред - `dsh` PATH рдкрд░ рдорд┐рд▓рдирд╛ рдЪрд╛рд╣рд┐рдП (рдпрд╛ `dshBin` рд╕реЗрдЯ рдХрд░реЗрдВ); Windows рдкрд░ npm рдХрд╛ `.cmd`/`.bat` shim рд╕реНрд╡рддрдГ рдкрд╛рд░реНрд╕ рд╣реЛрддрд╛ рд╣реИ, рдХреЗрд╡рд▓ `.ps1` рдорд┐рд▓рдиреЗ рдкрд░ `dshBin` рдорд╛рдБрдЧрд╛ рдЬрд╛рддрд╛ рд╣реИред - рдмреИрдЪ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдХреНрд░рдорд┐рдХ рдЪрд▓рддреЗ рд╣реИрдВ; `batchConcurrency` рдмрдврд╝рд╛рдиреЗ рд╕реЗ рдХреЗрд╡рд▓ pnpm-рд╕реНрдЯреЛрд░ рдбрд┐рд╕реНрдХ рд╡рд┐рд╡рд╛рдж рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реЛрддрд╛ рд╣реИ, рд╢реБрджреНрдзрддрд╛ рдирд╣реАрдВред ## Development (рд╡рд┐рдХрд╛рд╕) ```sh pnpm install pnpm run typecheck && pnpm run typecheck:ci && pnpm test pnpm run build && pnpm run verify:self-contained && pnpm run verify:artifacts && pnpm pack ``` - `typecheck` рд╕реНрдерд╛рдиреАрдп harness рдЪреЗрдХрдЖрдЙрдЯ рд╕реЗ `@deepseek-ai/*` рд╣рд▓ рдХрд░рддрд╛ рд╣реИ; `typecheck:ci` рдкреНрд░рдХрд╛рд╢рд┐рдд `0.1.7-rc.2` рдкреНрд░рдХрд╛рд░реЛрдВ рд╕реЗ рдЬрд╛рдБрдЪрддрд╛ рд╣реИред - рдкрд░реАрдХреНрд╖рдг рд╡рд╛рд╕реНрддрд╡рд┐рдХ `Context`/`Session`/`ToolRuntime`/`LocalJobRegistry`/рд╕реНрдЯреЛрд░реЗрдЬ рд╕реНрдЯреИрдХ рдФрд░ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯреЗрдб subprocess рдкреНрд░рджрд╛рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред - рд╡рд╛рд╕реНрддрд╡рд┐рдХ-CLI рдПрдВрдб-рдЯреВ-рдПрдВрдб (рдиреЗрдЯрд╡рд░реНрдХ + PATH рдкрд░ `dsh` рдЖрд╡рд╢реНрдпрдХ): `DSH_TESTDRIVE_E2E=1 pnpm run test:e2e` тАФ рдЗрд╕реА рдкреИрдХреЗрдЬ рдХреЗ рдЪреЗрдХрдЖрдЙрдЯ рдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЗрдВрд╕реНрдЯреЙрд▓-рд╕реНрдореЛрдХ рд▓реВрдк рд╕реЗ рдкрд░рдЦрддрд╛ рд╣реИред - рд░рд┐рд▓реАрдЬрд╝: `node scripts/release.mjs ` (рд╕рдВрд╕реНрдХрд░рдг рдмрдврд╝рд╛рддрд╛, CHANGELOG рдореБрд╣рд░ рд▓рдЧрд╛рддрд╛, рджреНрд╡рд╛рд░ рдлрд┐рд░ рдЪрд▓рд╛рддрд╛, commit + tag; рдХрднреА push рдирд╣реАрдВ)ред ## Topics `dsh`, `dsh-plugin`, `deepseek-harness`, `deepseek`, `cordis`, `plugin-testing`, `install-smoke`, `compatibility-matrix`, `ci` ## Contributors (рдпреЛрдЧрджрд╛рдирдХрд░реНрддрд╛) [PerryLink](https://github.com/PerryLink) тАФ рдбрд┐рдЬрд╝рд╛рдЗрди рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиред ## PerryLink DSH Plugin Family рдпрд╣ рдкреНрд░реЛрдЬреЗрдХреНрдЯ [PerryLink](https://github.com/PerryLink) рдХреЗ DeepSeek Harness рдкреНрд▓рдЧрдЗрди рдкрд░рд┐рд╡рд╛рд░ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рдкреВрд░реА рд╕реВрдЪреА рдиреАрдЪреЗ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд░рдЦреА рдЧрдИ рд╣реИ рддрд╛рдХрд┐ рд╣рд░ README рдХреА рдкрд╣рд▓реА рд╕реНрдХреНрд░реАрди рдЫреЛрдЯреА рд░рд╣реЗ; рд╣рд░ рдкрдВрдХреНрддрд┐ рдФрд░ рдЙрд╕рдХреА рд╕реНрдерд┐рддрд┐ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдЦреЛрд▓реЗрдВред
рд╕рднреА рдкреНрд▓рдЧрдЗрди рдЦреЛрд▓реЗрдВ | рдкреНрд▓рдЧрдЗрди | рд╕реНрдерд┐рддрд┐ | |---|---| | **[dsh-aqua-input-check](https://github.com/PerryLink/dsh-aqua-input-check)** | | | **[dsh-archive-check](https://github.com/PerryLink/dsh-archive-check)** | | | **[dsh-auto-review](https://github.com/PerryLink/dsh-auto-review)** | | | **[dsh-autotier](https://github.com/PerryLink/dsh-autotier)** | | | **[dsh-bid-ca-precheck](https://github.com/PerryLink/dsh-bid-ca-precheck)** | | | **[dsh-bid-qual-check](https://github.com/PerryLink/dsh-bid-qual-check)** | | | **[dsh-cert-mcp](https://github.com/PerryLink/dsh-cert-mcp)** | | | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | | | **[dsh-click](https://github.com/PerryLink/dsh-click)** | | | **[dsh-composer-history](https://github.com/PerryLink/dsh-composer-history)** | | | **[dsh-contract-stance](https://github.com/PerryLink/dsh-contract-stance)** | | | **[dsh-customs-doc-check](https://github.com/PerryLink/dsh-customs-doc-check)** | | | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | | | **[dsh-demurrage-ledger](https://github.com/PerryLink/dsh-demurrage-ledger)** | | | **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | | | **[dsh-drill-script-check](https://github.com/PerryLink/dsh-drill-script-check)** | | | **[dsh-eia-guide-check](https://github.com/PerryLink/dsh-eia-guide-check)** | | | **[dsh-emergency-plan](https://github.com/PerryLink/dsh-emergency-plan)** | | | **[dsh-essay-rubric-check](https://github.com/PerryLink/dsh-essay-rubric-check)** | | | **[dsh-evidence-check](https://github.com/PerryLink/dsh-evidence-check)** | | | **[dsh-export-ctl-check](https://github.com/PerryLink/dsh-export-ctl-check)** | | | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | | | **[dsh-fmea-table-check](https://github.com/PerryLink/dsh-fmea-table-check)** | | | **[dsh-forecast-penalty](https://github.com/PerryLink/dsh-forecast-penalty)** | | | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | | | **[dsh-github](https://github.com/PerryLink/dsh-github)** | | | **[dsh-gongwen-flow-check](https://github.com/PerryLink/dsh-gongwen-flow-check)** | | | **[dsh-gongwen-word-check](https://github.com/PerryLink/dsh-gongwen-word-check)** | | | **[dsh-guard-plan-qc](https://github.com/PerryLink/dsh-guard-plan-qc)** | | | **[dsh-hazchem-check](https://github.com/PerryLink/dsh-hazchem-check)** | | | **[dsh-hazplan-check](https://github.com/PerryLink/dsh-hazplan-check)** | | | **[dsh-hidden-risk-map](https://github.com/PerryLink/dsh-hidden-risk-map)** | | | **[dsh-hs-classify](https://github.com/PerryLink/dsh-hs-classify)** | | | **[dsh-icd-rule-check](https://github.com/PerryLink/dsh-icd-rule-check)** | | | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | | | **[dsh-lawcite-adapter](https://github.com/PerryLink/dsh-lawcite-adapter)** | | | **[dsh-laya](https://github.com/PerryLink/dsh-laya)** | | | **[dsh-lc-doc-check](https://github.com/PerryLink/dsh-lc-doc-check)** | | | **[dsh-learning-gap-check](https://github.com/PerryLink/dsh-learning-gap-check)** | | | **[dsh-library](https://github.com/PerryLink/dsh-library)** | | | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | | | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | | | **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | | | **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | | | **[dsh-medrec-qc](https://github.com/PerryLink/dsh-medrec-qc)** | | | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | | | **[dsh-nsfc-form-check](https://github.com/PerryLink/dsh-nsfc-form-check)** | | | **[dsh-nurse-record-check](https://github.com/PerryLink/dsh-nurse-record-check)** | | | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | | | **[dsh-origin-rvc-check](https://github.com/PerryLink/dsh-origin-rvc-check)** | | | **[dsh-ota-review-check](https://github.com/PerryLink/dsh-ota-review-check)** | | | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | | | **[dsh-paper-doc-adapter](https://github.com/PerryLink/dsh-paper-doc-adapter)** | | | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | | | **[dsh-permit-report-check](https://github.com/PerryLink/dsh-permit-report-check)** | | | **[dsh-pipeline-check](https://github.com/PerryLink/dsh-pipeline-check)** | | | **[dsh-pleading-draft](https://github.com/PerryLink/dsh-pleading-draft)** | | | **[dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor)** | | | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | | | **[dsh-plugin-kit](https://github.com/PerryLink/dsh-plugin-kit)** | | | **[dsh-plugin-upgrade](https://github.com/PerryLink/dsh-plugin-upgrade)** | | | **[dsh-policy-brief-draft](https://github.com/PerryLink/dsh-policy-brief-draft)** | | | **[dsh-power-loss-split](https://github.com/PerryLink/dsh-power-loss-split)** | | | **[dsh-power-ticket-check](https://github.com/PerryLink/dsh-power-ticket-check)** | | | **[dsh-ppap-check](https://github.com/PerryLink/dsh-ppap-check)** | | | **[dsh-protest-deadline](https://github.com/PerryLink/dsh-protest-deadline)** | | | **[dsh-railway-window](https://github.com/PerryLink/dsh-railway-window)** | | | **[dsh-repair-order-qc](https://github.com/PerryLink/dsh-repair-order-qc)** | | | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | | | **[dsh-review-reply-check](https://github.com/PerryLink/dsh-review-reply-check)** | | | **[dsh-rulefile-check](https://github.com/PerryLink/dsh-rulefile-check)** | | | **[dsh-safety-brief-check](https://github.com/PerryLink/dsh-safety-brief-check)** | | | **[dsh-score](https://github.com/PerryLink/dsh-score)** | | | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | | | **[dsh-site-log-check](https://github.com/PerryLink/dsh-site-log-check)** | | | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | | | **[dsh-soe-decision-check](https://github.com/PerryLink/dsh-soe-decision-check)** | | | **[dsh-soilwater-check](https://github.com/PerryLink/dsh-soilwater-check)** | | | **[dsh-sop-sync-check](https://github.com/PerryLink/dsh-sop-sync-check)** | | | **[dsh-spc-gbt-adapter](https://github.com/PerryLink/dsh-spc-gbt-adapter)** | | | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | | | **[dsh-tender-extract](https://github.com/PerryLink/dsh-tender-extract)** | | | **[dsh-tender-matrix](https://github.com/PerryLink/dsh-tender-matrix)** | | | **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | | | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | | | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | | | **[dsh-warranty-calc](https://github.com/PerryLink/dsh-warranty-calc)** | | | **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | ЁЯзК рдлрд╝реНрд░реЛрдЬрд╝рди тАФ рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА README рджреЗрдЦреЗрдВ | | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | ЁЯзК рдлрд╝реНрд░реЛрдЬрд╝рди тАФ рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА README рджреЗрдЦреЗрдВ | | **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | ЁЯзК рдлрд╝реНрд░реЛрдЬрд╝рди тАФ рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА README рджреЗрдЦреЗрдВ | | **[dsh-draw](https://github.com/PerryLink/dsh-draw)** | ЁЯзК рдлрд╝реНрд░реЛрдЬрд╝рди тАФ рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА README рджреЗрдЦреЗрдВ | | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | ЁЯзК рдлрд╝реНрд░реЛрдЬрд╝рди тАФ рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА README рджреЗрдЦреЗрдВ | | **[dsh-background-agents](https://github.com/PerryLink/dsh-background-agents)** | ЁЯЪл рд╕реЗрд╡рд╛рдирд┐рд╡реГрддреНрдд тАФ рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА README рджреЗрдЦреЗрдВ | | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | ЁЯЪл рд╕реЗрд╡рд╛рдирд┐рд╡реГрддреНрдд тАФ рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА README рджреЗрдЦреЗрдВ | | **[dsh-team-rooms](https://github.com/PerryLink/dsh-team-rooms)** | ЁЯЪл рд╕реЗрд╡рд╛рдирд┐рд╡реГрддреНрдд тАФ рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА README рджреЗрдЦреЗрдВ |
## License (рд▓рд╛рдЗрд╕реЗрдВрд╕) [Apache-2.0](LICENSE) ### DSH Desktop рдорд╛рд░реНрдХреЗрдЯ рд╕реЗ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдВ рд╕рднреА PerryLink рдкреНрд▓рдЧрдЗрди DSH Desktop рдХреЗ рдмрд┐рд▓реНрдЯ-рдЗрди рдорд╛рд░реНрдХреЗрдЯ рдореЗрдВ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ: **Market тЖТ Sources тЖТ add source тЖТ рдкреЗрд╕реНрдЯ рдХрд░реЗрдВ** `https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json` **тЖТ рдЪреБрдиреЗрдВ**ред рдЗрдВрд╕реНрдЯреЙрд▓реЗрд╢рди рдорд╛рд░реНрдХреЗрдЯ рдХреЗ npm-identity рд╕рддреНрдпрд╛рдкрди рдФрд░ рдЖрдкрдХреА рдкреБрд╖реНрдЯрд┐ рд╕реЗ рд╣реА рд╣реЛрддрд╛ рд╣реИред ### рдЙрджрд╛рд╣рд░рдг рдпреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рд╣реИрдВ; рдЗрдВрд╕реНрдЯреЙрд▓ рдХреЗ рдмрд╛рдж рдПрдХ рдЪрд▓рд╛рдПрдБред #### рд╡рд┐рд╕реНрддреГрдд рдЙрджрд╛рд╣рд░рдг **рдХрдорд╛рдВрдб** ~~~sh test_drive({ target: "dsh-click" }) ~~~ **рдЖрдЙрдЯрдкреБрдЯ** ~~~text # Test drive tdr_0b9b6e6a61e3e80cc4620f2e - Target: `dsh-click` (npm) - Verdict: тЬЕ pass тАФ install, patch, boot, task, and uninstall all verified - Installed: dsh-click@0.2.0 - Isolation: throwaway DSH_HOME + workspace + pnpm store; host profile untouched | Stage | Result | Exit | Duration | Summary | |---|---|---|---|---| | install | тЬЕ pass | 0 | 1 ms | install ok (exit 0) | | config (--dump-config) | тЬЕ pass | 0 | 0 ms | patch effective: dsh-click | | smoke (headless boot) | тЬЕ pass | 0 | 0 ms | booted cleanly and the headless task completed | | capability | тПня╕П skipped | null | 0 ms | capability assertion disabled (config.capability.enabled is false and no per-drive capability given) | | uninstall | тЬЕ pass | 0 | 0 ms | remove ok (exit 0) | | cleanup | тЬЕ pass | тАФ | тАФ | owned temp root quarantined and removed | ~~~ *рд╕реНрд░реЛрдд `README.md:153-163,174-211; tests/drive.spec.ts:73-101; src/report.ts:34-55`* #### рд╡рд┐рдлрд▓рддрд╛ рд╢рд╛рдЦрд╛ **рдЗрдирдкреБрдЯ** ~~~text {"target":" "} ~~~ **рдЖрдЙрдЯрдкреБрдЯ** ~~~text isError=true; error.message=dsh-test-drive: target must be a non-empty string ~~~ *рд╕реНрд░реЛрдд `plugins/dsh-test-drive/src/tools.ts:297-299 (blank target check); exercised through plugins/dsh-test-drive/tests/harness.ts`* #### рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЙрджрд╛рд╣рд░рдг