dsh-oc-tui 0.2.0 → 0.3.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.
Files changed (50) hide show
  1. package/README.md +21 -563
  2. package/bin/mcp-sse-bridge.mjs +499 -499
  3. package/docs/assets/conversation.png +0 -0
  4. package/docs/assets/cover.png +0 -0
  5. package/docs/assets/home.png +0 -0
  6. package/docs/assets/settings.png +0 -0
  7. package/docs/dsh-std-/346/216/245/345/205/245/350/257/264/346/230/216.md +566 -0
  8. package/docs/user-guide.md +616 -0
  9. package/docs//347/224/250/346/210/267/346/211/213/345/206/214.md +607 -593
  10. package/dsh-plugin.json +69 -69
  11. package/lib/boot-block.js +129 -0
  12. package/lib/diagnostics.js +162 -120
  13. package/lib/dsh-version.js +161 -0
  14. package/lib/git-branch.js +157 -157
  15. package/lib/i18n.js +283 -283
  16. package/lib/image.js +2 -1
  17. package/lib/index.js +5183 -4812
  18. package/lib/locales/ar.js +670 -635
  19. package/lib/locales/de.js +639 -604
  20. package/lib/locales/en.js +35 -0
  21. package/lib/locales/es.js +639 -604
  22. package/lib/locales/fr.js +639 -604
  23. package/lib/locales/id.js +641 -606
  24. package/lib/locales/it.js +639 -604
  25. package/lib/locales/ja.js +639 -604
  26. package/lib/locales/ko.js +639 -604
  27. package/lib/locales/nl.js +639 -604
  28. package/lib/locales/pl.js +653 -618
  29. package/lib/locales/pt-BR.js +639 -604
  30. package/lib/locales/ru.js +653 -618
  31. package/lib/locales/tr.js +639 -604
  32. package/lib/locales/vi.js +641 -606
  33. package/lib/locales/zh-CN.js +640 -605
  34. package/lib/locales/zh-TW.js +640 -605
  35. package/lib/markdown.js +101 -27
  36. package/lib/mcp-monitor.js +189 -0
  37. package/lib/mcp-skill.js +93 -93
  38. package/lib/mcp.js +865 -838
  39. package/lib/model-route.js +66 -0
  40. package/lib/providers.js +712 -712
  41. package/lib/screenshot.js +140 -0
  42. package/lib/splash-opencode.js +29 -26
  43. package/lib/startup.js +66 -48
  44. package/lib/term.js +53 -11
  45. package/lib/themes.js +101 -0
  46. package/lib/ui.js +685 -443
  47. package/lib/updates.js +5 -2
  48. package/lib/web-settings.js +52 -21
  49. package/package.json +160 -146
  50. package/skills/mcp-import/SKILL.md +216 -216
@@ -1,216 +1,216 @@
1
- ---
2
- name: mcp-import
3
- description: "Use when the user asks to add, import, connect or configure an MCP server for the dsh-oc-tui TUI — a local command (stdio), a Streamable HTTP endpoint, or a legacy SSE endpoint — or to fix, disable, or remove an existing one; 用户要求添加、导入、连接或配置 MCP 服务器(本地命令 stdio / HTTP / SSE),或修改、停用、删除已有 MCP 服务器时使用。"
4
- whenToUse: "The user names a concrete MCP server, package, command, or endpoint; importing one is a read-merge-write of one JSON config file, not a code change."
5
- ---
6
-
7
- # Import and connect MCP servers
8
-
9
- MCP servers for this TUI live in JSON config files that you edit directly. There
10
- is no CLI command and no settings field for this: read the target file, merge in
11
- one entry under `servers`, write the file back. The next session picks it up.
12
-
13
- ## 1. Which file to edit
14
-
15
- | Scope | File | Applies to |
16
- | --- | --- | --- |
17
- | User | `$DSH_HOME/mcp.json` | every session |
18
- | Project | `<dir>/.dsh/mcp.json` | sessions whose cwd is `<dir>` or below |
19
-
20
- - `$DSH_HOME` defaults to `~/.dsh`; on Windows that is `%USERPROFILE%\.dsh`.
21
- - At session start the TUI walks from the session cwd up to the filesystem root,
22
- collecting every `.dsh/mcp.json` along the way, then adds the user file. When
23
- the same server name is defined more than once, the file nearest the cwd wins.
24
- - Default to the user file. Use the project file when the user wants the server
25
- for one project only ("only in this repo", "只在这个项目里"). Create the `.dsh`
26
- directory if it is missing.
27
-
28
- ## 2. Document shape
29
-
30
- ```json
31
- {
32
- "version": 1,
33
- "servers": {
34
- "github": {
35
- "type": "stdio",
36
- "command": "npx",
37
- "args": ["-y", "@modelcontextprotocol/server-github"]
38
- }
39
- }
40
- }
41
- ```
42
-
43
- - `version` is `1`; `servers` maps each server **name** to its record.
44
- - The name is the object key, not a field. Do not write `name` or `serverName`
45
- inside the record.
46
- - A name must match `[A-Za-z0-9_-]{1,32}` — 1 to 32 letters, digits, `_`, or `-`.
47
- - A missing file is a valid empty configuration. A file with broken JSON, or with
48
- a `servers` value that is not an object, is reported as an error for that file
49
- alone and does not affect the other files.
50
-
51
- ## 3. Records
52
-
53
- `timeoutMs` and `enabled` are accepted on every type:
54
-
55
- | Field | Meaning |
56
- | --- | --- |
57
- | `timeoutMs` | Milliseconds allowed for one tool call or resource request. Integer 1–3600000, default `30000`. |
58
- | `enabled` | `false` keeps the entry but never connects it. Default `true`. |
59
-
60
- Write only the fields documented below.
61
-
62
- ### `stdio` — a local command
63
-
64
- ```json
65
- {
66
- "type": "stdio",
67
- "command": "npx",
68
- "args": ["-y", "@modelcontextprotocol/server-github"],
69
- "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_example" },
70
- "timeoutMs": 30000,
71
- "enabled": true
72
- }
73
- ```
74
-
75
- `command` is required: an executable resolved on `PATH`. `args` is an array of
76
- strings. `env` is an object of string values that becomes the child environment.
77
-
78
- ### `http` — Streamable HTTP
79
-
80
- ```json
81
- {
82
- "type": "http",
83
- "url": "https://mcp.example.com/mcp",
84
- "headers": { "Authorization": "Bearer example-token" },
85
- "timeoutMs": 30000,
86
- "enabled": true
87
- }
88
- ```
89
-
90
- `url` is required and must parse as a URL with an `http` or `https` protocol.
91
- `headers` is an object of string values.
92
-
93
- ### `sse` — legacy HTTP+SSE
94
-
95
- ```json
96
- {
97
- "type": "sse",
98
- "url": "https://mcp.example.com/sse",
99
- "headers": { "Authorization": "Bearer example-token" },
100
- "timeoutMs": 30000,
101
- "enabled": true
102
- }
103
- ```
104
-
105
- Same fields as `http`. This is the legacy HTTP+SSE transport, which the TUI
106
- bridges for the host, so the entry behaves like the others.
107
-
108
- Choose by endpoint, not by preference: `http` is Streamable HTTP and fits a
109
- modern `/mcp` endpoint; `sse` is only for a server whose endpoint really is a
110
- legacy `/sse`. When unsure, use `http`.
111
-
112
- ## 4. Rules for editing
113
-
114
- 1. Read the target file first when it exists, then merge: change only the one key
115
- under `servers`. Keep every other server and every other document key exactly
116
- as it was — never regenerate the file from scratch.
117
- 2. Keep the JSON valid: double quotes, no comments, no trailing commas.
118
- 3. Write the whole file back (read-modify-write); do not append a second document.
119
- 4. If the requested name already exists, that is an edit, not an import. Replace
120
- that entry only when the user means to change that server; never silently
121
- repoint an existing name at a different server.
122
- 5. Secrets belong in `env` (stdio) or `headers` (`http` / `sse`). `mcp.json` is
123
- plain text on disk with no encryption, so say so before writing a token there.
124
- 6. Do not touch the TUI's `settings.yaml`, the TUI source, or anything else for
125
- this — server definitions live only in `mcp.json`.
126
- 7. If a required token is missing, ask for it. If you must write first, use a
127
- visible placeholder such as `"<token>"` and state that it still needs filling in.
128
-
129
- ## 5. Verify
130
-
131
- 1. The entry applies to the **next** session: tell the user to open a new session
132
- (or restart the TUI). A session already running keeps the servers it started
133
- with.
134
- 2. In the TUI, `Ctrl+P` opens Settings; `Tab` to the **MCP** tab
135
- (Main → Model → Update → MCP). The server is listed there with its scope, a
136
- live connection state, and a tool count.
137
- 3. Tools from a connected server are callable as `mcp__<name>__<tool>`: a server
138
- named `github` that exposes `create_issue` gives `mcp__github__create_issue`.
139
- 4. A bad entry is not fatal. It shows as an error row in the MCP tab while the
140
- rest of the TUI keeps working.
141
- 5. Sanity-check the file before handing it over, substituting the real path:
142
-
143
- ```sh
144
- node -e "JSON.parse(require('node:fs').readFileSync('PATH_TO_MCP_JSON','utf8'));console.log('valid')"
145
- ```
146
-
147
- ## 6. Worked examples
148
-
149
- ### stdio — "帮我加一个 github mcp"
150
-
151
- Read `$DSH_HOME/mcp.json` (it may not exist yet), add `servers.github`, write it
152
- back, and report the plain-text secret with the verification step:
153
-
154
- ```json
155
- {
156
- "version": 1,
157
- "servers": {
158
- "github": {
159
- "type": "stdio",
160
- "command": "npx",
161
- "args": ["-y", "@modelcontextprotocol/server-github"],
162
- "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_example" },
163
- "timeoutMs": 30000,
164
- "enabled": true
165
- }
166
- }
167
- }
168
- ```
169
-
170
- Then: open a new session, `Ctrl+P` → MCP, confirm `github` is connected and note
171
- its tool count. Mention that the token sits unencrypted in `$DSH_HOME/mcp.json`.
172
-
173
- ### http — "把 https://mcp.example.com/mcp 接进来,用 Bearer token"
174
-
175
- `$DSH_HOME/mcp.json`, preserving any other servers already in the file:
176
-
177
- ```json
178
- {
179
- "version": 1,
180
- "servers": {
181
- "web": {
182
- "type": "http",
183
- "url": "https://mcp.example.com/mcp",
184
- "headers": { "Authorization": "Bearer example-token" },
185
- "timeoutMs": 30000,
186
- "enabled": true
187
- }
188
- }
189
- }
190
- ```
191
-
192
- Then: new session, `Ctrl+P` → MCP, confirm `web` is connected, and check that its
193
- tools appear as `mcp__web__<tool>`.
194
-
195
- ### sse — "这个服务器只提供 legacy /sse 端点"
196
-
197
- Only because the endpoint is `/sse`; otherwise this would be `http`:
198
-
199
- ```json
200
- {
201
- "version": 1,
202
- "servers": {
203
- "legacy": {
204
- "type": "sse",
205
- "url": "https://mcp.example.com/sse",
206
- "headers": { "Authorization": "Bearer example-token" },
207
- "timeoutMs": 30000,
208
- "enabled": true
209
- }
210
- }
211
- }
212
- ```
213
-
214
- Then: new session, `Ctrl+P` → MCP, confirm `legacy` is connected and note its tool
215
- count. If it reports an error, check that the endpoint is really SSE and not a
216
- Streamable HTTP `/mcp` endpoint.
1
+ ---
2
+ name: mcp-import
3
+ description: "Use when the user asks to add, import, connect or configure an MCP server for the dsh-oc-tui TUI — a local command (stdio), a Streamable HTTP endpoint, or a legacy SSE endpoint — or to fix, disable, or remove an existing one; 用户要求添加、导入、连接或配置 MCP 服务器(本地命令 stdio / HTTP / SSE),或修改、停用、删除已有 MCP 服务器时使用。"
4
+ whenToUse: "The user names a concrete MCP server, package, command, or endpoint; importing one is a read-merge-write of one JSON config file, not a code change."
5
+ ---
6
+
7
+ # Import and connect MCP servers
8
+
9
+ MCP servers for this TUI live in JSON config files that you edit directly. There
10
+ is no CLI command and no settings field for this: read the target file, merge in
11
+ one entry under `servers`, write the file back. The next session picks it up.
12
+
13
+ ## 1. Which file to edit
14
+
15
+ | Scope | File | Applies to |
16
+ | --- | --- | --- |
17
+ | User | `$DSH_HOME/mcp.json` | every session |
18
+ | Project | `<dir>/.dsh/mcp.json` | sessions whose cwd is `<dir>` or below |
19
+
20
+ - `$DSH_HOME` defaults to `~/.dsh`; on Windows that is `%USERPROFILE%\.dsh`.
21
+ - At session start the TUI walks from the session cwd up to the filesystem root,
22
+ collecting every `.dsh/mcp.json` along the way, then adds the user file. When
23
+ the same server name is defined more than once, the file nearest the cwd wins.
24
+ - Default to the user file. Use the project file when the user wants the server
25
+ for one project only ("only in this repo", "只在这个项目里"). Create the `.dsh`
26
+ directory if it is missing.
27
+
28
+ ## 2. Document shape
29
+
30
+ ```json
31
+ {
32
+ "version": 1,
33
+ "servers": {
34
+ "github": {
35
+ "type": "stdio",
36
+ "command": "npx",
37
+ "args": ["-y", "@modelcontextprotocol/server-github"]
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ - `version` is `1`; `servers` maps each server **name** to its record.
44
+ - The name is the object key, not a field. Do not write `name` or `serverName`
45
+ inside the record.
46
+ - A name must match `[A-Za-z0-9_-]{1,32}` — 1 to 32 letters, digits, `_`, or `-`.
47
+ - A missing file is a valid empty configuration. A file with broken JSON, or with
48
+ a `servers` value that is not an object, is reported as an error for that file
49
+ alone and does not affect the other files.
50
+
51
+ ## 3. Records
52
+
53
+ `timeoutMs` and `enabled` are accepted on every type:
54
+
55
+ | Field | Meaning |
56
+ | --- | --- |
57
+ | `timeoutMs` | Milliseconds allowed for one tool call or resource request. Integer 1–3600000, default `30000`. |
58
+ | `enabled` | `false` keeps the entry but never connects it. Default `true`. |
59
+
60
+ Write only the fields documented below.
61
+
62
+ ### `stdio` — a local command
63
+
64
+ ```json
65
+ {
66
+ "type": "stdio",
67
+ "command": "npx",
68
+ "args": ["-y", "@modelcontextprotocol/server-github"],
69
+ "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_example" },
70
+ "timeoutMs": 30000,
71
+ "enabled": true
72
+ }
73
+ ```
74
+
75
+ `command` is required: an executable resolved on `PATH`. `args` is an array of
76
+ strings. `env` is an object of string values that becomes the child environment.
77
+
78
+ ### `http` — Streamable HTTP
79
+
80
+ ```json
81
+ {
82
+ "type": "http",
83
+ "url": "https://mcp.example.com/mcp",
84
+ "headers": { "Authorization": "Bearer example-token" },
85
+ "timeoutMs": 30000,
86
+ "enabled": true
87
+ }
88
+ ```
89
+
90
+ `url` is required and must parse as a URL with an `http` or `https` protocol.
91
+ `headers` is an object of string values.
92
+
93
+ ### `sse` — legacy HTTP+SSE
94
+
95
+ ```json
96
+ {
97
+ "type": "sse",
98
+ "url": "https://mcp.example.com/sse",
99
+ "headers": { "Authorization": "Bearer example-token" },
100
+ "timeoutMs": 30000,
101
+ "enabled": true
102
+ }
103
+ ```
104
+
105
+ Same fields as `http`. This is the legacy HTTP+SSE transport, which the TUI
106
+ bridges for the host, so the entry behaves like the others.
107
+
108
+ Choose by endpoint, not by preference: `http` is Streamable HTTP and fits a
109
+ modern `/mcp` endpoint; `sse` is only for a server whose endpoint really is a
110
+ legacy `/sse`. When unsure, use `http`.
111
+
112
+ ## 4. Rules for editing
113
+
114
+ 1. Read the target file first when it exists, then merge: change only the one key
115
+ under `servers`. Keep every other server and every other document key exactly
116
+ as it was — never regenerate the file from scratch.
117
+ 2. Keep the JSON valid: double quotes, no comments, no trailing commas.
118
+ 3. Write the whole file back (read-modify-write); do not append a second document.
119
+ 4. If the requested name already exists, that is an edit, not an import. Replace
120
+ that entry only when the user means to change that server; never silently
121
+ repoint an existing name at a different server.
122
+ 5. Secrets belong in `env` (stdio) or `headers` (`http` / `sse`). `mcp.json` is
123
+ plain text on disk with no encryption, so say so before writing a token there.
124
+ 6. Do not touch the TUI's `settings.yaml`, the TUI source, or anything else for
125
+ this — server definitions live only in `mcp.json`.
126
+ 7. If a required token is missing, ask for it. If you must write first, use a
127
+ visible placeholder such as `"<token>"` and state that it still needs filling in.
128
+
129
+ ## 5. Verify
130
+
131
+ 1. The entry applies to the **next** session: tell the user to open a new session
132
+ (or restart the TUI). A session already running keeps the servers it started
133
+ with.
134
+ 2. In the TUI, `Ctrl+P` opens Settings; `Tab` to the **MCP** tab
135
+ (Main → Model → Update → MCP). The server is listed there with its scope, a
136
+ live connection state, and a tool count.
137
+ 3. Tools from a connected server are callable as `mcp__<name>__<tool>`: a server
138
+ named `github` that exposes `create_issue` gives `mcp__github__create_issue`.
139
+ 4. A bad entry is not fatal. It shows as an error row in the MCP tab while the
140
+ rest of the TUI keeps working.
141
+ 5. Sanity-check the file before handing it over, substituting the real path:
142
+
143
+ ```sh
144
+ node -e "JSON.parse(require('node:fs').readFileSync('PATH_TO_MCP_JSON','utf8'));console.log('valid')"
145
+ ```
146
+
147
+ ## 6. Worked examples
148
+
149
+ ### stdio — "帮我加一个 github mcp"
150
+
151
+ Read `$DSH_HOME/mcp.json` (it may not exist yet), add `servers.github`, write it
152
+ back, and report the plain-text secret with the verification step:
153
+
154
+ ```json
155
+ {
156
+ "version": 1,
157
+ "servers": {
158
+ "github": {
159
+ "type": "stdio",
160
+ "command": "npx",
161
+ "args": ["-y", "@modelcontextprotocol/server-github"],
162
+ "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_example" },
163
+ "timeoutMs": 30000,
164
+ "enabled": true
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ Then: open a new session, `Ctrl+P` → MCP, confirm `github` is connected and note
171
+ its tool count. Mention that the token sits unencrypted in `$DSH_HOME/mcp.json`.
172
+
173
+ ### http — "把 https://mcp.example.com/mcp 接进来,用 Bearer token"
174
+
175
+ `$DSH_HOME/mcp.json`, preserving any other servers already in the file:
176
+
177
+ ```json
178
+ {
179
+ "version": 1,
180
+ "servers": {
181
+ "web": {
182
+ "type": "http",
183
+ "url": "https://mcp.example.com/mcp",
184
+ "headers": { "Authorization": "Bearer example-token" },
185
+ "timeoutMs": 30000,
186
+ "enabled": true
187
+ }
188
+ }
189
+ }
190
+ ```
191
+
192
+ Then: new session, `Ctrl+P` → MCP, confirm `web` is connected, and check that its
193
+ tools appear as `mcp__web__<tool>`.
194
+
195
+ ### sse — "这个服务器只提供 legacy /sse 端点"
196
+
197
+ Only because the endpoint is `/sse`; otherwise this would be `http`:
198
+
199
+ ```json
200
+ {
201
+ "version": 1,
202
+ "servers": {
203
+ "legacy": {
204
+ "type": "sse",
205
+ "url": "https://mcp.example.com/sse",
206
+ "headers": { "Authorization": "Bearer example-token" },
207
+ "timeoutMs": 30000,
208
+ "enabled": true
209
+ }
210
+ }
211
+ }
212
+ ```
213
+
214
+ Then: new session, `Ctrl+P` → MCP, confirm `legacy` is connected and note its tool
215
+ count. If it reports an error, check that the endpoint is really SSE and not a
216
+ Streamable HTTP `/mcp` endpoint.