dsh-gitbash-shell 0.16.1 → 0.17.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.md +11 -3
- package/README_EN.md +11 -2
- package/dsh.plugin.json +1 -1
- package/package.json +1 -1
- package/src/client.js +21 -21
- package/src/index.js +258 -31
package/README.md
CHANGED
|
@@ -157,10 +157,18 @@ PTC/创造及用户自建模式一律覆盖。
|
|
|
157
157
|
- **提示词源头替换**:组装期(`system-prompt/assemble`)把官方提示词 sections / contexts /
|
|
158
158
|
variables 里的 Windows 绝对路径**原位**改写成 `/c/...`——不增删任何内容、不动工具 schema;
|
|
159
159
|
- **一句话指示**:经 `systemPrompt.context`(order 126)注入全局指示——shell 是 Git for
|
|
160
|
-
Windows bash,路径用 MSYS
|
|
161
|
-
|
|
160
|
+
Windows bash,路径用 MSYS 盘根,所有工具都直接接受这种写法——含 `~`、`/tmp`、`/dev/null`、
|
|
161
|
+
`/usr` 等 bash 原生习惯(v0.17.0 起与 Git Bash 挂载表一致地解析);
|
|
162
|
+
- **参数翻译**:`tools/execute` 上把工具的路径参数(`file_path` / `path` / `workdir`,含 present
|
|
163
|
+
的嵌套 `files[].path`)由 `/c/...` 翻回 `C:/...` 交给 Node 文件工具;bash 的 `command` 字段
|
|
164
|
+
不动——那是 Git Bash 母语;**bash 虚拟路径按 Git Bash 挂载表解析(v0.17.0)**:`/tmp` → 用户
|
|
165
|
+
TEMP、`/dev/null` → Windows NUL 空设备、`~` → 家目录、`/usr` `/bin` `/etc` 等 → Git 安装根,
|
|
166
|
+
与 bash 写入/读取同一物理位置;glob 的绝对 pattern(`/c/.../*.md`)自动拆成 `path` + 相对
|
|
167
|
+
`pattern`(原先静默匹配空);
|
|
162
168
|
`/c/...` 翻回 `C:/...` 交给 Node 文件工具;bash 的 `command` 字段不动——那是 Git Bash 母语;
|
|
163
|
-
- **结果回流**:成功结果里的路径元数据(`read`/`write`/`edit` 的 `path`、`glob` 的
|
|
169
|
+
- **结果回流**:成功结果里的路径元数据(`read`/`read_image`/`write`/`edit` 的 `path`、`glob` 的
|
|
170
|
+
`paths[]`、`grep` 的 `matches[].path`、`present` 的 `files[].path`)改写回 MSYS 形式,其中落在
|
|
171
|
+
用户 TEMP 下的路径回显为 `/tmp/...`(与 bash 的 `$TMP` 一致);文件内容与错误结果不动;
|
|
164
172
|
`grep` 的 `matches[].path`)改写回 MSYS 形式;文件内容与错误结果不动;
|
|
165
173
|
- **运行时事实**:向官方 `dsh-shell-env` 注册表贡献 `DSH_PATH_DIALECT=msys`,模型可在执行时
|
|
166
174
|
核验(随开关实时生效)。
|
package/README_EN.md
CHANGED
|
@@ -99,11 +99,20 @@ While it is on (Windows only), `posixPaths` gates all of the following:
|
|
|
99
99
|
/c/... form — nothing is added or removed, and tool schemas stay untouched;
|
|
100
100
|
- **One-sentence directive**: a global directive via `systemPrompt.context` (order 126) — the
|
|
101
101
|
shell is Git for Windows bash, paths use MSYS drive roots, and every tool accepts that form
|
|
102
|
+
directly — including the bash-native habits (`~`, `/tmp`, `/dev/null`, `/usr`), which resolve
|
|
103
|
+
exactly as bash itself resolves them (v0.17.0, mirroring the Git Bash mount table);
|
|
102
104
|
directly;
|
|
103
|
-
- **Argument translation**: on `tools/execute` the
|
|
105
|
+
- **Argument translation**: on `tools/execute` the tools' path arguments (`file_path` / `path` /
|
|
106
|
+
`workdir`, plus present's nested `files[].path`) are translated from /c/... back to C:/... for
|
|
107
|
+
the Node-backed file tools; a bash command's `command` field is left alone — that is Git Bash's
|
|
108
|
+
native form; **bash virtual paths resolve through the Git Bash mount table (v0.17.0)**: /tmp is
|
|
109
|
+
the user TEMP dir, /dev/null the Windows NUL device, ~ the home directory, and /usr /bin /etc
|
|
110
|
+
live under the Git install root — the same physical locations bash itself reads and writes; an
|
|
111
|
+
absolute glob pattern (/c/.../*.md) is split into `path` + a relative `pattern` (it used to
|
|
112
|
+
silently match nothing);
|
|
104
113
|
`path` / `workdir`) are translated from /c/... back to C:/... for the Node-backed file tools;
|
|
105
114
|
a bash command's `command` field is left alone — that is Git Bash's native form;
|
|
106
|
-
- **Result round-trip**: path metadata in successful results (`path` of read/write/edit,
|
|
115
|
+
- **Result round-trip**: path metadata in successful results (`path` of read/read_image/write/edit,
|
|
107
116
|
`paths[]` of glob, `matches[].path` of grep) flows back in the MSYS form; file contents and
|
|
108
117
|
error results are untouched;
|
|
109
118
|
- **Runtime fact**: `DSH_PATH_DIALECT=msys` is contributed to the official `dsh-shell-env`
|
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-external/dsh-gitbash-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"description": "Windows 全模式 Git Bash:用 Git for Windows bash 替换 PowerShell 执行器,并物化 standard/minimal/code/cordis 的 Git Bash 变体 preset。双 era 适配 dsh <= 0.1.1(内置 id 'code')与 >= 0.1.2(改名 'ptc'),启动探测自动选择,preset id 永不变。联动:dsh-ptc-cordis-preset(两者同装时 PTC 创造模式自动物化为 Git Bash 版)+ dsh-better-sidebar(终端 UI 标签与模型 terminal_* 工具自动切到 Git Bash)。",
|
|
6
6
|
"engines": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-gitbash-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "Windows 上让 agent 的每条 shell 命令改经 Git for Windows bash 执行;物化四个内置预设的 Git Bash 变体,统一 MSYS 盘根路径方言,侧栏终端接管可开关。· Run every agent shell command through Git for Windows bash on Windows; materialize Git Bash variants of the built-in presets, unify the MSYS drive-root path dialect, and adopt the sidebar terminal behind a switch.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
package/src/client.js
CHANGED
|
@@ -62,7 +62,7 @@ window.__ModuleLoader__.load({
|
|
|
62
62
|
"switch.on": "启用",
|
|
63
63
|
"switch.off": "停用",
|
|
64
64
|
"error": "写入失败",
|
|
65
|
-
"hint": "启用后:所有工具(bash 命令与 workdir、read/write/edit/read_image/glob/grep 的路径参数)统一使用 MSYS 盘根 POSIX 路径(/c/Users/...)
|
|
65
|
+
"hint": "启用后:所有工具(bash 命令与 workdir、read/write/edit/read_image/glob/grep 与 present 的路径参数)统一使用 MSYS 盘根 POSIX 路径(/c/Users/...);bash 的原生习惯——~ 家目录、/tmp 临时目录、/dev/null、/usr 等——在所有工具中同样有效(与 Git Bash 挂载表一致),路径参数由宿主自动翻译,模型无感。停用后恢复 dsh 原生行为(文件工具用 Windows 路径)。bash 始终是 Git Bash,不受此开关影响。",
|
|
66
66
|
"adopt.label": "接管侧栏终端",
|
|
67
67
|
"adopt.hint": "开启时把 dsh-better-sidebar 的终端 shell 写成 Git Bash(默认开启);关闭后恢复接管前的值,已手动改过的终端设置不会被碰。模型侧的 bash 工具不受此开关影响——那由插件本体提供。",
|
|
68
68
|
};
|
|
@@ -76,7 +76,7 @@ window.__ModuleLoader__.load({
|
|
|
76
76
|
"switch.on": "Enable",
|
|
77
77
|
"switch.off": "Disable",
|
|
78
78
|
"error": "write failed",
|
|
79
|
-
"hint": "Enabled: every tool (bash commands and workdir, read/write/edit/read_image/glob/grep path arguments) uses MSYS drive-root POSIX paths (/c/Users/...); the
|
|
79
|
+
"hint": "Enabled: every tool (bash commands and workdir, read/write/edit/read_image/glob/grep and present path arguments) uses MSYS drive-root POSIX paths (/c/Users/...); bash-native habits — the ~ home shorthand, /tmp, /dev/null, /usr — resolve in every tool exactly as bash itself resolves them, and the host translates the path fields automatically. Disabled restores dsh-native behavior (Windows paths for file tools). Bash is always Git Bash while the plugin is installed; this switch only governs the cross-tool path dialect.",
|
|
80
80
|
"adopt.label": "Adopt sidebar terminal",
|
|
81
81
|
"adopt.hint": "On (default) writes Git Bash into dsh-better-sidebar's terminal shell; turning it off restores the pre-adoption value and never touches a manually chosen one. The model-side bash tool is unaffected — the plugin itself provides that.",
|
|
82
82
|
};
|
|
@@ -100,7 +100,7 @@ window.__ModuleLoader__.load({
|
|
|
100
100
|
"switch.on": "تفعيل",
|
|
101
101
|
"switch.off": "تعطيل",
|
|
102
102
|
"error": "فشل الكتابة",
|
|
103
|
-
"hint": "عند التفعيل: تستخدم كل الأدوات (أوامر bash و workdir، ومعاملات المسار في read/write/edit/read_image/glob/grep) مسارات POSIX من جذر قرص MSYS (/c/Users/...)؛ ويتولّى المضيف ترجمة حقول المسار
|
|
103
|
+
"hint": "عند التفعيل: تستخدم كل الأدوات (أوامر bash و workdir، ومعاملات المسار في read/write/edit/read_image/glob/grep و present) مسارات POSIX من جذر قرص MSYS (/c/Users/...)؛ وعادات bash الأصلية — ~ للمجلد الرئيسي و /tmp و /dev/null و /usr — تعمل في كل أداة تمامًا كما تحلّها bash نفسها، ويتولّى المضيف ترجمة حقول المسار تلقائيًا. عند التعطيل يعود السلوك الأصلي لـ dsh (مسارات Windows لأدوات الملفات). يبقى bash دائمًا Git Bash ما دامت الإضافة مثبَّتة؛ هذا المفتاح لا يحكم سوى لهجة المسارات بين الأدوات.",
|
|
104
104
|
"adopt.label": "تبنّي طرفية الشريط الجانبي",
|
|
105
105
|
"adopt.hint": "عند التفعيل (افتراضي) تُكتب Git Bash كـ shell لطرفية dsh-better-sidebar؛ وعند التعطيل تُستعاد القيمة السابقة ولا تُلمس القيمة المختارة يدويًا أبدًا. أداة bash الخاصة بالنموذج لا تتأثر — الإضافة نفسها توفرها.",
|
|
106
106
|
},
|
|
@@ -114,7 +114,7 @@ window.__ModuleLoader__.load({
|
|
|
114
114
|
"switch.on": "Aktivieren",
|
|
115
115
|
"switch.off": "Deaktivieren",
|
|
116
116
|
"error": "Schreiben fehlgeschlagen",
|
|
117
|
-
"hint": "Aktiviert: Alle Tools (bash-Befehle und workdir sowie Pfadargumente von read/write/edit/read_image/glob/grep) verwenden POSIX-Pfade ab der MSYS-Laufwerkswurzel (/c/Users/...); der Host übersetzt die Pfadfelder
|
|
117
|
+
"hint": "Aktiviert: Alle Tools (bash-Befehle und workdir sowie Pfadargumente von read/write/edit/read_image/glob/grep und present) verwenden POSIX-Pfade ab der MSYS-Laufwerkswurzel (/c/Users/...); bash-eigene Gewohnheiten — ~ für das Home-Verzeichnis, /tmp, /dev/null, /usr — funktionieren in jedem Tool genau so, wie bash sie selbst auflöst, und der Host übersetzt die Pfadfelder automatisch. Deaktiviert stellt das dsh-native Verhalten wieder her (Windows-Pfade für Dateitools). Bash ist bei installiertem Plugin immer Git Bash; dieser Schalter steuert nur den Pfaddialekt zwischen den Tools.",
|
|
118
118
|
"adopt.label": "Sidebar-Terminal übernehmen",
|
|
119
119
|
"adopt.hint": "Ein (Standard) schreibt Git Bash als Shell des dsh-better-sidebar-Terminals; Aus stellt den vorherigen Wert wieder her und fasst nie eine manuell gewählte Einstellung an. Das bash-Werkzeug des Modells bleibt unberührt — das liefert das Plugin selbst.",
|
|
120
120
|
},
|
|
@@ -128,7 +128,7 @@ window.__ModuleLoader__.load({
|
|
|
128
128
|
"switch.on": "Activer",
|
|
129
129
|
"switch.off": "Désactiver",
|
|
130
130
|
"error": "échec de l'écriture",
|
|
131
|
-
"hint": "Activé : tous les outils (commandes bash et workdir, arguments de chemin de read/write/edit/read_image/glob/grep) utilisent des chemins POSIX à racine de lecteur MSYS (/c/Users/...) ; l'hôte traduit
|
|
131
|
+
"hint": "Activé : tous les outils (commandes bash et workdir, arguments de chemin de read/write/edit/read_image/glob/grep et de present) utilisent des chemins POSIX à racine de lecteur MSYS (/c/Users/...) ; les habitudes natives de bash — ~ pour le dossier personnel, /tmp, /dev/null, /usr — fonctionnent dans chaque outil exactement comme bash les résout lui-même, et l'hôte traduit les champs de chemin automatiquement. Désactivé rétablit le comportement natif de dsh (chemins Windows pour les outils de fichiers). Bash reste toujours Git Bash tant que le plugin est installé ; ce commutateur ne régit que le dialecte de chemins entre outils.",
|
|
132
132
|
"adopt.label": "Adopter le terminal latéral",
|
|
133
133
|
"adopt.hint": "Activé (par défaut) : écrit Git Bash comme shell du terminal dsh-better-sidebar ; désactivé : restaure la valeur davant et ne touche jamais un choix manuel. Loutil bash du modèle nest pas concerné — le plugin le fournit lui-même.",
|
|
134
134
|
},
|
|
@@ -142,7 +142,7 @@ window.__ModuleLoader__.load({
|
|
|
142
142
|
"switch.on": "सक्षम करें",
|
|
143
143
|
"switch.off": "अक्षम करें",
|
|
144
144
|
"error": "लिखना विफल रहा",
|
|
145
|
-
"hint": "सक्षम होने पर: सभी टूल (bash कमांड और workdir, तथा read/write/edit/read_image/glob/grep के पथ तर्क) MSYS ड्राइव-रूट POSIX पथ (/c/Users/...) का उपयोग करते हैं;
|
|
145
|
+
"hint": "सक्षम होने पर: सभी टूल (bash कमांड और workdir, तथा read/write/edit/read_image/glob/grep और present के पथ तर्क) MSYS ड्राइव-रूट POSIX पथ (/c/Users/...) का उपयोग करते हैं; bash की मूल आदतें — होम के लिए ~, /tmp, /dev/null, /usr — हर टूल में ठीक वैसे काम करती हैं जैसे bash स्वयं उन्हें हल करता है, और होस्ट पथ फ़ील्ड स्वतः अनुवादित करता है। अक्षम करने पर dsh का मूल व्यवहार बहाल होता है (फ़ाइल टूल के लिए Windows पथ)। जब तक प्लगइन इंस्टॉल है bash हमेशा Git Bash रहता है; यह स्विच केवल टूल के बीच पथ शैली नियंत्रित करता है।",
|
|
146
146
|
"adopt.label": "साइडबार टर्मिनल अपनाएँ",
|
|
147
147
|
"adopt.hint": "चालू (डिफ़ॉल्ट) होने पर dsh-better-sidebar के टर्मिनल में Git Bash लिखा जाता है; बंद करने पर पहले वाली मान बहाल होती है और मैन्युअल चुनी गई सेटिंग कभी नहीं छुई जाती। मॉडल का bash टूल अप्रभावित रहता है — वह प्लगइन स्वयं देता है।",
|
|
148
148
|
},
|
|
@@ -156,7 +156,7 @@ window.__ModuleLoader__.load({
|
|
|
156
156
|
"switch.on": "Aktifkan",
|
|
157
157
|
"switch.off": "Nonaktifkan",
|
|
158
158
|
"error": "gagal menulis",
|
|
159
|
-
"hint": "Saat aktif: semua alat (perintah bash dan workdir, serta argumen path read/write/edit/read_image/glob/grep) memakai path POSIX berakar drive MSYS (/c/Users/...);
|
|
159
|
+
"hint": "Saat aktif: semua alat (perintah bash dan workdir, serta argumen path read/write/edit/read_image/glob/grep dan present) memakai path POSIX berakar drive MSYS (/c/Users/...); kebiasaan asli bash — ~ untuk direktori home, /tmp, /dev/null, /usr — bekerja di setiap alat persis seperti bash sendiri menyelesaikannya, dan host menerjemahkan bidang path secara otomatis. Saat nonaktif, perilaku asli dsh dipulihkan (path Windows untuk alat berkas). Bash selalu Git Bash selama plugin terpasang; sakelar ini hanya mengatur dialek path antaralat.",
|
|
160
160
|
"adopt.label": "Adopsi terminal sidebar",
|
|
161
161
|
"adopt.hint": "Nyala (bawaan) menulis Git Bash sebagai shell terminal dsh-better-sidebar; dimatikan memulihkan nilai sebelumnya dan tidak pernah menyentuh pilihan manual. Alat bash sisi model tak terpengaruh — plugin sendiri yang menyediakannya.",
|
|
162
162
|
},
|
|
@@ -170,7 +170,7 @@ window.__ModuleLoader__.load({
|
|
|
170
170
|
"switch.on": "Attiva",
|
|
171
171
|
"switch.off": "Disattiva",
|
|
172
172
|
"error": "scrittura non riuscita",
|
|
173
|
-
"hint": "Attivato: tutti gli strumenti (comandi bash e workdir, argomenti di percorso di read/write/edit/read_image/glob/grep) usano percorsi POSIX con radice di unità MSYS (/c/Users/...); l'host traduce automaticamente i campi di percorso
|
|
173
|
+
"hint": "Attivato: tutti gli strumenti (comandi bash e workdir, argomenti di percorso di read/write/edit/read_image/glob/grep e di present) usano percorsi POSIX con radice di unità MSYS (/c/Users/...); le abitudini native di bash — ~ per la home, /tmp, /dev/null, /usr — funzionano in ogni strumento esattamente come le risolve bash stesso, e l'host traduce automaticamente i campi di percorso. Disattivato ripristina il comportamento nativo di dsh (percorsi Windows per gli strumenti per i file). Bash resta sempre Git Bash finché il plugin è installato; questo interruttore governa solo il dialetto dei percorsi tra gli strumenti.",
|
|
174
174
|
"adopt.label": "Adotta il terminale laterale",
|
|
175
175
|
"adopt.hint": "Attivo (predefinito) imposta Git Bash come shell del terminale di dsh-better-sidebar; disattivo ripristina il valore precedente e non tocca mai una scelta manuale. Lo strumento bash del modello non è interessato — lo fornisce il plugin stesso.",
|
|
176
176
|
},
|
|
@@ -184,7 +184,7 @@ window.__ModuleLoader__.load({
|
|
|
184
184
|
"switch.on": "有効にする",
|
|
185
185
|
"switch.off": "無効にする",
|
|
186
186
|
"error": "書き込みに失敗しました",
|
|
187
|
-
"hint": "有効にすると、すべてのツール(bash コマンドと workdir、read/write/edit/read_image/glob/grep のパス引数)が MSYS ドライブルートの POSIX パス(/c/Users/...)
|
|
187
|
+
"hint": "有効にすると、すべてのツール(bash コマンドと workdir、read/write/edit/read_image/glob/grep と present のパス引数)が MSYS ドライブルートの POSIX パス(/c/Users/...)を使います。bash のネイティブな習慣——ホームの ~、/tmp、/dev/null、/usr——も、bash 自身が解決するのとまったく同じようにすべてのツールで動作し、パスフィールドはホストが自動的に変換します。無効にすると dsh 本来の動作(ファイルツールは Windows パス)に戻ります。bash はプラグインがインストールされている限り常に Git Bash で、このスイッチの影響を受けません。",
|
|
188
188
|
"adopt.label": "サイドバーターミナルを引き継ぐ",
|
|
189
189
|
"adopt.hint": "オン(既定)では dsh-better-sidebar のターミナルシェルに Git Bash を書き込みます。オフにすると以前の値へ戻し、手動で選択した設定には決して触れません。モデル側の bash ツールには影響しません——それはプラグイン本体が提供します。",
|
|
190
190
|
},
|
|
@@ -198,7 +198,7 @@ window.__ModuleLoader__.load({
|
|
|
198
198
|
"switch.on": "사용",
|
|
199
199
|
"switch.off": "사용 안 함",
|
|
200
200
|
"error": "쓰기 실패",
|
|
201
|
-
"hint": "켜면 모든 도구(bash 명령과 workdir, read/write/edit/read_image/glob/grep의 경로 인수)가 MSYS 드라이브 루트 POSIX 경로(/c/Users/...)를 사용합니다.
|
|
201
|
+
"hint": "켜면 모든 도구(bash 명령과 workdir, read/write/edit/read_image/glob/grep 및 present의 경로 인수)가 MSYS 드라이브 루트 POSIX 경로(/c/Users/...)를 사용합니다. bash 고유 습관——홈의 ~, /tmp, /dev/null, /usr——도 bash 자신이 해석하는 그대로 모든 도구에서 작동하며 호스트가 경로 필드를 자동 변환합니다. 끄면 dsh 기본 동작(파일 도구에 Windows 경로 사용)으로 돌아갑니다. 플러그인이 설치되어 있는 동안 bash는 항상 Git Bash이며 이 스위치의 영향을 받지 않습니다.",
|
|
202
202
|
"adopt.label": "사이드바 터미널 인수",
|
|
203
203
|
"adopt.hint": "켜짐(기본)이면 dsh-better-sidebar 터미널 셸에 Git Bash를 기록하고, 끄면 이전 값을 복원하며 수동으로 고른 설정은 절대 건드리지 않습니다. 모델 측 bash 도구에는 영향이 없습니다 — 플러그인이 직접 제공합니다.",
|
|
204
204
|
},
|
|
@@ -212,7 +212,7 @@ window.__ModuleLoader__.load({
|
|
|
212
212
|
"switch.on": "Inschakelen",
|
|
213
213
|
"switch.off": "Uitschakelen",
|
|
214
214
|
"error": "schrijven mislukt",
|
|
215
|
-
"hint": "Ingeschakeld: alle tools (bash-opdrachten en workdir, padargumenten van read/write/edit/read_image/glob/grep) gebruiken POSIX-paden vanaf de MSYS-schijfwortel (/c/Users/...); de
|
|
215
|
+
"hint": "Ingeschakeld: alle tools (bash-opdrachten en workdir, padargumenten van read/write/edit/read_image/glob/grep en present) gebruiken POSIX-paden vanaf de MSYS-schijfwortel (/c/Users/...); bash-eigen gewoonten — ~ voor de home-map, /tmp, /dev/null, /usr — werken in elke tool precies zoals bash ze zelf oplost, en de host vertaalt de padvelden automatisch. Uitgeschakeld herstelt het oorspronkelijke dsh-gedrag (Windows-paden voor bestandstools). Bash is altijd Git Bash zolang de plugin is geïnstalleerd; deze schakelaar bepaalt alleen het paddialect tussen de tools.",
|
|
216
216
|
"adopt.label": "Zijbalkterminal overnemen",
|
|
217
217
|
"adopt.hint": "Aan (standaard) schrijft Git Bash als shell van de dsh-better-sidebar-terminal; uit herstelt de vorige waarde en raakt nooit een handmatige keuze aan. De bash-tool van het model blijft buiten beschouwing — die levert de plugin zelf.",
|
|
218
218
|
},
|
|
@@ -226,7 +226,7 @@ window.__ModuleLoader__.load({
|
|
|
226
226
|
"switch.on": "Włącz",
|
|
227
227
|
"switch.off": "Wyłącz",
|
|
228
228
|
"error": "zapis nie powiódł się",
|
|
229
|
-
"hint": "Po włączeniu: wszystkie narzędzia (polecenia bash i workdir
|
|
229
|
+
"hint": "Po włączeniu: wszystkie narzędzia (polecenia bash i workdir, argumenty ścieżek w read/write/edit/read_image/glob/grep i w present) używają ścieżek POSIX od korzenia dysku MSYS (/c/Users/...); natywne nawyki basha — ~ dla katalogu domowego, /tmp, /dev/null, /usr — działają w każdym narzędziu dokładnie tak, jak rozwiązuje je sam bash, a host automatycznie tłumaczy pola ścieżek. Wyłączenie przywraca natywne zachowanie dsh (ścieżki Windows dla narzędzi plikowych). Bash jest zawsze Git Bash, dopóki wtyczka jest zainstalowana; ten przełącznik reguluje wyłącznie dialekt ścieżek między narzędziami.",
|
|
230
230
|
"adopt.label": "Przejmij terminal boczny",
|
|
231
231
|
"adopt.hint": "Włączony (domyślnie) zapisuje Git Bash jako shell terminala dsh-better-sidebar; wyłączony przywraca poprzednią wartość i nigdy nie narusza ręcznie wybranego ustawienia. Narzędzie bash po stronie modelu jest nietknięte — zapewnia je sama wtyczka.",
|
|
232
232
|
},
|
|
@@ -240,7 +240,7 @@ window.__ModuleLoader__.load({
|
|
|
240
240
|
"switch.on": "Ativar",
|
|
241
241
|
"switch.off": "Desativar",
|
|
242
242
|
"error": "falha ao gravar",
|
|
243
|
-
"hint": "Ativada: todas as ferramentas (comandos bash e workdir, argumentos de caminho de read/write/edit/read_image/glob/grep) usam caminhos POSIX a partir da raiz da unidade MSYS (/c/Users/...); o host traduz
|
|
243
|
+
"hint": "Ativada: todas as ferramentas (comandos bash e workdir, argumentos de caminho de read/write/edit/read_image/glob/grep e de present) usam caminhos POSIX a partir da raiz da unidade MSYS (/c/Users/...); os hábitos nativos do bash — ~ para a pasta pessoal, /tmp, /dev/null, /usr — funcionam em cada ferramenta exatamente como o próprio bash os resolve, e o host traduz os campos de caminho automaticamente. Desativada restaura o comportamento nativo do dsh (caminhos Windows para as ferramentas de arquivo). O bash é sempre Git Bash enquanto o plugin estiver instalado; este interruptor rege apenas o dialeto de caminhos entre ferramentas.",
|
|
244
244
|
"adopt.label": "Adotar o terminal lateral",
|
|
245
245
|
"adopt.hint": "Ligado (padrão) grava o Git Bash como shell do terminal do dsh-better-sidebar; desligado restaura o valor anterior e nunca altera uma escolha manual. A ferramenta bash do modelo não é afetada — o próprio plug-in a fornece.",
|
|
246
246
|
},
|
|
@@ -254,7 +254,7 @@ window.__ModuleLoader__.load({
|
|
|
254
254
|
"switch.on": "Включить",
|
|
255
255
|
"switch.off": "Выключить",
|
|
256
256
|
"error": "не удалось записать",
|
|
257
|
-
"hint": "Включено: все инструменты (команды bash и workdir, аргументы путей read/write/edit/read_image/glob/grep) используют POSIX-пути от корня диска MSYS (/c/Users/...); хост автоматически преобразует поля
|
|
257
|
+
"hint": "Включено: все инструменты (команды bash и workdir, аргументы путей read/write/edit/read_image/glob/grep и present) используют POSIX-пути от корня диска MSYS (/c/Users/...); собственные привычки bash — ~ для домашнего каталога, /tmp, /dev/null, /usr — работают в каждом инструменте ровно так, как их разрешает сам bash, а хост автоматически преобразует поля путей. Выключение возвращает исходное поведение dsh (пути Windows для файловых инструментов). Пока плагин установлен, bash всегда остаётся Git Bash; этот переключатель управляет только диалектом путей между инструментами.",
|
|
258
258
|
"adopt.label": "Перехватывать терминал боковой панели",
|
|
259
259
|
"adopt.hint": "Включено (по умолчанию): Git Bash записывается как shell терминала dsh-better-sidebar; выключено — восстанавливается прежнее значение, вручную выбранные настройки не трогаются. Инструмент bash у модели не затронут — его предоставляет сам плагин.",
|
|
260
260
|
},
|
|
@@ -268,7 +268,7 @@ window.__ModuleLoader__.load({
|
|
|
268
268
|
"switch.on": "Aktivera",
|
|
269
269
|
"switch.off": "Inaktivera",
|
|
270
270
|
"error": "skrivning misslyckades",
|
|
271
|
-
"hint": "Aktiverad: alla verktyg (bash-kommandon och workdir, sökvägsargument för read/write/edit/read_image/glob/grep) använder POSIX-sökvägar från MSYS-enhetsroten (/c/Users/...); värden översätter sökvägsfälten
|
|
271
|
+
"hint": "Aktiverad: alla verktyg (bash-kommandon och workdir, sökvägsargument för read/write/edit/read_image/glob/grep och present) använder POSIX-sökvägar från MSYS-enhetsroten (/c/Users/...); bash egna vanor — ~ för hemkatalogen, /tmp, /dev/null, /usr — fungerar i varje verktyg exakt som bash själv löser dem, och värden översätter sökvägsfälten automatiskt. Inaktiverad återställer dsh:s ursprungliga beteende (Windows-sökvägar för filverktygen). Bash är alltid Git Bash så länge insticksprogrammet är installerat; den här växeln styr bara sökvägsdialekten mellan verktygen.",
|
|
272
272
|
"adopt.label": "Överta sidolistterminal",
|
|
273
273
|
"adopt.hint": "På (standard) skriver Git Bash som terminal-shell i dsh-better-sidebar; av återställer det tidigare värdet och rör aldrig ett manuellt val. Modellens bash-verktyg påverkas inte — det tillhandahålls av pluginet självt.",
|
|
274
274
|
},
|
|
@@ -282,7 +282,7 @@ window.__ModuleLoader__.load({
|
|
|
282
282
|
"switch.on": "เปิดใช้งาน",
|
|
283
283
|
"switch.off": "ปิดใช้งาน",
|
|
284
284
|
"error": "เขียนไม่สำเร็จ",
|
|
285
|
-
"hint": "เมื่อเปิดใช้งาน: เครื่องมือทั้งหมด (คำสั่ง bash และ workdir รวมถึงอาร์กิวเมนต์พาธของ read/write/edit/read_image/glob/grep) ใช้พาธ POSIX จากรากไดรฟ์ของ MSYS (/c/Users/...)
|
|
285
|
+
"hint": "เมื่อเปิดใช้งาน: เครื่องมือทั้งหมด (คำสั่ง bash และ workdir รวมถึงอาร์กิวเมนต์พาธของ read/write/edit/read_image/glob/grep และ present) ใช้พาธ POSIX จากรากไดรฟ์ของ MSYS (/c/Users/...); พฤติกรรมดั้งเดิมของ bash — ~ สำหรับโฮม, /tmp, /dev/null, /usr — ทำงานในทุกเครื่องมือเหมือนที่ bash แก้เองพอดี และโฮสต์แปลฟิลด์พาธให้อัตโนมัติ เมื่อปิดใช้งานจะกลับสู่พฤติกรรมดั้งเดิมของ dsh (เครื่องมือจัดการไฟล์ใช้พาธ Windows) bash เป็น Git Bash เสมอเมื่อติดตั้งปลั๊กอินนี้ สวิตช์นี้ควบคุมเฉพาะรูปแบบพาธระหว่างเครื่องมือเท่านั้น",
|
|
286
286
|
"adopt.label": "รับช่วงเทอร์มินัลแถบข้าง",
|
|
287
287
|
"adopt.hint": "เปิด (ค่าเริ่มต้น) จะเขียน Git Bash เป็น shell ของเทอร์มินัล dsh-better-sidebar; ปิดแล้วคืนค่าเดิมและไม่แตะการตั้งค่าที่เลือกเอง เครื่องมือ bash ของโมเดลไม่กระทบ — ปลั๊กอินจัดหาเอง",
|
|
288
288
|
},
|
|
@@ -296,7 +296,7 @@ window.__ModuleLoader__.load({
|
|
|
296
296
|
"switch.on": "Etkinleştir",
|
|
297
297
|
"switch.off": "Devre dışı bırak",
|
|
298
298
|
"error": "yazma başarısız",
|
|
299
|
-
"hint": "Etkinleştirildiğinde: tüm araçlar (bash komutları ve workdir ile read/write/edit/read_image/glob/grep yol bağımsız değişkenleri) MSYS sürücü kökünden POSIX yolları (/c/Users/...) kullanır; ana süreç
|
|
299
|
+
"hint": "Etkinleştirildiğinde: tüm araçlar (bash komutları ve workdir ile read/write/edit/read_image/glob/grep ve present yol bağımsız değişkenleri) MSYS sürücü kökünden POSIX yolları (/c/Users/...) kullanır; bash'e özgü alışkanlıklar — ev için ~, /tmp, /dev/null, /usr — her araçta tam bash'in kendisinin çözdüğü gibi çalışır ve ana süreç yol alanlarını otomatik olarak çevirir. Devre dışı bırakıldığında dsh yerel davranışına döner (dosya araçları için Windows yolları). Eklenti kurulu olduğu sürece bash her zaman Git Bash olarak kalır; bu anahtar yalnızca araçlar arası yol lehçesini yönetir.",
|
|
300
300
|
"adopt.label": "Kenar çubuğu terminalini devral",
|
|
301
301
|
"adopt.hint": "Açık (varsayılan) Git Bashi dsh-better-sidebar terminalinin shelli olarak yazar; kapalı önceki değeri geri getirir ve elle seçilmiş bir ayara asla dokunmaz. Model tarafındaki bash aracı etkilenmez — onu eklentinin kendisi sağlar.",
|
|
302
302
|
},
|
|
@@ -310,7 +310,7 @@ window.__ModuleLoader__.load({
|
|
|
310
310
|
"switch.on": "Bật",
|
|
311
311
|
"switch.off": "Tắt",
|
|
312
312
|
"error": "ghi thất bại",
|
|
313
|
-
"hint": "Khi bật: mọi công cụ (lệnh bash và workdir, tham số đường dẫn của read/write/edit/read_image/glob/grep) dùng đường dẫn POSIX từ gốc ổ đĩa MSYS (/c/Users/...); máy chủ tự động chuyển đổi trường đường dẫn
|
|
313
|
+
"hint": "Khi bật: mọi công cụ (lệnh bash và workdir, tham số đường dẫn của read/write/edit/read_image/glob/grep và present) dùng đường dẫn POSIX từ gốc ổ đĩa MSYS (/c/Users/...); thói quen gốc của bash — ~ cho thư mục home, /tmp, /dev/null, /usr — hoạt động trong mọi công cụ đúng như chính bash giải quyết chúng, và máy chủ tự động chuyển đổi trường đường dẫn. Khi tắt, hành vi gốc của dsh được khôi phục (công cụ tệp dùng đường dẫn Windows). bash luôn là Git Bash khi plugin được cài đặt; công tắc này chỉ điều khiển phương ngữ đường dẫn giữa các công cụ.",
|
|
314
314
|
"adopt.label": "Tiếp nhận terminal thanh bên",
|
|
315
315
|
"adopt.hint": "Bật (mặc định) ghi Git Bash làm shell terminal của dsh-better-sidebar; tắt khôi phục giá trị trước đó và không bao giờ đụng tới lựa chọn thủ công. Công cụ bash phía mô hình không bị ảnh hưởng — chính plugin cung cấp nó.",
|
|
316
316
|
},
|
|
@@ -324,7 +324,7 @@ window.__ModuleLoader__.load({
|
|
|
324
324
|
"switch.on": "啟用",
|
|
325
325
|
"switch.off": "停用",
|
|
326
326
|
"error": "寫入失敗",
|
|
327
|
-
"hint": "啟用後:所有工具(bash 指令同 workdir、read/write/edit/read_image/glob/grep 嘅路徑參數)統一使用 MSYS 磁碟根 POSIX 路徑(/c/Users/...)
|
|
327
|
+
"hint": "啟用後:所有工具(bash 指令同 workdir、read/write/edit/read_image/glob/grep 同 present 嘅路徑參數)統一使用 MSYS 磁碟根 POSIX 路徑(/c/Users/...);bash 原生習慣——~ 家目錄、/tmp、/dev/null、/usr——喺所有工具一樣有效(同 Git Bash 掛載表一致),路徑參數由宿主自動翻譯,模型無感。停用後回復 dsh 原生行為(檔案工具用 Windows 路徑)。bash 永遠係 Git Bash,唔受呢個開關影響。",
|
|
328
328
|
"adopt.label": "接管側欄終端",
|
|
329
329
|
"adopt.hint": "開啟(預設)會把 dsh-better-sidebar 的終端 shell 寫成 Git Bash;關閉後還原接管前的值,手動改過的設定永不被碰。模型側的 bash 工具不受影響——由插件本身提供。",
|
|
330
330
|
},
|
|
@@ -338,7 +338,7 @@ window.__ModuleLoader__.load({
|
|
|
338
338
|
"switch.on": "啟用",
|
|
339
339
|
"switch.off": "停用",
|
|
340
340
|
"error": "寫入失敗",
|
|
341
|
-
"hint": "啟用後:所有工具(bash 指令同 workdir、read/write/edit/read_image/glob/grep 嘅路徑參數)統一使用 MSYS 磁碟根 POSIX 路徑(/c/Users/...)
|
|
341
|
+
"hint": "啟用後:所有工具(bash 指令同 workdir、read/write/edit/read_image/glob/grep 同 present 嘅路徑參數)統一使用 MSYS 磁碟根 POSIX 路徑(/c/Users/...);bash 原生習慣——~ 家目錄、/tmp、/dev/null、/usr——喺所有工具一樣有效(同 Git Bash 掛載表一致),路徑參數由宿主自動翻譯,模型無感。停用後回復 dsh 原生行為(檔案工具用 Windows 路徑)。bash 永遠係 Git Bash,唔受呢個開關影響。",
|
|
342
342
|
"adopt.label": "接管側欄終端",
|
|
343
343
|
"adopt.hint": "開啟(預設)會把 dsh-better-sidebar 的終端 shell 寫成 Git Bash;關閉後還原接管前的值,手動改過的設定永不被碰。模型側的 bash 工具不受影響——由插件本身提供。",
|
|
344
344
|
},
|
|
@@ -352,7 +352,7 @@ window.__ModuleLoader__.load({
|
|
|
352
352
|
"switch.on": "啟用",
|
|
353
353
|
"switch.off": "停用",
|
|
354
354
|
"error": "寫入失敗",
|
|
355
|
-
"hint": "啟用後:所有工具(bash 指令與 workdir,以及 read/write/edit/read_image/glob/grep 的路徑參數)統一使用 MSYS 磁碟根 POSIX 路徑(/c/Users/...)
|
|
355
|
+
"hint": "啟用後:所有工具(bash 指令與 workdir,以及 read/write/edit/read_image/glob/grep 與 present 的路徑參數)統一使用 MSYS 磁碟根 POSIX 路徑(/c/Users/...);bash 原生習慣——~ 家目錄、/tmp、/dev/null、/usr——在所有工具同樣有效(與 Git Bash 掛載表一致),路徑參數由宿主自動轉譯,模型無感。停用後恢復 dsh 原生行為(檔案工具使用 Windows 路徑)。bash 一律是 Git Bash,不受此開關影響。",
|
|
356
356
|
"adopt.label": "接管側欄終端機",
|
|
357
357
|
"adopt.hint": "開啟(預設)會把 dsh-better-sidebar 的終端機 shell 寫成 Git Bash;關閉後還原接管前的值,手動改過的設定永不被碰。模型側的 bash 工具不受影響——由插件本身提供。",
|
|
358
358
|
},
|
package/src/index.js
CHANGED
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
rmSync,
|
|
51
51
|
writeFileSync,
|
|
52
52
|
} from 'node:fs'
|
|
53
|
+
import { homedir, tmpdir } from 'node:os'
|
|
53
54
|
import { dirname, join } from 'node:path'
|
|
54
55
|
import { fileURLToPath } from 'node:url'
|
|
55
56
|
|
|
@@ -662,7 +663,7 @@ export function installRegisterShim(reg) {
|
|
|
662
663
|
const SETTINGS_NAMESPACE = 'gitbash-shell'
|
|
663
664
|
|
|
664
665
|
/** The full directive text, injected only while posixPaths is on. */
|
|
665
|
-
const POSIX_DIRECTIVE_TEXT = 'The working shell is Git for Windows bash: paths use MSYS drive roots (/c/Users/...), and every tool accepts that form directly.'
|
|
666
|
+
const POSIX_DIRECTIVE_TEXT = 'The working shell is Git for Windows bash: paths use MSYS drive roots (/c/Users/...), and every tool accepts that form directly — including the bash-native habits (~ home shorthand, /tmp, /dev/null, /usr/bin/...), which resolve in every tool exactly as bash itself resolves them.'
|
|
666
667
|
|
|
667
668
|
// Official runtime counterpart to the directive (v0.11.0): dsh-shell-env is
|
|
668
669
|
// the host-plane registry behind the model-visible $DSH_* facts, and the
|
|
@@ -670,7 +671,7 @@ const POSIX_DIRECTIVE_TEXT = 'The working shell is Git for Windows bash: paths u
|
|
|
670
671
|
// lives there, verifiable at runtime instead of only stated in the prompt.
|
|
671
672
|
const PATH_DIALECT_KEY = 'DSH_PATH_DIALECT'
|
|
672
673
|
const PATH_DIALECT_VALUE = 'msys'
|
|
673
|
-
const PATH_DIALECT_DESCRIPTION = 'Path dialect for tool calls and tool results: MSYS drive roots (/c/Users/...); every tool accepts
|
|
674
|
+
const PATH_DIALECT_DESCRIPTION = 'Path dialect for tool calls and tool results: MSYS drive roots (/c/Users/...) plus the bash-native mounts (~, /tmp, /dev/null, /usr); every tool accepts these forms directly.'
|
|
674
675
|
|
|
675
676
|
/** Read the posixPaths switch from the live settings service; never throws. */
|
|
676
677
|
export function readPosixPaths(ctxLike) {
|
|
@@ -724,29 +725,75 @@ function posixSeparators(value) {
|
|
|
724
725
|
}
|
|
725
726
|
|
|
726
727
|
/**
|
|
727
|
-
* Rewrite
|
|
728
|
-
*
|
|
729
|
-
* `
|
|
730
|
-
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
733
|
-
*
|
|
734
|
-
* @returns {object} a new value when any field changed, the input otherwise.
|
|
728
|
+
* Rewrite Windows absolute paths inside an ERROR result's text blocks to
|
|
729
|
+
* the MSYS dialect (pure, v0.17.1). Error results cannot carry a
|
|
730
|
+
* replacement `value` (the registry rejects that), but replacing `content`
|
|
731
|
+
* is the official post-execute channel, so the message the model reads
|
|
732
|
+
* stays in one dialect — it must not relearn Windows forms from failure
|
|
733
|
+
* text. Non-drive-letter diagnostics (device paths, URLs) never match
|
|
734
|
+
* windowsToMsys and are left verbatim.
|
|
735
735
|
*/
|
|
736
|
-
|
|
736
|
+
/**
|
|
737
|
+
* The only tools whose ERROR content is dialect-translated (v0.17.1).
|
|
738
|
+
* These messages are harness-generated path diagnostics (cannot read
|
|
739
|
+
* "C:\..."), so rewriting them is safe. Every other tool — bash above all,
|
|
740
|
+
* whose failed runs carry raw command stdout/stderr — keeps its error
|
|
741
|
+
* content VERBATIM: output is data, never rewritten (the same red line as
|
|
742
|
+
* file content in successful results).
|
|
743
|
+
*/
|
|
744
|
+
const ERROR_CONTENT_TOOLS = new Set(['read', 'read_image', 'write', 'edit', 'glob', 'grep', 'present'])
|
|
745
|
+
|
|
746
|
+
export function rewriteErrorContent(content) {
|
|
747
|
+
if (!Array.isArray(content)) return content
|
|
748
|
+
let changed = false
|
|
749
|
+
const next = content.map((block) => {
|
|
750
|
+
if (!block || typeof block !== 'object' || typeof block.text !== 'string') return block
|
|
751
|
+
const out = windowsToMsys(block.text)
|
|
752
|
+
if (out === block.text) return block
|
|
753
|
+
changed = true
|
|
754
|
+
return { ...block, text: out }
|
|
755
|
+
})
|
|
756
|
+
return changed ? next : content
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
export function rewriteResultPaths(name, value, env) {
|
|
737
760
|
if (!value || typeof value !== 'object') return value
|
|
761
|
+
// v0.17.0: paths under the user TEMP directory echo back in the bash
|
|
762
|
+
// /tmp dialect (that IS what /tmp means in Git Bash), so the model sees
|
|
763
|
+
// the same short root bash itself prints for $TMP.
|
|
764
|
+
const tempRoot = env && env.tmpDir ? windowsToMsys(env.tmpDir) : ''
|
|
765
|
+
const toMsys = (p) => {
|
|
766
|
+
const out = windowsToMsys(p)
|
|
767
|
+
if (!tempRoot) return out
|
|
768
|
+
const lower = out.toLowerCase()
|
|
769
|
+
const rootLower = tempRoot.toLowerCase()
|
|
770
|
+
if (lower === rootLower) return '/tmp'
|
|
771
|
+
if (lower.startsWith(rootLower + '/')) return '/tmp' + out.slice(tempRoot.length)
|
|
772
|
+
return out
|
|
773
|
+
}
|
|
738
774
|
if (name === 'read' || name === 'read_image' || name === 'write' || name === 'edit') {
|
|
739
775
|
if (typeof value.path === 'string' && value.path !== '') {
|
|
740
|
-
const out =
|
|
776
|
+
const out = toMsys(value.path)
|
|
741
777
|
if (out !== value.path) return { ...value, path: out }
|
|
742
778
|
}
|
|
743
779
|
return value
|
|
744
780
|
}
|
|
781
|
+
if (name === 'present' && Array.isArray(value.files)) {
|
|
782
|
+
let changed = false
|
|
783
|
+
const files = value.files.map((file) => {
|
|
784
|
+
if (!file || typeof file !== 'object' || typeof file.path !== 'string' || file.path === '') return file
|
|
785
|
+
const out = posixSeparators(toMsys(file.path))
|
|
786
|
+
if (out === file.path) return file
|
|
787
|
+
changed = true
|
|
788
|
+
return { ...file, path: out }
|
|
789
|
+
})
|
|
790
|
+
return changed ? { ...value, files } : value
|
|
791
|
+
}
|
|
745
792
|
if (name === 'glob' && Array.isArray(value.paths)) {
|
|
746
793
|
let changed = false
|
|
747
794
|
const paths = value.paths.map((p) => {
|
|
748
795
|
if (typeof p !== 'string') return p
|
|
749
|
-
const out = posixSeparators(
|
|
796
|
+
const out = posixSeparators(toMsys(p))
|
|
750
797
|
if (out === p) return p
|
|
751
798
|
changed = true
|
|
752
799
|
return out
|
|
@@ -757,7 +804,7 @@ export function rewriteResultPaths(name, value) {
|
|
|
757
804
|
let changed = false
|
|
758
805
|
const matches = value.matches.map((m) => {
|
|
759
806
|
if (!m || typeof m !== 'object' || typeof m.path !== 'string') return m
|
|
760
|
-
const out = posixSeparators(
|
|
807
|
+
const out = posixSeparators(toMsys(m.path))
|
|
761
808
|
if (out === m.path) return m
|
|
762
809
|
changed = true
|
|
763
810
|
return { ...m, path: out }
|
|
@@ -782,28 +829,128 @@ export function rewriteResultPaths(name, value) {
|
|
|
782
829
|
// directive still stands).
|
|
783
830
|
|
|
784
831
|
const MSYS_DRIVE_ROOT = /^\/([a-z])\/(.*)$/i
|
|
832
|
+
const MSYS_BARE_DRIVE = /^\/([a-z])$/i
|
|
785
833
|
const TRANSLATABLE_PATH_FIELDS = new Set(['file_path', 'path', 'workdir'])
|
|
786
834
|
|
|
787
|
-
|
|
788
|
-
|
|
835
|
+
// ── virtual mounts + env (v0.17.0) ─────────────────────────────────────
|
|
836
|
+
//
|
|
837
|
+
// Git Bash resolves a few POSIX roots through its OWN mount table before
|
|
838
|
+
// any drive root applies (`mount` inside Git Bash): /tmp is the user TEMP
|
|
839
|
+
// dir (usertemp), /dev/null is the Windows NUL device, and /usr /bin /etc
|
|
840
|
+
// /var /home /root /mnt live under the Git install root. The model carries
|
|
841
|
+
// those bash habits into EVERY tool, so the translation layer mirrors the
|
|
842
|
+
// same table or the file tools silently misplace them (/tmp becomes a
|
|
843
|
+
// fresh C:/tmp on the current drive; /dev/null becomes a real file under
|
|
844
|
+
// C:/dev). All matches are segment-bounded and case-sensitive, exactly
|
|
845
|
+
// like the msys mount table itself (/Tmp does NOT match).
|
|
846
|
+
//
|
|
847
|
+
// /home is deliberately the GIT mount (git-root/home, usually empty), NOT
|
|
848
|
+
// the user profile: bash itself resolves /home/x there, while the home
|
|
849
|
+
// SHORTHAND ~ expands to $HOME (= C:/Users/<u>) — mirroring both keeps
|
|
850
|
+
// file tools and bash in perfect agreement. A bare '/' is never
|
|
851
|
+
// translated: it would scope tools to the whole Git install tree.
|
|
852
|
+
|
|
853
|
+
/** The Windows null device — the exact target of Git Bash's /dev/null. */
|
|
854
|
+
const NUL_DEVICE = '\\\\.\\NUL'
|
|
855
|
+
|
|
856
|
+
/** Git-root mounts: MSYS path -> subdirectory under the Git install root. */
|
|
857
|
+
const GIT_MOUNTS = new Map([
|
|
858
|
+
['/usr', 'usr'],
|
|
859
|
+
['/bin', 'usr/bin'],
|
|
860
|
+
['/etc', 'etc'],
|
|
861
|
+
['/var', 'var'],
|
|
862
|
+
['/home', 'home'],
|
|
863
|
+
['/root', 'root'],
|
|
864
|
+
['/mnt', 'mnt'],
|
|
865
|
+
])
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* The runtime facts the virtual mounts resolve against (all optional — a
|
|
869
|
+
* missing fact simply leaves its paths untranslated). Probed once per
|
|
870
|
+
* process: tmpdir/homedir are cheap; the Git root walks the candidate
|
|
871
|
+
* bash.exe list (the default install plus every PATH entry — which also
|
|
872
|
+
* covers a Git-usr-bin PATH entry) and accepts a root only when
|
|
873
|
+
* <root>/usr/bin exists, which excludes the WSL bash shim in WindowsApps.
|
|
874
|
+
*/
|
|
875
|
+
let translateEnvCache
|
|
876
|
+
export function buildTranslateEnv() {
|
|
877
|
+
if (translateEnvCache) return translateEnvCache
|
|
878
|
+
const env = { tmpDir: undefined, home: undefined, gitRoot: undefined }
|
|
879
|
+
try {
|
|
880
|
+
const t = tmpdir()
|
|
881
|
+
if (t && existsSync(t)) env.tmpDir = t.replace(/\\/g, '/')
|
|
882
|
+
} catch { /* keep undefined */ }
|
|
883
|
+
try {
|
|
884
|
+
const h = homedir()
|
|
885
|
+
if (h && existsSync(h)) env.home = h.replace(/\\/g, '/')
|
|
886
|
+
} catch { /* keep undefined */ }
|
|
887
|
+
try {
|
|
888
|
+
const candidates = [DEFAULT_GIT_BASH]
|
|
889
|
+
for (const dir of String(process.env.PATH ?? '').split(';')) {
|
|
890
|
+
const clean = dir && dir.trim()
|
|
891
|
+
if (clean) candidates.push(clean.replace(/\\/g, '/') + '/bash.exe')
|
|
892
|
+
}
|
|
893
|
+
for (const candidate of candidates) {
|
|
894
|
+
try {
|
|
895
|
+
if (!existsSync(candidate)) continue
|
|
896
|
+
const root = dirname(dirname(candidate))
|
|
897
|
+
if (existsSync(join(root, 'usr', 'bin'))) {
|
|
898
|
+
env.gitRoot = root.replace(/\\/g, '/')
|
|
899
|
+
break
|
|
900
|
+
}
|
|
901
|
+
} catch { /* try the next candidate */ }
|
|
902
|
+
}
|
|
903
|
+
} catch { /* keep undefined */ }
|
|
904
|
+
translateEnvCache = env
|
|
905
|
+
return env
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* '/c/Users/x' -> 'C:/Users/x'. With an env, the bash-native habits resolve
|
|
910
|
+
* first (~ -> home) and the virtual mounts (/tmp, /dev/null, /usr & friends)
|
|
911
|
+
* resolve after the drive roots; any other shape returns the input
|
|
912
|
+
* unchanged. Pure: the env is a plain fact bag, nothing is probed here.
|
|
913
|
+
*/
|
|
914
|
+
export function translateMsysPath(value, env) {
|
|
789
915
|
if (typeof value !== 'string') return value
|
|
916
|
+
if (env && env.home && (value === '~' || value.startsWith('~/'))) {
|
|
917
|
+
return value === '~' ? env.home : env.home + '/' + value.slice(2)
|
|
918
|
+
}
|
|
790
919
|
const match = MSYS_DRIVE_ROOT.exec(value)
|
|
791
|
-
if (
|
|
792
|
-
|
|
920
|
+
if (match) return match[1].toUpperCase() + ':/' + match[2]
|
|
921
|
+
const bare = MSYS_BARE_DRIVE.exec(value)
|
|
922
|
+
if (bare) return bare[1].toUpperCase() + ':/'
|
|
923
|
+
if (value === '/dev/null') return NUL_DEVICE
|
|
924
|
+
if (env && env.tmpDir && (value === '/tmp' || value.startsWith('/tmp/'))) {
|
|
925
|
+
return value === '/tmp' ? env.tmpDir : env.tmpDir + value.slice(4)
|
|
926
|
+
}
|
|
927
|
+
if (env && env.gitRoot) {
|
|
928
|
+
for (const [mount, target] of GIT_MOUNTS) {
|
|
929
|
+
if (value === mount || value.startsWith(mount + '/')) {
|
|
930
|
+
const rest = value === mount ? '' : value.slice(mount.length)
|
|
931
|
+
return env.gitRoot + '/' + target + rest
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
return value
|
|
793
936
|
}
|
|
794
937
|
|
|
795
938
|
/**
|
|
796
939
|
* Return an arguments object whose path fields carry drive-letter roots.
|
|
797
940
|
* Pure: builds a NEW object when any field changes and returns the ORIGINAL
|
|
798
941
|
* reference otherwise — the registry deep-freezes exec.arguments at exec
|
|
799
|
-
* construction (0.10.2 lesson: in-place writes throw in strict mode and
|
|
800
|
-
* silently swallowed), so the caller REPLACES the exec.arguments
|
|
801
|
-
* (the exec object itself is not frozen until tools/result;
|
|
802
|
-
* replacement is the registry's own precedent).
|
|
942
|
+
* construction (0.10.2 lesson: in-place writes throw in strict mode and
|
|
943
|
+
* were silently swallowed), so the caller REPLACES the exec.arguments
|
|
944
|
+
* property (the exec object itself is not frozen until tools/result;
|
|
945
|
+
* signal replacement is the registry's own precedent).
|
|
946
|
+
*
|
|
947
|
+
* v0.17.0: present's NESTED files[].path rides along (the field-name
|
|
948
|
+
* whitelist only sees top-level keys, and present is the one tool whose
|
|
949
|
+
* path arguments live one level down).
|
|
803
950
|
* @returns {object} the translated arguments object, or the input when
|
|
804
951
|
* nothing changed (also the input itself when args is not an object).
|
|
805
952
|
*/
|
|
806
|
-
export function translatePathArguments(args) {
|
|
953
|
+
export function translatePathArguments(args, env) {
|
|
807
954
|
if (!args || typeof args !== 'object') return args
|
|
808
955
|
let changed = false
|
|
809
956
|
const next = { ...args }
|
|
@@ -811,14 +958,80 @@ export function translatePathArguments(args) {
|
|
|
811
958
|
if (!TRANSLATABLE_PATH_FIELDS.has(key)) continue
|
|
812
959
|
const value = next[key]
|
|
813
960
|
if (typeof value !== 'string') continue
|
|
814
|
-
const translated = translateMsysPath(value)
|
|
961
|
+
const translated = translateMsysPath(value, env)
|
|
815
962
|
if (translated === value) continue
|
|
816
963
|
next[key] = translated
|
|
817
964
|
changed = true
|
|
818
965
|
}
|
|
966
|
+
if (Array.isArray(next.files)) {
|
|
967
|
+
const files = next.files.map((file) => {
|
|
968
|
+
if (!file || typeof file !== 'object' || typeof file.path !== 'string') return file
|
|
969
|
+
const translated = translateMsysPath(file.path, env)
|
|
970
|
+
return translated === file.path ? file : { ...file, path: translated }
|
|
971
|
+
})
|
|
972
|
+
if (files.some((file, index) => file !== next.files[index])) {
|
|
973
|
+
next.files = files
|
|
974
|
+
changed = true
|
|
975
|
+
}
|
|
976
|
+
}
|
|
819
977
|
return changed ? next : args
|
|
820
978
|
}
|
|
821
979
|
|
|
980
|
+
// ── absolute glob patterns (v0.17.0) ────────────────────────────────────
|
|
981
|
+
//
|
|
982
|
+
// The glob tool takes its search root in the `path` argument and expects a
|
|
983
|
+
// RELATIVE pattern; an absolute pattern ('/c/Users/x/*.md', or the Windows
|
|
984
|
+
// form) is treated as relative text and silently matches nothing. A model
|
|
985
|
+
// raised on bash writes absolute patterns anyway, so for the glob tool the
|
|
986
|
+
// wrapper splits an absolute pattern at the last directory separator
|
|
987
|
+
// before the first wildcard and moves the translated directory into
|
|
988
|
+
// `path` ('/c/a/*/b/*.md' -> path 'C:/a', pattern '*/b/*.md'). An absolute
|
|
989
|
+
// path WITHOUT wildcards splits into directory + basename. Runs only for
|
|
990
|
+
// the glob tool and only for patterns that start absolute.
|
|
991
|
+
|
|
992
|
+
const GLOB_META = /[*?\[\]]/
|
|
993
|
+
|
|
994
|
+
/** Split an absolute glob pattern into { prefix, rest }; null when relative. */
|
|
995
|
+
function splitGlobPrefix(pattern) {
|
|
996
|
+
if (typeof pattern !== 'string') return null
|
|
997
|
+
let p = pattern
|
|
998
|
+
// A Windows drive head ('C:' + separator) is normalized to the MSYS form
|
|
999
|
+
// first so both absolute dialects split through the same code path.
|
|
1000
|
+
const winHead = /^([A-Za-z]):[\\/]+(.*)$/.exec(p)
|
|
1001
|
+
if (winHead) p = '/' + winHead[1].toLowerCase() + '/' + winHead[2].replace(/[\\/]+/g, '/')
|
|
1002
|
+
if (p[0] !== '/') return null
|
|
1003
|
+
const meta = GLOB_META.exec(p)
|
|
1004
|
+
const cut = meta ? p.lastIndexOf('/', meta.index) : p.lastIndexOf('/')
|
|
1005
|
+
if (cut <= 0) return null
|
|
1006
|
+
const rest = p.slice(cut + 1)
|
|
1007
|
+
if (rest === '') return null
|
|
1008
|
+
return { prefix: p.slice(0, cut), rest }
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
/** Translate the (always MSYS-form) directory prefix; null when it is not one. */
|
|
1013
|
+
function normalizeAbsolutePrefix(prefix, env) {
|
|
1014
|
+
const translated = translateMsysPath(prefix, env)
|
|
1015
|
+
return translated !== prefix ? translated : null
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* Rewrite a glob call's absolute pattern into the { path, pattern } pair
|
|
1021
|
+
* the tool actually supports; any existing `path` is superseded (an
|
|
1022
|
+
* absolute pattern already names its root). Pure; returns the input on any
|
|
1023
|
+
* miss.
|
|
1024
|
+
*/
|
|
1025
|
+
export function translateGlobArguments(args, env) {
|
|
1026
|
+
if (!args || typeof args !== 'object' || typeof args.pattern !== 'string') return args
|
|
1027
|
+
const split = splitGlobPrefix(args.pattern)
|
|
1028
|
+
if (!split) return args
|
|
1029
|
+
const prefix = normalizeAbsolutePrefix(split.prefix, env)
|
|
1030
|
+
if (!prefix) return args
|
|
1031
|
+
return { ...args, pattern: split.rest, path: prefix }
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
|
|
822
1035
|
// ── dsh-better-sidebar shell cooperation ───────────────────────────────────
|
|
823
1036
|
//
|
|
824
1037
|
// dsh-better-sidebar (v0.15.2+) resolves its terminal shell PER OPEN: a
|
|
@@ -1160,7 +1373,12 @@ export async function apply(ctx, config = {}) {
|
|
|
1160
1373
|
ctx.on('tools/execute', (exec, next) => {
|
|
1161
1374
|
try {
|
|
1162
1375
|
if (exec && exec.arguments && typeof exec.arguments === 'object' && readPosixPaths(ctx)) {
|
|
1163
|
-
const
|
|
1376
|
+
const env = buildTranslateEnv()
|
|
1377
|
+
let translated = translatePathArguments(exec.arguments, env)
|
|
1378
|
+
if (exec.name === 'glob') {
|
|
1379
|
+
const globTranslated = translateGlobArguments(translated, env)
|
|
1380
|
+
if (globTranslated !== translated) translated = globTranslated
|
|
1381
|
+
}
|
|
1164
1382
|
if (translated !== exec.arguments) exec.arguments = translated
|
|
1165
1383
|
}
|
|
1166
1384
|
} catch { /* never block a call on translation */ }
|
|
@@ -1183,17 +1401,26 @@ export async function apply(ctx, config = {}) {
|
|
|
1183
1401
|
try {
|
|
1184
1402
|
ctx.on('tools/post-execute', (exec, result, next) => {
|
|
1185
1403
|
let patch
|
|
1404
|
+
let contentPatch
|
|
1186
1405
|
try {
|
|
1187
|
-
if (readPosixPaths(ctx) && result &&
|
|
1188
|
-
|
|
1189
|
-
|
|
1406
|
+
if (readPosixPaths(ctx) && result && typeof result === 'object') {
|
|
1407
|
+
if (result.isError === false && result.value && typeof result.value === 'object') {
|
|
1408
|
+
const value = rewriteResultPaths(exec && exec.name, result.value, buildTranslateEnv())
|
|
1409
|
+
if (value !== result.value) patch = value
|
|
1410
|
+
} else if (result.isError === true && exec && ERROR_CONTENT_TOOLS.has(exec.name) && Array.isArray(result.content)) {
|
|
1411
|
+
const content = rewriteErrorContent(result.content)
|
|
1412
|
+
if (content !== result.content) contentPatch = content
|
|
1413
|
+
}
|
|
1190
1414
|
}
|
|
1191
1415
|
} catch { /* never block a result */ }
|
|
1192
1416
|
const chain = next()
|
|
1193
|
-
if (patch === undefined) return chain
|
|
1417
|
+
if (patch === undefined && contentPatch === undefined) return chain
|
|
1194
1418
|
return chain.then((decision) => {
|
|
1195
1419
|
try {
|
|
1196
|
-
if (decision && decision.kind === 'accept')
|
|
1420
|
+
if (decision && decision.kind === 'accept') {
|
|
1421
|
+
if (patch !== undefined) return { ...decision, value: patch }
|
|
1422
|
+
return { ...decision, content: contentPatch }
|
|
1423
|
+
}
|
|
1197
1424
|
} catch { /* keep the downstream decision */ }
|
|
1198
1425
|
return decision
|
|
1199
1426
|
})
|
|
@@ -1324,4 +1551,4 @@ export async function apply(ctx, config = {}) {
|
|
|
1324
1551
|
}
|
|
1325
1552
|
|
|
1326
1553
|
// Test surface: pure helpers, no Cordis context required.
|
|
1327
|
-
export const _internal = { PRESET_IDS, translateMsysPath, translatePathArguments, readPosixPaths, readAdoptSidebar, windowsToMsys, rewriteResultPaths, MARKER_FILE, classify, materialize, cleanupOnDispose, firstUserRoot, hashTree, skillsHashes, syncDecision, installRegisterShim, baseForRoster, detectBase, pickComposition, personaEraForText, detectPersonaEra, injectPresentRow, hostHasToolPresent, detectPresentSupport, injectPluginManagerRow, hostHasPluginManagerTools, rowFormOf, rowFormsOf, alignEngineRow, alignRalphRow, ROW_SOURCE }
|
|
1554
|
+
export const _internal = { PRESET_IDS, translateMsysPath, translatePathArguments, translateGlobArguments, buildTranslateEnv, rewriteErrorContent, ERROR_CONTENT_TOOLS, readPosixPaths, readAdoptSidebar, windowsToMsys, rewriteResultPaths, MARKER_FILE, classify, materialize, cleanupOnDispose, firstUserRoot, hashTree, skillsHashes, syncDecision, installRegisterShim, baseForRoster, detectBase, pickComposition, personaEraForText, detectPersonaEra, injectPresentRow, hostHasToolPresent, detectPresentSupport, injectPluginManagerRow, hostHasPluginManagerTools, rowFormOf, rowFormsOf, alignEngineRow, alignRalphRow, ROW_SOURCE }
|