dsh-gitbash-shell 0.15.0 → 0.16.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/assets/cordis-gitbash/agent.cordis.ptc.ps.yml +11 -1
- package/dsh.plugin.json +1 -1
- package/package.json +2 -2
- package/src/client.js +116 -26
- package/src/index.js +189 -59
|
@@ -34,10 +34,20 @@
|
|
|
34
34
|
|
|
35
35
|
Two planes decide where an edit belongs. The HOST composition holds the registries and anything shared across sessions — persistence, the sandbox and approval stack, the model route, the subagent registry and its backends. An AGENT PRESET holds what one session contributes to those registries: its tools, its persona, its prompt sections. A row that publishes a service belongs in the host composition, or inside an `isolate` realm if the preset genuinely owns that service and nothing outside one agent reads it.
|
|
36
36
|
|
|
37
|
-
Presets you author live one directory per preset under `${DSH_HOME:-$HOME/.dsh}/.agent-presets/<id
|
|
37
|
+
Presets you author live one directory per preset under `${DSH_HOME:-$HOME/.dsh}/.agent-presets/<id>/`. Load `editing-cordis-compositions` for file discovery and copying instructions. NEVER edit or delete the shipped preset install (the `agent-presets` directory beside the deployment's own config): it belongs to the deployment, an upgrade overwrites it, and corrupting the `cordis` preset would disable this very mode. To change what a shipped preset does, copy its composition into a new preset directory and edit the copy.
|
|
38
38
|
|
|
39
39
|
Load the `editing-cordis-compositions` skill before writing or changing a composition.
|
|
40
40
|
|
|
41
|
+
Use plugin_manager for persistent bundle installation, removal and enablement in the current profile. Author plugin code and configuration as ordinary workspace bundle files. Changes affect every session in that profile. Read saved-state and activation outcomes separately; restart-required means the new capability is not available yet.
|
|
42
|
+
|
|
43
|
+
In Creator mode, requests to make a visual object, decoration, or widget mean creating an installed UI plugin that displays it in this Harness Web UI, unless the user specifies another destination. Choose reasonable visual details and proceed. Load cordis-plugin-development, inspect the Client slots, build the plugin in the workspace, and install it with plugin_manager. Install a minimal working version before visual refinement; use the connected page as its preview. Verify that the open page renders it; a standalone image or HTML file does not complete an in-app creation request.
|
|
44
|
+
|
|
45
|
+
Load the cordis-plugin-development skill before authoring an installed plugin. Use cordis_inspect_list to discover Host and Client providers, then cordis_inspect_query to read exact Service, Event, Tool, Theme or Slot APIs. These tools are read-only; queries do not invoke business methods.
|
|
46
|
+
|
|
47
|
+
To connect an MCP server, create a configuration-only bundle whose patch inserts @deepseek-ai/dsh-mcp-client, then install it with plugin_manager. Load cordis-plugin-development for the package and YAML examples. After successful activation, call one of the newly available mcp__<serverName>__<tool> tools to verify the connection.
|
|
48
|
+
|
|
49
|
+
Use installed bundles for new plugin code. Package installation may require explicit user approval for build scripts. Preserve returned failures and pending states; only report success after observing the requested capability.
|
|
50
|
+
|
|
41
51
|
- id: agent-instructions
|
|
42
52
|
name: '@deepseek-ai/dsh-agent-instructions'
|
|
43
53
|
config:
|
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.16.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,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-gitbash-shell",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.16.1",
|
|
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": {
|
|
7
7
|
"type": "git",
|
package/src/client.js
CHANGED
|
@@ -63,6 +63,8 @@ window.__ModuleLoader__.load({
|
|
|
63
63
|
"switch.off": "停用",
|
|
64
64
|
"error": "写入失败",
|
|
65
65
|
"hint": "启用后:所有工具(bash 命令与 workdir、read/write/edit/read_image/glob/grep 的路径参数)统一使用 MSYS 盘根 POSIX 路径(/c/Users/...);文件工具的路径参数由宿主自动翻译,模型无感。停用后恢复 dsh 原生行为(文件工具用 Windows 路径)。bash 始终是 Git Bash,不受此开关影响。",
|
|
66
|
+
"adopt.label": "接管侧栏终端",
|
|
67
|
+
"adopt.hint": "开启时把 dsh-better-sidebar 的终端 shell 写成 Git Bash(默认开启);关闭后恢复接管前的值,已手动改过的终端设置不会被碰。模型侧的 bash 工具不受此开关影响——那由插件本体提供。",
|
|
66
68
|
};
|
|
67
69
|
|
|
68
70
|
var en = {
|
|
@@ -75,6 +77,8 @@ window.__ModuleLoader__.load({
|
|
|
75
77
|
"switch.off": "Disable",
|
|
76
78
|
"error": "write failed",
|
|
77
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 host translates path fields for the file tools 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
|
+
"adopt.label": "Adopt sidebar terminal",
|
|
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.",
|
|
78
82
|
};
|
|
79
83
|
|
|
80
84
|
/* Third-language dictionaries: one entry per language, each preceded
|
|
@@ -97,6 +101,8 @@ window.__ModuleLoader__.load({
|
|
|
97
101
|
"switch.off": "تعطيل",
|
|
98
102
|
"error": "فشل الكتابة",
|
|
99
103
|
"hint": "عند التفعيل: تستخدم كل الأدوات (أوامر bash و workdir، ومعاملات المسار في read/write/edit/read_image/glob/grep) مسارات POSIX من جذر قرص MSYS (/c/Users/...)؛ ويتولّى المضيف ترجمة حقول المسار لأدوات الملفات تلقائيًا. عند التعطيل يعود السلوك الأصلي لـ dsh (مسارات Windows لأدوات الملفات). يبقى bash دائمًا Git Bash ما دامت الإضافة مثبَّتة؛ هذا المفتاح لا يحكم سوى لهجة المسارات بين الأدوات.",
|
|
104
|
+
"adopt.label": "تبنّي طرفية الشريط الجانبي",
|
|
105
|
+
"adopt.hint": "عند التفعيل (افتراضي) تُكتب Git Bash كـ shell لطرفية dsh-better-sidebar؛ وعند التعطيل تُستعاد القيمة السابقة ولا تُلمس القيمة المختارة يدويًا أبدًا. أداة bash الخاصة بالنموذج لا تتأثر — الإضافة نفسها توفرها.",
|
|
100
106
|
},
|
|
101
107
|
/* locale: de */
|
|
102
108
|
"de": {
|
|
@@ -109,6 +115,8 @@ window.__ModuleLoader__.load({
|
|
|
109
115
|
"switch.off": "Deaktivieren",
|
|
110
116
|
"error": "Schreiben fehlgeschlagen",
|
|
111
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 der Dateitools 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
|
+
"adopt.label": "Sidebar-Terminal übernehmen",
|
|
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.",
|
|
112
120
|
},
|
|
113
121
|
/* locale: fr */
|
|
114
122
|
"fr": {
|
|
@@ -121,6 +129,8 @@ window.__ModuleLoader__.load({
|
|
|
121
129
|
"switch.off": "Désactiver",
|
|
122
130
|
"error": "échec de l'écriture",
|
|
123
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 automatiquement les champs de chemin des outils de fichiers. 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
|
+
"adopt.label": "Adopter le terminal latéral",
|
|
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.",
|
|
124
134
|
},
|
|
125
135
|
/* locale: hi */
|
|
126
136
|
"hi": {
|
|
@@ -133,6 +143,8 @@ window.__ModuleLoader__.load({
|
|
|
133
143
|
"switch.off": "अक्षम करें",
|
|
134
144
|
"error": "लिखना विफल रहा",
|
|
135
145
|
"hint": "सक्षम होने पर: सभी टूल (bash कमांड और workdir, तथा read/write/edit/read_image/glob/grep के पथ तर्क) MSYS ड्राइव-रूट POSIX पथ (/c/Users/...) का उपयोग करते हैं; फ़ाइल टूल के पथ फ़ील्ड होस्ट स्वतः अनुवादित करता है। अक्षम करने पर dsh का मूल व्यवहार बहाल होता है (फ़ाइल टूल के लिए Windows पथ)। जब तक प्लगइन इंस्टॉल है bash हमेशा Git Bash रहता है; यह स्विच केवल टूल के बीच पथ शैली नियंत्रित करता है।",
|
|
146
|
+
"adopt.label": "साइडबार टर्मिनल अपनाएँ",
|
|
147
|
+
"adopt.hint": "चालू (डिफ़ॉल्ट) होने पर dsh-better-sidebar के टर्मिनल में Git Bash लिखा जाता है; बंद करने पर पहले वाली मान बहाल होती है और मैन्युअल चुनी गई सेटिंग कभी नहीं छुई जाती। मॉडल का bash टूल अप्रभावित रहता है — वह प्लगइन स्वयं देता है।",
|
|
136
148
|
},
|
|
137
149
|
/* locale: id */
|
|
138
150
|
"id": {
|
|
@@ -145,6 +157,8 @@ window.__ModuleLoader__.load({
|
|
|
145
157
|
"switch.off": "Nonaktifkan",
|
|
146
158
|
"error": "gagal menulis",
|
|
147
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/...); host menerjemahkan bidang path untuk alat berkas 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
|
+
"adopt.label": "Adopsi terminal sidebar",
|
|
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.",
|
|
148
162
|
},
|
|
149
163
|
/* locale: it */
|
|
150
164
|
"it": {
|
|
@@ -157,6 +171,8 @@ window.__ModuleLoader__.load({
|
|
|
157
171
|
"switch.off": "Disattiva",
|
|
158
172
|
"error": "scrittura non riuscita",
|
|
159
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 degli strumenti per i file. 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
|
+
"adopt.label": "Adotta il terminale laterale",
|
|
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.",
|
|
160
176
|
},
|
|
161
177
|
/* locale: ja */
|
|
162
178
|
"ja": {
|
|
@@ -169,6 +185,8 @@ window.__ModuleLoader__.load({
|
|
|
169
185
|
"switch.off": "無効にする",
|
|
170
186
|
"error": "書き込みに失敗しました",
|
|
171
187
|
"hint": "有効にすると、すべてのツール(bash コマンドと workdir、read/write/edit/read_image/glob/grep のパス引数)が MSYS ドライブルートの POSIX パス(/c/Users/...)を使います。ファイルツールのパスフィールドはホストが自動的に変換します。無効にすると dsh 本来の動作(ファイルツールは Windows パス)に戻ります。bash はプラグインがインストールされている限り常に Git Bash で、このスイッチの影響を受けません。",
|
|
188
|
+
"adopt.label": "サイドバーターミナルを引き継ぐ",
|
|
189
|
+
"adopt.hint": "オン(既定)では dsh-better-sidebar のターミナルシェルに Git Bash を書き込みます。オフにすると以前の値へ戻し、手動で選択した設定には決して触れません。モデル側の bash ツールには影響しません——それはプラグイン本体が提供します。",
|
|
172
190
|
},
|
|
173
191
|
/* locale: ko */
|
|
174
192
|
"ko": {
|
|
@@ -181,6 +199,8 @@ window.__ModuleLoader__.load({
|
|
|
181
199
|
"switch.off": "사용 안 함",
|
|
182
200
|
"error": "쓰기 실패",
|
|
183
201
|
"hint": "켜면 모든 도구(bash 명령과 workdir, read/write/edit/read_image/glob/grep의 경로 인수)가 MSYS 드라이브 루트 POSIX 경로(/c/Users/...)를 사용합니다. 파일 도구의 경로 필드는 호스트가 자동으로 변환합니다. 끄면 dsh 기본 동작(파일 도구에 Windows 경로 사용)으로 돌아갑니다. 플러그인이 설치되어 있는 동안 bash는 항상 Git Bash이며 이 스위치의 영향을 받지 않습니다.",
|
|
202
|
+
"adopt.label": "사이드바 터미널 인수",
|
|
203
|
+
"adopt.hint": "켜짐(기본)이면 dsh-better-sidebar 터미널 셸에 Git Bash를 기록하고, 끄면 이전 값을 복원하며 수동으로 고른 설정은 절대 건드리지 않습니다. 모델 측 bash 도구에는 영향이 없습니다 — 플러그인이 직접 제공합니다.",
|
|
184
204
|
},
|
|
185
205
|
/* locale: nl */
|
|
186
206
|
"nl": {
|
|
@@ -193,6 +213,8 @@ window.__ModuleLoader__.load({
|
|
|
193
213
|
"switch.off": "Uitschakelen",
|
|
194
214
|
"error": "schrijven mislukt",
|
|
195
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 host vertaalt de padvelden voor de bestandstools 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
|
+
"adopt.label": "Zijbalkterminal overnemen",
|
|
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.",
|
|
196
218
|
},
|
|
197
219
|
/* locale: pl */
|
|
198
220
|
"pl": {
|
|
@@ -205,6 +227,8 @@ window.__ModuleLoader__.load({
|
|
|
205
227
|
"switch.off": "Wyłącz",
|
|
206
228
|
"error": "zapis nie powiódł się",
|
|
207
229
|
"hint": "Po włączeniu: wszystkie narzędzia (polecenia bash i workdir oraz argumenty ścieżek w read/write/edit/read_image/glob/grep) używają ścieżek POSIX od korzenia dysku MSYS (/c/Users/...); host automatycznie tłumaczy pola ścieżek narzędzi plikowych. 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
|
+
"adopt.label": "Przejmij terminal boczny",
|
|
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.",
|
|
208
232
|
},
|
|
209
233
|
/* locale: pt */
|
|
210
234
|
"pt": {
|
|
@@ -217,6 +241,8 @@ window.__ModuleLoader__.load({
|
|
|
217
241
|
"switch.off": "Desativar",
|
|
218
242
|
"error": "falha ao gravar",
|
|
219
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 automaticamente os campos de caminho das ferramentas de arquivo. 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
|
+
"adopt.label": "Adotar o terminal lateral",
|
|
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.",
|
|
220
246
|
},
|
|
221
247
|
/* locale: ru */
|
|
222
248
|
"ru": {
|
|
@@ -229,6 +255,8 @@ window.__ModuleLoader__.load({
|
|
|
229
255
|
"switch.off": "Выключить",
|
|
230
256
|
"error": "не удалось записать",
|
|
231
257
|
"hint": "Включено: все инструменты (команды bash и workdir, аргументы путей read/write/edit/read_image/glob/grep) используют POSIX-пути от корня диска MSYS (/c/Users/...); хост автоматически преобразует поля путей для файловых инструментов. Выключение возвращает исходное поведение dsh (пути Windows для файловых инструментов). Пока плагин установлен, bash всегда остаётся Git Bash; этот переключатель управляет только диалектом путей между инструментами.",
|
|
258
|
+
"adopt.label": "Перехватывать терминал боковой панели",
|
|
259
|
+
"adopt.hint": "Включено (по умолчанию): Git Bash записывается как shell терминала dsh-better-sidebar; выключено — восстанавливается прежнее значение, вручную выбранные настройки не трогаются. Инструмент bash у модели не затронут — его предоставляет сам плагин.",
|
|
232
260
|
},
|
|
233
261
|
/* locale: sv */
|
|
234
262
|
"sv": {
|
|
@@ -241,6 +269,8 @@ window.__ModuleLoader__.load({
|
|
|
241
269
|
"switch.off": "Inaktivera",
|
|
242
270
|
"error": "skrivning misslyckades",
|
|
243
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 för filverktygen automatiskt. Inaktiverad återställer dsh:s ursprungliga beteende (Windows-sökvägar för filverktyg). Bash är alltid Git Bash så länge insticksprogrammet är installerat; den här växeln styr bara sökvägsdialekten mellan verktygen.",
|
|
272
|
+
"adopt.label": "Överta sidolistterminal",
|
|
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.",
|
|
244
274
|
},
|
|
245
275
|
/* locale: th */
|
|
246
276
|
"th": {
|
|
@@ -253,6 +283,8 @@ window.__ModuleLoader__.load({
|
|
|
253
283
|
"switch.off": "ปิดใช้งาน",
|
|
254
284
|
"error": "เขียนไม่สำเร็จ",
|
|
255
285
|
"hint": "เมื่อเปิดใช้งาน: เครื่องมือทั้งหมด (คำสั่ง bash และ workdir รวมถึงอาร์กิวเมนต์พาธของ read/write/edit/read_image/glob/grep) ใช้พาธ POSIX จากรากไดรฟ์ของ MSYS (/c/Users/...) โฮสต์จะแปลฟิลด์พาธของเครื่องมือจัดการไฟล์ให้อัตโนมัติ เมื่อปิดใช้งานจะกลับสู่พฤติกรรมดั้งเดิมของ dsh (เครื่องมือจัดการไฟล์ใช้พาธ Windows) bash เป็น Git Bash เสมอเมื่อติดตั้งปลั๊กอินนี้ สวิตช์นี้ควบคุมเฉพาะรูปแบบพาธระหว่างเครื่องมือเท่านั้น",
|
|
286
|
+
"adopt.label": "รับช่วงเทอร์มินัลแถบข้าง",
|
|
287
|
+
"adopt.hint": "เปิด (ค่าเริ่มต้น) จะเขียน Git Bash เป็น shell ของเทอร์มินัล dsh-better-sidebar; ปิดแล้วคืนค่าเดิมและไม่แตะการตั้งค่าที่เลือกเอง เครื่องมือ bash ของโมเดลไม่กระทบ — ปลั๊กอินจัดหาเอง",
|
|
256
288
|
},
|
|
257
289
|
/* locale: tr */
|
|
258
290
|
"tr": {
|
|
@@ -265,6 +297,8 @@ window.__ModuleLoader__.load({
|
|
|
265
297
|
"switch.off": "Devre dışı bırak",
|
|
266
298
|
"error": "yazma başarısız",
|
|
267
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ç dosya araçlarının 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
|
+
"adopt.label": "Kenar çubuğu terminalini devral",
|
|
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.",
|
|
268
302
|
},
|
|
269
303
|
/* locale: vi */
|
|
270
304
|
"vi": {
|
|
@@ -277,6 +311,8 @@ window.__ModuleLoader__.load({
|
|
|
277
311
|
"switch.off": "Tắt",
|
|
278
312
|
"error": "ghi thất bại",
|
|
279
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 cho các công cụ tệp. 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
|
+
"adopt.label": "Tiếp nhận terminal thanh bên",
|
|
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ó.",
|
|
280
316
|
},
|
|
281
317
|
/* locale: zh-hk */
|
|
282
318
|
"zh-hk": {
|
|
@@ -289,6 +325,8 @@ window.__ModuleLoader__.load({
|
|
|
289
325
|
"switch.off": "停用",
|
|
290
326
|
"error": "寫入失敗",
|
|
291
327
|
"hint": "啟用後:所有工具(bash 指令同 workdir、read/write/edit/read_image/glob/grep 嘅路徑參數)統一使用 MSYS 磁碟根 POSIX 路徑(/c/Users/...);檔案工具嘅路徑參數由宿主自動翻譯,模型無感。停用後回復 dsh 原生行為(檔案工具用 Windows 路徑)。bash 永遠係 Git Bash,唔受呢個開關影響。",
|
|
328
|
+
"adopt.label": "接管側欄終端",
|
|
329
|
+
"adopt.hint": "開啟(預設)會把 dsh-better-sidebar 的終端 shell 寫成 Git Bash;關閉後還原接管前的值,手動改過的設定永不被碰。模型側的 bash 工具不受影響——由插件本身提供。",
|
|
292
330
|
},
|
|
293
331
|
/* locale: zh-mo */
|
|
294
332
|
"zh-mo": {
|
|
@@ -301,6 +339,8 @@ window.__ModuleLoader__.load({
|
|
|
301
339
|
"switch.off": "停用",
|
|
302
340
|
"error": "寫入失敗",
|
|
303
341
|
"hint": "啟用後:所有工具(bash 指令同 workdir、read/write/edit/read_image/glob/grep 嘅路徑參數)統一使用 MSYS 磁碟根 POSIX 路徑(/c/Users/...);檔案工具嘅路徑參數由宿主自動翻譯,模型無感。停用後回復 dsh 原生行為(檔案工具用 Windows 路徑)。bash 永遠係 Git Bash,唔受呢個開關影響。",
|
|
342
|
+
"adopt.label": "接管側欄終端",
|
|
343
|
+
"adopt.hint": "開啟(預設)會把 dsh-better-sidebar 的終端 shell 寫成 Git Bash;關閉後還原接管前的值,手動改過的設定永不被碰。模型側的 bash 工具不受影響——由插件本身提供。",
|
|
304
344
|
},
|
|
305
345
|
/* locale: zh-tw */
|
|
306
346
|
"zh-tw": {
|
|
@@ -313,6 +353,8 @@ window.__ModuleLoader__.load({
|
|
|
313
353
|
"switch.off": "停用",
|
|
314
354
|
"error": "寫入失敗",
|
|
315
355
|
"hint": "啟用後:所有工具(bash 指令與 workdir,以及 read/write/edit/read_image/glob/grep 的路徑參數)統一使用 MSYS 磁碟根 POSIX 路徑(/c/Users/...);檔案工具的路徑參數由宿主自動轉譯,模型無感。停用後恢復 dsh 原生行為(檔案工具使用 Windows 路徑)。bash 一律是 Git Bash,不受此開關影響。",
|
|
356
|
+
"adopt.label": "接管側欄終端機",
|
|
357
|
+
"adopt.hint": "開啟(預設)會把 dsh-better-sidebar 的終端機 shell 寫成 Git Bash;關閉後還原接管前的值,手動改過的設定永不被碰。模型側的 bash 工具不受影響——由插件本身提供。",
|
|
316
358
|
},
|
|
317
359
|
};
|
|
318
360
|
|
|
@@ -389,6 +431,8 @@ window.__ModuleLoader__.load({
|
|
|
389
431
|
".gb-chevron{flex:none;color:var(--dsw-alias-label-tertiary);transition:transform .16s}",
|
|
390
432
|
".gb-chevron.gb-chevronOpen{transform:rotate(180deg)}",
|
|
391
433
|
".gb-body{display:flex;flex-direction:column;gap:12px;padding:4px 16px 16px;max-width:640px}",
|
|
434
|
+
".gb-page{max-width:640px}",
|
|
435
|
+
".gb-pageBody{display:flex;flex-direction:column;gap:12px;padding:0 0 8px}",
|
|
392
436
|
".gb-row{display:flex;align-items:baseline;gap:8px;font-size:13px;line-height:1.5;color:var(--dsw-alias-label-secondary)}",
|
|
393
437
|
".gb-rowLabel{flex:none;color:var(--dsw-alias-label-tertiary)}",
|
|
394
438
|
".gb-rowValue{min-width:0;overflow-wrap:anywhere;color:var(--dsw-alias-label-primary)}",
|
|
@@ -507,10 +551,11 @@ window.__ModuleLoader__.load({
|
|
|
507
551
|
|
|
508
552
|
var value = snap.value || {};
|
|
509
553
|
var enabled = value.posixPaths === true;
|
|
554
|
+
var adopt = value.adoptSidebar !== false;
|
|
510
555
|
|
|
511
|
-
function
|
|
556
|
+
function writeField(key, next) {
|
|
512
557
|
setError("");
|
|
513
|
-
scope.set(
|
|
558
|
+
scope.set(key, next)
|
|
514
559
|
.then(function () { bumpTick(function (n) { return n + 1; }); })
|
|
515
560
|
.catch(function (err) {
|
|
516
561
|
bumpTick(function (n) { return n + 1; });
|
|
@@ -520,6 +565,51 @@ window.__ModuleLoader__.load({
|
|
|
520
565
|
|
|
521
566
|
var Chevron = icon("IconChevronDownOutline14");
|
|
522
567
|
|
|
568
|
+
// dsh 0.1.6-alpha.2: the Plugins page renders this card through the
|
|
569
|
+
// `plugins.bundle.config` slot with view="page" — the page draws the
|
|
570
|
+
// title itself, so the collapsible shell is only for the legacy seat.
|
|
571
|
+
var pageView = props.view === "page";
|
|
572
|
+
|
|
573
|
+
var bodyContent = E("div", { className: pageView ? "gb-pageBody" : "gb-body" },
|
|
574
|
+
E("div", { className: "gb-row" },
|
|
575
|
+
E("span", { className: "gb-rowLabel" }, t("state.label") + ":"),
|
|
576
|
+
E("span", { className: "gb-rowValue" }, enabled ? t("state.on") : t("state.off")),
|
|
577
|
+
),
|
|
578
|
+
E("div", { className: "gb-seg" },
|
|
579
|
+
E("button", {
|
|
580
|
+
type: "button",
|
|
581
|
+
className: "gb-segBtn" + (enabled ? " gb-segActive" : ""),
|
|
582
|
+
onClick: function () { if (!enabled) writeField("posixPaths", true); },
|
|
583
|
+
}, t("switch.on")),
|
|
584
|
+
E("button", {
|
|
585
|
+
type: "button",
|
|
586
|
+
className: "gb-segBtn" + (!enabled ? " gb-segActive" : ""),
|
|
587
|
+
onClick: function () { if (enabled) writeField("posixPaths", false); },
|
|
588
|
+
}, t("switch.off")),
|
|
589
|
+
),
|
|
590
|
+
E("p", { className: "gb-hint" }, t("hint")),
|
|
591
|
+
E("div", { className: "gb-row" },
|
|
592
|
+
E("span", { className: "gb-rowLabel" }, t("adopt.label") + ":"),
|
|
593
|
+
E("span", { className: "gb-rowValue" }, adopt ? t("state.on") : t("state.off")),
|
|
594
|
+
),
|
|
595
|
+
E("div", { className: "gb-seg" },
|
|
596
|
+
E("button", {
|
|
597
|
+
type: "button",
|
|
598
|
+
className: "gb-segBtn" + (adopt ? " gb-segActive" : ""),
|
|
599
|
+
onClick: function () { if (!adopt) writeField("adoptSidebar", true); },
|
|
600
|
+
}, t("switch.on")),
|
|
601
|
+
E("button", {
|
|
602
|
+
type: "button",
|
|
603
|
+
className: "gb-segBtn" + (!adopt ? " gb-segActive" : ""),
|
|
604
|
+
onClick: function () { if (adopt) writeField("adoptSidebar", false); },
|
|
605
|
+
}, t("switch.off")),
|
|
606
|
+
),
|
|
607
|
+
E("p", { className: "gb-hint" }, t("adopt.hint")),
|
|
608
|
+
error ? E("p", { className: "gb-error" }, error) : null,
|
|
609
|
+
);
|
|
610
|
+
|
|
611
|
+
if (pageView) return E("div", { className: "gb-page" }, bodyContent);
|
|
612
|
+
|
|
523
613
|
return E("li", { className: "gb-card" + (open ? " gb-open" : "") },
|
|
524
614
|
E("button", {
|
|
525
615
|
type: "button",
|
|
@@ -535,26 +625,7 @@ window.__ModuleLoader__.load({
|
|
|
535
625
|
? E(Chevron, { className: "gb-chevron" + (open ? " gb-chevronOpen" : "") })
|
|
536
626
|
: E("span", { className: "gb-chevron" + (open ? " gb-chevronOpen" : "") }, "▾"),
|
|
537
627
|
),
|
|
538
|
-
open ?
|
|
539
|
-
E("div", { className: "gb-row" },
|
|
540
|
-
E("span", { className: "gb-rowLabel" }, t("state.label") + ":"),
|
|
541
|
-
E("span", { className: "gb-rowValue" }, enabled ? t("state.on") : t("state.off")),
|
|
542
|
-
),
|
|
543
|
-
E("div", { className: "gb-seg" },
|
|
544
|
-
E("button", {
|
|
545
|
-
type: "button",
|
|
546
|
-
className: "gb-segBtn" + (enabled ? " gb-segActive" : ""),
|
|
547
|
-
onClick: function () { if (!enabled) write(true); },
|
|
548
|
-
}, t("switch.on")),
|
|
549
|
-
E("button", {
|
|
550
|
-
type: "button",
|
|
551
|
-
className: "gb-segBtn" + (!enabled ? " gb-segActive" : ""),
|
|
552
|
-
onClick: function () { if (enabled) write(false); },
|
|
553
|
-
}, t("switch.off")),
|
|
554
|
-
),
|
|
555
|
-
error ? E("p", { className: "gb-error" }, error) : null,
|
|
556
|
-
E("p", { className: "gb-hint" }, t("hint")),
|
|
557
|
-
) : null,
|
|
628
|
+
open ? bodyContent : null,
|
|
558
629
|
);
|
|
559
630
|
}
|
|
560
631
|
|
|
@@ -599,15 +670,19 @@ window.__ModuleLoader__.load({
|
|
|
599
670
|
console.warn(TAG + " slots service unavailable; settings card idle");
|
|
600
671
|
return;
|
|
601
672
|
}
|
|
673
|
+
var injected = function () {
|
|
674
|
+
// The inject factory's returned members become the component's
|
|
675
|
+
// props: the bound settings scope rides here as a PLAIN member
|
|
676
|
+
// (top-level options fields do NOT reach the component).
|
|
677
|
+
return { scope: scope };
|
|
678
|
+
};
|
|
679
|
+
// Legacy seat (dsh <= 0.1.6-alpha.1): Settings → Plugins card.
|
|
602
680
|
slots.inject("settings.plugin.item", function () {
|
|
603
681
|
return slots.register({
|
|
604
682
|
name: "settings.plugin.item",
|
|
605
683
|
key: SETTINGS_NAMESPACE,
|
|
606
684
|
locale: NS,
|
|
607
|
-
|
|
608
|
-
// props: the bound settings scope rides here as a PLAIN member
|
|
609
|
-
// (top-level options fields do NOT reach the component).
|
|
610
|
-
inject: function () { return { scope: scope }; },
|
|
685
|
+
inject: injected,
|
|
611
686
|
}, function CardWithLocale(props) {
|
|
612
687
|
/* The registration's locale field also hands out the framework's own
|
|
613
688
|
t seat; the plugin's lookup wins (21 locale tags against the catalog's
|
|
@@ -615,6 +690,21 @@ window.__ModuleLoader__.load({
|
|
|
615
690
|
return E(LocaleLive, { ctx: ctx, t: t, cardProps: props });
|
|
616
691
|
});
|
|
617
692
|
});
|
|
693
|
+
// dsh 0.1.6-alpha.2+: the Plugins page's bundle configuration seat,
|
|
694
|
+
// keyed by the PACKAGE name. Each inject waits for its own slot
|
|
695
|
+
// declaration, so exactly one seat is live on any host version.
|
|
696
|
+
slots.inject("plugins.bundle.config", function () {
|
|
697
|
+
return slots.register({
|
|
698
|
+
name: "plugins.bundle.config",
|
|
699
|
+
key: "dsh-gitbash-shell",
|
|
700
|
+
locale: NS,
|
|
701
|
+
inject: injected,
|
|
702
|
+
}, function BundleConfigWithBoundary(props) {
|
|
703
|
+
/* Same LocaleLive wrap as the legacy seat: the plugin's 21-tag
|
|
704
|
+
dictionary wins over the catalog's zh/en t seat. */
|
|
705
|
+
return E(LocaleLive, { ctx: ctx, t: t, cardProps: props });
|
|
706
|
+
});
|
|
707
|
+
});
|
|
618
708
|
} catch (error) {
|
|
619
709
|
console.warn(TAG + " settings card registration failed:", error && error.message ? error.message : error);
|
|
620
710
|
}
|
package/src/index.js
CHANGED
|
@@ -427,7 +427,7 @@ function pickComposition(base, persona, available) {
|
|
|
427
427
|
}
|
|
428
428
|
|
|
429
429
|
/** Startup decision for an existing unmodified tree: 'refresh' or 'idle'. */
|
|
430
|
-
function syncDecision({ state, marker, version, sourceHashes, base = 'code', persona = 'text', present = false, rows = '' }) {
|
|
430
|
+
function syncDecision({ state, marker, version, sourceHashes, base = 'code', persona = 'text', present = false, pluginManager = false, rows = '' }) {
|
|
431
431
|
if (state !== 'unmodified' || !marker) return 'refresh'
|
|
432
432
|
if (marker.version !== version) return 'refresh'
|
|
433
433
|
if (marker.base !== base) return 'refresh'
|
|
@@ -445,6 +445,10 @@ function syncDecision({ state, marker, version, sourceHashes, base = 'code', per
|
|
|
445
445
|
// host resolves it — and a host upgrade past that point must re-materialize
|
|
446
446
|
// to gain it (same marker-dimension pattern as persona).
|
|
447
447
|
if ((marker.present ?? false) !== present) return 'refresh'
|
|
448
|
+
// Host-capability flip: @deepseek-ai/dsh-plugin-manager/tools first shipped
|
|
449
|
+
// with dsh 0.1.6-alpha.2 — same mount-rejection stakes and the same marker
|
|
450
|
+
// dimension pattern as present above.
|
|
451
|
+
if ((marker.pluginManager ?? false) !== pluginManager) return 'refresh'
|
|
448
452
|
const recorded = {}
|
|
449
453
|
for (const k of Object.keys(marker.files)) if (k.startsWith('skills/')) recorded[k] = marker.files[k]
|
|
450
454
|
if (sourceHashes === null) return Object.keys(recorded).length === 0 ? 'idle' : 'refresh'
|
|
@@ -497,8 +501,48 @@ async function hostHasToolPresent() {
|
|
|
497
501
|
return toolPresentCache
|
|
498
502
|
}
|
|
499
503
|
|
|
504
|
+
/*
|
|
505
|
+
* Conditional plugin-manager-row injection (v0.15.0, dsh 0.1.6-alpha.2 sync).
|
|
506
|
+
* Official ptc/standard/cordis gained `- id: tool-plugin-manager / name:
|
|
507
|
+
* '@deepseek-ai/dsh-plugin-manager/tools'` (persistent plugin management;
|
|
508
|
+
* the official ptc preset carries it DISABLED, Creation keeps it on). The
|
|
509
|
+
* package only exists from 0.1.6-alpha.2 on, so the row is injected as plain
|
|
510
|
+
* text behind a host probe — never committed into the assets — anchored
|
|
511
|
+
* after the present row when there is one, else at the tail, mirroring the
|
|
512
|
+
* official order (tool-presentation → present → tool-plugin-manager).
|
|
513
|
+
* Per-variant shape mirrors each variant's official base: code-gitbash (ptc
|
|
514
|
+
* base) DISABLED, standard/cordis-gitbash ENABLED, minimal untouched
|
|
515
|
+
* (official minimal never gained the row), code-era files frozen history.
|
|
516
|
+
*/
|
|
517
|
+
const PLUGIN_MANAGER_ROW_ON = "- id: tool-plugin-manager\n name: '@deepseek-ai/dsh-plugin-manager/tools'\n"
|
|
518
|
+
const PLUGIN_MANAGER_ROW_OFF = "- id: tool-plugin-manager\n name: '@deepseek-ai/dsh-plugin-manager/tools'\n disabled: true\n"
|
|
519
|
+
const PRESENT_ROW_FULL = "\n- id: present\n name: '@deepseek-ai/dsh-tool-present'\n"
|
|
520
|
+
|
|
521
|
+
function injectPluginManagerRow(text, { enabled }) {
|
|
522
|
+
if (text.includes("'@deepseek-ai/dsh-plugin-manager/tools'")) return text
|
|
523
|
+
const body = enabled ? PLUGIN_MANAGER_ROW_ON : PLUGIN_MANAGER_ROW_OFF
|
|
524
|
+
const at = text.indexOf(PRESENT_ROW_FULL)
|
|
525
|
+
if (at !== -1) return text.slice(0, at + PRESENT_ROW_FULL.length) + body + text.slice(at + PRESENT_ROW_FULL.length)
|
|
526
|
+
return text.endsWith('\n') ? text + body : text + '\n' + body
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
let pluginManagerToolsCache
|
|
531
|
+
/** Probe whether THIS host can resolve the plugin-manager tools package (cached per boot). */
|
|
532
|
+
async function hostHasPluginManagerTools() {
|
|
533
|
+
if (pluginManagerToolsCache !== undefined) return pluginManagerToolsCache
|
|
534
|
+
try {
|
|
535
|
+
const { createRequire } = await import('node:module')
|
|
536
|
+
createRequire(import.meta.url).resolve('@deepseek-ai/dsh-plugin-manager/tools')
|
|
537
|
+
pluginManagerToolsCache = true
|
|
538
|
+
} catch {
|
|
539
|
+
pluginManagerToolsCache = false
|
|
540
|
+
}
|
|
541
|
+
return pluginManagerToolsCache
|
|
542
|
+
}
|
|
543
|
+
|
|
500
544
|
/** Write one preset directory from scratch. Returns 'ok' or 'no-skills-source'. */
|
|
501
|
-
function materialize({ target, presetId, skillsSource, version, base = 'code', persona = 'text', present = false, rows }) {
|
|
545
|
+
function materialize({ target, presetId, skillsSource, version, base = 'code', persona = 'text', present = false, pluginManager = false, rows }) {
|
|
502
546
|
rmSync(target, { recursive: true, force: true })
|
|
503
547
|
mkdirSync(target, { recursive: true })
|
|
504
548
|
|
|
@@ -506,6 +550,12 @@ function materialize({ target, presetId, skillsSource, version, base = 'code', p
|
|
|
506
550
|
const compositionFile = pickComposition(base, persona, available)
|
|
507
551
|
let composition = readFileSync(join(pkgDir, 'assets', presetId, compositionFile), 'utf8')
|
|
508
552
|
if (present && compositionFile.includes('.ptc.')) composition = injectPresentRow(composition)
|
|
553
|
+
// v0.15.0: ptc-era files only; the ptc-based variant mirrors the official
|
|
554
|
+
// ptc DISABLED form, standard/cordis mirror their ENABLED bases, minimal is
|
|
555
|
+
// untouched (official minimal never gained the row).
|
|
556
|
+
if (pluginManager && compositionFile.includes('.ptc.') && presetId !== 'minimal-gitbash') {
|
|
557
|
+
composition = injectPluginManagerRow(composition, { enabled: presetId !== 'code-gitbash' })
|
|
558
|
+
}
|
|
509
559
|
// Row-form alignment (v0.14.0): the committed assets pin one spelling of the
|
|
510
560
|
// workflow-engine row, but a host renames it out from under them (dsh
|
|
511
561
|
// 0.1.6-alpha.1) and a row whose module fails to import rejects the whole
|
|
@@ -531,7 +581,7 @@ function materialize({ target, presetId, skillsSource, version, base = 'code', p
|
|
|
531
581
|
}
|
|
532
582
|
}
|
|
533
583
|
|
|
534
|
-
const marker = { managedBy: MANAGED_BY, version, presetId, base, persona, present, rows: rowFingerprint(rows, presetId), files: hashTree(target) }
|
|
584
|
+
const marker = { managedBy: MANAGED_BY, version, presetId, base, persona, present, pluginManager, rows: rowFingerprint(rows, presetId), files: hashTree(target) }
|
|
535
585
|
writeFileSync(join(target, MARKER_FILE), JSON.stringify(marker, null, 2) + '\n')
|
|
536
586
|
return skills
|
|
537
587
|
}
|
|
@@ -633,6 +683,20 @@ export function readPosixPaths(ctxLike) {
|
|
|
633
683
|
}
|
|
634
684
|
}
|
|
635
685
|
|
|
686
|
+
/**
|
|
687
|
+
* Read the adoptSidebar switch (v0.15.0, default ON). Unlike posixPaths the
|
|
688
|
+
* default is on, so only an explicit false disables the takeover.
|
|
689
|
+
*/
|
|
690
|
+
export function readAdoptSidebar(ctxLike) {
|
|
691
|
+
try {
|
|
692
|
+
const settings = ctxLike && typeof ctxLike.get === 'function' ? ctxLike.get('settings') : undefined
|
|
693
|
+
const value = settings && typeof settings.get === 'function' ? settings.get(SETTINGS_NAMESPACE) : undefined
|
|
694
|
+
return !(value && value.adoptSidebar === false)
|
|
695
|
+
} catch {
|
|
696
|
+
return true
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
636
700
|
// Windows absolute path -> MSYS drive-root form, for rewriting the OFFICIAL
|
|
637
701
|
// prompt text in place (v0.10.0). Two patterns keep quoted spaced paths
|
|
638
702
|
// ("C:\Program Files\Git") whole while bare paths stop at whitespace or a
|
|
@@ -772,72 +836,119 @@ const SIDEBAR_NS = 'dsh-better-sidebar'
|
|
|
772
836
|
const SIDEBAR_TRIES = 12
|
|
773
837
|
const SIDEBAR_RETRY_MS = 1500
|
|
774
838
|
|
|
839
|
+
// Owner scope of the gitbash-shell namespace once registered (shared with
|
|
840
|
+
// the register callback so a late registration can reconcile + watch).
|
|
841
|
+
let sidebarScope = undefined
|
|
842
|
+
|
|
843
|
+
// Reconciler installed by adoptSidebarShell; a no-op until then.
|
|
844
|
+
let reconcileSidebar = () => {}
|
|
845
|
+
|
|
775
846
|
/**
|
|
776
|
-
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
780
|
-
*
|
|
847
|
+
* Reconcile the better-sidebar `terminalShell` takeover with the adoptSidebar
|
|
848
|
+
* setting (v0.15.0, default ON). ON writes our bashPath (remembering what was
|
|
849
|
+
* there before); OFF restores that previous value — but only while the current
|
|
850
|
+
* value is still ours, so a user's manual choice is never clobbered. The
|
|
851
|
+
* polling keeps the original ready-wait behavior: at boot the settings
|
|
852
|
+
* service may not be provided yet when this row's apply runs. Never throws.
|
|
781
853
|
*/
|
|
782
854
|
function adoptSidebarShell(ctx, bashPath) {
|
|
855
|
+
let adopted = false
|
|
856
|
+
let previous = ''
|
|
783
857
|
let tried = 0
|
|
784
858
|
let timer = null
|
|
785
859
|
ctx.effect(() => () => { if (timer) clearTimeout(timer) }, 'dsh-gitbash-shell: sidebar adoption polling')
|
|
786
|
-
|
|
787
|
-
|
|
860
|
+
|
|
861
|
+
const readShell = () => {
|
|
788
862
|
const settings = ctx.get('settings')
|
|
789
|
-
|
|
790
|
-
if (!ready) {
|
|
791
|
-
if (tried < SIDEBAR_TRIES) {
|
|
792
|
-
timer = setTimeout(run, SIDEBAR_RETRY_MS)
|
|
793
|
-
return
|
|
794
|
-
}
|
|
795
|
-
console.log(`${TAG} better-sidebar shell adoption skipped: settings service unavailable after ${tried} tries`)
|
|
796
|
-
return
|
|
797
|
-
}
|
|
798
|
-
let current
|
|
863
|
+
if (!settings || typeof settings.get !== 'function' || typeof settings.update !== 'function') return null
|
|
799
864
|
try {
|
|
800
|
-
|
|
865
|
+
const value = settings.get(SIDEBAR_NS)
|
|
866
|
+
return value && typeof value === 'object' && typeof value.terminalShell === 'string' ? value.terminalShell : ''
|
|
801
867
|
} catch {
|
|
802
|
-
|
|
868
|
+
return null // namespace not registered yet / sidebar absent
|
|
803
869
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
reconcileSidebar = (desired) => {
|
|
873
|
+
const current = readShell()
|
|
874
|
+
if (current === null) return false
|
|
875
|
+
const settings = ctx.get('settings')
|
|
876
|
+
if (desired && current !== bashPath) {
|
|
877
|
+
const was = current
|
|
878
|
+
settings.update(SIDEBAR_NS, { terminalShell: bashPath })
|
|
879
|
+
.then(() => {
|
|
880
|
+
previous = was
|
|
881
|
+
adopted = true
|
|
882
|
+
console.log(
|
|
883
|
+
`${TAG} dsh-better-sidebar terminal shell -> Git Bash (${bashPath})` +
|
|
884
|
+
(was ? ` (took over from '${was}')` : ''),
|
|
885
|
+
)
|
|
886
|
+
})
|
|
887
|
+
.catch((error) => {
|
|
888
|
+
console.log(`${TAG} better-sidebar shell adoption unavailable: ${error?.message ?? error}`)
|
|
889
|
+
})
|
|
890
|
+
return true
|
|
891
|
+
}
|
|
892
|
+
if (desired && current === bashPath) {
|
|
893
|
+
adopted = true
|
|
894
|
+
return true
|
|
895
|
+
}
|
|
896
|
+
if (!desired && adopted && current === bashPath) {
|
|
897
|
+
settings.update(SIDEBAR_NS, { terminalShell: previous })
|
|
898
|
+
.then(() => {
|
|
899
|
+
adopted = false
|
|
900
|
+
console.log(`${TAG} dsh-better-sidebar terminal shell restored ('${previous || 'sidebar default'}') — adoptSidebar off`)
|
|
901
|
+
})
|
|
902
|
+
.catch(() => {})
|
|
903
|
+
return true
|
|
904
|
+
}
|
|
905
|
+
return true
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
const run = () => {
|
|
909
|
+
tried += 1
|
|
910
|
+
const ok = reconcileSidebar(readAdoptSidebar(ctx))
|
|
911
|
+
if (ok) {
|
|
912
|
+
// The namespace scope may register after the settings service; hook
|
|
913
|
+
// the live watch once it exists (idempotent via the effect disposer).
|
|
914
|
+
if (sidebarScope && typeof sidebarScope.watch === 'function' && !run.watched) {
|
|
915
|
+
run.watched = true
|
|
916
|
+
try {
|
|
917
|
+
const off = sidebarScope.watch((next) => { reconcileSidebar(next && next.adoptSidebar !== false) })
|
|
918
|
+
ctx.effect(() => off, 'dsh-gitbash-shell: adoptSidebar watch (polling path)')
|
|
919
|
+
} catch { /* best effort */ }
|
|
812
920
|
}
|
|
813
|
-
console.log(`${TAG} better-sidebar shell adoption unavailable: ${error?.message ?? error}`)
|
|
814
921
|
return
|
|
815
922
|
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
const s = ctx.get('settings')
|
|
822
|
-
if (!s || typeof s.update !== 'function') return
|
|
823
|
-
let now
|
|
824
|
-
try {
|
|
825
|
-
now = s.get(SIDEBAR_NS)
|
|
826
|
-
} catch {
|
|
827
|
-
return
|
|
828
|
-
}
|
|
829
|
-
if (String(now?.terminalShell ?? '') === bashPath) {
|
|
830
|
-
s.update(SIDEBAR_NS, { terminalShell: previous }).catch(() => {})
|
|
831
|
-
}
|
|
832
|
-
},
|
|
833
|
-
'dsh-gitbash-shell: sidebar shell revert',
|
|
834
|
-
)
|
|
835
|
-
console.log(
|
|
836
|
-
`${TAG} dsh-better-sidebar terminal shell -> Git Bash (${bashPath})` +
|
|
837
|
-
(previous ? ` (took over from '${previous}')` : ''),
|
|
838
|
-
)
|
|
923
|
+
if (tried < SIDEBAR_TRIES) {
|
|
924
|
+
timer = setTimeout(run, SIDEBAR_RETRY_MS)
|
|
925
|
+
return
|
|
926
|
+
}
|
|
927
|
+
console.log(`${TAG} better-sidebar shell adoption skipped: settings service unavailable after ${tried} tries`)
|
|
839
928
|
}
|
|
929
|
+
run.watched = false
|
|
840
930
|
void run()
|
|
931
|
+
|
|
932
|
+
// Dispose: while we still hold the value, restore what was there before.
|
|
933
|
+
let reverted = false
|
|
934
|
+
ctx.effect(
|
|
935
|
+
() => () => {
|
|
936
|
+
if (reverted || !adopted) return
|
|
937
|
+
reverted = true
|
|
938
|
+
const s = ctx.get('settings')
|
|
939
|
+
if (!s || typeof s.update !== 'function') return
|
|
940
|
+
let now
|
|
941
|
+
try {
|
|
942
|
+
now = s.get(SIDEBAR_NS)
|
|
943
|
+
} catch {
|
|
944
|
+
return
|
|
945
|
+
}
|
|
946
|
+
if (String(now?.terminalShell ?? '') === bashPath) {
|
|
947
|
+
s.update(SIDEBAR_NS, { terminalShell: previous }).catch(() => {})
|
|
948
|
+
}
|
|
949
|
+
},
|
|
950
|
+
'dsh-gitbash-shell: sidebar shell revert',
|
|
951
|
+
)
|
|
841
952
|
}
|
|
842
953
|
|
|
843
954
|
// ── plugin ──────────────────────────────────────────────────────────────────
|
|
@@ -940,10 +1051,24 @@ export async function apply(ctx, config = {}) {
|
|
|
940
1051
|
const ns = typeof ds.settingsNamespace === 'function'
|
|
941
1052
|
? ds.settingsNamespace(SETTINGS_NAMESPACE)
|
|
942
1053
|
: SETTINGS_NAMESPACE
|
|
943
|
-
settings.register(ns, Schema.object({
|
|
1054
|
+
const scope = settings.register(ns, Schema.object({
|
|
944
1055
|
posixPaths: Schema.boolean().default(true),
|
|
1056
|
+
adoptSidebar: Schema.boolean().default(true),
|
|
945
1057
|
}))
|
|
946
|
-
|
|
1058
|
+
sidebarScope = scope
|
|
1059
|
+
console.log(`${TAG} settings namespace registered: ${SETTINGS_NAMESPACE} (posixPaths default on, adoptSidebar default on)`)
|
|
1060
|
+
// A late register (settings service up after the adoption polling
|
|
1061
|
+
// finished) still reconciles once, and the live watch flips the
|
|
1062
|
+
// takeover when the user toggles the card switch.
|
|
1063
|
+
try {
|
|
1064
|
+
if (typeof scope?.watch === 'function') {
|
|
1065
|
+
const off = scope.watch((next) => { reconcileSidebar(next && next.adoptSidebar !== false) })
|
|
1066
|
+
ctx.effect(() => off, 'dsh-gitbash-shell: adoptSidebar watch')
|
|
1067
|
+
}
|
|
1068
|
+
reconcileSidebar(readAdoptSidebar(ctx))
|
|
1069
|
+
} catch (error) {
|
|
1070
|
+
console.log(`${TAG} adoptSidebar watch wiring failed: ${error?.message ?? error}`)
|
|
1071
|
+
}
|
|
947
1072
|
})
|
|
948
1073
|
.catch((error) => {
|
|
949
1074
|
console.log(`${TAG} settings namespace registration FAILED: ${error && error.stack || String(error)}`)
|
|
@@ -1145,6 +1270,11 @@ export async function apply(ctx, config = {}) {
|
|
|
1145
1270
|
// resolving from this plugin's own tree (covers hosts where the roster
|
|
1146
1271
|
// probe is unavailable).
|
|
1147
1272
|
const present = (await detectPresentSupport(ctx.agentPresets)) || (await hostHasToolPresent())
|
|
1273
|
+
// v0.15.0 (dsh 0.1.6-alpha.2): official ptc/standard/cordis gained the
|
|
1274
|
+
// tool-plugin-manager row; inject behind the same host-package probe as
|
|
1275
|
+
// present (resolve-only is sufficient — the package cannot exist on an
|
|
1276
|
+
// older host, so a roster text probe adds nothing).
|
|
1277
|
+
const pluginManager = await hostHasPluginManagerTools()
|
|
1148
1278
|
// Row spellings of the built-in presets these variants mirror: the
|
|
1149
1279
|
// workflow-engine row was renamed and its old package deleted in dsh
|
|
1150
1280
|
// 0.1.6-alpha.1, so the materializer copies whatever the host itself ships.
|
|
@@ -1179,12 +1309,12 @@ export async function apply(ctx, config = {}) {
|
|
|
1179
1309
|
const sourceHashes = presetId === 'cordis-gitbash' ? skillsHashes(skillsSource) : null
|
|
1180
1310
|
const marker = readMarker(target)
|
|
1181
1311
|
const markerRows = rowFingerprint(rows, presetId)
|
|
1182
|
-
if (state === 'unmodified' && syncDecision({ state, marker, version, sourceHashes, base, persona, present, rows: markerRows }) === 'idle') {
|
|
1312
|
+
if (state === 'unmodified' && syncDecision({ state, marker, version, sourceHashes, base, persona, present, pluginManager, rows: markerRows }) === 'idle') {
|
|
1183
1313
|
ctx.logger?.('gitbash-shell')?.debug?.( `preset '${presetId}' up to date (v${version}, ${base}-era${persona === 'split' ? ', persona-split' : ''}) — idle`)
|
|
1184
1314
|
continue
|
|
1185
1315
|
}
|
|
1186
1316
|
|
|
1187
|
-
const skills = materialize({ target, presetId, skillsSource, version, base, persona, present, rows })
|
|
1317
|
+
const skills = materialize({ target, presetId, skillsSource, version, base, persona, present, pluginManager, rows })
|
|
1188
1318
|
const verb = state === 'absent' ? 'materialized' : 'refreshed'
|
|
1189
1319
|
console.log(
|
|
1190
1320
|
`${TAG} ${verb} preset '${presetId}' into ${userRootPath} (v${version}, ${base}-era composition${persona === 'split' ? ', persona-split' : ''})` +
|
|
@@ -1194,4 +1324,4 @@ export async function apply(ctx, config = {}) {
|
|
|
1194
1324
|
}
|
|
1195
1325
|
|
|
1196
1326
|
// Test surface: pure helpers, no Cordis context required.
|
|
1197
|
-
export const _internal = { PRESET_IDS, translateMsysPath, translatePathArguments, readPosixPaths, windowsToMsys, rewriteResultPaths, MARKER_FILE, classify, materialize, cleanupOnDispose, firstUserRoot, hashTree, skillsHashes, syncDecision, installRegisterShim, baseForRoster, detectBase, pickComposition, personaEraForText, detectPersonaEra, injectPresentRow, hostHasToolPresent, detectPresentSupport, rowFormOf, rowFormsOf, alignEngineRow, alignRalphRow, ROW_SOURCE }
|
|
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 }
|