dsh-gitbash-shell 0.19.1 → 0.20.0

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/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-gitbash-shell",
3
- "version": "0.19.1",
3
+ "version": "0.20.0",
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.19.1",
3
+ "version": "0.20.0",
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
@@ -71,6 +71,8 @@ window.__ModuleLoader__.load({
71
71
  "errs.hint": "文件工具报错里的 Windows 路径翻回 /c/ 形式并附设备路径引导;关闭则保留原文(便于排障复制)。",
72
72
  "split.label": "glob 绝对路径拆分",
73
73
  "split.hint": "glob 的绝对 pattern(/c/.../*.md)自动拆为 path + 相对 pattern;关闭则原样传递。",
74
+ "code.label": "run_code 程序内路径",
75
+ "code.hint": "run_code 程序里写的 /c/... 等路径字面量在执行前按同一张挂载表翻译;注释、插值模板、$VAR 与非路径字符串不动,扫描有任何不确定就整份不改。",
74
76
  "bash.label": "Git Bash 路径",
75
77
  "bash.hint": "自定义 bash.exe 完整路径,用于 /usr 等挂载的 Git 根解析;留空自动探测默认安装与 PATH。",
76
78
  "bash.save": "保存",
@@ -97,6 +99,8 @@ window.__ModuleLoader__.load({
97
99
  "errs.hint": "Windows paths in file-tool errors rewrite back to /c/ with NUL guidance; off keeps raw text (easier to copy while debugging).",
98
100
  "split.label": "Glob absolute-pattern split",
99
101
  "split.hint": "An absolute glob pattern (/c/.../*.md) splits into path + relative pattern; off passes it through verbatim.",
102
+ "code.label": "run_code program paths",
103
+ "code.hint": "Path literals inside a run_code program are translated through the same mount table before it runs; comments, interpolated templates, $VARs and non-path strings stay untouched, and any uncertainty leaves the whole program as written.",
100
104
  "bash.label": "Git Bash path",
101
105
  "bash.hint": "Full path of a custom bash.exe for resolving /usr mounts; empty = auto-detect the default install and PATH.",
102
106
  "bash.save": "Save",
@@ -133,6 +137,8 @@ window.__ModuleLoader__.load({
133
137
  "errs.hint": "مسارات Windows في أخطاء أدوات الملفات تُعاد بصيغة /c/ مع إرشاد NUL؛ الإيقاف يحتفظ بالنص الأصلي.",
134
138
  "split.label": "تقسيم نمط glob المطلق",
135
139
  "split.hint": "نمط glob المطلق يُقسم إلى path + نمط نسبي؛ الإيقاف يمرره كما هو.",
140
+ "code.label": "مسارات برامج run_code",
141
+ "code.hint": "تُترجم السلاسل النصية للمسارات المكتوبة داخل برنامج run_code عبر جدول التحميل نفسه قبل التشغيل؛ وتبقى التعليقات والقوالب ذات الإدراج و$VAR والسلاسل غير المسارية كما هي، وأي التباس يُبقي البرنامج كاملًا دون تغيير.",
136
142
  "bash.label": "مسار Git Bash",
137
143
  "bash.hint": "المسار الكامل لنسخة bash.exe مخصصة؛ فارغ = اكتشاف تلقائي.",
138
144
  "bash.save": "حفظ",
@@ -159,6 +165,8 @@ window.__ModuleLoader__.load({
159
165
  "errs.hint": "Windows-Pfade in Dateitool-Fehlern werden zu /c/ zurückgeschrieben; aus erhält den Originaltext.",
160
166
  "split.label": "Glob-Absolutmuster-Split",
161
167
  "split.hint": "Ein absolutes Glob-Muster zerfällt in Pfad + relatives Muster; aus übergibt es unverändert.",
168
+ "code.label": "Pfade in run_code-Programmen",
169
+ "code.hint": "Pfadliterale in einem run_code-Programm werden vor dem Start über dieselbe Mount-Tabelle übersetzt; Kommentare, interpolierte Templates, $VARs und Nicht-Pfad-Strings bleiben unangetastet, und bei Unklarheit bleibt das ganze Programm unverändert.",
162
170
  "bash.label": "Git-Bash-Pfad",
163
171
  "bash.hint": "Vollständiger Pfad einer benutzerdefinierten bash.exe; leer = automatische Erkennung.",
164
172
  "bash.save": "Speichern",
@@ -185,6 +193,8 @@ window.__ModuleLoader__.load({
185
193
  "errs.hint": "Les chemins Windows dans les erreurs des outils fichiers sont réécrits en /c/ ; désactivé conserve le texte brut.",
186
194
  "split.label": "Découpage des motifs glob absolus",
187
195
  "split.hint": "Un motif glob absolu se scinde en chemin + motif relatif ; désactivé le passe tel quel.",
196
+ "code.label": "chemins dans les programmes run_code",
197
+ "code.hint": "Les littéraux de chemin écrits dans un programme run_code sont traduits via la même table de montage avant exécution; commentaires, gabarits interpolés, $VAR et chaînes non-chemin restent intacts, et la moindre incertitude laisse le programme tel quel.",
188
198
  "bash.label": "Chemin Git Bash",
189
199
  "bash.hint": "Chemin complet d'un bash.exe personnalisé ; vide = détection automatique.",
190
200
  "bash.save": "Enregistrer",
@@ -211,6 +221,8 @@ window.__ModuleLoader__.load({
211
221
  "errs.hint": "फ़ाइल टूल की त्रुटियों में Windows पथ /c/ रूप में लिखे जाते हैं; बंद = मूल पाठ।",
212
222
  "split.label": "glob एब्सोल्यूट-पैटर्न विभाजन",
213
223
  "split.hint": "एब्सोल्यूट glob पैटर्न path + रिलेटिव पैटर्न में विभाजित होता है; बंद इसे वैसे ही पास करता है।",
224
+ "code.label": "run_code प्रोग्राम पथ",
225
+ "code.hint": "run_code प्रोग्राम में लिखे पथ लिटरल चलने से पहले उसी माउंट तालिका से अनूदित होते हैं; टिप्पणियाँ, इंटरपोलेटेड टेम्पलेट, $VAR और गैर-पथ स्ट्रिंग अछूते रहते हैं, और किसी भी अनिश्चितता पर पूरा प्रोग्राम अपरिवर्तित रहता है।",
214
226
  "bash.label": "Git Bash पथ",
215
227
  "bash.hint": "कस्टम bash.exe का पूर्ण पथ; खाली = ऑटो-डिटेक्ट।",
216
228
  "bash.save": "सहेजें",
@@ -237,6 +249,8 @@ window.__ModuleLoader__.load({
237
249
  "errs.hint": "Path Windows di error alat berkas ditulis balik ke /c/; nonaktif mempertahankan teks asli.",
238
250
  "split.label": "Pemisahan pattern glob absolut",
239
251
  "split.hint": "Pattern glob absolut dipecah menjadi path + pattern relatif; nonaktif meneruskannya apa adanya.",
252
+ "code.label": "jalur dalam program run_code",
253
+ "code.hint": "Literal jalur yang ditulis di program run_code diterjemahkan lewat tabel mount yang sama sebelum dijalankan; komentar, template berinterpolasi, $VAR, dan string non-jalur dibiarkan, dan bila ada keraguan seluruh program tidak diubah.",
240
254
  "bash.label": "Path Git Bash",
241
255
  "bash.hint": "Path lengkap bash.exe kustom; kosong = deteksi otomatis.",
242
256
  "bash.save": "Simpan",
@@ -263,6 +277,8 @@ window.__ModuleLoader__.load({
263
277
  "errs.hint": "I percorsi Windows negli errori degli strumenti file tornano in /c/; off mantiene il testo originale.",
264
278
  "split.label": "Suddivisione pattern glob assoluti",
265
279
  "split.hint": "Un pattern glob assoluto si divide in percorso + pattern relativo; off lo passa invariato.",
280
+ "code.label": "percorsi nei programmi run_code",
281
+ "code.hint": "I letterali di percorso scritti in un programma run_code vengono tradotti con la stessa tabella di mount prima dell'esecuzione; commenti, template interpolati, $VAR e stringhe non di percorso restano intatti e qualsiasi incertezza lascia il programma invariato.",
266
282
  "bash.label": "Percorso Git Bash",
267
283
  "bash.hint": "Percorso completo di un bash.exe personalizzato; vuoto = rilevamento automatico.",
268
284
  "bash.save": "Salva",
@@ -289,6 +305,8 @@ window.__ModuleLoader__.load({
289
305
  "errs.hint": "ファイルツールのエラー内の Windows パスを /c/ 形式に書き戻します;オフなら原文維持。",
290
306
  "split.label": "glob 絶対パターン分割",
291
307
  "split.hint": "絶対 glob パターンを path + 相対パターンに分割;オフならそのまま渡します。",
308
+ "code.label": "run_code プログラム内のパス",
309
+ "code.hint": "run_code プログラム内に書いた /c/... などのパスリテラルは実行前に同じマウント表で変換されます。コメント・補間テンプレート・$VAR・パス以外の文字列は変更せず、解析に不確かさがあればプログラム全体をそのまま実行します。",
292
310
  "bash.label": "Git Bash パス",
293
311
  "bash.hint": "カスタム bash.exe の完全パス;空欄なら自動検出。",
294
312
  "bash.save": "保存",
@@ -315,6 +333,8 @@ window.__ModuleLoader__.load({
315
333
  "errs.hint": "파일 도구 오류의 Windows 경로를 /c/ 형식으로 되돌립니다; 끄면 원문 유지.",
316
334
  "split.label": "glob 절대 패턴 분할",
317
335
  "split.hint": "절대 glob 패턴을 path + 상대 패턴으로 분할; 끄면 그대로 전달.",
336
+ "code.label": "run_code 프로그램 경로",
337
+ "code.hint": "run_code 프로그램에 쓴 /c/... 경로 리터럴은 실행 전에 같은 마운트 표로 변환됩니다. 주석, 보간 템플릿, $VAR, 경로가 아닌 문자열은 그대로 두고, 스캔이 불확실하면 프로그램 전체를 그대로 둡니다.",
318
338
  "bash.label": "Git Bash 경로",
319
339
  "bash.hint": "사용자 bash.exe 전체 경로; 비우면 자동 감지.",
320
340
  "bash.save": "저장",
@@ -341,6 +361,8 @@ window.__ModuleLoader__.load({
341
361
  "errs.hint": "Windows-paden in fouten van bestandstools keren terug als /c/; uit behoudt de brontekst.",
342
362
  "split.label": "Glob absoluut-patroon-splitsing",
343
363
  "split.hint": "Een absoluut glob-patroon splitst in pad + relatief patroon; uit geeft het ongewijzigd door.",
364
+ "code.label": "paden in run_code-programma's",
365
+ "code.hint": "Pad-literalen in een run_code-programma worden vóór uitvoering via dezelfde mounttabel vertaald; opmerkingen, geïnterpoleerde templates, $VAR's en niet-pad-strings blijven ongemoeid, en bij twijfel blijft het hele programma ongewijzigd.",
344
366
  "bash.label": "Git Bash-pad",
345
367
  "bash.hint": "Volledig pad van een aangepaste bash.exe; leeg = automatisch detecteren.",
346
368
  "bash.save": "Opslaan",
@@ -367,6 +389,8 @@ window.__ModuleLoader__.load({
367
389
  "errs.hint": "Ścieżki Windows w błędach narzędzi plikowych wracają jako /c/; wył. zachowuje oryginalny tekst.",
368
390
  "split.label": "Podział wzorców glob absolutnych",
369
391
  "split.hint": "Absolutny wzorzec glob dzieli się na ścieżkę + wzorzec względny; wył. przekazuje bez zmian.",
392
+ "code.label": "ścieżki w programach run_code",
393
+ "code.hint": "Literały ścieżek w programie run_code są tłumaczone przez tę samą tabelę montowania przed uruchomieniem; komentarze, szablony z interpolacją, $VAR i ciągi niebędące ścieżkami pozostają nietknięte, a każda niepewność pozostawia program bez zmian.",
370
394
  "bash.label": "Ścieżka Git Bash",
371
395
  "bash.hint": "Pełna ścieżka własnego bash.exe; puste = autodetekcja.",
372
396
  "bash.save": "Zapisz",
@@ -393,6 +417,8 @@ window.__ModuleLoader__.load({
393
417
  "errs.hint": "Caminhos Windows nos erros das ferramentas voltam como /c/; desligado mantém o texto original.",
394
418
  "split.label": "Divisão de padrão glob absoluto",
395
419
  "split.hint": "Um padrão glob absoluto divide em caminho + padrão relativo; desligado passa-o inalterado.",
420
+ "code.label": "caminhos em programas run_code",
421
+ "code.hint": "Literais de caminho escritos num programa run_code são traduzidos pela mesma tabela de montagem antes da execução; comentários, modelos interpolados, $VAR e strings que não são caminhos ficam intactos, e qualquer incerteza deixa o programa como está.",
396
422
  "bash.label": "Caminho do Git Bash",
397
423
  "bash.hint": "Caminho completo de um bash.exe personalizado; vazio = detecção automática.",
398
424
  "bash.save": "Salvar",
@@ -419,6 +445,8 @@ window.__ModuleLoader__.load({
419
445
  "errs.hint": "Пути Windows в ошибках файловых инструментов возвращаются как /c/; выкл сохраняет исходный текст.",
420
446
  "split.label": "Разбор абсолютного glob-шаблона",
421
447
  "split.hint": "Абсолютный glob-шаблон разбивается на path + относительный шаблон; выкл передаёт как есть.",
448
+ "code.label": "пути в программах run_code",
449
+ "code.hint": "Строковые литералы путей в программе run_code переводятся по той же таблице монтирования до запуска; комментарии, шаблоны с интерполяцией, $VAR и строки-не-пути не трогаются, а при любой неопределённости программа остаётся без изменений.",
422
450
  "bash.label": "Путь Git Bash",
423
451
  "bash.hint": "Полный путь кастомного bash.exe; пусто = автоопределение.",
424
452
  "bash.save": "Сохранить",
@@ -445,6 +473,8 @@ window.__ModuleLoader__.load({
445
473
  "errs.hint": "Windows-sökvägar i filverktygens fel skrivs tillbaka som /c/; av behåller originaltexten.",
446
474
  "split.label": "Glob absolut mönsterdelning",
447
475
  "split.hint": "Ett absolut glob-mönster delas i sökväg + relativt mönster; av skickar det oförändrat.",
476
+ "code.label": "sökvägar i run_code-program",
477
+ "code.hint": "Sökvägslitteraler i ett run_code-program översätts via samma monteringstabell före körning; kommentarer, interpolerade mallar, $VAR och strängar som inte är sökvägar lämnas orörda, och vid minsta osäkerhet lämnas hela programmet oförändrat.",
448
478
  "bash.label": "Git Bash-sökväg",
449
479
  "bash.hint": "Fullständig sökväg till egen bash.exe; tom = automatisk detektering.",
450
480
  "bash.save": "Spara",
@@ -471,6 +501,8 @@ window.__ModuleLoader__.load({
471
501
  "errs.hint": "เส้นทาง Windows ในข้อผิดพลาดของเครื่องมือไฟล์เขียนกลับเป็น /c/; ปิดคงข้อความต้นฉบับ",
472
502
  "split.label": "การแยก pattern glob แบบสัมบูรณ์",
473
503
  "split.hint": "pattern glob สัมบูรณ์แยกเป็น path + pattern สัมพัทธ์; ปิดส่งต่อตามเดิม",
504
+ "code.label": "พาธในโปรแกรม run_code",
505
+ "code.hint": "สตริงพาธที่เขียนในโปรแกรม run_code จะถูกแปลผ่านตาราง mount เดียวกันก่อนรัน ความคิดเห็น เทมเพลตที่มีการแทรก $VAR และสตริงที่ไม่ใช่พาธจะไม่ถูกแตะ และหากไม่แน่ใจทั้งโปรแกรมจะไม่ถูกแก้ไข",
474
506
  "bash.label": "เส้นทาง Git Bash",
475
507
  "bash.hint": "เส้นทางเต็มของ bash.exe แบบกำหนดเอง; ว่าง = ตรวจจับอัตโนมัติ",
476
508
  "bash.save": "บันทึก",
@@ -497,6 +529,8 @@ window.__ModuleLoader__.load({
497
529
  "errs.hint": "Dosya aracı hatalarındaki Windows yolları /c/ olarak geri yazılır; kapalı özgün metni korur.",
498
530
  "split.label": "Glob mutlak örüntü ayrıştırma",
499
531
  "split.hint": "Mutlak glob örüntüsü path + göreli örüntüye ayrılır; kapalı olduğu gibi geçirir.",
532
+ "code.label": "run_code program yolları",
533
+ "code.hint": "Bir run_code programında yazılan yol dizeleri çalıştırılmadan önce aynı bağlama tablosuyla çevrilir; yorumlar, enterpolasyonlu şablonlar, $VAR ve yol olmayan dizeler olduğu gibi kalır, herhangi bir belirsizlikte programın tamamı değişmeden bırakılır.",
500
534
  "bash.label": "Git Bash yolu",
501
535
  "bash.hint": "Özel bash.exe tam yolu; boş = otomatik algılama.",
502
536
  "bash.save": "Kaydet",
@@ -523,6 +557,8 @@ window.__ModuleLoader__.load({
523
557
  "errs.hint": "Đường dẫn Windows trong lỗi công cụ tệp viết lại thành /c/; tắt giữ nguyên văn bản gốc.",
524
558
  "split.label": "Tách pattern glob tuyệt đối",
525
559
  "split.hint": "Pattern glob tuyệt đối tách thành path + pattern tương đối; tắt truyền nguyên văn.",
560
+ "code.label": "đường dẫn trong chương trình run_code",
561
+ "code.hint": "Chuỗi đường dẫn viết trong chương trình run_code được dịch qua cùng bảng mount trước khi chạy; chú thích, template nội suy, $VAR và chuỗi không phải đường dẫn được giữ nguyên, và mọi điểm không chắc chắn sẽ khiến cả chương trình không bị sửa.",
526
562
  "bash.label": "Đường dẫn Git Bash",
527
563
  "bash.hint": "Đường dẫn đầy đủ của bash.exe tùy chỉnh; để trống = tự dò tìm.",
528
564
  "bash.save": "Lưu",
@@ -549,6 +585,8 @@ window.__ModuleLoader__.load({
549
585
  "errs.hint": "檔案工具報錯入面嘅 Windows 路徑翻回 /c/ 形式;關閉就保留原文。",
550
586
  "split.label": "glob 絕對路徑拆分",
551
587
  "split.hint": "glob 嘅絕對 pattern 自動拆做 path + 相對 pattern;關閉就原樣傳遞。",
588
+ "code.label": "run_code 程式內路徑",
589
+ "code.hint": "run_code 程式內寫的 /c/... 路徑字面量會在執行前按同一張掛載表翻譯;註解、插值模板、$VAR 與非路徑字串不動,掃描有任何不確定就整份不改。",
552
590
  "bash.label": "Git Bash 路徑",
553
591
  "bash.hint": "自訂 bash.exe 完整路徑;留空自動探測。",
554
592
  "bash.save": "儲存",
@@ -575,6 +613,8 @@ window.__ModuleLoader__.load({
575
613
  "errs.hint": "檔案工具報錯入面嘅 Windows 路徑翻回 /c/ 形式;關閉就保留原文。",
576
614
  "split.label": "glob 絕對路徑拆分",
577
615
  "split.hint": "glob 嘅絕對 pattern 自動拆做 path + 相對 pattern;關閉就原樣傳遞。",
616
+ "code.label": "run_code 程式內路徑",
617
+ "code.hint": "run_code 程式內寫的 /c/... 路徑字面量會在執行前按同一張掛載表翻譯;註解、插值模板、$VAR 與非路徑字串不動,掃描有任何不確定就整份不改。",
578
618
  "bash.label": "Git Bash 路徑",
579
619
  "bash.hint": "自訂 bash.exe 完整路徑;留空自動探測。",
580
620
  "bash.save": "儲存",
@@ -601,6 +641,8 @@ window.__ModuleLoader__.load({
601
641
  "errs.hint": "檔案工具報錯裡的 Windows 路徑翻回 /c/ 形式;關閉則保留原文。",
602
642
  "split.label": "glob 絕對路徑拆分",
603
643
  "split.hint": "glob 的絕對 pattern 自動拆為 path + 相對 pattern;關閉則原樣傳遞。",
644
+ "code.label": "run_code 程式內路徑",
645
+ "code.hint": "run_code 程式內寫的 /c/... 路徑字面量會在執行前按同一張掛載表翻譯;註解、插值模板、$VAR 與非路徑字串不動,掃描有任何不確定就整份不改。",
604
646
  "bash.label": "Git Bash 路徑",
605
647
  "bash.hint": "自訂 bash.exe 完整路徑;留空自動探測。",
606
648
  "bash.save": "儲存",
@@ -849,6 +891,7 @@ window.__ModuleLoader__.load({
849
891
  var mounts = snap.value.virtualMounts !== false;
850
892
  var errs = snap.value.errorDialect !== false;
851
893
  var splits = snap.value.globSplit !== false;
894
+ var codes = snap.value.codePaths !== false;
852
895
 
853
896
  var dialectSection = E("div", { className: "gb-section" },
854
897
  E("div", { className: "gb-sectionTitle" }, t("sec.dialect")),
@@ -889,6 +932,15 @@ window.__ModuleLoader__.load({
889
932
  E("button", { type: "button", className: "gb-segBtn" + (!splits ? " gb-segActive" : ""), onClick: function () { if (splits) writeField("globSplit", false); } }, t("switch.off")),
890
933
  ),
891
934
  E("p", { className: "gb-hint" }, t("split.hint")),
935
+ E("div", { className: "gb-row" },
936
+ E("span", { className: "gb-rowLabel" }, t("code.label") + ":"),
937
+ E("span", { className: "gb-rowValue" }, codes ? t("state.on") : t("state.off")),
938
+ ),
939
+ E("div", { className: "gb-seg" },
940
+ E("button", { type: "button", className: "gb-segBtn" + (codes ? " gb-segActive" : ""), onClick: function () { if (!codes) writeField("codePaths", true); } }, t("switch.on")),
941
+ E("button", { type: "button", className: "gb-segBtn" + (!codes ? " gb-segActive" : ""), onClick: function () { if (codes) writeField("codePaths", false); } }, t("switch.off")),
942
+ ),
943
+ E("p", { className: "gb-hint" }, t("code.hint")),
892
944
  E("div", { className: "gb-row" },
893
945
  E("span", { className: "gb-rowLabel" }, t("bash.label") + ":"),
894
946
  ),
package/src/index.js CHANGED
@@ -663,10 +663,10 @@ export function installRegisterShim(reg) {
663
663
  const SETTINGS_NAMESPACE = 'gitbash-shell'
664
664
 
665
665
  /** The full directive text, injected only while posixPaths is on. */
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
+ 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. Path literals written inside a run_code program are translated the same way before the program runs; shell expansion is not available there, so spell paths out instead of relying on $VARS.'
667
667
 
668
668
  /** Strict drive-root-only directive (v0.19.0): used while virtualMounts is off. */
669
- const POSIX_DIRECTIVE_TEXT_STRICT = 'The working shell is Git for Windows bash: paths use MSYS drive roots (/c/Users/...), and every tool accepts that form directly.'
669
+ const POSIX_DIRECTIVE_TEXT_STRICT = 'The working shell is Git for Windows bash: paths use MSYS drive roots (/c/Users/...), and every tool accepts that form directly — including path literals written inside a run_code program, which are translated before the program runs.'
670
670
 
671
671
  // Official runtime counterpart to the directive (v0.11.0): dsh-shell-env is
672
672
  // the host-plane registry behind the model-visible $DSH_* facts, and the
@@ -696,7 +696,7 @@ export function readPosixPaths(ctxLike) {
696
696
  * first. All default ON (schema defaults); never throws.
697
697
  */
698
698
  export function readDialectSettings(ctxLike) {
699
- const fallback = { posixPaths: false, virtualMounts: false, globSplit: false, errorDialect: false, bashPath: '' }
699
+ const fallback = { posixPaths: false, virtualMounts: false, globSplit: false, errorDialect: false, codePaths: false, bashPath: '' }
700
700
  try {
701
701
  const settings = ctxLike && typeof ctxLike.get === 'function' ? ctxLike.get('settings') : undefined
702
702
  const value = settings && typeof settings.get === 'function' ? settings.get(SETTINGS_NAMESPACE) : undefined
@@ -706,6 +706,7 @@ export function readDialectSettings(ctxLike) {
706
706
  virtualMounts: v.virtualMounts === true,
707
707
  globSplit: v.globSplit === true,
708
708
  errorDialect: v.errorDialect === true,
709
+ codePaths: v.codePaths === true,
709
710
  bashPath: typeof v.bashPath === 'string' ? v.bashPath : '',
710
711
  }
711
712
  } catch {
@@ -1076,6 +1077,232 @@ export function translatePathArguments(args, env) {
1076
1077
  return changed ? next : args
1077
1078
  }
1078
1079
 
1080
+ // ── MSYS paths written INSIDE a run_code program (v0.20.0) ───────────────
1081
+ //
1082
+ // run_code hands the model's program to a native Node process: a path literal
1083
+ // in that source is plain program DATA, so '/c/Users/x' is resolved by Node
1084
+ // against the current drive ('<drive>:\\c\\Users\\x') — that is where the stray
1085
+ // C:\\c\\... directories came from, since the tool-argument translation never
1086
+ // sees it (see AGENTS.md 4c). The same mount table is therefore applied to the
1087
+ // program's string literals — but ONLY when the whole program scans cleanly and
1088
+ // a literal's ENTIRE content is an absolute MSYS path. Anything unclear — an
1089
+ // unterminated literal, a template with ${} interpolation, a regex we cannot
1090
+ // place — turns the whole rewrite into a no-op: a half-rewritten program would
1091
+ // be far worse than an untranslated one, and this layer never guesses.
1092
+ //
1093
+ // Deliberately NOT translated: shell-style '$VAR/x' (a JS literal is data, not
1094
+ // a shell word) and anything carrying a scheme ('http://...').
1095
+
1096
+ /** Source text allowed inside a rewritten literal: no escapes, no dollar sign. */
1097
+ const CODE_LITERAL_SAFE = /^[A-Za-z0-9._@+~\-/ ]+$/
1098
+
1099
+ /** Previous significant character that lets a '/' start a regex literal. */
1100
+ function regexCanStart(previous) {
1101
+ if (previous === '') return true
1102
+ return '(,=:[!&|?{};+-*%<>~^'.indexOf(previous) >= 0
1103
+ }
1104
+
1105
+ /** Index after the closing quote of the literal at `index`, or -1. */
1106
+ function skipQuotedLiteral(code, index) {
1107
+ const quote = code[index]
1108
+ let i = index + 1
1109
+ while (i < code.length) {
1110
+ const c = code[i]
1111
+ if (c === '\\') { i += 2; continue }
1112
+ if (c === '\n') return -1
1113
+ if (c === quote) return i + 1
1114
+ i += 1
1115
+ }
1116
+ return -1
1117
+ }
1118
+
1119
+ /** Index after a regex literal (body + flags), or -1 when it cannot be walked. */
1120
+ function skipRegexLiteral(code, index) {
1121
+ let i = index + 1
1122
+ let inClass = false
1123
+ while (i < code.length) {
1124
+ const c = code[i]
1125
+ if (c === '\\') { i += 2; continue }
1126
+ if (c === '\n') return -1
1127
+ if (c === '[') inClass = true
1128
+ else if (c === ']') inClass = false
1129
+ else if (c === '/' && inClass === false) {
1130
+ i += 1
1131
+ while (i < code.length && /[a-z]/i.test(code[i])) i += 1
1132
+ return i
1133
+ }
1134
+ i += 1
1135
+ }
1136
+ return -1
1137
+ }
1138
+
1139
+ /** Index after the '}' matching an already-consumed interpolation, or -1. */
1140
+ function skipBracedExpression(code, index) {
1141
+ let depth = 1
1142
+ let i = index
1143
+ let last = ''
1144
+ while (i < code.length) {
1145
+ const c = code[i]
1146
+ const next = code[i + 1]
1147
+ if (c === '/' && next === '/') {
1148
+ const nl = code.indexOf('\n', i)
1149
+ if (nl === -1) return -1
1150
+ i = nl
1151
+ continue
1152
+ }
1153
+ if (c === '/' && next === '*') {
1154
+ const close = code.indexOf('*/', i + 2)
1155
+ if (close === -1) return -1
1156
+ i = close + 2
1157
+ continue
1158
+ }
1159
+ if (c === '"' || c === "'") {
1160
+ const end = skipQuotedLiteral(code, i)
1161
+ if (end === -1) return -1
1162
+ i = end
1163
+ last = 'x'
1164
+ continue
1165
+ }
1166
+ if (c === '`') {
1167
+ const inner = skipTemplateLiteral(code, i)
1168
+ if (inner === null) return -1
1169
+ i = inner.end
1170
+ last = 'x'
1171
+ continue
1172
+ }
1173
+ if (c === '/' && regexCanStart(last)) {
1174
+ const end = skipRegexLiteral(code, i)
1175
+ if (end === -1) return -1
1176
+ i = end
1177
+ last = 'x'
1178
+ continue
1179
+ }
1180
+ if (c === '{') depth += 1
1181
+ else if (c === '}') {
1182
+ depth -= 1
1183
+ if (depth === 0) return i + 1
1184
+ }
1185
+ if (c.trim() !== '') last = c
1186
+ i += 1
1187
+ }
1188
+ return -1
1189
+ }
1190
+
1191
+ /**
1192
+ * Walk a template literal. Returns { end, plain } — plain means it holds no
1193
+ * interpolation, i.e. its text is one literal value — or null when the
1194
+ * template could not be walked to its end.
1195
+ */
1196
+ function skipTemplateLiteral(code, index) {
1197
+ let i = index + 1
1198
+ let plain = true
1199
+ while (i < code.length) {
1200
+ const c = code[i]
1201
+ if (c === '\\') { i += 2; continue }
1202
+ if (c === '`') return { end: i + 1, plain: plain }
1203
+ if (c === '$' && code[i + 1] === '{') {
1204
+ plain = false
1205
+ const after = skipBracedExpression(code, i + 2)
1206
+ if (after === -1) return null
1207
+ i = after
1208
+ continue
1209
+ }
1210
+ i += 1
1211
+ }
1212
+ return null
1213
+ }
1214
+
1215
+ /**
1216
+ * Every plain string-literal span of a program, or null when the source could
1217
+ * not be walked with certainty. Spans cover the CONTENT (quotes excluded).
1218
+ */
1219
+ export function scanCodeLiterals(code) {
1220
+ const spans = []
1221
+ let i = 0
1222
+ let last = ''
1223
+ while (i < code.length) {
1224
+ const c = code[i]
1225
+ const next = code[i + 1]
1226
+ if (c === '/' && next === '/') {
1227
+ const nl = code.indexOf('\n', i)
1228
+ if (nl === -1) return null
1229
+ i = nl
1230
+ continue
1231
+ }
1232
+ if (c === '/' && next === '*') {
1233
+ const close = code.indexOf('*/', i + 2)
1234
+ if (close === -1) return null
1235
+ i = close + 2
1236
+ continue
1237
+ }
1238
+ if (c === '"' || c === "'") {
1239
+ const end = skipQuotedLiteral(code, i)
1240
+ if (end === -1) return null
1241
+ spans.push({ start: i + 1, end: end - 1 })
1242
+ i = end
1243
+ last = 'x'
1244
+ continue
1245
+ }
1246
+ if (c === '`') {
1247
+ const template = skipTemplateLiteral(code, i)
1248
+ if (template === null) return null
1249
+ if (template.plain) spans.push({ start: i + 1, end: template.end - 1 })
1250
+ i = template.end
1251
+ last = 'x'
1252
+ continue
1253
+ }
1254
+ if (c === '/' && regexCanStart(last)) {
1255
+ const end = skipRegexLiteral(code, i)
1256
+ if (end === -1) return null
1257
+ i = end
1258
+ last = 'x'
1259
+ continue
1260
+ }
1261
+ if (c.trim() !== '') last = c
1262
+ i += 1
1263
+ }
1264
+ return spans
1265
+ }
1266
+
1267
+ /**
1268
+ * Translates MSYS path literals inside a run_code program. Returns the input
1269
+ * unchanged when nothing matched or when the scan was not certain.
1270
+ * @param {string} code the model's program
1271
+ * @param {{tmpDir?: string, home?: string, gitRoot?: string}|null} env mounts
1272
+ * @returns {string} the program to execute
1273
+ */
1274
+ export function rewriteCodePaths(code, env) {
1275
+ if (typeof code !== 'string' || code === '') return code
1276
+ if (code.indexOf('/') === -1) return code
1277
+ const spans = scanCodeLiterals(code)
1278
+ if (spans === null) return code
1279
+ let out = ''
1280
+ let cursor = 0
1281
+ let changed = false
1282
+ for (const span of spans) {
1283
+ const raw = code.slice(span.start, span.end)
1284
+ if (raw.charCodeAt(0) !== 47 && raw.startsWith('~/') === false) continue
1285
+ if (raw.indexOf('$') >= 0 || raw.indexOf('\\') >= 0) continue
1286
+ if (CODE_LITERAL_SAFE.test(raw) === false) continue
1287
+ if (raw.indexOf('://') >= 0) continue
1288
+ const translated = translateMsysPath(raw, env)
1289
+ if (typeof translated !== 'string' || translated === raw) continue
1290
+ // What lands in the program is SOURCE text, not the value: a backslash in
1291
+ // the translated path (the NUL device) must be escaped for the literal it
1292
+ // is written into, and a quote inside it (a home directory with an
1293
+ // apostrophe) would end that literal early — refuse rather than corrupt.
1294
+ const quote = code[span.start - 1]
1295
+ if (translated.indexOf(quote) >= 0) continue
1296
+ if (quote === '`' && translated.indexOf('${') >= 0) continue
1297
+ const source = translated.replace(/\\/g, '\\\\')
1298
+ out += code.slice(cursor, span.start) + source
1299
+ cursor = span.end
1300
+ changed = true
1301
+ }
1302
+ if (changed === false) return code
1303
+ return out + code.slice(cursor)
1304
+ }
1305
+
1079
1306
  // ── absolute glob patterns (v0.17.0) ────────────────────────────────────
1080
1307
  //
1081
1308
  // The glob tool takes its search root in the `path` argument and expects a
@@ -1372,6 +1599,7 @@ export async function apply(ctx, config = {}) {
1372
1599
  virtualMounts: Schema.boolean().default(true),
1373
1600
  globSplit: Schema.boolean().default(true),
1374
1601
  errorDialect: Schema.boolean().default(true),
1602
+ codePaths: Schema.boolean().default(true),
1375
1603
  bashPath: Schema.string().default(''),
1376
1604
  adoptSidebar: Schema.boolean().default(true),
1377
1605
  }))
@@ -1487,6 +1715,15 @@ export async function apply(ctx, config = {}) {
1487
1715
  const globTranslated = translateGlobArguments(translated, env)
1488
1716
  if (globTranslated !== translated) translated = globTranslated
1489
1717
  }
1718
+ // v0.20.0: a run_code program is DATA for a native Node process, so
1719
+ // a '/c/...' literal inside it never reached this layer and landed
1720
+ // on the current drive as '<drive>:\\c\\...'. The same mount table
1721
+ // now covers the program's path literals (see rewriteCodePaths;
1722
+ // anything unclear leaves the code untouched).
1723
+ if (exec.name === 'run_code' && dialect.codePaths && typeof translated.code === 'string') {
1724
+ const rewritten = rewriteCodePaths(translated.code, env)
1725
+ if (rewritten !== translated.code) translated = { ...translated, code: rewritten }
1726
+ }
1490
1727
  if (translated !== exec.arguments) exec.arguments = translated
1491
1728
  }
1492
1729
  } catch { /* never block a call on translation */ }
@@ -1661,4 +1898,4 @@ export async function apply(ctx, config = {}) {
1661
1898
  }
1662
1899
 
1663
1900
  // Test surface: pure helpers, no Cordis context required.
1664
- export const _internal = { PRESET_IDS, translateMsysPath, translatePathArguments, translateGlobArguments, buildTranslateEnv, rewriteErrorContent, ERROR_CONTENT_TOOLS, readPosixPaths, readAdoptSidebar, readDialectSettings, 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 }
1901
+ export const _internal = { PRESET_IDS, translateMsysPath, translatePathArguments, rewriteCodePaths, scanCodeLiterals, translateGlobArguments, buildTranslateEnv, rewriteErrorContent, ERROR_CONTENT_TOOLS, readPosixPaths, readAdoptSidebar, readDialectSettings, 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 }