@woosau/dsh-custom-env 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -133
- package/README.zh-CN.md +18 -98
- package/lib/client.js +105 -87
- package/lib/types/client/format-remote-error.d.ts +10 -0
- package/lib/types/client/locales.d.ts +66 -8
- package/locale/en.json +1 -1
- package/locale/zh.json +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,133 +1,53 @@
|
|
|
1
|
-
# dsh-custom-env
|
|
2
|
-
|
|
3
|
-
English | [中文](README.zh-CN.md)
|
|
4
|
-
|
|
5
|
-
Community DeepSeek Harness
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
[](LICENSE)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Equivalent: `dsh plugin --profile web add https://github.com/ownduck/dsh-custom-env.git`
|
|
56
|
-
|
|
57
|
-
The dump should contain a `# == dsh-custom-env` layer and a `custom-env` plugin row. Restart DSH Web and hard-refresh the browser.
|
|
58
|
-
|
|
59
|
-
### Ask an agent to install it
|
|
60
|
-
|
|
61
|
-
```text
|
|
62
|
-
Install the DSH plugin github:ownduck/dsh-custom-env into my local desktop profile by running: dsh plugin --profile desktop add github:ownduck/dsh-custom-env. If pnpm reports ignored build scripts for koffi, add allowBuilds.koffi: true under the profile pnpm-workspace.yaml and re-run add. Then confirm Settings → Environment appears after restarting Desktop.
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### From a local clone (`file:` / `.`)
|
|
66
|
-
|
|
67
|
-
```powershell
|
|
68
|
-
git clone https://github.com/ownduck/dsh-custom-env.git
|
|
69
|
-
cd dsh-custom-env
|
|
70
|
-
dsh plugin --profile desktop add .
|
|
71
|
-
# or: dsh plugin --profile web add .
|
|
72
|
-
dsh --profile web --dump-config
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### From npm (optional, after publish)
|
|
76
|
-
|
|
77
|
-
```powershell
|
|
78
|
-
dsh plugin --profile desktop add @woosau/dsh-custom-env@latest --registry=https://registry.npmjs.org/
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Uninstall / reinstall
|
|
82
|
-
|
|
83
|
-
```powershell
|
|
84
|
-
dsh plugin --profile desktop remove @woosau/dsh-custom-env
|
|
85
|
-
dsh plugin --profile desktop add github:ownduck/dsh-custom-env
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
For a `file:` / local checkout, rebuild `lib/` after source changes, then restart DSH. Re-run `plugin add` only when `package.json` or `cordis.patch.yml` changed.
|
|
89
|
-
|
|
90
|
-
## Usage
|
|
91
|
-
|
|
92
|
-
1. Open **Settings → Environment**
|
|
93
|
-
2. Edit as a **draft**: **Confirm** writes `$DSH_HOME/.env` (and Host/OS live); **Cancel** only reverts the input
|
|
94
|
-
3. After Confirm, rows show a restart tip — **new** items say “added”; **modified** items (relative to Host start) also get **Restore** (writes back the Host-start value)
|
|
95
|
-
4. Restart DSH / open a new terminal for the full OS effect; after Host restart, tips and Restore clear
|
|
96
|
-
5. In the **dsh command** block, compare PATH vs expected; click **Install** only when offered
|
|
97
|
-
|
|
98
|
-
Do not store bootstrap names in `.env` (including `PATH`). Prefer ordinary names for app config. Names containing `KEY` / `SECRET` / `TOKEN` remain scrubbed from model-visible shells by existing harness policy.
|
|
99
|
-
|
|
100
|
-
### Installing the `dsh` CLI from Settings
|
|
101
|
-
|
|
102
|
-
Expected path is inferred from **how this Host was started** (Desktop packaged `resources/runtime/cli/bin`, or the Node/source launcher on `argv`).
|
|
103
|
-
|
|
104
|
-
| Platform | What Install does | Conflict note |
|
|
105
|
-
| --- | --- | --- |
|
|
106
|
-
| **Windows** | Prepends the expected bin directory to the **user** `Path` (registry). Ownership key: `Software\dsh-custom-env\Command` (not DeepSeekHarness). | Can coexist with Desktop’s PATH entry; whichever directory is first wins in new terminals. |
|
|
107
|
-
| **macOS** | Writes symlink `/usr/local/bin/dsh` → expected launcher. Receipt: `.dsh-custom-env-command.json`. | **Same path as Desktop “Manage dsh Command…”** — installing here may replace that link. |
|
|
108
|
-
| **Linux** | Status only; no Install button. | — |
|
|
109
|
-
|
|
110
|
-
Open a **new** terminal after Install. This plugin never calls Desktop `app.relaunch`.
|
|
111
|
-
|
|
112
|
-
## Development
|
|
113
|
-
|
|
114
|
-
```powershell
|
|
115
|
-
cd dsh-custom-env
|
|
116
|
-
pnpm test # or: node --import tsx/esm --test tests/*.spec.ts
|
|
117
|
-
pnpm build # rebuilds lib/ (needs sibling vertax-work esbuild for client bundle)
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Tests live under [`tests/`](tests/) (`env-file.spec.ts`, `cli-path.spec.ts`). Docs are this README pair only.
|
|
121
|
-
|
|
122
|
-
## GitHub vs npmjs
|
|
123
|
-
|
|
124
|
-
| Channel | Enough for users? | Install command |
|
|
125
|
-
| --- | --- | --- |
|
|
126
|
-
| **GitHub only** | Yes | `dsh plugin add github:ownduck/dsh-custom-env` |
|
|
127
|
-
| **npmjs** | Optional | `dsh plugin add @woosau/dsh-custom-env` |
|
|
128
|
-
|
|
129
|
-
Pushing to GitHub is enough to share and install. Publishing to npmjs is optional convenience (shorter name, version tags, npm badges), similar to community plugins that also publish `@scope/name` on the registry.
|
|
130
|
-
|
|
131
|
-
## License
|
|
132
|
-
|
|
133
|
-
MIT
|
|
1
|
+
# dsh-custom-env
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
Community DeepSeek Harness plugin: manage `$DSH_HOME/.env` from **Settings → Environment**. Not an official DeepSeek AI product.
|
|
6
|
+
|
|
7
|
+
Edits apply to the Host immediately and sync to the Windows / macOS user environment (new terminals pick up OS changes). Linux user-env sync is not supported.
|
|
8
|
+
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- CRUD for `$DSH_HOME/.env` in Settings
|
|
14
|
+
- Hot-apply to the current Host process
|
|
15
|
+
- Sync to Windows / macOS user environment
|
|
16
|
+
- Rejects bootstrap names (`PATH`, `DSH_*`, `XDG_*`, …)
|
|
17
|
+
- Optional **Install** for the `dsh` CLI used by this Host (Windows / macOS)
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
Requires a working DSH install with the `dsh` CLI. Use profile `desktop` or `web`.
|
|
22
|
+
|
|
23
|
+
```powershell
|
|
24
|
+
dsh plugin --profile desktop add @woosau/dsh-custom-env
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```powershell
|
|
28
|
+
dsh plugin --profile web add @woosau/dsh-custom-env
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
GitHub: `dsh plugin --profile desktop add github:ownduck/dsh-custom-env`
|
|
32
|
+
|
|
33
|
+
Close Desktop first if `plugin` hits `EPERM` on the profile `package.json`. GitHub installs may need `allowBuilds.koffi: true` in the profile `pnpm-workspace.yaml` (native `koffi`). Then restart DSH and open **Settings → Environment**.
|
|
34
|
+
|
|
35
|
+
## Uninstall
|
|
36
|
+
|
|
37
|
+
```powershell
|
|
38
|
+
dsh plugin --profile desktop remove @woosau/dsh-custom-env
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
1. Open **Settings → Environment**
|
|
44
|
+
2. Edit as a draft: **Confirm** writes `.env` and live Host/OS; **Cancel** reverts the inputs
|
|
45
|
+
3. After Confirm, restart tips appear for new/changed rows; **Restore** writes back the Host-start value
|
|
46
|
+
4. Restart DSH or open a new terminal for the full OS effect
|
|
47
|
+
5. Use **Install** in the dsh block only when offered (Windows user PATH / macOS `/usr/local/bin/dsh`; may replace Desktop’s link on macOS)
|
|
48
|
+
|
|
49
|
+
Do not put bootstrap names (including `PATH`) in `.env`.
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
MIT
|
package/README.zh-CN.md
CHANGED
|
@@ -2,131 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | 中文
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
社区 DeepSeek Harness 插件:在 **设置 → 环境变量** 管理 `$DSH_HOME/.env`。非 DeepSeek AI 官方产品。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
保存后立即作用于 Host,并同步到 Windows / macOS 用户环境(新开终端可见 OS 侧变更)。不同步 Linux 用户环境。
|
|
8
8
|
|
|
9
9
|
[](LICENSE)
|
|
10
|
-
[](https://github.com/ownduck/dsh-custom-env)
|
|
11
10
|
|
|
12
11
|
## 功能
|
|
13
12
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
- Windows / macOS
|
|
17
|
-
- 拒绝 bootstrap 名(`PATH`、`DSH_*`、`XDG_*`
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
## 前置条件
|
|
21
|
-
|
|
22
|
-
- 已安装可用的 DeepSeek Harness,且终端里能运行 `dsh`(CLI 或 Desktop 自带 CLI)
|
|
23
|
-
- 选择 profile:`desktop`(Electron)或 `web`(浏览器)。下文两种都有。
|
|
13
|
+
- 设置页管理 `$DSH_HOME/.env`
|
|
14
|
+
- 热写当前 Host 进程
|
|
15
|
+
- 同步 Windows / macOS 用户环境
|
|
16
|
+
- 拒绝 bootstrap 名(`PATH`、`DSH_*`、`XDG_*` 等)
|
|
17
|
+
- 可选为本 Host **安装** `dsh` CLI(Windows / macOS)
|
|
24
18
|
|
|
25
19
|
## 安装
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
### Desktop(推荐)
|
|
30
|
-
|
|
31
|
-
若 `plugin` 报 profile `package.json` 的 `EPERM`,先退出 Desktop / VertaxWork。
|
|
21
|
+
需已安装 DSH 且可用 `dsh` CLI。profile 选 `desktop` 或 `web`。
|
|
32
22
|
|
|
33
23
|
```powershell
|
|
34
|
-
dsh plugin --profile desktop add
|
|
24
|
+
dsh plugin --profile desktop add @woosau/dsh-custom-env
|
|
35
25
|
```
|
|
36
26
|
|
|
37
|
-
本插件依赖原生包 `koffi`。若 pnpm 拦截其 install 脚本,在该 profile 的 `pnpm-workspace.yaml` 中加入后重新 `add`:
|
|
38
|
-
|
|
39
|
-
```yaml
|
|
40
|
-
allowBuilds:
|
|
41
|
-
koffi: true
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
重启 Desktop,打开 **设置 → 环境变量**。
|
|
45
|
-
|
|
46
|
-
### Web
|
|
47
|
-
|
|
48
27
|
```powershell
|
|
49
|
-
|
|
50
|
-
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
51
|
-
dsh plugin --profile web add github:ownduck/dsh-custom-env
|
|
52
|
-
dsh --profile web --dump-config
|
|
28
|
+
dsh plugin --profile web add @woosau/dsh-custom-env
|
|
53
29
|
```
|
|
54
30
|
|
|
55
|
-
|
|
31
|
+
GitHub:`dsh plugin --profile desktop add github:ownduck/dsh-custom-env`
|
|
56
32
|
|
|
57
|
-
|
|
33
|
+
若 `plugin` 报 profile `package.json` 的 `EPERM`,先退出 Desktop。从 GitHub 安装时,profile 的 `pnpm-workspace.yaml` 可能需要 `allowBuilds.koffi: true`(原生依赖 `koffi`)。然后重启 DSH,打开 **设置 → 环境变量**。
|
|
58
34
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
```text
|
|
62
|
-
请将 DSH 插件 github:ownduck/dsh-custom-env 安装到本机 desktop profile,执行:dsh plugin --profile desktop add github:ownduck/dsh-custom-env。若 pnpm 提示忽略 koffi 的 build scripts,在该 profile 的 pnpm-workspace.yaml 中加入 allowBuilds.koffi: true 后重新 add。重启 Desktop 后确认「设置 → 环境变量」可用。
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### 从本地克隆安装(`file:` / `.`)
|
|
66
|
-
|
|
67
|
-
```powershell
|
|
68
|
-
git clone https://github.com/ownduck/dsh-custom-env.git
|
|
69
|
-
cd dsh-custom-env
|
|
70
|
-
dsh plugin --profile desktop add .
|
|
71
|
-
# 或:dsh plugin --profile web add .
|
|
72
|
-
dsh --profile web --dump-config
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### 从 npm 安装(可选,发布后)
|
|
76
|
-
|
|
77
|
-
```powershell
|
|
78
|
-
dsh plugin --profile desktop add @woosau/dsh-custom-env@latest --registry=https://registry.npmjs.org/
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## 卸载 / 重装
|
|
35
|
+
## 卸载
|
|
82
36
|
|
|
83
37
|
```powershell
|
|
84
38
|
dsh plugin --profile desktop remove @woosau/dsh-custom-env
|
|
85
|
-
dsh plugin --profile desktop add github:ownduck/dsh-custom-env
|
|
86
39
|
```
|
|
87
40
|
|
|
88
|
-
本地 `file:` 开发:改 `src` 后重建 `lib/`,再重启 DSH。只有改了 `package.json` / `cordis.patch.yml` 才需要重新 `plugin add`。
|
|
89
|
-
|
|
90
41
|
## 使用
|
|
91
42
|
|
|
92
43
|
1. 打开 **设置 → 环境变量**
|
|
93
|
-
2.
|
|
94
|
-
3.
|
|
95
|
-
4. 完整生效请重启 DSH
|
|
96
|
-
5.
|
|
97
|
-
|
|
98
|
-
不要把 bootstrap 名(含 `PATH`)写进 `.env`。应用配置用普通名字即可。名称含 `KEY` / `SECRET` / `TOKEN` 时仍会被现有 harness 策略从模型可见 shell 中 scrub。
|
|
99
|
-
|
|
100
|
-
### 在设置页安装 `dsh` CLI
|
|
101
|
-
|
|
102
|
-
期望路径由 **当前 Host 的启动方式** 推断(Desktop 打包的 `resources/runtime/cli/bin`,或 Node/源码启动的 `argv` 启动器)。
|
|
103
|
-
|
|
104
|
-
| 平台 | 安装行为 | 冲突说明 |
|
|
105
|
-
| --- | --- | --- |
|
|
106
|
-
| **Windows** | 将期望 bin 目录写入用户 `Path`(注册表)。所有权键:`Software\dsh-custom-env\Command`(不用 DeepSeekHarness)。 | 可与 Desktop 的 PATH 条目并存;新终端里谁排前用谁。 |
|
|
107
|
-
| **macOS** | 写符号链接 `/usr/local/bin/dsh` → 期望启动器。收据:`.dsh-custom-env-command.json`。 | **与 Desktop「管理 dsh 命令…」同一路径**,可能覆盖其链接。 |
|
|
108
|
-
| **Linux** | 仅展示状态,无安装按钮。 | — |
|
|
109
|
-
|
|
110
|
-
安装后请 **新开** 终端。本插件不会调用 Desktop `app.relaunch`。
|
|
111
|
-
|
|
112
|
-
## 开发
|
|
113
|
-
|
|
114
|
-
```powershell
|
|
115
|
-
cd dsh-custom-env
|
|
116
|
-
pnpm test # 或:node --import tsx/esm --test tests/*.spec.ts
|
|
117
|
-
pnpm build # 重建 lib/(client 打包依赖旁路的 vertax-work esbuild)
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
测试在 [`tests/`](tests/)(`env-file.spec.ts`、`cli-path.spec.ts`)。文档即本 README 中英双语。
|
|
121
|
-
|
|
122
|
-
## GitHub 与 npmjs
|
|
123
|
-
|
|
124
|
-
| 渠道 | 够不够用 | 安装命令 |
|
|
125
|
-
| --- | --- | --- |
|
|
126
|
-
| **只推 GitHub** | 够 | `dsh plugin add github:ownduck/dsh-custom-env` |
|
|
127
|
-
| **再发 npmjs** | 可选 | `dsh plugin add @woosau/dsh-custom-env` |
|
|
44
|
+
2. 草稿编辑:**确定** 写入 `.env` 并热写 Host/OS;**取消** 只恢复输入框
|
|
45
|
+
3. 确定后新增/修改行旁有重启提示;**恢复** 可写回 Host 启动时的值
|
|
46
|
+
4. 完整生效请重启 DSH 或新开终端
|
|
47
|
+
5. **dsh** 区块仅在出现按钮时点 **安装**(Windows 用户 PATH / macOS `/usr/local/bin/dsh`;macOS 上可能覆盖 Desktop 的链接)
|
|
128
48
|
|
|
129
|
-
|
|
49
|
+
不要把 bootstrap 名(含 `PATH`)写进 `.env`。
|
|
130
50
|
|
|
131
51
|
## 许可证
|
|
132
52
|
|
package/lib/client.js
CHANGED
|
@@ -402,6 +402,20 @@ var typert_remote_client_default = TYPERT_REMOTE;
|
|
|
402
402
|
var import_react = require("react");
|
|
403
403
|
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
404
404
|
|
|
405
|
+
// src/client/format-remote-error.ts
|
|
406
|
+
function isRemoteFailure(value) {
|
|
407
|
+
return typeof value === "object" && value !== null && value.isDSHRemoteError === true && typeof value.code === "string";
|
|
408
|
+
}
|
|
409
|
+
function formatRemoteError(error, t) {
|
|
410
|
+
if (isRemoteFailure(error)) {
|
|
411
|
+
if (error.code === "custom-env/invalid-name") return t("error.invalidName");
|
|
412
|
+
if (error.code === "custom-env/invalid-value") return t("error.invalidValue");
|
|
413
|
+
if (error.code === "custom-env/restore-failed") return t("error.restoreFailed");
|
|
414
|
+
if (error.code === "custom-env/cli-install-failed") return t("error.cliInstall");
|
|
415
|
+
}
|
|
416
|
+
return t("error.generic");
|
|
417
|
+
}
|
|
418
|
+
|
|
405
419
|
// src/client/EnvSettingsSection.module.css
|
|
406
420
|
var css = ".EnvSettingsSection_section {\n display: flex;\n flex-direction: column;\n gap: 16px;\n max-width: 760px;\n color: var(--dsw-alias-label-primary);\n}\n\n.EnvSettingsSection_heading {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n line-height: 1.3;\n}\n\n/* \u2014\u2014 dsh CLI: exactly two lines (label + path) \u2014\u2014 */\n.EnvSettingsSection_cli {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.EnvSettingsSection_cliHeading {\n margin: 0;\n font-size: 13px;\n font-weight: 500;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.EnvSettingsSection_cliBody {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 28px;\n gap: 8px;\n align-items: center;\n height: 28px;\n}\n\n.EnvSettingsSection_cliPath {\n margin: 0;\n min-width: 0;\n font-size: 13px;\n line-height: 28px;\n color: var(--dsw-alias-label-tertiary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.EnvSettingsSection_cliSlot {\n display: flex;\n width: 28px;\n height: 28px;\n align-items: center;\n justify-content: center;\n}\n\n.EnvSettingsSection_cliSlot[data-empty='true'] {\n visibility: hidden;\n pointer-events: none;\n}\n\n.EnvSettingsSection_notice,\n.EnvSettingsSection_empty {\n margin: 0;\n font-size: 13px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.EnvSettingsSection_notice[data-tone='error'] {\n color: var(--dsw-alias-label-danger, #c62828);\n}\n\n/* \u2014\u2014 variable list: CSS grid, not table (avoids Input overflow overlap) \u2014\u2014 */\n.EnvSettingsSection_list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 0;\n}\n\n.EnvSettingsSection_header,\n.EnvSettingsSection_row {\n display: grid;\n grid-template-columns: minmax(120px, 0.85fr) minmax(0, 1.55fr) 100px;\n gap: 10px;\n align-items: center;\n min-width: 0;\n}\n\n.EnvSettingsSection_header {\n padding: 0 0 2px;\n}\n\n.EnvSettingsSection_headerLabel {\n margin: 0;\n font-size: 12px;\n font-weight: 500;\n line-height: 1.3;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.EnvSettingsSection_headerActions {\n width: 100px;\n}\n\n.EnvSettingsSection_field {\n min-width: 0;\n overflow: hidden;\n}\n\n.EnvSettingsSection_fieldInput {\n display: flex;\n box-sizing: border-box;\n width: 100%;\n max-width: 100%;\n min-width: 0;\n}\n\n.EnvSettingsSection_actions {\n display: grid;\n grid-template-columns: repeat(3, 28px);\n gap: 4px;\n align-items: center;\n justify-content: end;\n width: 100px;\n margin-left: auto;\n flex-shrink: 0;\n}\n\n.EnvSettingsSection_slot {\n display: flex;\n width: 28px;\n height: 28px;\n align-items: center;\n justify-content: center;\n}\n\n.EnvSettingsSection_slot[data-empty='true'] {\n visibility: hidden;\n pointer-events: none;\n}\n\n.EnvSettingsSection_iconButton {\n display: inline-flex;\n width: 28px;\n height: 28px;\n margin: 0;\n padding: 0;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: var(--dsw-radius-sm, 6px);\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n.EnvSettingsSection_iconButton:hover:not(:disabled) {\n background: var(--dsw-alias-fill-hover, rgba(127, 127, 127, 0.12));\n color: var(--dsw-alias-label-primary);\n}\n\n.EnvSettingsSection_iconButton:disabled {\n opacity: 0.45;\n cursor: default;\n}\n\n.EnvSettingsSection_iconButtonDanger:hover:not(:disabled) {\n color: var(--dsw-alias-label-danger, #c62828);\n}\n\n.EnvSettingsSection_iconButtonPrimary {\n color: var(--dsw-alias-brand-primary, #247bbf);\n}\n\n.EnvSettingsSection_restartBadge {\n display: inline-flex;\n width: 28px;\n height: 28px;\n align-items: center;\n justify-content: center;\n color: var(--dsw-alias-label-warning, #c67c00);\n}\n\n.EnvSettingsSection_spinner {\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .EnvSettingsSection_spinner {\n animation: none;\n }\n}\n";
|
|
407
421
|
if (typeof document !== "undefined" && !document.getElementById("dsh-custom-env-css")) {
|
|
@@ -453,10 +467,10 @@ function RowActions({
|
|
|
453
467
|
onRestore,
|
|
454
468
|
onRemove
|
|
455
469
|
}) {
|
|
456
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.actions, role: "group", "aria-label": t("actions"), children: [
|
|
457
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slot, { empty: !dirty && !pending, children: dirty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: loading ? t("loading") : t("confirm"), primary: true, disabled: busy || !canConfirm, onClick: onConfirm, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconLoadingOutlineRegular, { className: EnvSettingsSection_default.spinner, size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconCheckOutlineRegular, { size: 14 }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Tooltip, { portal: true, label: t("restartRequired"), side: "top", delayMs: 400, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: EnvSettingsSection_default.restartBadge, role: "img", "aria-label": t("restartRequired"), title: t("restartRequired"), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconWarningOutlineRegular, { size: 14 }) }) }) }),
|
|
458
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slot, { empty: !dirty && !pending, children: dirty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: t("cancel"), disabled: busy, onClick: onCancel, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconCloseOutlineRegular, { size: 14 }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: t("restore"), disabled: busy, onClick: onRestore, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconRefreshOutlineRegular, { size: 14 }) }) }),
|
|
459
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slot, { empty: !showRemove, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: t("remove"), danger: true, disabled: busy, onClick: onRemove, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: 14 }) }) })
|
|
470
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.actions, role: "group", "aria-label": t("field.actions"), children: [
|
|
471
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slot, { empty: !dirty && !pending, children: dirty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: loading ? t("panel.loading") : t("action.confirm"), primary: true, disabled: busy || !canConfirm, onClick: onConfirm, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconLoadingOutlineRegular, { className: EnvSettingsSection_default.spinner, size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconCheckOutlineRegular, { size: 14 }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Tooltip, { portal: true, label: t("status.restartRequired"), side: "top", delayMs: 400, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: EnvSettingsSection_default.restartBadge, role: "img", "aria-label": t("status.restartRequired"), title: t("status.restartRequired"), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconWarningOutlineRegular, { size: 14 }) }) }) }),
|
|
472
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slot, { empty: !dirty && !pending, children: dirty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: t("action.cancel"), disabled: busy, onClick: onCancel, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconCloseOutlineRegular, { size: 14 }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: t("action.restore"), disabled: busy, onClick: onRestore, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconRefreshOutlineRegular, { size: 14 }) }) }),
|
|
473
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slot, { empty: !showRemove, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: t("action.remove"), danger: true, disabled: busy, onClick: onRemove, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: 14 }) }) })
|
|
460
474
|
] });
|
|
461
475
|
}
|
|
462
476
|
function Field(props) {
|
|
@@ -515,8 +529,8 @@ function EnvSettingsSection({
|
|
|
515
529
|
setError(void 0);
|
|
516
530
|
try {
|
|
517
531
|
applySnapshot(await action());
|
|
518
|
-
} catch {
|
|
519
|
-
setError(t
|
|
532
|
+
} catch (err) {
|
|
533
|
+
setError(formatRemoteError(err, t));
|
|
520
534
|
} finally {
|
|
521
535
|
setBusyTarget(void 0);
|
|
522
536
|
}
|
|
@@ -531,8 +545,8 @@ function EnvSettingsSection({
|
|
|
531
545
|
} catch {
|
|
532
546
|
setCli(void 0);
|
|
533
547
|
}
|
|
534
|
-
} catch {
|
|
535
|
-
setError(t
|
|
548
|
+
} catch (err) {
|
|
549
|
+
setError(formatRemoteError(err, t));
|
|
536
550
|
} finally {
|
|
537
551
|
setBusyTarget(void 0);
|
|
538
552
|
}
|
|
@@ -558,11 +572,11 @@ function EnvSettingsSection({
|
|
|
558
572
|
const cliInstalling = busyTarget === "cli";
|
|
559
573
|
const cliBooting = busyTarget === "boot" || cli === void 0;
|
|
560
574
|
const showCliAction = cli?.canInstall === true || cliInstalling;
|
|
561
|
-
const notice = error ?? (nameError ? t("invalidName") : void 0) ?? (cli?.reason === "could-not-resolve-expected-cli" ? t("
|
|
575
|
+
const notice = error ?? (nameError ? t("error.invalidName") : void 0) ?? (cli?.reason === "could-not-resolve-expected-cli" ? t("error.cliUnresolved") : void 0) ?? (cli?.reason === "unsupported-platform" ? t("error.cliUnsupported") : void 0);
|
|
562
576
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.section, children: [
|
|
563
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: EnvSettingsSection_default.heading, children: t("title") }),
|
|
564
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: EnvSettingsSection_default.cli, "aria-label": t("
|
|
565
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: EnvSettingsSection_default.cliHeading, children: t("
|
|
577
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: EnvSettingsSection_default.heading, children: t("panel.title") }),
|
|
578
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: EnvSettingsSection_default.cli, "aria-label": t("cli.title"), children: [
|
|
579
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: EnvSettingsSection_default.cliHeading, children: t("cli.title") }),
|
|
566
580
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.cliBody, children: [
|
|
567
581
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
568
582
|
"p",
|
|
@@ -570,13 +584,13 @@ function EnvSettingsSection({
|
|
|
570
584
|
className: EnvSettingsSection_default.cliPath,
|
|
571
585
|
title: cliBooting ? void 0 : cli.activePath ?? void 0,
|
|
572
586
|
"aria-busy": cliBooting || cliInstalling,
|
|
573
|
-
children: cliBooting ? t("loading") : cli.activePath === null ? t("
|
|
587
|
+
children: cliBooting ? t("panel.loading") : cli.activePath === null ? t("cli.activeMissing") : cli.activePath
|
|
574
588
|
}
|
|
575
589
|
),
|
|
576
590
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: EnvSettingsSection_default.cliSlot, "data-empty": showCliAction ? "false" : "true", children: showCliAction ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
577
591
|
IconAction,
|
|
578
592
|
{
|
|
579
|
-
label: cliInstalling ? t("loading") : cli?.platform === "darwin" ? t("
|
|
593
|
+
label: cliInstalling ? t("panel.loading") : cli?.platform === "darwin" ? t("cli.macConflict") : t("cli.install"),
|
|
580
594
|
disabled: busy,
|
|
581
595
|
onClick: () => {
|
|
582
596
|
if (busyTarget !== void 0) return;
|
|
@@ -585,8 +599,8 @@ function EnvSettingsSection({
|
|
|
585
599
|
void (async () => {
|
|
586
600
|
try {
|
|
587
601
|
setCli(await cliInstall());
|
|
588
|
-
} catch {
|
|
589
|
-
setError(t
|
|
602
|
+
} catch (err) {
|
|
603
|
+
setError(formatRemoteError(err, t));
|
|
590
604
|
} finally {
|
|
591
605
|
setBusyTarget(void 0);
|
|
592
606
|
}
|
|
@@ -600,11 +614,11 @@ function EnvSettingsSection({
|
|
|
600
614
|
notice !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: EnvSettingsSection_default.notice, "data-tone": error !== void 0 || nameError ? "error" : void 0, role: "status", children: notice }) : null,
|
|
601
615
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.list, children: [
|
|
602
616
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.header, children: [
|
|
603
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: EnvSettingsSection_default.headerLabel, children: t("name") }),
|
|
604
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: EnvSettingsSection_default.headerLabel, children: t("value") }),
|
|
617
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: EnvSettingsSection_default.headerLabel, children: t("field.name") }),
|
|
618
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: EnvSettingsSection_default.headerLabel, children: t("field.value") }),
|
|
605
619
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: EnvSettingsSection_default.headerActions, "aria-hidden": "true" })
|
|
606
620
|
] }),
|
|
607
|
-
snapshot !== void 0 && entries.length === 0 && notice === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: EnvSettingsSection_default.empty, children: t("empty") }) : null,
|
|
621
|
+
snapshot !== void 0 && entries.length === 0 && notice === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: EnvSettingsSection_default.empty, children: t("panel.empty") }) : null,
|
|
608
622
|
entries.map((entry) => {
|
|
609
623
|
const draft = drafts[entry.id] ?? { name: entry.name, value: entry.value };
|
|
610
624
|
const dirty = draft.name !== entry.name || draft.value !== entry.value;
|
|
@@ -621,7 +635,7 @@ function EnvSettingsSection({
|
|
|
621
635
|
disabled: busy,
|
|
622
636
|
title: draft.name,
|
|
623
637
|
invalid: nameError && dirty,
|
|
624
|
-
label: t("name"),
|
|
638
|
+
label: t("field.name"),
|
|
625
639
|
onChange: (name) => {
|
|
626
640
|
setNameError(false);
|
|
627
641
|
setDraft(entry.id, { name });
|
|
@@ -635,7 +649,7 @@ function EnvSettingsSection({
|
|
|
635
649
|
value: draft.value,
|
|
636
650
|
disabled: busy,
|
|
637
651
|
title: draft.value,
|
|
638
|
-
label: t("value"),
|
|
652
|
+
label: t("field.value"),
|
|
639
653
|
onChange: (value) => {
|
|
640
654
|
setDraft(entry.id, { value });
|
|
641
655
|
}
|
|
@@ -674,10 +688,10 @@ function EnvSettingsSection({
|
|
|
674
688
|
id: "env-new-name",
|
|
675
689
|
value: newDraft.name,
|
|
676
690
|
disabled: busy,
|
|
677
|
-
placeholder: t("namePlaceholder"),
|
|
678
|
-
title: newDraft.name || t("namePlaceholder"),
|
|
691
|
+
placeholder: t("field.namePlaceholder"),
|
|
692
|
+
title: newDraft.name || t("field.namePlaceholder"),
|
|
679
693
|
invalid: nameError,
|
|
680
|
-
label: t("name"),
|
|
694
|
+
label: t("field.name"),
|
|
681
695
|
onChange: (name) => {
|
|
682
696
|
setNameError(false);
|
|
683
697
|
setDraft(NEW_ID, { name });
|
|
@@ -690,9 +704,9 @@ function EnvSettingsSection({
|
|
|
690
704
|
id: "env-new-value",
|
|
691
705
|
value: newDraft.value,
|
|
692
706
|
disabled: busy,
|
|
693
|
-
placeholder: t("valuePlaceholder"),
|
|
694
|
-
title: newDraft.value || t("valuePlaceholder"),
|
|
695
|
-
label: t("value"),
|
|
707
|
+
placeholder: t("field.valuePlaceholder"),
|
|
708
|
+
title: newDraft.value || t("field.valuePlaceholder"),
|
|
709
|
+
label: t("field.value"),
|
|
696
710
|
onChange: (value) => {
|
|
697
711
|
setDraft(NEW_ID, { value });
|
|
698
712
|
}
|
|
@@ -727,13 +741,13 @@ function EnvSettingsSection({
|
|
|
727
741
|
onClose: () => {
|
|
728
742
|
if (!busy) setPendingRemove(void 0);
|
|
729
743
|
},
|
|
730
|
-
title: t("removeConfirmTitle"),
|
|
731
|
-
closeLabel: t("close"),
|
|
732
|
-
description: pendingRemove ? t("removeConfirm", { name: pendingRemove.name }) : void 0,
|
|
744
|
+
title: t("action.removeConfirmTitle"),
|
|
745
|
+
closeLabel: t("action.close"),
|
|
746
|
+
description: pendingRemove ? t("action.removeConfirm", { name: pendingRemove.name }) : void 0,
|
|
733
747
|
footer: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
734
748
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "outline", disabled: busy, onClick: () => {
|
|
735
749
|
setPendingRemove(void 0);
|
|
736
|
-
}, children: t("cancel") }),
|
|
750
|
+
}, children: t("action.cancel") }),
|
|
737
751
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
738
752
|
import_dsh_client_ui_primitives.Button,
|
|
739
753
|
{
|
|
@@ -745,7 +759,7 @@ function EnvSettingsSection({
|
|
|
745
759
|
setPendingRemove(void 0);
|
|
746
760
|
void run(`row:${id}`, () => remove(id));
|
|
747
761
|
},
|
|
748
|
-
children: t("remove")
|
|
762
|
+
children: t("action.remove")
|
|
749
763
|
}
|
|
750
764
|
)
|
|
751
765
|
] })
|
|
@@ -756,61 +770,65 @@ function EnvSettingsSection({
|
|
|
756
770
|
|
|
757
771
|
// src/client/locales.ts
|
|
758
772
|
var NS = "settings.env";
|
|
759
|
-
var en = {
|
|
760
|
-
nav: "Environment",
|
|
761
|
-
title: "Environment",
|
|
762
|
-
empty: "No variables",
|
|
763
|
-
name: "Name",
|
|
764
|
-
value: "Value",
|
|
765
|
-
actions: "Actions",
|
|
766
|
-
confirm: "Confirm",
|
|
767
|
-
cancel: "Cancel",
|
|
768
|
-
remove: "Delete",
|
|
769
|
-
removeConfirmTitle: "Delete variable",
|
|
770
|
-
removeConfirm: "Delete {name}?",
|
|
771
|
-
restore: "Restore original",
|
|
772
|
-
close: "Close",
|
|
773
|
-
namePlaceholder: "MY_VAR",
|
|
774
|
-
valuePlaceholder: "value",
|
|
775
|
-
loading: "Loading\u2026",
|
|
776
|
-
error: "Update failed",
|
|
777
|
-
invalidName: "Invalid name",
|
|
778
|
-
restartRequired: "Restart the client",
|
|
779
|
-
cliTitle: "dsh",
|
|
780
|
-
cliActiveMissing: "Not found",
|
|
781
|
-
cliInstall: "Install",
|
|
782
|
-
cliMacConflict: "Replaces /usr/local/bin/dsh",
|
|
783
|
-
cliInstallError: "Install failed",
|
|
784
|
-
cliReasonUnresolved: "Install unavailable",
|
|
785
|
-
cliReasonUnsupported: "Windows / macOS only"
|
|
786
|
-
};
|
|
787
773
|
var zh = {
|
|
788
|
-
nav: "\u73AF\u5883\u53D8\u91CF",
|
|
789
|
-
title: "\u73AF\u5883\u53D8\u91CF",
|
|
790
|
-
empty: "\u6682\u65E0\u53D8\u91CF",
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
774
|
+
"panel.nav": "\u73AF\u5883\u53D8\u91CF",
|
|
775
|
+
"panel.title": "\u73AF\u5883\u53D8\u91CF",
|
|
776
|
+
"panel.empty": "\u6682\u65E0\u53D8\u91CF",
|
|
777
|
+
"panel.loading": "\u52A0\u8F7D\u4E2D\u2026",
|
|
778
|
+
"field.name": "\u540D\u79F0",
|
|
779
|
+
"field.value": "\u503C",
|
|
780
|
+
"field.actions": "\u64CD\u4F5C",
|
|
781
|
+
"field.namePlaceholder": "MY_VAR",
|
|
782
|
+
"field.valuePlaceholder": "\u503C",
|
|
783
|
+
"action.confirm": "\u786E\u5B9A",
|
|
784
|
+
"action.cancel": "\u53D6\u6D88",
|
|
785
|
+
"action.remove": "\u5220\u9664",
|
|
786
|
+
"action.removeConfirmTitle": "\u5220\u9664\u53D8\u91CF",
|
|
787
|
+
"action.removeConfirm": "\u5220\u9664 {name}\uFF1F",
|
|
788
|
+
"action.restore": "\u6062\u590D\u539F\u503C",
|
|
789
|
+
"action.close": "\u5173\u95ED",
|
|
790
|
+
"status.restartRequired": "\u9700\u91CD\u542F\u5BA2\u6237\u7AEF",
|
|
791
|
+
"cli.title": "dsh",
|
|
792
|
+
"cli.activeMissing": "\u672A\u627E\u5230",
|
|
793
|
+
"cli.install": "\u5B89\u88C5",
|
|
794
|
+
"cli.macConflict": "\u5C06\u66FF\u6362 /usr/local/bin/dsh",
|
|
795
|
+
"error.generic": "\u66F4\u65B0\u5931\u8D25",
|
|
796
|
+
"error.invalidName": "\u540D\u79F0\u65E0\u6548",
|
|
797
|
+
"error.invalidValue": "\u503C\u65E0\u6548",
|
|
798
|
+
"error.restoreFailed": "\u6062\u590D\u5931\u8D25",
|
|
799
|
+
"error.cliInstall": "\u5B89\u88C5\u5931\u8D25",
|
|
800
|
+
"error.cliUnresolved": "\u65E0\u6CD5\u5B89\u88C5",
|
|
801
|
+
"error.cliUnsupported": "\u4EC5 Windows / macOS"
|
|
802
|
+
};
|
|
803
|
+
var en = {
|
|
804
|
+
"panel.nav": "Environment",
|
|
805
|
+
"panel.title": "Environment",
|
|
806
|
+
"panel.empty": "No variables",
|
|
807
|
+
"panel.loading": "Loading\u2026",
|
|
808
|
+
"field.name": "Name",
|
|
809
|
+
"field.value": "Value",
|
|
810
|
+
"field.actions": "Actions",
|
|
811
|
+
"field.namePlaceholder": "MY_VAR",
|
|
812
|
+
"field.valuePlaceholder": "value",
|
|
813
|
+
"action.confirm": "Confirm",
|
|
814
|
+
"action.cancel": "Cancel",
|
|
815
|
+
"action.remove": "Delete",
|
|
816
|
+
"action.removeConfirmTitle": "Delete variable",
|
|
817
|
+
"action.removeConfirm": "Delete {name}?",
|
|
818
|
+
"action.restore": "Restore original",
|
|
819
|
+
"action.close": "Close",
|
|
820
|
+
"status.restartRequired": "Restart the client",
|
|
821
|
+
"cli.title": "dsh",
|
|
822
|
+
"cli.activeMissing": "Not found",
|
|
823
|
+
"cli.install": "Install",
|
|
824
|
+
"cli.macConflict": "Replaces /usr/local/bin/dsh",
|
|
825
|
+
"error.generic": "Update failed",
|
|
826
|
+
"error.invalidName": "Invalid name",
|
|
827
|
+
"error.invalidValue": "Invalid value",
|
|
828
|
+
"error.restoreFailed": "Restore failed",
|
|
829
|
+
"error.cliInstall": "Install failed",
|
|
830
|
+
"error.cliUnresolved": "Install unavailable",
|
|
831
|
+
"error.cliUnsupported": "Windows / macOS only"
|
|
814
832
|
};
|
|
815
833
|
|
|
816
834
|
// src/client/mount.ts
|
|
@@ -826,7 +844,7 @@ function registerUi(ctx) {
|
|
|
826
844
|
name: "settings.section",
|
|
827
845
|
id: "env",
|
|
828
846
|
order: 25,
|
|
829
|
-
label: () => t("nav"),
|
|
847
|
+
label: () => t("panel.nav"),
|
|
830
848
|
locale: NS,
|
|
831
849
|
inject: () => ({
|
|
832
850
|
load: async () => call(await ctx.remote.customEnv.list()),
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Map Host Remote failures to settings.env locale strings. */
|
|
2
|
+
import type { EnvSettingsKey } from './locales.ts';
|
|
3
|
+
type Translate = (key: EnvSettingsKey) => string;
|
|
4
|
+
/**
|
|
5
|
+
* Localize a caught Remote failure for the settings section.
|
|
6
|
+
* @param error - thrown value from inject call helpers.
|
|
7
|
+
* @param t - bound settings.env translator.
|
|
8
|
+
*/
|
|
9
|
+
export declare function formatRemoteError(error: unknown, t: Translate): string;
|
|
10
|
+
export {};
|
|
@@ -1,9 +1,67 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** `settings.env` namespace dictionaries for the environment settings section. */
|
|
2
2
|
/** Dictionary namespace owned by this plugin. */
|
|
3
|
-
export declare const NS
|
|
4
|
-
/**
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
export declare const NS: "settings.env";
|
|
4
|
+
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
5
|
+
export declare const zh: {
|
|
6
|
+
'panel.nav': string;
|
|
7
|
+
'panel.title': string;
|
|
8
|
+
'panel.empty': string;
|
|
9
|
+
'panel.loading': string;
|
|
10
|
+
'field.name': string;
|
|
11
|
+
'field.value': string;
|
|
12
|
+
'field.actions': string;
|
|
13
|
+
'field.namePlaceholder': string;
|
|
14
|
+
'field.valuePlaceholder': string;
|
|
15
|
+
'action.confirm': string;
|
|
16
|
+
'action.cancel': string;
|
|
17
|
+
'action.remove': string;
|
|
18
|
+
'action.removeConfirmTitle': string;
|
|
19
|
+
'action.removeConfirm': string;
|
|
20
|
+
'action.restore': string;
|
|
21
|
+
'action.close': string;
|
|
22
|
+
'status.restartRequired': string;
|
|
23
|
+
'cli.title': string;
|
|
24
|
+
'cli.activeMissing': string;
|
|
25
|
+
'cli.install': string;
|
|
26
|
+
'cli.macConflict': string;
|
|
27
|
+
'error.generic': string;
|
|
28
|
+
'error.invalidName': string;
|
|
29
|
+
'error.invalidValue': string;
|
|
30
|
+
'error.restoreFailed': string;
|
|
31
|
+
'error.cliInstall': string;
|
|
32
|
+
'error.cliUnresolved': string;
|
|
33
|
+
'error.cliUnsupported': string;
|
|
34
|
+
};
|
|
35
|
+
/** The settings.env namespace key union. */
|
|
36
|
+
export type EnvSettingsKey = keyof typeof zh;
|
|
37
|
+
/** English dictionary, checked complete against the zh key set. */
|
|
38
|
+
export declare const en: {
|
|
39
|
+
'panel.nav': string;
|
|
40
|
+
'panel.title': string;
|
|
41
|
+
'panel.empty': string;
|
|
42
|
+
'panel.loading': string;
|
|
43
|
+
'field.name': string;
|
|
44
|
+
'field.value': string;
|
|
45
|
+
'field.actions': string;
|
|
46
|
+
'field.namePlaceholder': string;
|
|
47
|
+
'field.valuePlaceholder': string;
|
|
48
|
+
'action.confirm': string;
|
|
49
|
+
'action.cancel': string;
|
|
50
|
+
'action.remove': string;
|
|
51
|
+
'action.removeConfirmTitle': string;
|
|
52
|
+
'action.removeConfirm': string;
|
|
53
|
+
'action.restore': string;
|
|
54
|
+
'action.close': string;
|
|
55
|
+
'status.restartRequired': string;
|
|
56
|
+
'cli.title': string;
|
|
57
|
+
'cli.activeMissing': string;
|
|
58
|
+
'cli.install': string;
|
|
59
|
+
'cli.macConflict': string;
|
|
60
|
+
'error.generic': string;
|
|
61
|
+
'error.invalidName': string;
|
|
62
|
+
'error.invalidValue': string;
|
|
63
|
+
'error.restoreFailed': string;
|
|
64
|
+
'error.cliInstall': string;
|
|
65
|
+
'error.cliUnresolved': string;
|
|
66
|
+
'error.cliUnsupported': string;
|
|
67
|
+
};
|
package/locale/en.json
CHANGED
package/locale/zh.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@woosau/dsh-custom-env",
|
|
3
|
-
"description": "DSH plugin: manage $DSH_HOME/.env from Settings
|
|
4
|
-
"version": "0.1.
|
|
3
|
+
"description": "DSH plugin: manage $DSH_HOME/.env from Settings",
|
|
4
|
+
"version": "0.1.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/types/index.d.ts",
|