# ЁЯзк 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) [![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-х╛╜чла) [![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)
--- ## Compatibility (рд╕рдВрдЧрддрддрд╛) | рдШрдЯрдХ | рд╕рдВрд╕реНрдХрд░рдг | |---|---| | DeepSeek Harness | **`dsh-v0.1.5-rc.2`** (GitHub tag, 2026-09-11 рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд: рдкреВрд░реНрдг рдЧреЗрдЯ рд╢реНрд░реГрдВрдЦрд▓рд╛ + рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдЗрдВрд╕реНрдЯреЙрд▓ рд╕реНрдореЛрдХ)ред npm рдирд┐рд░реНрднрд░рддрд╛ рд▓рд╛рдЗрди `0.1.2-rc.1` рдФрд░ `0.1.5-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` рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред ## Install & uninstall (рдЗрдВрд╕реНрдЯреЙрд▓ рдФрд░ рдЕрдирдЗрдВрд╕реНрдЯреЙрд▓) ```sh dsh plugin --profile web add dsh-test-drive # рдЗрдВрд╕реНрдЯреЙрд▓ (npm) тАФ рдпрд╛ рдКрдкрд░ рд╡рд╛рд▓рд╛ git рд░реВрдк dsh plugin --profile web remove dsh-test-drive # рдЕрдирдЗрдВрд╕реНрдЯреЙрд▓ ``` ## 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.5-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.5-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) рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрд░рдХреНрд╖рд┐рдд [37 DeepSeek Harness рдкреНрд▓рдЧрдЗрдиреЛрдВ](https://github.com/PerryLink) рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рдЕрдЧрд░ рдпрд╣ рдЖрдкрдХреА рдорджрдж рдХрд░рддрд╛ рд╣реИ, рддреЛ рдмрд╛рдХреА рднреА рдХрд░реЗрдВрдЧреЗ: | Plugin | One-liner | |---|---| | **[dsh-auto-review](https://github.com/PerryLink/dsh-auto-review)** | рдЕрдиреБрдореЛрджрди рд╢реНрд░реГрдВрдЦрд▓рд╛ рдкрд░ рджреНрд╡рд┐рддреАрдп-рдореЙрдбрд▓ рд╕реНрд╡рддрдГ-рд╕рдореАрдХреНрд╖рд╛, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╡рд┐рдлрд▓-рдмрдВрдж | | | **[dsh-background-agents](https://github.com/PerryLink/dsh-background-agents)** | рд╡реЗрдм UI рд╕рд╛рдЗрдбрдмрд╛рд░, рд╕рдВрджреЗрд╢ рдФрд░ рдЕрд╡рд░реЛрдзрди рдХреЗ рд╕рд╛рде рдЯрд┐рдХрд╛рдК рдкреГрд╖реНрдарднреВрдорд┐ рдЪрд╛рдЗрд▓реНрдб рдПрдЬреЗрдВрдЯ | | | **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧрдд рдкреНрд░рд╢рд╛рд╕рди: рдмрдЬрдЯ, рдХрд╛рд░реНрдмрди рдФрд░ рд╡рд┐рд▓рдВрдмрддрд╛ рдПрдХ рдкреИрдирд▓ рдореЗрдВред | | | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | Claude Code /rewind-рд╕рдорддреБрд▓реНрдп: рд╕реНрдиреИрдкрд╢реЙрдЯ, рд╕рддреНрд░ рдлрд╝реЙрд░реНрдХ, рдПрдХ-рдмрд╛рд░ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ | | | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | Claude Code рд╕рддреНрд░, рдореЗрдореЛрд░реА, рдХреМрд╢рд▓ рдФрд░ CLAUDE.md рдХреЛ DSH рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ | | | **[dsh-click](https://github.com/PerryLink/dsh-click)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдиреЗрдЯрд┐рд╡ рдбреЗрд╕реНрдХрдЯреЙрдк рдирд┐рдпрдВрддреНрд░рдг тАФ Windows рдкрд╣рд▓реЗред | | | **[dsh-composer-history](https://github.com/PerryLink/dsh-composer-history)** | рд╡реЗрдм рдХрдВрдкреЛрдЬрд╝рд░ рдХреЗ рд▓рд┐рдП рдЯрд░реНрдорд┐рдирд▓-рд╢реИрд▓реА рдЗрдирдкреБрдЯ рдЗрддрд┐рд╣рд╛рд╕: рддреАрд░, Ctrl+R рдЦреЛрдЬ | | | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | рдбреЗрдЯрд╛рд╕реЗрдЯ рдЧреБрдгрд╡рддреНрддрд╛ рдЬрд╛рдБрдЪ рд╡ рдЙрджреНрдзрд░рдг рд╕рддреНрдпрд╛рдкрди (рдпрд╣рд╛рдБ рдЙрдкрднреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдВрдЦреНрдпрд╛-рд╕реЗрддреБ) | | | **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рдкреНрд░реЙрдореНрдкреНрдЯ-рдЗрдВрдЬреЗрдХреНрд╢рди, рдЬреЗрд▓рдмреНрд░реЗрдХ рдФрд░ рд╕реАрдХреНрд░реЗрдЯ-рд▓реАрдХ рд░рдХреНрд╖рд╛ред | | | **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ-рдЕрдиреБрд╢рд╛рд╕рди рд░рдХреНрд╖рдХ: рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреА рдкреВрдЫрддрд╛рдЫ, рдкрд░реАрдХреНрд╖рдг рджреНрд╡рд╛рд░, рдкреНрд░рддрд┐рджреНрд╡рдВрджреНрд╡реА рд╕рдореАрдХреНрд╖рд╛ | | | **[dsh-draw](https://github.com/PerryLink/dsh-draw)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рдПрдХреАрдХреГрдд рд╕реНрдереИрддрд┐рдХ-рдЫрд╡рд┐ рдирд┐рд░реНрдорд╛рдг рд░реВрдЯрд┐рдВрдЧред | | | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рд░реАрдб-рдУрдирд▓реА рдкреНрд░рджрд░реНрд╢рди рдбрд╛рдпрдЧреНрдиреЛрд╕реНрдЯрд┐рдХреНрд╕ред | | | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | рдЪреАрдиреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдореНрдпреВрдЪреБрдЕрд▓ рдлрдВрдб рдХреЗ рд▓рд┐рдП рдирд┐рдпрддрд╛рддреНрдордХ рдЕрдиреБрд╕рдВрдзрд╛рди рд░рд┐рдкреЛрд░реНрдЯ | | | **[dsh-github](https://github.com/PerryLink/dsh-github)** | DSH рдХреЗ рд▓рд┐рдП GitHub PR/issues рдПрдХреАрдХрд░рдг, рд╣рд░ рд▓реЗрдЦрди рдЕрдиреБрдореЛрджрди-рджреНрд╡рд╛рд░рд┐рдд | | | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | рдЙрджреНрдпреЛрдЧ-рдЕрдиреБрд╕рдВрдзрд╛рди рдСрд░реНрдХреЗрд╕реНрдЯреНрд░реЗрд╢рди рдЬреЛ рдЗрд╕ рдкреНрд▓рдЧрд┐рди рдХреЗ `ctx.researchReport.assemble` рд╕реЗ рдбрд┐рд▓реАрд╡рд░реЗрдмрд▓ рд╕реАрд▓ рдХрд░рддрд╛ рд╣реИ | | | **[dsh-library](https://github.com/PerryLink/dsh-library)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдиреАрдп рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдЬреНрдЮрд╛рдирдХреЛрд╢ред | | | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдиреАрдп-рдореЙрдбрд▓ (Ollama) рдПрдХреАрдХрд░рдгред | | | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | рднрд╛рд╖рд╛ рд╕рд░реНрд╡рд░реЛрдВ рдкрд░ LSP рдирд┐рджрд╛рди, рдлрд╝реЙрд░реНрдореЗрдЯрд┐рдВрдЧ, рдкреВрд░реНрдгрддрд╛, рдХреЛрдб рдХреНрд░рд┐рдпрд╛рдПрдБ рдФрд░ рдирд╛рдо рдмрджрд▓рдирд╛ | | | **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | PII рдорд╛рд╕реНрдХрд┐рдВрдЧ рдорд┐рдбрд▓рд╡реЗрдпрд░: рдореЙрдбрд▓ рд╕реАрдорд╛ рдкрд░ рдЕрдирд╛рдо рдХрд░реЗрдВ, рдбрд┐рд╕реНрдкреНрд▓реЗ рд▓реЗрдпрд░ рдкрд░ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ | | | **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рд╡рд╛рд▓рд╛ MCP рд░рдирдЯрд╛рдЗрдо рдкреИрдирд▓: /mcp рдХрдорд╛рдВрдб + рд╕реНрдерд┐рддрд┐, рдЯреВрд▓ рдФрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╡рд╛рд▓рд╛ Settings рдЯреИрдм | | | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | рдЕрдиреБрдореЛрджрди-рджреНрд╡рд╛рд░рд┐рдд рдХреНрд░реЙрд╕-рд╕рддреНрд░ рдореЗрдореЛрд░реА: ctx.memory рд╕реАрдо + SQLite + рдореЗрдореЛрд░реА рдЯреВрд▓ | | | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП OpenTelemetry рдФрд░ Langfuse рдЕрд╡рд▓реЛрдХрдиреАрдпрддрд╛ рдирд┐рд░реНрдпрд╛рддрдХред | | | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | Claude Code outputStyles-рд╕рдорддреБрд▓реНрдп рд░рдирдЯрд╛рдЗрдо рд╢реИрд▓реА рдмрджрд▓рд╛рд╡ | | | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | рдСрдбрд┐рдЯ рдХреЗ рд╕рд╛рде Claude Code-рд╢реИрд▓реА рдШреЛрд╖рдгрд╛рддреНрдордХ allow/deny/ask рдЕрдиреБрдорддрд┐ рдирд┐рдпрдо | | | **[dsh-personal-directive](https://github.com/PerryLink/dsh-personal-directive)** | рд╢реАрд░реНрд╖-рдмрд╛рд░ рдЯреЙрдЧрд▓ рдХреЗ рд╕рд╛рде рд╡реНрдпрдХреНрддрд┐рдЧрдд рдирд┐рд░реНрджреЗрд╢ рдЗрдВрдЬреЗрдХреНрдЯрд░ (рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕рдВрд╕реНрдХрд░рдг) | | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | рдорд╛рдБрдЧ рдкрд░ рдПрдЬреЗрдВрдЯ рдХреМрд╢рд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд▓рдЧрдЗрди-рд╡рд┐рдХрд╛рд╕ рдЬреНрдЮрд╛рди рдЖрдзрд╛рд░ | | | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | рдорд▓реНрдЯреА-рдЪреИрдирд▓ рдЕрдиреБрдореЛрджрди/рдкреНрд░рд╢реНрди рдмреНрд░рд┐рдЬ: WeChat/Telegram/Feishu, рд╕рддреНрд░ рдХрдВрд╕реЛрд▓ | | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | рд╕рд╛рдордЧреНрд░реА-рдкрддрд╛ рд╕рд╛рдХреНрд╖реНрдп рдФрд░ рд╕реАрд▓рдмрдВрдж рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рд╡рд╛рд▓рд╛ рд╕рддреНрдпрд╛рдкрди-рдпреЛрдЧреНрдп рдЕрдиреБрд╕рдВрдзрд╛рди-рд░рд┐рдкреЛрд░реНрдЯ рдЗрдВрдЬрди | | | **[dsh-score](https://github.com/PerryLink/dsh-score)** | DeepSeek Harness рдкреНрд▓рдЧрд┐рдиреЛрдВ рдХреА рдмрд╣реБ-рдЖрдпрд╛рдореА рдЧреБрдгрд╡рддреНрддрд╛ рд╕реНрдХреЛрд░рд┐рдВрдЧред | | | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | рдЯрд┐рдХрд╛рдК рдХреНрд░рдо рдХреЗ рд╕рд╛рде рд╡реЗрдм рд╕рд╛рдЗрдбрдмрд╛рд░ рдореЗрдВ рд╕рддреНрд░ рдкрд┐рди рдХрд░реЗрдВ | | | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рдХреНрд░реЙрд╕-рдбрд┐рд╡рд╛рдЗрд╕ рд╕рддреНрд░ рд╕рд┐рдВрдХ тАФ рдЖрдкрдХреЗ рд╕рддреНрд░ рд╕реНрдЯреЛрд░ рдХрд╛ рдПрдХ рд╕рдорд░реНрдкрд┐рдд git рдорд┐рд░рд░ред | | | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | рд╕реБрд░рдХреНрд╖рд╛-рдСрдбрд┐рдЯ рдХреМрд╢рд▓ рдкреИрдХ: рдЧреБрдкреНрдд рд╕реНрдХреИрди, рдирд┐рд░реНрднрд░рддрд╛ рдФрд░ рдЖрдкреВрд░реНрддрд┐-рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╕рдореАрдХреНрд╖рд╛ | | | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рдЖрд╡рд╛рдЬрд╝-рдкреНрд░рдердо рд╕рддреНрд░ рд▓реВрдк: рдмреЛрд▓реЗрдВ рдФрд░ рдЙрддреНрддрд░ рд╕реБрдиреЗрдВред | | | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | TickTick/Dida365 рдХрд╛рд░реНрдп рдмреНрд░рд┐рдЬ: рд╕рддреНрд░-рд╣реЗрдбрд░ рдкреИрдирд▓ + 11 рдЯреВрд▓ | | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рд╡реЗрдВрдбрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдЕрдиреБрд╡рд╛рдж рдФрд░ рдирд┐рдпрддрд╛рддреНрдордХ JSON рдорд░рдореНрдорддред | | | **[dsh-wechat](https://github.com/PerryLink/dsh-wechat)** | WeChat тЖФ DSH рдмреНрд░рд┐рдЬ (Tencent iLink bot): рдЯреЗрдХреНрд╕реНрдЯ/рдЗрдореЗрдЬ/рдлрд╝рд╛рдЗрд▓/рдЖрд╡рд╛рдЬрд╝, рдЪреИрдЯ рдореЗрдВ рдЕрдиреБрдореЛрджрди | ## 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 рд╕рддреНрдпрд╛рдкрди рдФрд░ рдЖрдкрдХреА рдкреБрд╖реНрдЯрд┐ рд╕реЗ рд╣реА рд╣реЛрддрд╛ рд╣реИред