# dsh-coding-remote-kit **v0.7.1** · DeepSeek Harness `0.1.1-rc.2` / `0.1.5-rc.2` · GitHub `dsh-coding-remote-kit` **Accès distant par téléphone pour [DeepSeek Harness](https://github.com/deepseek-ai/dsh).** Appariez un téléphone au bureau qui exécute déjà `dsh web`, observez les sessions et effectuez un ensemble restreint d'écritures — sans exposer l'API Web complète. [![npm](https://img.shields.io/npm/v/dsh-coding-remote-kit.svg)](https://www.npmjs.com/package/dsh-coding-remote-kit) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md) *[English](README.md) · [中文版](README.zh-CN.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Português (BR)](README.pt-BR.md) · [Español](README.es.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Русский](README.ru.md)*
--- > **Upgrade / 升级:** Follow the versioned steps in [`INSTALL.md`](INSTALL.md). Install into the existing `web` profile, keep profile/config/credential files, and restart one existing DSH Web process after all packages are updated. When Hub and Subscription are both used, `dsh-coding-oauth-core@0.1.2` is their shared npm dependency, not a separate DSH plugin. --- Plugin communautaire. **Non affilié à DeepSeek, et non approuvé par DeepSeek.** L'intention produit est plus proche d'[Orca Mobile Companion](https://www.onorca.dev/docs/mobile) que d'une seconde copie de l'IDE de bureau. Lisez [`AGENTS.md`](AGENTS.md) avant de modifier ce dépôt : **ne redémarrez pas vous-même le `dsh-web` de production.** Préparez le tarball ; l'opérateur redémarre. ## Noms Développé d'abord sous le nom GitHub `dsh-mobile-remote`. Le nom npm **`dsh-mobile-remote` est un autre projet** (plugin de télécommande WeChat). Ce plugin est publié sous `dsh-coding-remote-kit`. | | Utilisez ceci | Notes | |---|---|---| | npm | `dsh-coding-remote-kit@0.7.1` | `dsh plugin --profile web add dsh-coding-remote-kit@0.7.1` | | GitHub | [`lninghaha/dsh-coding-remote-kit`](https://github.com/lninghaha/dsh-coding-remote-kit) | ancien nom de checkout `dsh-mobile-remote` | | id du plugin Cordis | `mobile-remote` | inchangé | | HTTP de la page Réglages | `/api/mobile-remote/*` | inchangé | | Stockage | `$DSH_HOME/storages/mobile-remote/` | inchangé | Ne faites **pas** `dsh plugin add dsh-mobile-remote` — cela installe le plugin WeChat sans rapport. ## État | Jalon | État | | --- | --- | | Recherche (Orca / écosystème DSH) | terminé — [`docs/research/`](docs/research/) | | M1 squelette du plugin + ADR / modèle de menaces | terminé | | M2 appariement / plan de données LAN | terminé | | M3 RPC restreint / approbations | terminé | | M4 HTTPS signé / application native | non commencé | | M5 Worker de rendez-vous auto-hébergé | terminé — [`docs/05-cloud-relay.md`](docs/05-cloud-relay.md) | ## Fonctionnalités - **UI bilingue** — chinois et anglais pour les Réglages bureau et le companion téléphone (`?lang=` / bascule in-app ; défaut `navigator.language`). - **Apparier une fois** — le bureau affiche un QR code ou un PIN à 8 chiffres ; le téléphone épingle la clé publique X25519 du bureau et conserve un `deviceToken` (le serveur ne stocke que le SHA-256). - **Double plan** — les routes de gestion restent sur le `dsh web` en loopback ; le plan de données mobile est un port dédié (par défaut `6879`) avec une liste blanche RPC. - **E2EE après le handshake** — tweetnacl secretbox sur `/m/ws` ; les sockets non authentifiés ne voient jamais le contenu de session. - **Écritures restreintes** — observer les sessions, répondre aux approbations/questions, réponses courtes ; l'édition lourde reste sur le bureau. - **Réseau privé d'abord** — LAN / Tailscale préférés. Le Cloudflare Quick Tunnel optionnel n'expose **que** le plan de données, jamais le port `3080`. Worker de rendez-vous auto-hébergé optionnel : bureau et téléphone sortent tous deux en outbound ; les trames métier restent E2EE. - **Forme standard de plugin** — un plugin Cordis serveur + page Réglages classic-script. `dsh plugin --profile web add` avec un **file tarball**, jamais un arbre de travail `link:`. ## Captures d'écran

Réglages bureau — offre d'appariement avec QR et PIN   Réglages bureau — état du canal et appareils appariés

Bureau Settings → Mobile Remote : créer une offre d'appariement (gauche) · état du canal et appareils (droite)

Écran d'appariement sur le téléphone    Liste des sessions sur le téléphone

Companion téléphone : saisir le PIN / scanner (gauche) · liste des sessions après appariement (droite)

## Problèmes que ce plugin résout | Vous avez cherché / vu | Ce qui était vraiment cassé | Ce que fait ce plugin | |---|---|---| | « companion téléphone style Orca pour DSH » | DSH officiel n'a pas d'app mobile appariée de première classe | Companion sémantique : appariement + E2EE + RPC en liste blanche | | `dsh-pocket` / `dsh-web-remote` sur un téléphone | Surface complète de `dsh web` sur LAN/public | Double plan ; les méthodes RPC inconnues sont `forbidden` | | Téléphone en cellulaire, bureau en LAN | Une page HTTP LAN brute peut être MITM | Préférer Tailscale ; Quick Tunnel optionnel (TLS au bord, origine localhost) | | L'`import` du plugin a échoué et le port 3080 est mort | DSH fait fail-fast de tout l'arbre de plugins | Porte sandbox + tarball copié *hors* du dépôt ; pas de `link:` | ## Démarrage rapide ```bash dsh plugin --profile web add dsh-coding-remote-kit@0.7.1 ``` Ensuite l'**opérateur** redémarre le processus `dsh web` existant dans sa propre fenêtre. Ouvrez **Settings → 移動远程**, créez une offre d'appariement, scannez le QR (ou saisissez le PIN) sur le téléphone. Depuis un checkout source (développement) : ```bash pnpm test:sandbox pnpm pack mkdir -p "$HOME/.dsh/packages" cp dsh-coding-remote-kit-0.7.1.tgz "$HOME/.dsh/packages/" dsh plugin --profile web add "$HOME/.dsh/packages/dsh-coding-remote-kit-0.7.1.tgz" ``` Ne faites pas `dsh plugin add ./` depuis cet arbre de travail. pnpm 11 traite certains chemins `file:` de tarball comme source `link:`, et un import d'entrée raté fait tomber toute la GUI. ## Table des matières - [Noms](#noms) - [État](#état) - [Fonctionnalités](#fonctionnalités) - [Captures d'écran](#captures-décran) - [Problèmes que ce plugin résout](#problèmes-que-ce-plugin-résout) - [Démarrage rapide](#démarrage-rapide) - [Installation](#installation) - [Fonctionnement](#fonctionnement) - [Page des paramètres](#page-des-paramètres) - [RPC mobile](#rpc-mobile) - [Tunnel public](#tunnel-public) - [Sécurité](#sécurité) - [Architecture](#architecture) - [Documentation](#documentation) - [Projets connexes](#projets-connexes) - [Contribution](#contribution) - [Licence](#licence) ## Installation Nécessite DeepSeek Harness `0.1.1-rc.2` (épinglé) et Node.js 22.19+. Étapes complètes, appariement et notes de tunnel : [INSTALL.md](INSTALL.md). Développement : ```bash pnpm install && pnpm build && pnpm test # inside the Docker sandbox, not on a live GUI host pnpm test:sandbox # Dockerfile targets check / isolated-install / verify ``` Sorties de build : - `lib/server/index.js` — entrée Cordis (`name` / `inject` / `Config` / `apply`) - `lib/client.js` — classic-script de la page Réglages - `lib/mobile/` — page téléphone servie sur `/m` ## Fonctionnement ```text Settings (loopback) Phone browser │ │ │ QR / PIN ────────────────┤ ▼ ▼ /api/mobile-remote/* GET /m + WS /m/ws (dsh web, :3080) (data plane, :6879, E2EE) ``` La gestion reste derrière la clôture loopback du Web hôte. Le plan de données est un serveur séparé `node:http` + `ws`. L'appariement peut le relier de `127.0.0.1` à `0.0.0.0` pour les clients LAN ; un Quick Tunnel actif annonce son origine HTTPS au lieu d'élargir le bind. ## Page des paramètres Ouvrez **Settings → 移動远程** : - état (bind, port, écoute, appareils actifs, tunnel, rendez-vous) - canaux **LAN** / **Quick Tunnel** / **rendezvous** - créer une offre → QR + PIN à 8 chiffres - liste des appareils et révocation - installation optionnelle du `cloudflared` officiel (jamais lancée au `apply()` du plugin) - diagnostics de connexion (candidats assainis, pin/verify cloudflared, version de l’avertissement) - case d’avertissement Quick Tunnel (obligatoire avant Start) ## RPC mobile Méthodes en liste blanche (tout le reste est `forbidden`) : `status.get` · `session.list` · `session.history` · `session.subscribe` · `session.unsubscribe` · `host.subscribe` · `session.prompt` · `session.cancel` · `session.create` · `respond` · `device.name` Les pushes incluent les événements de session plus `approval.requested` / `question.requested` (avec `rpcId` pour `respond`). Format filaire : [docs/03-protocol.md](docs/03-protocol.md). ## Tunnel public Par défaut **éteint**. Démarrez depuis Réglages seulement après avoir accepté l’avertissement (`disclaimerAccepted: true`). Le Quick Tunnel `cloudflared` pointe **uniquement** vers `127.0.0.1:`. `/m` devient joignable sur une URL `https://.trycloudflare.com` ; l'appariement a toujours besoin du jeton de fragment (ou du PIN) et de l'E2EE. Le processus enfant est tué au unload / Stop du plugin. Ne tunnelez jamais le port `3080` / `dsh web`. Un Worker de rendez-vous auto-hébergé (bureau et téléphone tous deux outbound, trames métier toujours E2EE) est optionnel ; voir [docs/05-cloud-relay.md](docs/05-cloud-relay.md). Il faut un plan Cloudflare Workers Paid et ce n'est **pas** un relais public opéré par ce projet. ## Sécurité Invariants (modèle complet : [docs/04-threat-model.md](docs/04-threat-model.md)) : 1. Les connexions non authentifiées ne gèrent que le handshake. 2. `deviceToken` est stocké en SHA-256 ; les clés et fichiers de registre sont `0600`. 3. Liste blanche RPC, refus par défaut ; les écritures sont auditées vers `deviceId`. 4. Le plan de gestion est loopback + Host + CSRF. 5. Le plugin n'affaiblit pas `/api` de `dsh web` et ne s'empare pas des fournisseurs `api-proxy`. **Frontière honnête de v0 :** le premier téléchargement HTTP de `/m` sur un LAN brut peut être MITM. Préférez un VPN overlay. Interdictions : - Ne partagez pas les identifiants d'une autre personne. - Ne surveillez pas des comptes sans autorisation. - Ne liez pas le port du plan de données sur `0.0.0.0` à l'Internet public (le Quick Tunnel démarré explicitement par l'utilisateur est l'exception). - N'impliquez pas un soutien officiel de DeepSeek. Les exemples de la documentation n'utilisent que `example.com`, `127.0.0.1` et `YOUR_TOKEN`. ## Architecture Double plan, carte des modules, stockage et handshake : [docs/02-architecture.md](docs/02-architecture.md) · [中文](docs/02-architecture.zh-CN.md). Décision MVP (voie B) : [docs/01-mvp-scope.md](docs/01-mvp-scope.md). ## Documentation | Doc | Objet | |---|---| | [INSTALL.md](INSTALL.md) | Installer, apparier, tunnel | | [CHANGELOG.md](CHANGELOG.md) | Historique des versions | | [docs/00-project-rules.md](docs/00-project-rules.md) | Versionnage, publier vs local-only, limite DSH hôte | | [docs/01-mvp-scope.md](docs/01-mvp-scope.md) | ADR : périmètre MVP (chinois) | | [docs/02-architecture.md](docs/02-architecture.md) | Architecture interne · [中文](docs/02-architecture.zh-CN.md) | | [docs/03-protocol.md](docs/03-protocol.md) | Liste blanche RPC et enveloppes push (chinois) | | [docs/04-threat-model.md](docs/04-threat-model.md) | Actifs, attaquants, invariants (chinois) | | [docs/05-cloud-relay.md](docs/05-cloud-relay.md) | Worker de rendez-vous auto-hébergé (M5) | | [CONTRIBUTING.md](CONTRIBUTING.md) | Guide de contribution | | [AGENTS.md](AGENTS.md) | Règles agent/opérateur (pas de redémarrage production) | ## Projets connexes - [dsh-coding-subscription-oauth](https://github.com/lninghaha/dsh-coding-subscription-oauth) — plugin frère ; la mise en page de la documentation s'en inspire. - GitHub : [`lninghaha/dsh-coding-remote-kit`](https://github.com/lninghaha/dsh-coding-remote-kit). - Ce plugin est indépendant du plugin centre d'usage `dsh-hub-oauth-gateway`. - Il ne remplace pas `@deepseek-ai/dsh`. ## Contribution Issues et PR bienvenues. Voir [CONTRIBUTING.md](CONTRIBUTING.md) pour le sandbox Docker, les conventions de commit et les couches documentaires. ## Licence [MIT](LICENSE).