dsh-ide-git 0.12.0 → 0.13.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/README.md +2 -1
- package/README_EN.md +2 -1
- package/dsh.plugin.json +1 -1
- package/package.json +3 -3
- package/src/client.js +300 -23
- package/src/index.js +5 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
简体中文 | [English](README_EN.md)
|
|
6
6
|
|
|
7
|
-
> 给 [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) 的侧边栏装一个 **IDE 级的 Git 工具窗口**——左边分支树、中间提交图谱、右边变更与提交详情,操作方式对齐 JetBrains 系 IDE 的 Git 面板;以 [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) 原生 Tab
|
|
7
|
+
> 给 [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) 的侧边栏装一个 **IDE 级的 Git 工具窗口**——左边分支树、中间提交图谱、右边变更与提交详情,操作方式对齐 JetBrains 系 IDE 的 Git 面板;以 [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) 原生 Tab 的形式注册,右侧栏与底部面板都能用;v0.13.0 起还可挂在**主对话区**(「对话 / 轨迹」旁边的 Git 标签页,设置里可关)。
|
|
8
8
|
|
|
9
9
|
DSH 自带的 Git 面板覆盖「暂存 / 提交 / 还原 / 看历史」;`dsh-ide-git` 补齐 IDE 用户习惯的那一层:**分支树 + 右键分支操作 + 提交图谱 + 提交详情 + 变更列表 + 提交框**。
|
|
10
10
|
|
|
@@ -64,6 +64,7 @@ DSH 自带的 Git 面板覆盖「暂存 / 提交 / 还原 / 看历史」;`dsh-id
|
|
|
64
64
|
|---|---|---|
|
|
65
65
|
| **dsh-better-sidebar**(底座,可选) | 装了它 | 它的 Tab 系统:右侧栏里的原生 Tab **加上底部工作台**;它的设置页 `侧边卡片` 里能看到本插件的卡片 |
|
|
66
66
|
| **DSH 原生右侧栏** | 没装底座时自动接管 | 右侧栏 Guide 页里的 **Git** 胶囊 → 点开就是同一个面板 |
|
|
67
|
+
| **主对话区标签页**(v0.13.0 起) | 总是可用(可在设置里关闭) | 会话顶部「对话 / 轨迹」旁多一枚 **Git** 标签,点它整块主对话区变成 Git 工具窗口;开关在插件设置 →「面板放置」 |
|
|
67
68
|
|
|
68
69
|
底座在场时以它为准(它还带底部工作台);底座**晚到**会顶掉原生注册再挂到它那边。所以**只装本插件也能用**,没有任何前置要求。
|
|
69
70
|
|
package/README_EN.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[简体中文](README.md) | English
|
|
6
6
|
|
|
7
|
-
> An **IDE-grade Git tool window** for the [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) sidebar — branch tree on the left, commit graph in the middle, changes and commit details on the right, with JetBrains-style actions. Registered as a native [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) tab, usable in both the native right sidebar and the bottom workbench.
|
|
7
|
+
> An **IDE-grade Git tool window** for the [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) sidebar — branch tree on the left, commit graph in the middle, changes and commit details on the right, with JetBrains-style actions. Registered as a native [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) tab, usable in both the native right sidebar and the bottom workbench; since v0.13.0 also as a **conversation-area tab** (a Git tab beside Chat/Trajectory, switchable off in settings).
|
|
8
8
|
|
|
9
9
|
DSH's built-in Git panel covers stage / commit / revert / history. `dsh-ide-git` adds the layer IDE users expect: a **branch tree with a full context menu**, a **commit graph**, **commit details with per-file diffs**, a **grouped changes list** and a commit box.
|
|
10
10
|
|
|
@@ -56,6 +56,7 @@ The plugin registers once; which surface it lands on is the **host's** decision,
|
|
|
56
56
|
|---|---|---|
|
|
57
57
|
| **dsh-better-sidebar** (optional) | whenever it is installed | its tab system: the tab in the right sidebar **plus the bottom workbench**; the plugin also shows up as a card in its settings page |
|
|
58
58
|
| **DSH's own right sidebar** | automatically, when better-sidebar is absent | a **Git** capsule on the sidebar's guide page — the very same panel |
|
|
59
|
+
| **Conversation-area tab** (since v0.13.0) | always on (switchable in settings) | a **Git** tab beside Chat/Trajectory at the top of the conversation — clicking it turns the whole conversation area into the Git tool window; the switch lives in the plugin settings under Placement |
|
|
59
60
|
|
|
60
61
|
better-sidebar wins while it is there (it also carries the bottom workbench); a late-arriving better-sidebar takes the native registration down and hosts the tab itself. Installing this plugin alone is fully supported — no prerequisite.
|
|
61
62
|
|
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-external/dsh-ide-git",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"description": "IDE 级 Git 操作面板:分支树 + 提交图谱 + 变更/暂存/提交 + 提交详情。装了 dsh-better-sidebar 时挂成它的原生 tab(右侧栏 + 底部工作台);没装时直接挂 DSH 原生右侧栏,单独安装即可用。JetBrains 风格 Git 工具窗口 for DeepSeek Harness.",
|
|
6
6
|
"engines": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-ide-git",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "DSH plugin: an IDE-grade Git tool window as a native dsh-better-sidebar tab — branch tree, commit graph, changes, commit details, JetBrains-style actions, in the right sidebar and the bottom panel. | DSH 插件:IDE 级 Git 工具窗口,以 dsh-better-sidebar 原生 Tab 挂载——分支树 / 提交图谱 / 变更与提交详情 / JetBrains 风格操作,右侧栏与底部面板双布局自适应。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
},
|
|
28
28
|
"client": {
|
|
29
29
|
"inject": [
|
|
30
|
-
"@deepseek-ai/dsh-client-runtime",
|
|
31
30
|
"@deepseek-ai/dsh-client-locale",
|
|
32
31
|
"@deepseek-ai/dsh-client-ui-slots",
|
|
33
|
-
"@deepseek-ai/dsh-client-modules"
|
|
32
|
+
"@deepseek-ai/dsh-client-modules",
|
|
33
|
+
"@deepseek-ai/dsh-client-ui-conversation"
|
|
34
34
|
],
|
|
35
35
|
"platform": "web"
|
|
36
36
|
}
|
package/src/client.js
CHANGED
|
@@ -160,7 +160,10 @@ window.__ModuleLoader__.load({
|
|
|
160
160
|
'rail.settings': '动作条设置',
|
|
161
161
|
'rail.openSettings': '打开插件设置',
|
|
162
162
|
'settings.card.title': 'Git 工具窗口设置',
|
|
163
|
-
'settings.card.desc': '
|
|
163
|
+
'settings.card.desc': '面板放置、动作条按钮与 AI 提交信息',
|
|
164
|
+
'settings.placement.title': '面板放置',
|
|
165
|
+
'settings.placement.tab': '在主对话区显示 Git 标签页',
|
|
166
|
+
'settings.placement.tabHint': '关闭后仍可从右侧栏或底部面板打开。',
|
|
164
167
|
'settings.rail.title': '动作条按钮',
|
|
165
168
|
'settings.rail.hint': '勾选要显示在动作条上的动作;顺序固定为默认顺序,取消勾选即隐藏。',
|
|
166
169
|
'settings.rail.unavailable': '当前宿主没有设置服务,请用面板内的「动作条设置」。',
|
|
@@ -348,7 +351,10 @@ window.__ModuleLoader__.load({
|
|
|
348
351
|
'rail.settings': 'Action bar settings',
|
|
349
352
|
'rail.openSettings': 'Open plugin settings',
|
|
350
353
|
'settings.card.title': 'Git tool window settings',
|
|
351
|
-
'settings.card.desc': '
|
|
354
|
+
'settings.card.desc': 'Placement, action rail buttons and AI commit message',
|
|
355
|
+
'settings.placement.title': 'Placement',
|
|
356
|
+
'settings.placement.tab': 'Show the Git tab in the conversation area',
|
|
357
|
+
'settings.placement.tabHint': 'Off, the panel stays reachable from the right sidebar and the bottom panel.',
|
|
352
358
|
'settings.rail.title': 'Action rail buttons',
|
|
353
359
|
'settings.rail.hint': 'Tick the actions shown on the rail. The order is fixed; unticking one hides it.',
|
|
354
360
|
'settings.rail.unavailable': 'This host has no settings service; use the in-panel “Action rail settings”.',
|
|
@@ -544,7 +550,10 @@ window.__ModuleLoader__.load({
|
|
|
544
550
|
'rail.settings': '動作列設定',
|
|
545
551
|
'rail.openSettings': '開啟外掛設定',
|
|
546
552
|
'settings.card.title': 'Git 工具視窗設定',
|
|
547
|
-
'settings.card.desc': '
|
|
553
|
+
'settings.card.desc': '面板放置、動作列按鈕與 AI 提交訊息',
|
|
554
|
+
'settings.placement.title': '面板放置',
|
|
555
|
+
'settings.placement.tab': '喺主對話區顯示 Git 分頁',
|
|
556
|
+
'settings.placement.tabHint': '關閉之後仍可從右側欄或底部面板開啟。',
|
|
548
557
|
'settings.rail.title': '動作列按鈕',
|
|
549
558
|
'settings.rail.hint': '勾選要顯示在動作列上的動作;順序固定,取消勾選即隱藏。',
|
|
550
559
|
'settings.rail.unavailable': '目前宿主沒有設定服務,請用面板內的「動作條設定」。',
|
|
@@ -732,7 +741,10 @@ window.__ModuleLoader__.load({
|
|
|
732
741
|
'rail.settings': '動作列設定',
|
|
733
742
|
'rail.openSettings': '開啟外掛設定',
|
|
734
743
|
'settings.card.title': 'Git 工具視窗設定',
|
|
735
|
-
'settings.card.desc': '
|
|
744
|
+
'settings.card.desc': '面板放置、動作列按鈕與 AI 提交訊息',
|
|
745
|
+
'settings.placement.title': '面板放置',
|
|
746
|
+
'settings.placement.tab': '在主對話區顯示 Git 分頁',
|
|
747
|
+
'settings.placement.tabHint': '關閉之後仍可從右側欄或底部面板開啟。',
|
|
736
748
|
'settings.rail.title': '動作列按鈕',
|
|
737
749
|
'settings.rail.hint': '勾選要顯示在動作列上的動作;順序固定,取消勾選即隱藏。',
|
|
738
750
|
'settings.rail.unavailable': '目前宿主沒有設定服務,請用面板內的「動作條設定」。',
|
|
@@ -920,7 +932,10 @@ window.__ModuleLoader__.load({
|
|
|
920
932
|
'rail.settings': '動作列設定',
|
|
921
933
|
'rail.openSettings': '開啟外掛設定',
|
|
922
934
|
'settings.card.title': 'Git 工具視窗設定',
|
|
923
|
-
'settings.card.desc': '
|
|
935
|
+
'settings.card.desc': '面板放置、動作列按鈕與 AI 提交訊息',
|
|
936
|
+
'settings.placement.title': '面板放置',
|
|
937
|
+
'settings.placement.tab': '喺主對話區顯示 Git 分頁',
|
|
938
|
+
'settings.placement.tabHint': '關閉之後仍可從右側欄或底部面板開啟。',
|
|
924
939
|
'settings.rail.title': '動作列按鈕',
|
|
925
940
|
'settings.rail.hint': '勾選要顯示在動作列上的動作;順序固定,取消勾選即隱藏。',
|
|
926
941
|
'settings.rail.unavailable': '目前宿主沒有設定服務,請用面板內的「動作條設定」。',
|
|
@@ -1108,7 +1123,10 @@ window.__ModuleLoader__.load({
|
|
|
1108
1123
|
'rail.settings': 'アクションバーの設定',
|
|
1109
1124
|
'rail.openSettings': 'プラグイン設定を開く',
|
|
1110
1125
|
'settings.card.title': 'Gitツールウィンドウの設定',
|
|
1111
|
-
'settings.card.desc': '
|
|
1126
|
+
'settings.card.desc': 'パネル配置、アクションレールのボタンと AI コミットメッセージ',
|
|
1127
|
+
'settings.placement.title': 'パネル配置',
|
|
1128
|
+
'settings.placement.tab': '会話エリアに Git タブを表示',
|
|
1129
|
+
'settings.placement.tabHint': 'オフにしても右サイドバーと下部パネルから開けます。',
|
|
1112
1130
|
'settings.rail.title': 'アクションレールのボタン',
|
|
1113
1131
|
'settings.rail.hint': 'レールに表示する操作にチェックを入れてください。順序は固定で、チェックを外すと非表示になります。',
|
|
1114
1132
|
'settings.rail.unavailable': 'このホストには設定サービスがないため、パネル内の「アクションレール設定」を使ってください。',
|
|
@@ -1296,7 +1314,10 @@ window.__ModuleLoader__.load({
|
|
|
1296
1314
|
'rail.settings': '작업 표시줄 설정',
|
|
1297
1315
|
'rail.openSettings': '플러그인 설정 열기',
|
|
1298
1316
|
'settings.card.title': 'Git 도구 창 설정',
|
|
1299
|
-
'settings.card.desc': '액션 레일 버튼 및 AI 커밋 메시지',
|
|
1317
|
+
'settings.card.desc': '패널 배치, 액션 레일 버튼 및 AI 커밋 메시지',
|
|
1318
|
+
'settings.placement.title': '패널 배치',
|
|
1319
|
+
'settings.placement.tab': '대화 영역에 Git 탭 표시',
|
|
1320
|
+
'settings.placement.tabHint': '꺼도 오른쪽 사이드바와 하단 패널에서 열 수 있습니다.',
|
|
1300
1321
|
'settings.rail.title': '액션 레일 버튼',
|
|
1301
1322
|
'settings.rail.hint': '레일에 표시할 동작을 선택하세요. 순서는 고정이며 선택을 해제하면 숨겨집니다.',
|
|
1302
1323
|
'settings.rail.unavailable': '이 호스트에는 설정 서비스가 없으므로 패널의 "액션 레일 설정"을 사용하세요.',
|
|
@@ -1484,7 +1505,10 @@ window.__ModuleLoader__.load({
|
|
|
1484
1505
|
'rail.settings': 'Einstellungen der Aktionsleiste',
|
|
1485
1506
|
'rail.openSettings': 'Plugin-Einstellungen öffnen',
|
|
1486
1507
|
'settings.card.title': 'Git-Werkzeugfenster-Einstellungen',
|
|
1487
|
-
'settings.card.desc': 'Aktionsleisten-Schaltflächen und KI-Commit-Nachricht',
|
|
1508
|
+
'settings.card.desc': 'Panel-Platzierung, Aktionsleisten-Schaltflächen und KI-Commit-Nachricht',
|
|
1509
|
+
'settings.placement.title': 'Panel-Platzierung',
|
|
1510
|
+
'settings.placement.tab': 'Git-Tab im Gesprächsbereich anzeigen',
|
|
1511
|
+
'settings.placement.tabHint': 'Ausgeschaltet bleibt das Panel über rechte Seitenleiste und unteres Panel erreichbar.',
|
|
1488
1512
|
'settings.rail.title': 'Schaltflächen der Aktionsleiste',
|
|
1489
1513
|
'settings.rail.hint': 'Die auf der Leiste sichtbaren Aktionen ankreuzen. Die Reihenfolge ist fest; abwählen blendet eine aus.',
|
|
1490
1514
|
'settings.rail.unavailable': 'Dieser Host hat keinen Einstellungsdienst; nutze die „Aktionsleisten-Einstellungen“ im Panel.',
|
|
@@ -1672,7 +1696,10 @@ window.__ModuleLoader__.load({
|
|
|
1672
1696
|
'rail.settings': 'Réglages de la barre d\'actions',
|
|
1673
1697
|
'rail.openSettings': 'Ouvrir les réglages du plugin',
|
|
1674
1698
|
'settings.card.title': 'Paramètres de la fenêtre d’outils Git',
|
|
1675
|
-
'settings.card.desc': '
|
|
1699
|
+
'settings.card.desc': 'Placement du panneau, boutons de la barre d’actions et message de commit par IA',
|
|
1700
|
+
'settings.placement.title': 'Placement du panneau',
|
|
1701
|
+
'settings.placement.tab': 'Afficher l’onglet Git dans la zone de conversation',
|
|
1702
|
+
'settings.placement.tabHint': 'Désactivé, le panneau reste accessible depuis la barre latérale droite et le panneau inférieur.',
|
|
1676
1703
|
'settings.rail.title': 'Boutons de la barre d’actions',
|
|
1677
1704
|
'settings.rail.hint': 'Cochez les actions affichées sur la barre. L’ordre est fixe ; décocher masque une action.',
|
|
1678
1705
|
'settings.rail.unavailable': 'Cet hôte n’a pas de service de réglages ; utilisez « Réglages de la barre d’actions » dans le panneau.',
|
|
@@ -1860,7 +1887,10 @@ window.__ModuleLoader__.load({
|
|
|
1860
1887
|
'rail.settings': 'Настройки панели действий',
|
|
1861
1888
|
'rail.openSettings': 'Открыть настройки плагина',
|
|
1862
1889
|
'settings.card.title': 'Настройки окна инструментов Git',
|
|
1863
|
-
'settings.card.desc': '
|
|
1890
|
+
'settings.card.desc': 'Размещение панели, кнопки панели действий и сообщение коммита от ИИ',
|
|
1891
|
+
'settings.placement.title': 'Размещение панели',
|
|
1892
|
+
'settings.placement.tab': 'Показывать вкладку Git в области диалога',
|
|
1893
|
+
'settings.placement.tabHint': 'В выключенном виде панель доступна из правой боковой панели и нижней панели.',
|
|
1864
1894
|
'settings.rail.title': 'Кнопки панели действий',
|
|
1865
1895
|
'settings.rail.hint': 'Отметьте действия, показываемые на панели. Порядок фиксирован; снятие флажка скрывает действие.',
|
|
1866
1896
|
'settings.rail.unavailable': 'На этом хосте нет службы настроек; используйте «Настройки панели действий» в панели.',
|
|
@@ -2048,7 +2078,10 @@ window.__ModuleLoader__.load({
|
|
|
2048
2078
|
'rail.settings': 'Configurações da barra de ações',
|
|
2049
2079
|
'rail.openSettings': 'Abrir configurações do plugin',
|
|
2050
2080
|
'settings.card.title': 'Configurações da janela de ferramentas Git',
|
|
2051
|
-
'settings.card.desc': '
|
|
2081
|
+
'settings.card.desc': 'Posição do painel, botões da barra de ações e mensagem de commit por IA',
|
|
2082
|
+
'settings.placement.title': 'Posição do painel',
|
|
2083
|
+
'settings.placement.tab': 'Mostrar a aba Git na área de conversa',
|
|
2084
|
+
'settings.placement.tabHint': 'Desligado, o painel continua disponível na barra lateral direita e no painel inferior.',
|
|
2052
2085
|
'settings.rail.title': 'Botões da barra de ações',
|
|
2053
2086
|
'settings.rail.hint': 'Marque as ações exibidas na barra. A ordem é fixa; desmarcar oculta uma ação.',
|
|
2054
2087
|
'settings.rail.unavailable': 'Este host não tem serviço de configurações; use «Configurações da barra de ações» no painel.',
|
|
@@ -2236,7 +2269,10 @@ window.__ModuleLoader__.load({
|
|
|
2236
2269
|
'rail.settings': 'Impostazioni della barra delle azioni',
|
|
2237
2270
|
'rail.openSettings': 'Apri le impostazioni del plugin',
|
|
2238
2271
|
'settings.card.title': 'Impostazioni della finestra strumenti Git',
|
|
2239
|
-
'settings.card.desc': '
|
|
2272
|
+
'settings.card.desc': 'Posizione del pannello, pulsanti della barra azioni e messaggio di commit con IA',
|
|
2273
|
+
'settings.placement.title': 'Posizione del pannello',
|
|
2274
|
+
'settings.placement.tab': 'Mostra la scheda Git nell’area conversazione',
|
|
2275
|
+
'settings.placement.tabHint': 'Da spento, il pannello resta raggiungibile dalla barra laterale destra e dal pannello inferiore.',
|
|
2240
2276
|
'settings.rail.title': 'Pulsanti della barra azioni',
|
|
2241
2277
|
'settings.rail.hint': 'Seleziona le azioni mostrate sulla barra. L’ordine è fisso; deselezionando se ne nasconde una.',
|
|
2242
2278
|
'settings.rail.unavailable': 'Questo host non ha un servizio di impostazioni; usa «Impostazioni barra azioni» nel pannello.',
|
|
@@ -2424,7 +2460,10 @@ window.__ModuleLoader__.load({
|
|
|
2424
2460
|
'rail.settings': 'Instellingen van de actiebalk',
|
|
2425
2461
|
'rail.openSettings': 'Plugin-instellingen openen',
|
|
2426
2462
|
'settings.card.title': 'Instellingen van het Git-werkvenster',
|
|
2427
|
-
'settings.card.desc': '
|
|
2463
|
+
'settings.card.desc': 'Paneelplaatsing, knoppen van de actiebalk en AI-commitbericht',
|
|
2464
|
+
'settings.placement.title': 'Paneelplaatsing',
|
|
2465
|
+
'settings.placement.tab': 'Git-tabblad in het gespreksgebied tonen',
|
|
2466
|
+
'settings.placement.tabHint': 'Uitgeschakeld blijft het paneel bereikbaar via de rechterzijbalk en het onderpaneel.',
|
|
2428
2467
|
'settings.rail.title': 'Knoppen van de actiebalk',
|
|
2429
2468
|
'settings.rail.hint': 'Vink de acties aan die op de balk verschijnen. De volgorde ligt vast; uitvinken verbergt er een.',
|
|
2430
2469
|
'settings.rail.unavailable': 'Deze host heeft geen instellingenservice; gebruik "Actiebalk-instellingen" in het paneel.',
|
|
@@ -2612,7 +2651,10 @@ window.__ModuleLoader__.load({
|
|
|
2612
2651
|
'rail.settings': 'Ustawienia paska działań',
|
|
2613
2652
|
'rail.openSettings': 'Otwórz ustawienia wtyczki',
|
|
2614
2653
|
'settings.card.title': 'Ustawienia okna narzędzi Git',
|
|
2615
|
-
'settings.card.desc': '
|
|
2654
|
+
'settings.card.desc': 'Rozmieszczenie panelu, przyciski paska akcji i wiadomość commita od AI',
|
|
2655
|
+
'settings.placement.title': 'Rozmieszczenie panelu',
|
|
2656
|
+
'settings.placement.tab': 'Pokazuj kartę Git w obszarze rozmowy',
|
|
2657
|
+
'settings.placement.tabHint': 'Po wyłączeniu panel pozostaje dostępny z prawego paska bocznego i dolnego panelu.',
|
|
2616
2658
|
'settings.rail.title': 'Przyciski paska akcji',
|
|
2617
2659
|
'settings.rail.hint': 'Zaznacz akcje widoczne na pasku. Kolejność jest stała; odznaczenie ukrywa akcję.',
|
|
2618
2660
|
'settings.rail.unavailable': 'Ten host nie ma usługi ustawień; użyj „Ustawienia paska akcji” w panelu.',
|
|
@@ -2800,7 +2842,10 @@ window.__ModuleLoader__.load({
|
|
|
2800
2842
|
'rail.settings': 'Inställningar för åtgärdsfältet',
|
|
2801
2843
|
'rail.openSettings': 'Öppna plugininställningar',
|
|
2802
2844
|
'settings.card.title': 'Inställningar för Git-verktygsfönstret',
|
|
2803
|
-
'settings.card.desc': '
|
|
2845
|
+
'settings.card.desc': 'Panelplacering, knappar i åtgärdsfältet och AI-commitmeddelande',
|
|
2846
|
+
'settings.placement.title': 'Panelplacering',
|
|
2847
|
+
'settings.placement.tab': 'Visa Git-fliken i konversationsytan',
|
|
2848
|
+
'settings.placement.tabHint': 'Avstängd finns panelen kvar via höger sidopanel och nedre panelen.',
|
|
2804
2849
|
'settings.rail.title': 'Knappar i åtgärdsfältet',
|
|
2805
2850
|
'settings.rail.hint': 'Markera de åtgärder som visas i fältet. Ordningen är fast; avmarkering döljer en.',
|
|
2806
2851
|
'settings.rail.unavailable': 'Denna värd saknar inställningstjänst; använd ”Åtgärdsfältets inställningar” i panelen.',
|
|
@@ -2988,7 +3033,10 @@ window.__ModuleLoader__.load({
|
|
|
2988
3033
|
'rail.settings': 'Eylem çubuğu ayarları',
|
|
2989
3034
|
'rail.openSettings': 'Eklenti ayarlarını aç',
|
|
2990
3035
|
'settings.card.title': 'Git araç penceresi ayarları',
|
|
2991
|
-
'settings.card.desc': '
|
|
3036
|
+
'settings.card.desc': 'Panel yerleşimi, eylem çubuğu düğmeleri ve AI commit mesajı',
|
|
3037
|
+
'settings.placement.title': 'Panel yerleşimi',
|
|
3038
|
+
'settings.placement.tab': 'Konuşma alanında Git sekmesini göster',
|
|
3039
|
+
'settings.placement.tabHint': 'Kapatıldığında panel sağ kenar çubuğundan ve alt panelden açılabilir.',
|
|
2992
3040
|
'settings.rail.title': 'Eylem çubuğu düğmeleri',
|
|
2993
3041
|
'settings.rail.hint': 'Çubukta gösterilecek eylemleri işaretleyin. Sıra sabittir; işareti kaldırmak eylemi gizler.',
|
|
2994
3042
|
'settings.rail.unavailable': 'Bu ana bilgisayarda ayar hizmeti yok; paneldeki "Eylem çubuğu ayarları"nı kullanın.',
|
|
@@ -3176,7 +3224,10 @@ window.__ModuleLoader__.load({
|
|
|
3176
3224
|
'rail.settings': 'Pengaturan bilah tindakan',
|
|
3177
3225
|
'rail.openSettings': 'Buka pengaturan plugin',
|
|
3178
3226
|
'settings.card.title': 'Pengaturan jendela alat Git',
|
|
3179
|
-
'settings.card.desc': '
|
|
3227
|
+
'settings.card.desc': 'Penempatan panel, tombol bilah aksi dan pesan commit AI',
|
|
3228
|
+
'settings.placement.title': 'Penempatan panel',
|
|
3229
|
+
'settings.placement.tab': 'Tampilkan tab Git di area percakapan',
|
|
3230
|
+
'settings.placement.tabHint': 'Dimatikan, panel tetap bisa dibuka dari bilah sisi kanan dan panel bawah.',
|
|
3180
3231
|
'settings.rail.title': 'Tombol bilah aksi',
|
|
3181
3232
|
'settings.rail.hint': 'Centang aksi yang ditampilkan di bilah. Urutannya tetap; menghapus centang menyembunyikannya.',
|
|
3182
3233
|
'settings.rail.unavailable': 'Host ini tidak punya layanan pengaturan; gunakan "Pengaturan bilah aksi" di panel.',
|
|
@@ -3364,7 +3415,10 @@ window.__ModuleLoader__.load({
|
|
|
3364
3415
|
'rail.settings': 'Cài đặt thanh thao tác',
|
|
3365
3416
|
'rail.openSettings': 'Mở cài đặt plugin',
|
|
3366
3417
|
'settings.card.title': 'Cài đặt cửa sổ công cụ Git',
|
|
3367
|
-
'settings.card.desc': '
|
|
3418
|
+
'settings.card.desc': 'Vị trí bảng, nút thanh tác vụ và thông điệp commit do AI viết',
|
|
3419
|
+
'settings.placement.title': 'Vị trí bảng',
|
|
3420
|
+
'settings.placement.tab': 'Hiện thẻ Git trong vùng hội thoại',
|
|
3421
|
+
'settings.placement.tabHint': 'Tắt rồi, bảng vẫn mở được từ thanh bên phải và bảng dưới.',
|
|
3368
3422
|
'settings.rail.title': 'Nút thanh tác vụ',
|
|
3369
3423
|
'settings.rail.hint': 'Chọn các tác vụ hiển thị trên thanh. Thứ tự cố định; bỏ chọn sẽ ẩn tác vụ đó.',
|
|
3370
3424
|
'settings.rail.unavailable': 'Máy chủ này không có dịch vụ cài đặt; hãy dùng “Cài đặt thanh tác vụ” trong bảng điều khiển.',
|
|
@@ -3552,7 +3606,10 @@ window.__ModuleLoader__.load({
|
|
|
3552
3606
|
'rail.settings': 'إعدادات شريط الإجراءات',
|
|
3553
3607
|
'rail.openSettings': 'فتح إعدادات الإضافة',
|
|
3554
3608
|
'settings.card.title': 'إعدادات نافذة أدوات Git',
|
|
3555
|
-
'settings.card.desc': 'أزرار شريط الإجراءات ورسالة إيداع بالذكاء الاصطناعي',
|
|
3609
|
+
'settings.card.desc': 'موضع اللوحة، أزرار شريط الإجراءات ورسالة إيداع بالذكاء الاصطناعي',
|
|
3610
|
+
'settings.placement.title': 'موضع اللوحة',
|
|
3611
|
+
'settings.placement.tab': 'إظهار تبويب Git في منطقة المحادثة',
|
|
3612
|
+
'settings.placement.tabHint': 'عند الإيقاف تبقى اللوحة متاحة من الشريط الجانبي الأيمن واللوحة السفلية.',
|
|
3556
3613
|
'settings.rail.title': 'أزرار شريط الإجراءات',
|
|
3557
3614
|
'settings.rail.hint': 'حدّد الإجراءات المعروضة على الشريط. الترتيب ثابت، وإلغاء التحديد يخفي الإجراء.',
|
|
3558
3615
|
'settings.rail.unavailable': 'لا تتوفر خدمة إعدادات على هذا المضيف؛ استخدم «إعدادات شريط الإجراءات» في اللوحة.',
|
|
@@ -3740,7 +3797,10 @@ window.__ModuleLoader__.load({
|
|
|
3740
3797
|
'rail.settings': 'क्रिया पट्टी सेटिंग्स',
|
|
3741
3798
|
'rail.openSettings': 'प्लगइन सेटिंग खोलें',
|
|
3742
3799
|
'settings.card.title': 'Git टूल विंडो सेटिंग्स',
|
|
3743
|
-
'settings.card.desc': 'एक्शन रेल बटन और AI कमिट संदेश',
|
|
3800
|
+
'settings.card.desc': 'पैनल प्लेसमेंट, एक्शन रेल बटन और AI कमिट संदेश',
|
|
3801
|
+
'settings.placement.title': 'पैनल प्लेसमेंट',
|
|
3802
|
+
'settings.placement.tab': 'संवाद क्षेत्र में Git टैब दिखाएँ',
|
|
3803
|
+
'settings.placement.tabHint': 'बंद करने पर भी पैनल दाएँ साइडबार और निचले पैनल से खुलता है।',
|
|
3744
3804
|
'settings.rail.title': 'एक्शन रेल बटन',
|
|
3745
3805
|
'settings.rail.hint': 'रेल पर दिखने वाली क्रियाएँ चुनें। क्रम निश्चित है; चुनाव हटाने पर वह छिप जाती है।',
|
|
3746
3806
|
'settings.rail.unavailable': 'इस होस्ट में सेटिंग सेवा नहीं है; पैनल में «एक्शन रेल सेटिंग» का उपयोग करें।',
|
|
@@ -3928,7 +3988,10 @@ window.__ModuleLoader__.load({
|
|
|
3928
3988
|
'rail.settings': 'ตั้งค่าแถบการทำงาน',
|
|
3929
3989
|
'rail.openSettings': 'เปิดการตั้งค่าปลั๊กอิน',
|
|
3930
3990
|
'settings.card.title': 'การตั้งค่าหน้าต่างเครื่องมือ Git',
|
|
3931
|
-
'settings.card.desc': 'ปุ่มแถบการทำงานและข้อความคอมมิตโดย AI',
|
|
3991
|
+
'settings.card.desc': 'ตำแหน่งแผง, ปุ่มแถบการทำงานและข้อความคอมมิตโดย AI',
|
|
3992
|
+
'settings.placement.title': 'ตำแหน่งแผง',
|
|
3993
|
+
'settings.placement.tab': 'แสดงแท็บ Git ในพื้นที่บทสนทนา',
|
|
3994
|
+
'settings.placement.tabHint': 'ปิดแล้วยังเปิดแผงจากแถบข้างขวาหรือแผงล่างได้',
|
|
3932
3995
|
'settings.rail.title': 'ปุ่มแถบการทำงาน',
|
|
3933
3996
|
'settings.rail.hint': 'ทำเครื่องหมายการทำงานที่จะแสดงบนแถบ ลำดับคงที่; ยกเลิกเครื่องหมายเพื่อซ่อน',
|
|
3934
3997
|
'settings.rail.unavailable': 'โฮสต์นี้ไม่มีบริการตั้งค่า ให้ใช้ «ตั้งค่าแถบการทำงาน» ในแผง',
|
|
@@ -4088,12 +4151,76 @@ window.__ModuleLoader__.load({
|
|
|
4088
4151
|
|
|
4089
4152
|
/* ============================== api ============================== */
|
|
4090
4153
|
|
|
4154
|
+
/* ---- remote channel fallback core (pure: tests/smoke.mjs slices this
|
|
4155
|
+
block) ---- */
|
|
4156
|
+
/* dsh-remote-web-ui's browser channel rewrites only the host's own /api/,
|
|
4157
|
+
/sidebar/, /git/ and /pet/ prefixes onto its /remote/ proxy; a
|
|
4158
|
+
plugin-owned route like ours is not on that list, so from a paired
|
|
4159
|
+
remote client the direct call reaches the harness browser-auth gate and
|
|
4160
|
+
comes back 401/403 "forbidden" (issue #9: both sidebar and dock panels
|
|
4161
|
+
refused to open remotely). The proxy itself serves any loopback path
|
|
4162
|
+
under /remote/<full pathname> with the paired device's credentials, so
|
|
4163
|
+
the fallback is to retry the very same request through it — the exact
|
|
4164
|
+
URL shape the boot patch produces for the host prefixes ('/remote' +
|
|
4165
|
+
the request's full pathname, mount prefix included, query preserved). */
|
|
4166
|
+
function remoteFallbackUrl(ofPath) {
|
|
4167
|
+
/* Resolve through the SAME base the direct fetch used — document.baseURI
|
|
4168
|
+
(which honours <base href>; dsh 0.1.7 mounts the shell with one), so
|
|
4169
|
+
the retry lands on the proxy copy of the very URL that was rejected. */
|
|
4170
|
+
let resolved = null
|
|
4171
|
+
try {
|
|
4172
|
+
let base
|
|
4173
|
+
if (typeof document === 'object' && document !== null && typeof document.baseURI === 'string' && document.baseURI !== '') {
|
|
4174
|
+
base = document.baseURI
|
|
4175
|
+
} else if (typeof window === 'object' && window !== null && window.location !== undefined && window.location !== null) {
|
|
4176
|
+
base = window.location.href
|
|
4177
|
+
}
|
|
4178
|
+
if (base !== undefined) resolved = new URL(ofPath, base)
|
|
4179
|
+
} catch (error) { resolved = null }
|
|
4180
|
+
if (resolved === null) return '/remote/' + String(ofPath).replace(/^\//, '')
|
|
4181
|
+
return '/remote' + resolved.pathname + resolved.search
|
|
4182
|
+
}
|
|
4183
|
+
|
|
4184
|
+
/* A rejection worth retrying through the remote channel: the auth gate
|
|
4185
|
+
answers 401 (unauthenticated) or 403 (forbidden); every other status —
|
|
4186
|
+
including this route's own JSON errors, which answer 200/4xx with a
|
|
4187
|
+
parsed body — is a real answer, not a transport fence. */
|
|
4188
|
+
function isAuthRejection(status) {
|
|
4189
|
+
return status === 401 || status === 403
|
|
4190
|
+
}
|
|
4191
|
+
/* ---- end remote channel fallback core ---- */
|
|
4192
|
+
|
|
4193
|
+
/* Sticky remote-channel mode: once the proxy has answered, later calls go
|
|
4194
|
+
there directly — otherwise every call from a remote client pays the
|
|
4195
|
+
401/403 round trip first. Loopback desktop browsing never trips the
|
|
4196
|
+
fallback at all (same-origin requests are always admitted). */
|
|
4197
|
+
let viaRemoteChannel = false
|
|
4198
|
+
|
|
4091
4199
|
async function request(method, payload) {
|
|
4092
|
-
const
|
|
4200
|
+
const init = {
|
|
4093
4201
|
method: 'POST',
|
|
4094
4202
|
headers: { 'content-type': 'application/json' },
|
|
4095
4203
|
body: JSON.stringify(payload === undefined ? {} : payload),
|
|
4096
|
-
}
|
|
4204
|
+
}
|
|
4205
|
+
const direct = API_BASE + '/' + method
|
|
4206
|
+
let response = null
|
|
4207
|
+
if (viaRemoteChannel === true) {
|
|
4208
|
+
response = await fetch(remoteFallbackUrl(direct), init)
|
|
4209
|
+
} else {
|
|
4210
|
+
response = await fetch(direct, init)
|
|
4211
|
+
if (isAuthRejection(response.status) === true) {
|
|
4212
|
+
/* Off the origin's trust path: try the pairing proxy once. With no
|
|
4213
|
+
remote-web-ui installed the proxy path 404s — the retry then also
|
|
4214
|
+
fails, and the ORIGINAL rejection is what the caller sees (a
|
|
4215
|
+
proxy answer that is itself an auth rejection is discarded the
|
|
4216
|
+
same way, so a genuine cross-site refusal can never be masked). */
|
|
4217
|
+
const retried = await fetch(remoteFallbackUrl(direct), init)
|
|
4218
|
+
if (isAuthRejection(retried.status) !== true) {
|
|
4219
|
+
viaRemoteChannel = true
|
|
4220
|
+
response = retried
|
|
4221
|
+
}
|
|
4222
|
+
}
|
|
4223
|
+
}
|
|
4097
4224
|
let body = null
|
|
4098
4225
|
try { body = await response.json() } catch (error) { void error }
|
|
4099
4226
|
if (body === null || typeof body !== 'object') throw new Error('HTTP ' + response.status)
|
|
@@ -5447,6 +5574,49 @@ window.__ModuleLoader__.load({
|
|
|
5447
5574
|
E('span', { className: 'dig-settings-glyph' }, E(Icon, { name: spec.icon, size: 13 })),
|
|
5448
5575
|
E('span', { id: inputId + '-label', className: 'dig-settings-label', onClick: toggle }, t(spec.key)))
|
|
5449
5576
|
})),
|
|
5577
|
+
/* Placement (issue #8): one switch, the same optimistic-write contract
|
|
5578
|
+
the rail rows keep. The conversation tab registers/unregisters live
|
|
5579
|
+
(see door 3 in apply), so the flip is visible without a reload. */
|
|
5580
|
+
E('div', { className: 'dig-settings-sub' }, t('settings.placement.title')),
|
|
5581
|
+
(() => {
|
|
5582
|
+
const field = 'conversationTab'
|
|
5583
|
+
const inputId = 'dig-placement-' + field
|
|
5584
|
+
const shown = Object.prototype.hasOwnProperty.call(intent.current, field)
|
|
5585
|
+
? intent.current[field] === true
|
|
5586
|
+
: values[field] !== false
|
|
5587
|
+
const toggle = (event) => {
|
|
5588
|
+
if (readOnly === true) { setNote(t('settings.rail.readonly')); return }
|
|
5589
|
+
const fromControl = event !== undefined && event !== null && event.target !== null
|
|
5590
|
+
&& event.target !== undefined && typeof event.target.checked === 'boolean'
|
|
5591
|
+
? event.target.checked
|
|
5592
|
+
: null
|
|
5593
|
+
const wanted = fromControl !== null
|
|
5594
|
+
? fromControl
|
|
5595
|
+
: (Object.prototype.hasOwnProperty.call(intent.current, field)
|
|
5596
|
+
? intent.current[field] !== true
|
|
5597
|
+
: values[field] !== false) !== true
|
|
5598
|
+
intent.current[field] = wanted
|
|
5599
|
+
dirty.current.set(field, wanted)
|
|
5600
|
+
setPending((now) => Object.assign({}, now, { [field]: wanted }))
|
|
5601
|
+
setNote('')
|
|
5602
|
+
bump()
|
|
5603
|
+
scheduleFlush()
|
|
5604
|
+
}
|
|
5605
|
+
return E('div', { key: field },
|
|
5606
|
+
E('div', { className: 'dig-settings-row', 'data-placement-row': field },
|
|
5607
|
+
E('input', {
|
|
5608
|
+
id: inputId,
|
|
5609
|
+
type: 'checkbox',
|
|
5610
|
+
className: 'dig-settings-check',
|
|
5611
|
+
'aria-labelledby': inputId + '-label',
|
|
5612
|
+
checked: shown,
|
|
5613
|
+
disabled: readOnly === true,
|
|
5614
|
+
onChange: toggle,
|
|
5615
|
+
}),
|
|
5616
|
+
E('span', { className: 'dig-settings-glyph' }, E(Icon, { name: 'commit', size: 13 })),
|
|
5617
|
+
E('span', { id: inputId + '-label', className: 'dig-settings-label', onClick: toggle }, t('settings.placement.tab'))),
|
|
5618
|
+
E('div', { className: 'dig-settings-subnote' }, t('settings.placement.tabHint')))
|
|
5619
|
+
})(),
|
|
5450
5620
|
E('div', { className: 'dig-settings-sub' }, t('settings.commit.title')),
|
|
5451
5621
|
(() => {
|
|
5452
5622
|
/* The model row is a picker over the host's provider catalog; while
|
|
@@ -7757,6 +7927,10 @@ window.__ModuleLoader__.load({
|
|
|
7757
7927
|
const NATIVE_ID = 'dsh-ide-git'
|
|
7758
7928
|
const NATIVE_KIND = 'ide-git'
|
|
7759
7929
|
const NATIVE_WORKSPACE_ITEMS = (state) => state.items
|
|
7930
|
+
/* The conversation.view slot id (issue #8). Order 30 sits the tab after
|
|
7931
|
+
Chat (0) and Trajectory (10), and after dsh-context's tab (20) when both
|
|
7932
|
+
are installed. */
|
|
7933
|
+
const CONVERSATION_VIEW_ID = 'ide-git'
|
|
7760
7934
|
|
|
7761
7935
|
/* The native seat hands a tab the standard props; the panel wants
|
|
7762
7936
|
`{ scope, t }`. A session's working directory is the path of the
|
|
@@ -7789,6 +7963,55 @@ window.__ModuleLoader__.load({
|
|
|
7789
7963
|
return E(Panel, { scope: props.scope, t: props.t, visible: props.visible, dock: props.dock, openSettings: openSettings })
|
|
7790
7964
|
}
|
|
7791
7965
|
|
|
7966
|
+
/* The conversation-area seat (issue #8): the same panel as a view tab
|
|
7967
|
+
beside 对话/轨迹. The session's own cwd decides the repository — the
|
|
7968
|
+
harness records it when the session starts in a workspace, so this is
|
|
7969
|
+
the same source the sidebar seats resolve through. A session without a
|
|
7970
|
+
cwd (blank workspace, or a host without the sessions service) shows the
|
|
7971
|
+
panel's repo-pick state, never an error. */
|
|
7972
|
+
function sessionCwdOf(ctx, sessionId) {
|
|
7973
|
+
if (typeof sessionId !== 'string' || sessionId === '') return undefined
|
|
7974
|
+
try {
|
|
7975
|
+
const sessions = ctx.get('sessions')
|
|
7976
|
+
const list = sessions !== undefined && sessions !== null ? sessions.list : undefined
|
|
7977
|
+
if (list === undefined || typeof list.getSnapshot !== 'function') return undefined
|
|
7978
|
+
const snapshot = list.getSnapshot()
|
|
7979
|
+
const entry = snapshot !== null && typeof snapshot === 'object' && snapshot.byId !== undefined
|
|
7980
|
+
&& snapshot.byId[sessionId] !== undefined && snapshot.byId[sessionId] !== null
|
|
7981
|
+
? snapshot.byId[sessionId] : undefined
|
|
7982
|
+
if (entry !== undefined && typeof entry.cwd === 'string' && entry.cwd !== '') return entry.cwd
|
|
7983
|
+
} catch (error) { void error }
|
|
7984
|
+
return undefined
|
|
7985
|
+
}
|
|
7986
|
+
|
|
7987
|
+
function ConversationPanel(props) {
|
|
7988
|
+
const ctx = props.ctx
|
|
7989
|
+
const sessionId = typeof props.sessionId === 'string' ? props.sessionId : ''
|
|
7990
|
+
const [cwd, setCwd] = useState(() => sessionCwdOf(ctx, sessionId))
|
|
7991
|
+
useEffect(() => {
|
|
7992
|
+
let alive = true
|
|
7993
|
+
const sync = () => { if (alive === true) setCwd(sessionCwdOf(ctx, sessionId)) }
|
|
7994
|
+
sync()
|
|
7995
|
+
/* The session list is a live store; without a subscription a later
|
|
7996
|
+
start (first message in a blank session) would leave the tab on the
|
|
7997
|
+
no-repo chrome until the next remount. */
|
|
7998
|
+
let unsubscribe
|
|
7999
|
+
try {
|
|
8000
|
+
const sessions = ctx.get('sessions')
|
|
8001
|
+
const list = sessions !== undefined && sessions !== null ? sessions.list : undefined
|
|
8002
|
+
if (list !== undefined && typeof list.subscribe === 'function') unsubscribe = list.subscribe(sync)
|
|
8003
|
+
} catch (error) { void error }
|
|
8004
|
+
return () => {
|
|
8005
|
+
alive = false
|
|
8006
|
+
if (typeof unsubscribe === 'function') {
|
|
8007
|
+
try { unsubscribe() } catch (error) { void error }
|
|
8008
|
+
}
|
|
8009
|
+
}
|
|
8010
|
+
}, [ctx, sessionId])
|
|
8011
|
+
const scope = useMemo(() => ({ cwd: cwd, sessionId: sessionId }), [cwd, sessionId])
|
|
8012
|
+
return E(LocaleLive, { ctx: ctx, scope: scope, t: props.t, visible: true })
|
|
8013
|
+
}
|
|
8014
|
+
|
|
7792
8015
|
function NativePanel(props) {
|
|
7793
8016
|
const workspaces = typeof props.useWorkspaces === 'function'
|
|
7794
8017
|
? props.useWorkspaces(NATIVE_WORKSPACE_ITEMS)
|
|
@@ -7927,6 +8150,60 @@ window.__ModuleLoader__.load({
|
|
|
7927
8150
|
there, so only a host without better-sidebar reaches the native seats. */
|
|
7928
8151
|
if (!hostedByBetterSidebar) hostNatively()
|
|
7929
8152
|
|
|
8153
|
+
/* ---- door 3: the conversation-area view tab (issue #8) ---- */
|
|
8154
|
+
/* A third seat beside 对话/轨迹, registered into ui-conversation's
|
|
8155
|
+
`conversation.view` slot (the same contract dsh-context rides). It is
|
|
8156
|
+
ON by default and follows the plugin settings card's switch (row
|
|
8157
|
+
Config field `conversationTab`) live — no reload. Hosts without the
|
|
8158
|
+
row Config keep the tab: there is no editor surface there to turn it
|
|
8159
|
+
off with, and the card says as much for the rail already. The seat
|
|
8160
|
+
rides `slots` (already a declared inject), so a host without
|
|
8161
|
+
ui-conversation simply never mounts it — nothing throws. */
|
|
8162
|
+
const conversationTabEnabled = () => {
|
|
8163
|
+
const ready = railFormReady()
|
|
8164
|
+
if (ready === null) return true
|
|
8165
|
+
const value = ready.value !== null && typeof ready.value === 'object' ? ready.value.conversationTab : undefined
|
|
8166
|
+
return value !== false
|
|
8167
|
+
}
|
|
8168
|
+
ctx.inject(['slots'], (viewCtx) => {
|
|
8169
|
+
const slots = viewCtx.get('slots')
|
|
8170
|
+
if (slots === undefined || slots === null || typeof slots.inject !== 'function') return
|
|
8171
|
+
viewCtx.effect(() => {
|
|
8172
|
+
let offView = null
|
|
8173
|
+
const view = (viewProps) => E(ConversationPanel, Object.assign({}, viewProps, { t: t, ctx: ctx }))
|
|
8174
|
+
const sync = () => {
|
|
8175
|
+
const enabled = conversationTabEnabled()
|
|
8176
|
+
if (enabled === true && offView === null) {
|
|
8177
|
+
try {
|
|
8178
|
+
offView = slots.inject('conversation.view', () => slots.register(
|
|
8179
|
+
{ name: 'conversation.view', id: CONVERSATION_VIEW_ID, order: 30, locale: LOCALE_NS, label: () => t('title') },
|
|
8180
|
+
view,
|
|
8181
|
+
))
|
|
8182
|
+
} catch (error) {
|
|
8183
|
+
/* A late re-registration can lose a race with the previous
|
|
8184
|
+
entry's asynchronous disposal (same keyed cell, same
|
|
8185
|
+
priority): better one missed re-registration — the next
|
|
8186
|
+
config change or reload retries — than a sync that throws
|
|
8187
|
+
inside every rail-config notification. */
|
|
8188
|
+
console.warn('[dsh-ide-git] conversation seat registration failed: ' + String(error && error.message ? error.message : error))
|
|
8189
|
+
}
|
|
8190
|
+
} else if (enabled !== true && offView !== null) {
|
|
8191
|
+
try { offView() } catch (error) { void error }
|
|
8192
|
+
offView = null
|
|
8193
|
+
}
|
|
8194
|
+
}
|
|
8195
|
+
sync()
|
|
8196
|
+
const unsubscribe = subscribeRailConfig(sync)
|
|
8197
|
+
return () => {
|
|
8198
|
+
unsubscribe()
|
|
8199
|
+
if (offView !== null) {
|
|
8200
|
+
try { offView() } catch (error) { void error }
|
|
8201
|
+
offView = null
|
|
8202
|
+
}
|
|
8203
|
+
}
|
|
8204
|
+
}, 'dsh-ide-git: conversation view tab')
|
|
8205
|
+
})
|
|
8206
|
+
|
|
7930
8207
|
/* ---- settings: the row Config is the rail's source of truth ---- */
|
|
7931
8208
|
/* dsh >= 0.1.7 serves a plugin's row Config to the browser through
|
|
7932
8209
|
ctx.configForms; from then on the settings card and the rail read that one
|
package/src/index.js
CHANGED
|
@@ -65,6 +65,11 @@ function railConfigSchema(schema) {
|
|
|
65
65
|
shape.commitModel = live(schema.string().default(''))
|
|
66
66
|
shape.commitReasoning = live(schema.string().default(''))
|
|
67
67
|
shape.commitPrompt = live(schema.string().default(''))
|
|
68
|
+
/* Conversation-area view tab (issue #8): on by default, switchable off from
|
|
69
|
+
the plugin settings card. false means "do not register the
|
|
70
|
+
conversation.view seat at all" — the sidebar and dock seats are not
|
|
71
|
+
affected; a missing field means the default (shown). */
|
|
72
|
+
shape.conversationTab = live(schema.boolean().default(true))
|
|
68
73
|
return schema.object(shape)
|
|
69
74
|
}
|
|
70
75
|
|