dsh-bash-terminal-ts 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.fr.md ADDED
@@ -0,0 +1,205 @@
1
+ # dsh-bash-terminal-ts
2
+
3
+ > 🌐 [简体中文](README.md) | [English](README.en.md) | [Français](README.fr.md) | [Deutsch](README.de.md) | [Italiano](README.it.md) | [Русский](README.ru.md) | [Español](README.es.md) · Communauté : [LINUX DO](https://linux.do) · [GitHub](https://github.com/drscrewdriver/dsh-bash-terminal-ts)
4
+
5
+ ![test](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml/badge.svg)
6
+
7
+ Plugin DSH (DeepSeek Harness) : un outil `shell` qui exécute de manière unifiée sous Windows les commandes de **quatre** terminaux — **PowerShell / Git Bash / MSYS2 / WSL**.
8
+
9
+ > **Ce dépôt est une réécriture TypeScript de `MAXeaglet/dsh-bash-terminal`**, avec une prise en charge fonctionnelle de MSYS2/MINGW64. Les lignes de compatibilité sont découpées par segment de version de l'hôte DSH ; toutes les lignes partagent le nom de paquet `dsh-bash-terminal-ts` et se distinguent par un dist-tag npm :
10
+ >
11
+ > | Segment DSH | Branche | Version du plugin | dist-tag npm |
12
+ > |--------|------|----------|--------------|
13
+ > | `>=0.2.0-rc.1 <0.2.1-0` | `compat/0.2.0` (cette branche) | 0.7.x | `dsh-0.2.0` |
14
+ > | 0.1.7-rc.1 – 0.1.7.x | `compat/0.1.7` | 0.6.x | `dsh-0.1.7` |
15
+ > | 0.1.5-alpha.1 – 0.1.5-rc.x | `ts/0.1.5` (historique, gelée) | ≤ 0.5.2 | `dsh-0.1.5` |
16
+ > | 0.1.2-alpha.1 – 0.1.2-rc.x | `main` (historique, gelée) | ≤ 0.4.2 | `dsh-0.1.2` |
17
+ >
18
+ > Choisissez la ligne correspondant à votre version de DSH ; les séries de versions ne se chevauchent pas, une installation avec `^` ne peut donc pas résoudre d'une ligne à l'autre.
19
+
20
+ | Backend | Exécution réelle | Syntaxe / chemins | Variables d'environnement |
21
+ |------|----------|-------------|----------|
22
+ | `powershell` (par défaut) | `pwsh -NoLogo -NoProfile -NonInteractive -Command <cmd>` | PowerShell ; `C:\...` | `$env:NAME` |
23
+ | `gitbash` | `bash -lc <cmd>` du Git for Windows | POSIX ; `/d/workspace` ; PATH incluant `/usr/bin` et `/mingw64/bin` | `$NAME` |
24
+ | `msys2` | `bash -lc <cmd>` MSYS2 (`C:\msys64\usr\bin\bash.exe`) | POSIX ; `/c/...` ; PATH incluant `/usr/bin` et `/mingw64/bin` (gcc / make) | `$NAME` (injection automatique de `MSYSTEM=MINGW64`) |
25
+ | `wsl` | `wsl [-d <distro>] -e bash -lc <cmd>` | Linux ; `/mnt/d/...` | `$NAME` (via WSLENV) |
26
+
27
+ Chaque appel démarre un shell entièrement neuf : **aucun état n'est conservé** (cwd / variables / alias) — passez `workdir` au lieu d'utiliser `cd`.
28
+
29
+ ## Aperçu de l'interface
30
+
31
+ La ligne « Terminal par défaut » dans Paramètres → Général : l'utilisateur choisit entre PowerShell / Git Bash / MSYS2 / WSL, et l'outil `shell` s'exécute strictement selon ce réglage, sans que le modèle puisse le contourner :
32
+
33
+ ![Ligne de réglage du terminal par défaut](assets/shells.png)
34
+
35
+ ## Points de conception
36
+
37
+ - **Le terminal est décidé par l'utilisateur, l'IA ne peut pas le changer** : la page de réglages de l'UI Web (Paramètres → Général) affiche une liste déroulante « Terminal par défaut » (PowerShell / Git Bash / MSYS2 / WSL) ; l'outil `shell` utilise toujours exclusivement ce réglage et n'expose aucun paramètre de terminal au modèle. Le réglage est persisté via le système de settings de DSH (settings.yaml).
38
+ - **N'occupe pas le point d'extension `ctx.shell`** : l'outil `pwsh` sandboxé fourni avec DSH reste disponible tel quel ; l'outil `shell` de ce plugin constitue un point d'entrée multi-terminal **supplémentaire**.
39
+ - Les processus sont dérivés via le seam partagé `ctx.subprocess` : arrêt de l'arborescence de processus (`taskkill /T` sous Windows), SIGTERM → grâce → SIGKILL, fichiers de spill de sortie — comportement identique à celui des outils officiels `dsh-tool-bash` / `dsh-tool-pwsh`.
40
+ - Les tâches d'arrière-plan sont enregistrées dans le registre générique `jobs`, avec prise en charge de `run_in_background` / `job_output` / `job_kill`.
41
+ - La ligne « Terminal par défaut » de la page de réglages frontale est une énumération (automatiquement rendue en liste déroulante par l'UI) ; à chaque appel, le modèle s'exécute selon ce réglage et ne peut pas changer de terminal de son propre chef.
42
+
43
+ ## Installation (profil web)
44
+
45
+ ### Installation standard (après publication npm, mécanisme officiel de bundle)
46
+
47
+ Le plugin embarque le manifeste officiel `dsh.bundle` (`cordis.patch.yml` dans le paquet) ; dès qu'un profil liste ce paquet, DSH **applique automatiquement le montage**, sans qu'il soit nécessaire de modifier la configuration du profil à la main :
48
+
49
+ ```powershell
50
+ # 1. Installer le paquet du plugin
51
+ npm install -g dsh-bash-terminal-ts
52
+ dsh plugin --profile web add dsh-bash-terminal-ts # ajout automatique aux bundles du profil et application du patch
53
+
54
+ # 2. Patcher la liste blanche des réglages DSH (limitation DSH, voir l'explication ci-dessous)
55
+ powershell -ExecutionPolicy Bypass -File install.ps1 install
56
+
57
+ # 3. Redémarrer dsh web
58
+ ```
59
+
60
+ > Vérifié en pratique avec un profil temporaire : `bundles: [dsh-bash-terminal-ts]` → l'entrée `tool-bash-terminal` apparaît automatiquement dans le dump-config.
61
+
62
+ ### Installation pour développement local (junction, effet immédiat des modifications du code source)
63
+
64
+ ```powershell
65
+ # 1. Lier le paquet du plugin aux node_modules du profil (junction, les modifications du code source prennent effet immédiatement)
66
+ $profile = "$env:USERPROFILE\.dsh\profiles\web"
67
+ New-Item -ItemType Junction -Path "$profile\node_modules\dsh-bash-terminal-ts" -Target "D:\workspace\projects\dsh-bash-terminal-ts" | Out-Null
68
+
69
+ # 2. Permettre au plugin de résoudre les dépendances @deepseek-ai/* (junction vers l'arbre de dépendances du profil ; le plugin et l'hôte partagent la même instance des modules)
70
+ New-Item -ItemType Junction -Path "D:\workspace\projects\dsh-bash-terminal-ts\node_modules\@deepseek-ai" -Target "$profile\..\node_modules\@deepseek-ai" | Out-Null
71
+
72
+ # 3. Laisser le profil monter le plugin via le bundle officiel (install.ps1 install le fait automatiquement ; équivaut à ajouter "dsh-bash-terminal-ts" à dsh.profile.bundles)
73
+ # 4. (uniquement après modification du code front-end) reconstruire le bundle client :
74
+ # cd D:\workspace\projects\dsh-bash-terminal-ts && node scripts/build-client.mjs
75
+ # 5. Redémarrer dsh web
76
+ ```
77
+
78
+ > ⚠️ **N'exécutez pas `npm install` dans ce projet** : cela supprimerait la junction de l'étape 2 ci-dessus et installerait pour le plugin une copie **indépendante** de
79
+ > `@deepseek-ai/*` — le plugin et l'hôte ne partageraient alors plus les instances de modules, et après une montée de version de l'hôte, le plugin resterait bloqué sur l'ancienne API
80
+ > (ce projet s'est ainsi retrouvé bloqué sur 0.1.0-rc.6). Pour ne rafraîchir que le lock, utilisez `npm install --package-lock-only`.
81
+
82
+ > **Compatibilité** : exige DSH ≥ **0.1.7-rc.1** (ligne `compat/0.1.7`) ou ≥ **0.2.0-rc.1** (ligne `compat/0.2.0`, cette branche).
83
+ > Contexte historique : en 0.1.5, `@deepseek-ai/dsh-client-runtime` dans la table des modules client a été renommé `@deepseek-ai/dsh-client-store` et n'est résolu que par correspondance exacte du nom nu ; les anciens bundles échouent sur le nouvel hôte avec
84
+ > `Failed to load plugins` / `require(...) missed the module table`.
85
+ >
86
+ > Par ailleurs : depuis 0.1.5, la surface de réglages Web repose sur l'énumération dynamique `settings.describe()` et **n'a plus de liste blanche de namespaces**
87
+ > (`settings-not-exposed` n'existe plus) ; le patch de liste blanche présent dans `install.ps1` n'est qu'un vestige historique, il peut être ignoré.
88
+
89
+ > Il n'est désormais plus nécessaire de modifier manuellement le `cordis.patch.yml` du profil : le paquet du plugin embarque son propre `dsh.bundle.patch` (`cordis.patch.yml` dans le paquet) ; dès que `dsh-bash-terminal-ts` figure dans le `dsh.profile.bundles` du profil, DSH monte automatiquement le plugin.
90
+
91
+ Vérifier l'arbre combiné (sans redémarrage) :
92
+
93
+ ```powershell
94
+ node "$env:APPDATA\nvm\<node-version>\node_modules\@deepseek-ai\dsh\lib\bin.js" --profile web --dump-config | Select-String dsh-bash-terminal-ts
95
+ ```
96
+
97
+ ## Utilisation
98
+
99
+ **L'utilisateur choisit le terminal par défaut dans l'UI Web** : ouvrez les paramètres (roue dentée) → Général → liste déroulante « Terminal par défaut », puis choisissez l'un des terminaux PowerShell / Git Bash / MSYS2 / WSL. Le changement prend effet immédiatement et est persisté.
100
+
101
+ Lorsque le modèle voit l'outil `shell`, il l'emploie automatiquement avec le terminal que vous avez choisi (l'outil n'expose pas de paramètre de terminal ; le modèle ne peut pas changer votre choix) :
102
+
103
+ - Terminal par défaut = Git Bash : `shell(command: "git status")` passe par Git Bash
104
+ - Terminal par défaut = MSYS2 : `shell(command: "gcc --version")` passe par MSYS2 (environnement MINGW64, gcc et make de `/mingw64/bin` disponibles)
105
+ - Terminal par défaut = WSL : `shell(command: "ls -la /mnt/d/workspace")` passe par WSL ; `distro: "Ubuntu"` permet de préciser la distribution
106
+ - Terminal par défaut = PowerShell : `shell(command: "Get-Process node")` passe par PowerShell
107
+
108
+ ## Exemples d'utilisation pour le modèle
109
+
110
+ - Commande ponctuelle (terminal par défaut) : `shell(command: "git status", description: "voir l'état git")`
111
+ - État conservé d'un tour à l'autre (interactif) : `terminal(action: "open")` → noter le `sessionId` → `terminal(action: "send", sessionId, input: "cd /d/project\n")` → `terminal(action: "send", sessionId, input: "npm run dev\n")` → `terminal(action: "close", sessionId)`
112
+ - Interrompre un programme en cours d'exécution : `terminal(action: "signal", sessionId, signal: "SIGINT")`
113
+ - Consulter les sessions actives : `terminal(action: "list")`
114
+ - Escalade après un refus du bac à sable : `shell(command: ..., sandbox_permissions: "workspace-write", justification: "...")`
115
+
116
+ ## Configuration
117
+
118
+ **Réglages de l'UI Web** (recommandé) : Paramètres → Général → « Terminal par défaut ».
119
+
120
+ Le `config` de la ligne du plugin (surcharge les valeurs par défaut et sert de base de composition pour les réglages) :
121
+
122
+ | Clé | Par défaut | Description |
123
+ |----|------|------|
124
+ | `defaultShell` | `powershell` | Backend utilisé lorsque les réglages ne surchargent pas |
125
+ | `timeoutMs` | 120000 | Délai d'expiration par défaut |
126
+ | `maxTimeoutMs` | 600000 | Plafond du timeoutMs de l'appelant |
127
+ | `pwshPath` | détection automatique | Chemin fixe de pwsh.exe |
128
+ | `gitBashPath` | détection automatique | Chemin fixe de git bash.exe |
129
+ | `msys2Path` | détection automatique (`C:\msys64\usr\bin\bash.exe` en priorité, repli sur `msys2.exe`) | Chemin fixe de MSYS2 bash.exe |
130
+ | `wslPath` | détection automatique | Chemin fixe de wsl.exe |
131
+
132
+ ## Publication (npm)
133
+
134
+ Le compte npm a la vérification 2FA activée pour la publication ; un code à usage unique est requis :
135
+
136
+ ```powershell
137
+ cd D:\workspace\projects\dsh-bash-terminal-ts
138
+ npm publish --otp <code> # le code provient de votre authentificateur
139
+ ```
140
+
141
+ Avant de publier, faites un `npm pack --dry-run` pour vérifier le contenu, puis lancez `npm run build` pour tout reconstruire (compilation serveur tsc + bundle client + compilation des tests).
142
+
143
+ ## Désinstallation
144
+
145
+ Exécutez simplement :
146
+
147
+ ```powershell
148
+ powershell -ExecutionPolicy Bypass -File install.ps1 uninstall
149
+ ```
150
+
151
+ Cette commande supprime les junctions, restaure la liste blanche des réglages, nettoie les blocs de montage `cordis.patch.yml` laissés par les anciennes versions et retire `dsh-bash-terminal-ts` du `dsh.profile.bundles`. Redémarrez ensuite dsh web.
152
+
153
+ En cas de désinstallation manuelle, outre la suppression de `node_modules\dsh-bash-terminal-ts`, pensez également à retirer `dsh-bash-terminal-ts` du `dsh.profile.bundles` du `package.json` du profil.
154
+
155
+ ## Terminal interactif (outil `terminal`)
156
+
157
+ L'outil `terminal` fournit des **sessions interactives persistantes** sur le seam PTY (node-pty ; sous Windows, l'inspecteur de processus du `spawnTerminal` amont ne prenant en charge que POSIX, `lib/terminal.js` se connecte directement à node-pty ; hors Windows, le `ctx.subprocess.spawnTerminal` officiel reste utilisé) :
158
+
159
+ - `action: open` démarre une véritable session de terminal (selon votre terminal par défaut réglé ; pour wsl, `distro` peut être précisé) et renvoie un `sessionId`
160
+ - `action: send` écrit l'entrée et lit la nouvelle sortie ; `action: read` lit sans écrire ; `action: signal` envoie un signal au groupe de processus de premier plan (SIGINT = Ctrl+C)
161
+ - `action: close` met fin à la session
162
+ - **L'état de la session persiste entre les appels** (cwd / variables / alias), idéal pour les REPL, ssh et les CLI interactifs
163
+ - `send` attend la stabilisation de la sortie (300 ms de silence, plafond 5 s) et renvoie la **réponse complète** ; au-delà de 1 Mo de sortie, un avertissement `truncated` est émis
164
+ - L'entrée se termine par `\\n` (ou \\r) pour matérialiser la touche Entrée
165
+
166
+ ## Bac à sable (intégration au mécanisme officiel)
167
+
168
+ L'outil `shell` emprunte le seam officiel de bac à sable de DSH (`ctx.sandboxPolicy` + `ctx.sandbox`) :
169
+
170
+ - À chaque appel, la politique de bac à sable courante est résolue ; les sessions `danger-full-access` s'exécutent directement (sans enveloppement).
171
+ - Le backend PowerShell enveloppe argv via `ctx.sandbox.confine` — sémantique **fail-closed** identique à celle des exécuteurs officiels : si le mode restreint est demandé alors qu'aucun backend n'est disponible, une `SandboxUnavailableError` est levée, refusant toute exécution nue.
172
+ - Le backend Git Bash n'est pas enveloppé : le runner à jeton restreint ACL Windows de DSH est incompatible avec Cygwin/MSYS2 (bash s'arrête dès le démarrage avec l'erreur Win32 5 de `CreateFileMapping`) ; Git Bash s'exécute donc, même en mode restreint, sans enveloppement sandbox ; le résultat rapporte `enforcement: gitbash-unconfined`.
173
+ - Le backend MSYS2 n'est pas enveloppé non plus (même incompatibilité d'exécution Cygwin/MSYS2) ; le résultat rapporte `enforcement: msys2-unconfined`.
174
+ - Le backend WSL n'est pas enveloppé : la VM Linux indépendante de WSL constitue en soi l'isolation (le résultat rapporte `enforcement: wsl-isolation`).
175
+ - En cas de refus par le bac à sable en mode restreint, le résultat porte le marqueur officiel `[sandbox: file access denied under <mode> mode]` ainsi que l'indice d'escalade du même tour ; le modèle peut déclencher une escalade à l'aide de `sandbox_permissions` + `justification` (approbation de l'utilisateur via `ctx.approval`), exactement comme les outils officiels bash/pwsh.
176
+ - Remarque : lorsque le runner ACL Windows de DSH est disponible, le mode restreint de PowerShell est enveloppé par son intermédiaire ; Git Bash et MSYS2 restent non enveloppés en raison de l'incompatibilité Cygwin/MSYS2.
177
+
178
+ ## ⚠️ Note de sécurité
179
+
180
+ En mode restreint, l'outil `shell` : PowerShell est enveloppé via `ctx.sandbox.confine` (fail-closed) ; Git Bash et MSYS2 ne sont **pas enveloppés** en raison de l'incompatibilité entre Cygwin/MSYS2 et les jetons restreints ACL Windows (mêmes privilèges que le processus dsh) ; WSL n'est pas enveloppé grâce à sa VM Linux indépendante. Il s'agit d'un **point d'entrée multi-terminal supplémentaire** qui ne bénéficie pas des restrictions ConstrainedLanguage de l'outil officiel `pwsh`. Les outils de manipulation de fichiers de DSH (read/write/edit) restent soumis au bac à sable de fichiers. N'utilisez-le que dans des sessions de confiance ; pour un PowerShell protégé par le bac à sable, continuez d'utiliser l'outil officiel `pwsh`.
181
+
182
+ ## Limitations connues du terminal interactif (ConPTY)
183
+
184
+ - **PowerShell 5.1 ne peut pas démarrer dans un ConPTY** (0x8009001d) — pour un PowerShell interactif, installez [PowerShell 7](https://github.com/PowerShell/PowerShell/releases) (les commandes ponctuelles ne sont pas affectées).
185
+ - **Le mode interactif de wsl.exe peut déclencher une erreur RPC du service WSL sous ConPTY** (0x8007072c, intermittent) — les commandes ponctuelles `wsl -e bash -lc ...` fonctionnent normalement ; pour les sessions interactives, préférez Windows Terminal / un terminal WSL, ou réessayez.
186
+ - **node-pty n'accepte pas les signaux nommés sous Windows** : `SIGINT` de `signal` est traduit en Ctrl+C (`\x03`) ; les autres signaux (`SIGTERM` / `SIGKILL` / `SIGTSTP` / `SIGHUP`) se dégradent en simple terminaison de session.
187
+ - Les sessions interactives Git Bash fonctionnent parfaitement.
188
+
189
+ ## Limitations connues
190
+
191
+ - Les processus d'arrière-plan WSL peuvent subsister brièvement dans la distribution après un dépassement de délai ou une interruption (l'instance WSL s'éteint automatiquement après la sortie du dernier processus).
192
+ - Git Bash est un environnement msys2, avec des différences par rapport au comportement Linux de WSL (mappage des chemins, disponibilité des paquets).
193
+ - Le backend MSYS2 nécessite une installation locale de MSYS2 (`C:\msys64` par défaut) ; sans installation, `shell` signale `backend unavailable`, et `msys2Path` permet de préciser un emplacement personnalisé. L'ordre des candidats reste toujours `bash.exe` en priorité et `msys2.exe` en repli — avec un stdio en pipeline, `msys2.exe` renvoie silencieusement zéro octet et ne doit servir qu'en dernier recours.
194
+ - Ce plugin n'enregistre ses outils que sur la plateforme `win32`.
195
+
196
+ ## Tests
197
+
198
+ ```powershell
199
+ cd D:\workspace\projects\dsh-bash-terminal-ts
200
+ npm install # installer les dépendances (typescript inclus)
201
+ npm run build # compilation tsc de src/*.ts → lib/*.js ; client.tsx → lib/client.js + dist/client.js ; test/*.ts → test-dist/
202
+ npm test # node test-dist/unit.js → apply.js → client.js → terminal.js
203
+ ```
204
+
205
+ Le code source est en TypeScript (`strict` + `noUncheckedIndexedAccess`) ; les produits de compilation `lib/` et `dist/` sont commités avec le dépôt, et DSH se charge directement depuis `lib/index.js`, utilisable sans installation.
package/README.it.md ADDED
@@ -0,0 +1,205 @@
1
+ # dsh-bash-terminal-ts
2
+
3
+ > 🌐 [简体中文](README.md) | [English](README.en.md) | [Français](README.fr.md) | [Deutsch](README.de.md) | [Italiano](README.it.md) | [Русский](README.ru.md) | [Español](README.es.md) · Community: [LINUX DO](https://linux.do) · [GitHub](https://github.com/drscrewdriver/dsh-bash-terminal-ts)
4
+
5
+ ![test](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml/badge.svg)
6
+
7
+ Plugin DSH (DeepSeek Harness): uno strumento `shell` che esegue in modo unificato su Windows i comandi di **quattro** terminali — **PowerShell / Git Bash / MSYS2 / WSL**.
8
+
9
+ > **Questo repository è la riscrittura TypeScript di `MAXeaglet/dsh-bash-terminal`**, con supporto MSYS2/MINGW64 funzionante. Le linee di compatibilità sono ricavate per segmento di versione dell'host DSH; tutte le linee condividono il nome di pacchetto `dsh-bash-terminal-ts` e si distinguono tramite dist-tag npm:
10
+ >
11
+ > | Segmento DSH | Branch | Versione plugin | dist-tag npm |
12
+ > |--------|------|----------|--------------|
13
+ > | `>=0.2.0-rc.1 <0.2.1-0` | `compat/0.2.0` (questo branch) | 0.7.x | `dsh-0.2.0` |
14
+ > | 0.1.7-rc.1 – 0.1.7.x | `compat/0.1.7` | 0.6.x | `dsh-0.1.7` |
15
+ > | 0.1.5-alpha.1 – 0.1.5-rc.x | `ts/0.1.5` (storico, congelata) | ≤ 0.5.2 | `dsh-0.1.5` |
16
+ > | 0.1.2-alpha.1 – 0.1.2-rc.x | `main` (storico, congelata) | ≤ 0.4.2 | `dsh-0.1.2` |
17
+ >
18
+ > Scegli la linea corrispondente alla tua versione di DSH; le serie di versioni non si sovrappongono mai, quindi un'installazione con `^` non può risolvere da una linea all'altra.
19
+
20
+ | Backend | Esecuzione effettiva | Sintassi / percorsi | Variabili d'ambiente |
21
+ |------|----------|-------------|----------|
22
+ | `powershell` (predefinito) | `pwsh -NoLogo -NoProfile -NonInteractive -Command <cmd>` | PowerShell; `C:\...` | `$env:NAME` |
23
+ | `gitbash` | `bash -lc <cmd>` di Git for Windows | POSIX; `/d/workspace`; PATH con `/usr/bin` e `/mingw64/bin` | `$NAME` |
24
+ | `msys2` | `bash -lc <cmd>` di MSYS2 (`C:\msys64\usr\bin\bash.exe`) | POSIX; `/c/...`; PATH con `/usr/bin` e `/mingw64/bin` (gcc / make) | `$NAME` (injection automatica di `MSYSTEM=MINGW64`) |
25
+ | `wsl` | `wsl [-d <distro>] -e bash -lc <cmd>` | Linux; `/mnt/d/...` | `$NAME` (tramite WSLENV) |
26
+
27
+ Ogni chiamata avvia una shell completamente nuova: **nessuno stato viene conservato** (cwd / variabili / alias) — passa `workdir` invece di usare `cd`.
28
+
29
+ ## Anteprima dell'interfaccia
30
+
31
+ La riga «Terminale predefinito» in Impostazioni → Generali: l'utente sceglie tra PowerShell / Git Bash / MSYS2 / WSL e lo strumento `shell` esegue solo in base a questa impostazione, senza che il modello possa aggirarla:
32
+
33
+ ![Riga dell'impostazione del terminale predefinito](assets/shells.png)
34
+
35
+ ## Punti di progettazione
36
+
37
+ - **Il terminale lo decide l'utente, l'IA non può cambiarlo**: la pagina delle impostazioni della UI Web (Impostazioni → Generali) mostra un menu a discesa «Terminale predefinito» (PowerShell / Git Bash / MSYS2 / WSL); lo strumento `shell` usa sempre e solo quell'impostazione e non espone alcun parametro di terminale al modello. L'impostazione viene persistita tramite il sistema di settings di DSH (settings.yaml).
38
+ - **Non occupa la giunzione di capacità `ctx.shell`**: lo strumento `pwsh` sandboxato fornito con DSH resta utilizzabile così com'è; lo strumento `shell` di questo plugin è un **ulteriore** punto d'ingresso multi-terminale.
39
+ - I processi vengono avviati tramite la seam condivisa `ctx.subprocess`: terminazione dell'albero di processi (su Windows `taskkill /T`), SIGTERM → grazia → SIGKILL, file di spill dell'output — comportamento identico a quello degli strumenti ufficiali `dsh-tool-bash` / `dsh-tool-pwsh`.
40
+ - I lavori in background vengono registrati nel registro generico `jobs`, con supporto per `run_in_background` / `job_output` / `job_kill`.
41
+ - La riga «Terminale predefinito» della pagina delle impostazioni del frontend è un enumerazione (renderizzata automaticamente come menu a discesa dalla UI); a ogni chiamata il modello esegue solo in base a quell'impostazione e non può cambiare terminale per conto proprio.
42
+
43
+ ## Installazione (profilo web)
44
+
45
+ ### Installazione standard (dopo la pubblicazione npm, meccanismo ufficiale di bundle)
46
+
47
+ Il plugin include il manifest ufficiale `dsh.bundle` (`cordis.patch.yml` nel pacchetto); appena un profilo elenca questo pacchetto, DSH **applica automaticamente il mount**, senza dover modificare a mano la configurazione del profilo:
48
+
49
+ ```powershell
50
+ # 1. Installare il pacchetto del plugin
51
+ npm install -g dsh-bash-terminal-ts
52
+ dsh plugin --profile web add dsh-bash-terminal-ts # aggiunto automaticamente ai bundle del profilo e patch applicata
53
+
54
+ # 2. Patch della allowlist delle impostazioni DSH (limitazione DSH, vedi spiegazione sotto)
55
+ powershell -ExecutionPolicy Bypass -File install.ps1 install
56
+
57
+ # 3. Riavviare dsh web
58
+ ```
59
+
60
+ > Verificato nella pratica con un profilo temporaneo: `bundles: [dsh-bash-terminal-ts]` → la voce `tool-bash-terminal` compare automaticamente nel dump-config.
61
+
62
+ ### Installazione per lo sviluppo locale (junction, le modifiche al sorgente hanno effetto immediato)
63
+
64
+ ```powershell
65
+ # 1. Collegare il pacchetto del plugin ai node_modules del profilo (junction, le modifiche al sorgente hanno effetto immediato)
66
+ $profile = "$env:USERPROFILE\.dsh\profiles\web"
67
+ New-Item -ItemType Junction -Path "$profile\node_modules\dsh-bash-terminal-ts" -Target "D:\workspace\projects\dsh-bash-terminal-ts" | Out-Null
68
+
69
+ # 2. Consentire al plugin di risolvere le dipendenze @deepseek-ai/* (junction verso l'albero delle dipendenze del profilo; plugin e host condividono le stesse istanze dei moduli)
70
+ New-Item -ItemType Junction -Path "D:\workspace\projects\dsh-bash-terminal-ts\node_modules\@deepseek-ai" -Target "$profile\..\node_modules\@deepseek-ai" | Out-Null
71
+
72
+ # 3. Far montare il plugin al profilo tramite il bundle ufficiale (install.ps1 install lo fa automaticamente; equivale ad aggiungere "dsh-bash-terminal-ts" a dsh.profile.bundles)
73
+ # 4. (solo dopo modifiche al codice del frontend) ricompilare il bundle client:
74
+ # cd D:\workspace\projects\dsh-bash-terminal-ts && node scripts/build-client.mjs
75
+ # 5. Riavviare dsh web
76
+ ```
77
+
78
+ > ⚠️ **Non eseguire `npm install` in questo progetto**: cancellerebbe la junction del punto 2 qui sopra e installerebbe per il plugin una copia **indipendente** di
79
+ > `@deepseek-ai/*` — plugin e host smetterebbero così di condividere le istanze dei moduli e, dopo un aggiornamento dell'host, il plugin resterebbe bloccato sulla vecchia API
80
+ > (questo progetto rimase così bloccato su 0.1.0-rc.6). Per aggiornare solo il lock usare `npm install --package-lock-only`.
81
+
82
+ > **Compatibilità**: richiede DSH ≥ **0.1.7-rc.1** (linea `compat/0.1.7`) oppure ≥ **0.2.0-rc.1** (linea `compat/0.2.0`, questo branch).
83
+ > Contesto storico: in 0.1.5 `@deepseek-ai/dsh-client-runtime` nella tabella dei moduli client è stato rinominato `@deepseek-ai/dsh-client-store` e viene risolto solo con corrispondenza esatta del nome nudo; i bundle vecchi sull'host nuovo falliscono con
84
+ > `Failed to load plugins` / `require(...) missed the module table`.
85
+ >
86
+ > Inoltre: dal 0.1.5 la superficie delle impostazioni Web usa l'enumerazione dinamica `settings.describe()` e **non ha più una allowlist di namespace**
87
+ > (`settings-not-exposed` non esiste più); la patch della allowlist presente in `install.ps1` è solo un relitto storico e può essere ignorata.
88
+
89
+ > Non serve più modificare manualmente il `cordis.patch.yml` del profilo: il pacchetto del plugin include il suo `dsh.bundle.patch` (`cordis.patch.yml` nel pacchetto); basta che `dsh-bash-terminal-ts` figurì nel `dsh.profile.bundles` del profilo perché DSH monti automaticamente il plugin.
90
+
91
+ Verificare l'albero combinato (senza riavvio):
92
+
93
+ ```powershell
94
+ node "$env:APPDATA\nvm\<node-version>\node_modules\@deepseek-ai\dsh\lib\bin.js" --profile web --dump-config | Select-String dsh-bash-terminal-ts
95
+ ```
96
+
97
+ ## Uso
98
+
99
+ **L'utente imposta il terminale predefinito nella UI Web**: apri le impostazioni (ingranaggio) → Generali → menu a discesa «Terminale predefinito» e scegli uno tra PowerShell / Git Bash / MSYS2 / WSL. La modifica ha effetto immediato e viene persistita.
100
+
101
+ Quando il modello vede lo strumento `shell`, esegue automaticamente con il terminale che hai scelto (lo strumento non espone parametri di terminale; il modello non può cambiare la tua scelta):
102
+
103
+ - Terminale predefinito = Git Bash: `shell(command: "git status")` passa per Git Bash
104
+ - Terminale predefinito = MSYS2: `shell(command: "gcc --version")` passa per MSYS2 (ambiente MINGW64, gcc e make di `/mingw64/bin` disponibili)
105
+ - Terminale predefinito = WSL: `shell(command: "ls -la /mnt/d/workspace")` passa per WSL; con `distro: "Ubuntu"` si può indicare la distribuzione
106
+ - Terminale predefinito = PowerShell: `shell(command: "Get-Process node")` passa per PowerShell
107
+
108
+ ## Esempi di utilizzo per il modello
109
+
110
+ - Comando una tantum (terminale predefinito): `shell(command: "git status", description: "controllare lo stato git")`
111
+ - Stato preservato tra i turni (interattivo): `terminal(action: "open")` → annotare il `sessionId` → `terminal(action: "send", sessionId, input: "cd /d/project\n")` → `terminal(action: "send", sessionId, input: "npm run dev\n")` → `terminal(action: "close", sessionId)`
112
+ - Interrompere un programma in esecuzione: `terminal(action: "signal", sessionId, signal: "SIGINT")`
113
+ - Consultare le sessioni attive: `terminal(action: "list")`
114
+ - Escalation dopo un rifiuto della sandbox: `shell(command: ..., sandbox_permissions: "workspace-write", justification: "...")`
115
+
116
+ ## Configurazione
117
+
118
+ **Impostazioni della UI Web** (consigliato): Impostazioni → Generali → «Terminale predefinito».
119
+
120
+ Il `config` della riga del plugin (sovrascrive i predefiniti e funge da base di composizione per le impostazioni):
121
+
122
+ | Chiave | Predefinito | Descrizione |
123
+ |----|------|------|
124
+ | `defaultShell` | `powershell` | Backend usato quando le impostazioni non sovrascrivono |
125
+ | `timeoutMs` | 120000 | Timeout predefinito |
126
+ | `maxTimeoutMs` | 600000 | Limite superiore del timeoutMs del chiamante |
127
+ | `pwshPath` | rilevamento automatico | Percorso fisso di pwsh.exe |
128
+ | `gitBashPath` | rilevamento automatico | Percorso fisso di git bash.exe |
129
+ | `msys2Path` | rilevamento automatico (prima `C:\msys64\usr\bin\bash.exe`, ripiego su `msys2.exe`) | Percorso fisso di MSYS2 bash.exe |
130
+ | `wslPath` | rilevamento automatico | Percorso fisso di wsl.exe |
131
+
132
+ ## Pubblicazione (npm)
133
+
134
+ L'account npm ha la verifica 2FA attiva per la pubblicazione; serve un codice monouso:
135
+
136
+ ```powershell
137
+ cd D:\workspace\projects\dsh-bash-terminal-ts
138
+ npm publish --otp <codice> # il codice arriva dal tuo autenticatore
139
+ ```
140
+
141
+ Prima di pubblicare, fai un `npm pack --dry-run` per controllare il contenuto e lancia `npm run build` per ricompilare tutto (compilazione server tsc + bundle client + compilazione dei test).
142
+
143
+ ## Disinstallazione
144
+
145
+ Basta eseguire:
146
+
147
+ ```powershell
148
+ powershell -ExecutionPolicy Bypass -File install.ps1 uninstall
149
+ ```
150
+
151
+ Il comando rimuove le junction, ripristina la allowlist delle impostazioni, ripulisce i blocchi di mount `cordis.patch.yml` lasciati dalle versioni precedenti e rimuove `dsh-bash-terminal-ts` dal `dsh.profile.bundles`. Poi riavvia dsh web.
152
+
153
+ In caso di disinstallazione manuale, oltre a eliminare `node_modules\dsh-bash-terminal-ts`, ricorda anche di rimuovere `dsh-bash-terminal-ts` dal `dsh.profile.bundles` del `package.json` del profilo.
154
+
155
+ ## Terminale interattivo (strumento `terminal`)
156
+
157
+ Lo strumento `terminal` offre **sessioni interattive persistenti** sulla seam PTY (node-pty; su Windows `lib/terminal.js` si collega direttamente a node-pty perché il process inspector del `spawnTerminal` upstream supporta solo POSIX; fuori da Windows si continua a usare il `ctx.subprocess.spawnTerminal` ufficiale):
158
+
159
+ - `action: open` avvia una vera sessione di terminale (secondo il tuo terminale predefinito impostato; per wsl si può indicare `distro`) e restituisce un `sessionId`
160
+ - `action: send` scrive l'input e legge il nuovo output; `action: read` legge senza scrivere; `action: signal` invia un segnale al gruppo di processi in primo piano (SIGINT = Ctrl+C)
161
+ - `action: close` termina la sessione
162
+ - **Lo stato della sessione si preserva tra le chiamate** (cwd / variabili / alias), ideale per REPL, ssh e CLI interattive
163
+ - `send` attende che l'output si stabilizzi (300 ms di silenzio, tetto 5 s) e restituisce la **risposta completa**; oltre 1 MB di output viene emesso l'avviso `truncated`
164
+ - L'input termina con `\\n` (o \\r) per rappresentare il tasto Invio
165
+
166
+ ## Sandbox (integrazione con il meccanismo ufficiale)
167
+
168
+ Lo strumento `shell` passa per la seam ufficiale della sandbox di DSH (`ctx.sandboxPolicy` + `ctx.sandbox`):
169
+
170
+ - A ogni chiamata viene risolta la politica sandbox corrente; le sessioni `danger-full-access` vengono eseguite direttamente (senza incapsulamento).
171
+ - Il backend PowerShell incapsula argv tramite `ctx.sandbox.confine` — semantica **fail-closed** identica a quella degli executor ufficiali: se viene richiesto il modo ristretto ma non c'è un backend disponibile, viene sollevata una `SandboxUnavailableError`, rifiutando l'esecuzione nuda.
172
+ - Il backend Git Bash non viene incapsulato: il runner a token ristretto ACL Windows di DSH è incompatibile con Cygwin/MSYS2 (bash abortisce all'avvio con l'errore Win32 5 di `CreateFileMapping`); quindi Git Bash gira anche in modo ristretto senza incapsulamento sandbox; il risultato riporta `enforcement: gitbash-unconfined`.
173
+ - Il backend MSYS2 non viene incapsulato nemmeno lui (stessa incompatibilità di runtime Cygwin/MSYS2); il risultato riporta `enforcement: msys2-unconfined`.
174
+ - Il backend WSL non viene incapsulato: la VM Linux indipendente di WSL è di per sé l'isolamento (il risultato riporta `enforcement: wsl-isolation`).
175
+ - Quando la sandbox rifiuta in modo ristretto, il risultato porta il marker ufficiale `[sandbox: file access denied under <mode> mode]` e il suggerimento di escalation nello stesso turno; il modello può avviare un'escalation con `sandbox_permissions` + `justification` (approvazione dell'utente tramite `ctx.approval`), esattamente come gli strumenti ufficiali bash/pwsh.
176
+ - Nota: quando il runner ACL Windows di DSH è disponibile, il modo ristretto di PowerShell viene incapsulato tramite esso; Git Bash e MSYS2 restano non incapsulati per l'incompatibilità Cygwin/MSYS2.
177
+
178
+ ## ⚠️ Note sulla sicurezza
179
+
180
+ Lo strumento `shell` in modo ristretto: PowerShell viene incapsulato tramite `ctx.sandbox.confine` (fail-closed); Git Bash e MSYS2 **non vengono incapsulati** per l'incompatibilità tra Cygwin/MSYS2 e i token ristretti ACL Windows (stessi privilegi del processo dsh); WSL non viene incapsulato grazie alla sua VM Linux indipendente. È un **ulteriore punto d'ingresso multi-terminale** e non gode delle restrizioni ConstrainedLanguage dello strumento ufficiale `pwsh`. Gli strumenti di manipolazione dei file di DSH (read/write/edit) restano vincolati dalla sandbox dei file. Usalo solo in sessioni di cui ti fidi; per un PowerShell protetto dalla sandbox continua a usare lo strumento ufficiale `pwsh`.
181
+
182
+ ## Limitazioni note del terminale interattivo (ConPTY)
183
+
184
+ - **PowerShell 5.1 non può avviarsi in un ConPTY** (0x8009001d) — per il PowerShell interattivo installa [PowerShell 7](https://github.com/PowerShell/PowerShell/releases) (i comandi una tantum non sono interessati).
185
+ - **La modalità interattiva di wsl.exe può innescare un errore RPC del servizio WSL sotto ConPTY** (0x8007072c, intermittente) — i comandi una tantum `wsl -e bash -lc ...` funzionano regolarmente; per le sessioni interattive conviene usare direttamente Windows Terminal / un terminale WSL, oppure riprovare.
186
+ - **node-pty non accetta segnali nominati su Windows**: `SIGINT` di `signal` viene mappato su Ctrl+C (`\x03`); gli altri segnali (`SIGTERM` / `SIGKILL` / `SIGTSTP` / `SIGHUP`) degenerano nella terminazione della sessione.
187
+ - Le sessioni interattive Git Bash funzionano pienamente.
188
+
189
+ ## Limitazioni note
190
+
191
+ - I processi in background WSL possono sopravvivere brevemente nella distribuzione dopo un timeout/interruzione (l'istanza WSL si spegne automaticamente dopo l'uscita dell'ultimo processo).
192
+ - Git Bash è un ambiente msys2, con differenze rispetto al comportamento Linux di WSL (mapping dei percorsi, disponibilità dei pacchetti).
193
+ - Il backend MSYS2 richiede MSYS2 installato in locale (predefinito `C:\msys64`); senza installazione `shell` segnala `backend unavailable`, e con `msys2Path` si può indicare un percorso personalizzato. L'ordine dei candidati resta sempre `bash.exe` primo e `msys2.exe` come ripiego — con stdio tramite pipe `msys2.exe` restituisce silenziosamente zero byte e va usato solo come ultima spiaggia.
194
+ - Questo plugin registra i suoi strumenti solo sulla piattaforma `win32`.
195
+
196
+ ## Test
197
+
198
+ ```powershell
199
+ cd D:\workspace\projects\dsh-bash-terminal-ts
200
+ npm install # installare le dipendenze (typescript compreso)
201
+ npm run build # compilazione tsc di src/*.ts → lib/*.js; client.tsx → lib/client.js + dist/client.js; test/*.ts → test-dist/
202
+ npm test # node test-dist/unit.js → apply.js → client.js → terminal.js
203
+ ```
204
+
205
+ Il sorgente è TypeScript (`strict` + `noUncheckedIndexedAccess`); gli artefatti di compilazione `lib/` e `dist/` vengono committati nel repository e DSH carica direttamente `lib/index.js`, pronto all'uso senza installazione.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dsh-bash-terminal-ts
2
2
 
3
- > 🌐 [English](README.en.md) · 社区交流:[LINUX DO](https://linux.do) · [GitHub](https://github.com/drscrewdriver/dsh-bash-terminal-ts)
3
+ > 🌐 [简体中文](README.md) | [English](README.en.md) | [Français](README.fr.md) | [Deutsch](README.de.md) | [Italiano](README.it.md) | [Русский](README.ru.md) | [Español](README.es.md) · 社区交流:[LINUX DO](https://linux.do) · [GitHub](https://github.com/drscrewdriver/dsh-bash-terminal-ts)
4
4
 
5
5
  ![test](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml/badge.svg)
6
6
 
@@ -59,6 +59,24 @@ powershell -ExecutionPolicy Bypass -File install.ps1 install
59
59
 
60
60
  > 已用临时 profile 实测:`bundles: [dsh-bash-terminal-ts]` → dump-config 自动出现 `tool-bash-terminal` entry。
61
61
 
62
+ ### pnpm 用户须知:node-pty 构建脚本放行
63
+
64
+ 本插件依赖原生 PTY 库 [`node-pty`](https://www.npmjs.com/package/node-pty)(微软维护,VS Code 同款)实现交互终端。**自 0.7.1 起钉在 `1.2.0-beta.15`**(与 DSH 宿主两条版本线同版):该线 tarball 自带全平台预编译产物,pnpm 10+ 即使拦截安装脚本,运行时加载器也会兜底从 `prebuilds/<platform>-<arch>/` 加载,**不编译即可运行**。`pnpm add` 末尾的下述提示只是告知脚本被跳过,放行一次即可消除:
65
+
66
+ ```text
67
+ Error: ERR_PNPM_IGNORED_BUILDS
68
+ Ignored build scripts: node-pty@1.2.0-beta.15
69
+ ```
70
+
71
+ ```powershell
72
+ pnpm approve-builds # 交互式勾选 node-pty
73
+ # 或在 profile 的 package.json 声明后重建:
74
+ # "pnpm": { "onlyBuiltDependencies": ["node-pty"] }
75
+ pnpm rebuild node-pty
76
+ ```
77
+
78
+ > 自有 dsh 插件中**仅本插件**带原生依赖;其余 0.2.0 线插件(search-index、session-steward、patch-edit-plus、browser-cdp、date-wrapper)与 live-token-stats 均为纯 JS 包,pnpm 直接安装即可,无需放行。
79
+
62
80
  ### 本地开发安装(junction 直连,改源码即时生效)
63
81
 
64
82
  ```powershell