dsh-ptc-plus 0.2.2 → 0.2.4
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 +30 -11
- package/README.zh.md +30 -11
- package/assets/dsh-ptc-plus-banner-en.webp +0 -0
- package/assets/ptc-plus-settings-en.png +0 -0
- package/assets/ptc-plus-settings-zh.png +0 -0
- package/client.js +139 -46
- package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +25 -3
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +2 -1
- package/docs/adr/0022-stage-npm-releases-with-oidc.md +31 -0
- package/docs/architecture.md +6 -4
- package/docs/client-ui.md +2 -2
- package/docs/installation.md +5 -5
- package/docs/publishing.md +25 -1
- package/docs/runtime-reference.md +4 -2
- package/index.js +13 -11
- package/internal/config-spec.js +46 -1
- package/internal/direct-surface-owner.js +21 -18
- package/internal/edit-transport-owner.js +12 -1
- package/internal/failure-reporting.js +1 -0
- package/internal/recovery-tips.js +0 -1
- package/internal/rejected-cell-editor.js +21 -7
- package/internal/session-cell-executor.js +52 -26
- package/internal/session-runtime.js +12 -4
- package/internal/settings-compat.js +31 -0
- package/internal/validated-parse-repair.js +82 -0
- package/package.json +17 -11
- package/src/client.js +88 -26
- package/assets/ptc-plus-settings.png +0 -0
- /package/assets/{dsh-ptc-plus-banner.webp → dsh-ptc-plus-banner-zh.webp} +0 -0
package/README.md
CHANGED
|
@@ -1,17 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/dsh-ptc-plus-banner-en.webp" width="100%" alt="dsh-ptc-plus banner">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
<strong>English</strong> ·
|
|
7
|
+
<a href="README.zh.md">简体中文</a>
|
|
8
|
+
</p>
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="#what-default-ptc-mode-gets-wrong">Problems</a> ·
|
|
12
|
+
<a href="#three-scenes-that-matter-most">Scenes</a> ·
|
|
13
|
+
<a href="#settings">Settings</a> ·
|
|
14
|
+
<a href="#scope">Scope</a> ·
|
|
15
|
+
<a href="#install">Install</a> ·
|
|
16
|
+
<a href="#documentation">Docs</a>
|
|
17
|
+
</p>
|
|
10
18
|
|
|
11
19
|
<p align="center">
|
|
12
|
-
<
|
|
20
|
+
<a href="https://github.com/deepseek-ai/deepseek-harness"><img alt="DeepSeek Harness PTC mode" src="https://img.shields.io/badge/DeepSeek%20Harness-PTC%20mode-4b6bfb"></a>
|
|
21
|
+
<a href="package.json"><img alt="Node.js ^22.19.0 || >=24.0.0" src="https://img.shields.io/badge/Node.js-%5E22.19.0%20%7C%7C%20%3E%3D24.0.0-5fa04e?logo=nodedotjs&logoColor=white"></a>
|
|
22
|
+
<a href="https://www.npmjs.com/package/dsh-ptc-plus"><img alt="npm version" src="https://img.shields.io/npm/v/dsh-ptc-plus?logo=npm"></a>
|
|
23
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg"></a>
|
|
13
24
|
</p>
|
|
14
25
|
|
|
26
|
+
<p align="center">
|
|
27
|
+
<a href="https://awesome-dsh-plugin.com/"><img alt="Awesome DSH Plugin" src="https://awesome-dsh-plugin.com/badge.svg"></a>
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
15
32
|
**PTC Plus gives DSH PTC mode a session-bound persistent TypeScript REPL.** Every `run_code` continues in the same session. Variables, imports, and results from one `run_code` are still available in the next one.
|
|
16
33
|
|
|
17
34
|
> [!NOTE]
|
|
@@ -20,7 +37,7 @@ English | [简体中文](README.zh.md)
|
|
|
20
37
|
> [!IMPORTANT]
|
|
21
38
|
> Built for `danger-full-access`: direct Node.js and OS access with no extra sandbox. Use it only where that permission scope is acceptable.
|
|
22
39
|
|
|
23
|
-

|
|
40
|
+

|
|
24
41
|
|
|
25
42
|
*The settings card exposes live configuration and the `enabled` kill switch.*
|
|
26
43
|
|
|
@@ -73,6 +90,8 @@ edit_run_code({ edits: [{ old_string: 'deps.length', new_string: 'deps' }] })
|
|
|
73
90
|
|
|
74
91
|
Only the diff goes in. The full source stays out of the conversation. Exact replacements and regular expressions both have limits, so a bad pattern cannot hang.
|
|
75
92
|
|
|
93
|
+
When a rejected cell has exactly one validated missing closing token at the end, its diagnostic includes the complete `edit_run_code(...)` call needed to apply that correction and rerun the cell. That generated call carries an `expected_target_call_seq` precondition, so it is rejected without execution if another cell becomes the edit target first. PTC Plus never applies the suggestion automatically; ambiguous repairs or repairs without a persistent target identity still require corrected source.
|
|
94
|
+
|
|
76
95
|
### Module syntax
|
|
77
96
|
|
|
78
97
|
DSH PTC mode executes each `run_code` as an async function body, where static `import` and `export` declarations are invalid. PTC Plus adapts those forms before execution with AST analysis.
|
|
@@ -106,7 +125,7 @@ This is one stochastic paired observation, not a performance guarantee. Machine
|
|
|
106
125
|
|
|
107
126
|
## Settings
|
|
108
127
|
|
|
109
|
-
Open **Settings → Plugin configuration** to use the card shown above. The `enabled` switch is live: turning it off leaves only the card and that switch, while turning it on restores the session runtime and `run_code`/`edit_run_code`.
|
|
128
|
+
Open **Settings → Plugin configuration** to use the card shown above. The card follows the DSH UI language: it renders in English when the harness is set to English, and in 中文 when set to Chinese. The `enabled` switch is live: turning it off leaves only the card and that switch, while turning it on restores the session runtime and `run_code`/`edit_run_code`.
|
|
110
129
|
|
|
111
130
|
Every setting applies live and keeps existing bindings. A submitted cell uses one configuration for its complete execution; changes made while it runs apply to cells submitted afterward. A failed change rolls back. Node fixes a worker's V8 old-generation limit when the worker starts, so that one setting is rejected while a session worker is active and can be changed after the session is disposed. A failed enable is rolled back and persisted as disabled.
|
|
112
131
|
|
|
@@ -137,6 +156,6 @@ Restart that DSH profile after installation. Version-pinned npm, GitHub, local-c
|
|
|
137
156
|
|
|
138
157
|
## Documentation
|
|
139
158
|
|
|
140
|
-
[Installation](docs/installation.md) · [Runtime reference](docs/runtime-reference.md) · [Architecture](docs/architecture.md) · [All docs](docs/README.md)
|
|
159
|
+
[Installation](docs/installation.md) · [Runtime reference](docs/runtime-reference.md) · [Architecture](docs/architecture.md) · [Publishing](docs/publishing.md) · [All docs](docs/README.md)
|
|
141
160
|
|
|
142
161
|
MIT licensed. See [LICENSE](LICENSE).
|
package/README.zh.md
CHANGED
|
@@ -1,17 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/dsh-ptc-plus-banner-zh.webp" width="100%" alt="dsh-ptc-plus 横幅">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="README.md">English</a> ·
|
|
7
|
+
<strong>简体中文</strong>
|
|
8
|
+
</p>
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="#%E9%BB%98%E8%AE%A4-ptc-%E6%A8%A1%E5%BC%8F%E7%9A%84%E9%97%AE%E9%A2%98">问题</a> ·
|
|
12
|
+
<a href="#%E4%B8%89%E4%B8%AA%E6%9C%80%E7%9B%B4%E6%8E%A5%E7%9A%84%E5%9C%BA%E6%99%AF">场景</a> ·
|
|
13
|
+
<a href="#%E8%AE%BE%E7%BD%AE">设置</a> ·
|
|
14
|
+
<a href="#%E8%8C%83%E5%9B%B4">范围</a> ·
|
|
15
|
+
<a href="#%E5%AE%89%E8%A3%85">安装</a> ·
|
|
16
|
+
<a href="#%E6%96%87%E6%A1%A3">文档</a>
|
|
17
|
+
</p>
|
|
10
18
|
|
|
11
19
|
<p align="center">
|
|
12
|
-
<
|
|
20
|
+
<a href="https://github.com/deepseek-ai/deepseek-harness"><img alt="DeepSeek Harness PTC mode" src="https://img.shields.io/badge/DeepSeek%20Harness-PTC%20mode-4b6bfb"></a>
|
|
21
|
+
<a href="package.json"><img alt="Node.js ^22.19.0 || >=24.0.0" src="https://img.shields.io/badge/Node.js-%5E22.19.0%20%7C%7C%20%3E%3D24.0.0-5fa04e?logo=nodedotjs&logoColor=white"></a>
|
|
22
|
+
<a href="https://www.npmjs.com/package/dsh-ptc-plus"><img alt="npm version" src="https://img.shields.io/npm/v/dsh-ptc-plus?logo=npm"></a>
|
|
23
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg"></a>
|
|
13
24
|
</p>
|
|
14
25
|
|
|
26
|
+
<p align="center">
|
|
27
|
+
<a href="https://awesome-dsh-plugin.com/zh/"><img alt="Awesome DSH Plugin" src="https://awesome-dsh-plugin.com/badge.svg"></a>
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
15
32
|
**PTC Plus 给 DSH 的 PTC 模式一个会话绑定的持久 TypeScript REPL。** 每次 `run_code` 都在同一个会话里继续。上一次 `run_code` 的变量、导入和结果,下一次还能直接用。
|
|
16
33
|
|
|
17
34
|
> [!NOTE]
|
|
@@ -20,7 +37,7 @@
|
|
|
20
37
|
> [!IMPORTANT]
|
|
21
38
|
> 面向 `danger-full-access` 设计:可直接访问 Node.js 与操作系统,不另加沙箱。仅在可接受此权限的环境使用。
|
|
22
39
|
|
|
23
|
-

|
|
40
|
+

|
|
24
41
|
|
|
25
42
|
*设置卡片展示即时配置和 `enabled` 开关。*
|
|
26
43
|
|
|
@@ -73,6 +90,8 @@ edit_run_code({ edits: [{ old_string: 'deps.length', new_string: 'deps' }] })
|
|
|
73
90
|
|
|
74
91
|
模型只发改动,完整源码留在对话之外。精确文本替换和正则替换都有限制,坏的正则不会卡住。
|
|
75
92
|
|
|
93
|
+
当被拒 cell 的末尾可唯一验证为缺少一个闭合符时,诊断会直接给出应用该修正并重运行所需的完整 `edit_run_code(...)` 调用。生成的调用带有 `expected_target_call_seq` 前置条件;如果另一个 cell 已先成为 edit 目标,它会拒绝且不执行。PTC Plus 不会自动应用这项建议;有歧义或没有持久目标身份的修复仍需提交修正后的源码。
|
|
94
|
+
|
|
76
95
|
### 模块语法
|
|
77
96
|
|
|
78
97
|
DSH 的 PTC 模式把每个 `run_code` 当作 async function body 执行,静态 `import` 和 `export` 声明在这个函数体里无效。PTC Plus 会在执行前用 AST 分析适配这些形式。
|
|
@@ -106,7 +125,7 @@ import { readFile } from 'node:fs/promises'
|
|
|
106
125
|
|
|
107
126
|
## 设置
|
|
108
127
|
|
|
109
|
-
打开 **设置 → 插件配置**
|
|
128
|
+
打开 **设置 → 插件配置** 使用上面的设置卡片。卡片跟随 DSH 界面语言:界面设为 English 时显示英文,设为中文时显示中文。`enabled` 是即时生效的总开关:关闭后只保留卡片和这个开关,开启后恢复 session runtime 以及 `run_code`/`edit_run_code`。
|
|
110
129
|
|
|
111
130
|
所有设置都会实时应用,并保留已有 binding。已提交的 cell 在完整执行期间使用同一份配置;执行期间发生的更新用于随后提交的 cell。更新失败会回滚。Node 在 worker 创建时固定 V8 old-generation 上限,因此活动 session worker 存在时修改这一项会被拒绝,释放 session 后才能修改。启用失败时,运行时会回滚并把设置保持为停用。
|
|
112
131
|
|
|
@@ -137,6 +156,6 @@ dsh --profile <profile> --dump-config
|
|
|
137
156
|
|
|
138
157
|
## 文档
|
|
139
158
|
|
|
140
|
-
[安装指南](docs/installation.md) · [运行时参考](docs/runtime-reference.md) · [架构](docs/architecture.md) · [全部文档](docs/README.md)
|
|
159
|
+
[安装指南](docs/installation.md) · [运行时参考](docs/runtime-reference.md) · [架构](docs/architecture.md) · [发布](docs/publishing.md) · [全部文档](docs/README.md)
|
|
141
160
|
|
|
142
161
|
使用 [MIT License](LICENSE)。
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/client.js
CHANGED
|
@@ -8,14 +8,18 @@
|
|
|
8
8
|
type: "boolean",
|
|
9
9
|
default: true,
|
|
10
10
|
label: "\u542F\u7528 PTC Plus",
|
|
11
|
-
|
|
11
|
+
labelEn: "Enable PTC Plus",
|
|
12
|
+
description: "",
|
|
13
|
+
descriptionEn: ""
|
|
12
14
|
},
|
|
13
15
|
{
|
|
14
16
|
key: "cordisToolsEnabled",
|
|
15
17
|
type: "boolean",
|
|
16
18
|
default: false,
|
|
17
19
|
label: "\u5728 PTC \u6A21\u5F0F\u4E2D\u542F\u7528 Cordis \u5DE5\u5177",
|
|
18
|
-
|
|
20
|
+
labelEn: "Enable Cordis tools in PTC mode",
|
|
21
|
+
description: "\u5373\u65F6\u4E3A PTC agent \u52A0\u5165\u6216\u79FB\u9664\u5B98\u65B9 Cordis \u5DE5\u5177\u3002",
|
|
22
|
+
descriptionEn: "Adds or removes the official Cordis tools for the PTC agent immediately."
|
|
19
23
|
},
|
|
20
24
|
{
|
|
21
25
|
key: "computeMs",
|
|
@@ -24,7 +28,9 @@
|
|
|
24
28
|
min: 1,
|
|
25
29
|
max: Number.MAX_SAFE_INTEGER,
|
|
26
30
|
label: "\u5355 cell \u6700\u5927 CPU \u65F6\u95F4 (ms)",
|
|
27
|
-
|
|
31
|
+
labelEn: "Max CPU time per cell (ms)",
|
|
32
|
+
description: "\u540C\u6B65\u8BA1\u7B97\u8D85\u8FC7\u8BE5\u9884\u7B97\u7684 cell \u4F1A\u88AB\u4E2D\u65AD\u3002",
|
|
33
|
+
descriptionEn: "Cells whose synchronous computation exceeds this budget are interrupted."
|
|
28
34
|
},
|
|
29
35
|
{
|
|
30
36
|
key: "maxWallMs",
|
|
@@ -33,7 +39,9 @@
|
|
|
33
39
|
min: 1,
|
|
34
40
|
max: MAX_TIMER_DELAY_MS,
|
|
35
41
|
label: "\u5355 cell \u6700\u5927\u5899\u949F\u65F6\u95F4 (ms)",
|
|
36
|
-
|
|
42
|
+
labelEn: "Max wall-clock time per cell (ms)",
|
|
43
|
+
description: "\u5B8C\u6574 cell \u6267\u884C\uFF08\u542B\u5F02\u6B65\u7B49\u5F85\uFF09\u7684\u6700\u957F\u8017\u65F6\u3002",
|
|
44
|
+
descriptionEn: "The longest a full cell execution may take, including async waits."
|
|
37
45
|
},
|
|
38
46
|
{
|
|
39
47
|
key: "maxOutputBytes",
|
|
@@ -42,7 +50,9 @@
|
|
|
42
50
|
min: 1,
|
|
43
51
|
max: Number.MAX_SAFE_INTEGER,
|
|
44
52
|
label: "\u6700\u5927\u8F93\u51FA\u5B57\u8282",
|
|
45
|
-
|
|
53
|
+
labelEn: "Max output bytes",
|
|
54
|
+
description: "\u9650\u5236\u5355\u4E2A cell \u7684\u8F93\u51FA\u548C\u7ED3\u679C\u6570\u636E\u603B\u5927\u5C0F\u3002",
|
|
55
|
+
descriptionEn: "Caps the combined size of one cell output and result data."
|
|
46
56
|
},
|
|
47
57
|
{
|
|
48
58
|
key: "maxOldGenerationSizeMb",
|
|
@@ -51,7 +61,9 @@
|
|
|
51
61
|
min: 1,
|
|
52
62
|
max: Number.MAX_SAFE_INTEGER,
|
|
53
63
|
label: "worker \u65E7\u751F\u4EE3\u5185\u5B58\u4E0A\u9650 (MiB)",
|
|
54
|
-
|
|
64
|
+
labelEn: "Worker old-generation memory cap (MiB)",
|
|
65
|
+
description: "\u6BCF\u4E2A worker \u7684 V8 \u65E7\u751F\u4EE3\u4E0A\u9650\uFF1B\u6D3B\u52A8 worker \u5B58\u5728\u65F6\u4FEE\u6539\u4F1A\u88AB\u62D2\u7EDD\u3002",
|
|
66
|
+
descriptionEn: "Per-worker V8 old-generation limit; changes are rejected while an active worker exists."
|
|
55
67
|
},
|
|
56
68
|
{
|
|
57
69
|
key: "maxValueNodes",
|
|
@@ -60,7 +72,9 @@
|
|
|
60
72
|
min: 1,
|
|
61
73
|
max: Number.MAX_SAFE_INTEGER,
|
|
62
74
|
label: "Value Graph \u6700\u5927\u8282\u70B9\u6570",
|
|
63
|
-
|
|
75
|
+
labelEn: "Max Value Graph nodes",
|
|
76
|
+
description: "\u9650\u5236\u5355\u6B21\u8FD4\u56DE\u503C\u7684\u8282\u70B9\u6570\u3002",
|
|
77
|
+
descriptionEn: "Caps the node count of a single returned value."
|
|
64
78
|
},
|
|
65
79
|
{
|
|
66
80
|
key: "maxValueEdges",
|
|
@@ -69,7 +83,9 @@
|
|
|
69
83
|
min: 1,
|
|
70
84
|
max: Number.MAX_SAFE_INTEGER,
|
|
71
85
|
label: "Value Graph \u6700\u5927\u8FB9\u6570",
|
|
72
|
-
|
|
86
|
+
labelEn: "Max Value Graph edges",
|
|
87
|
+
description: "\u9650\u5236\u5355\u6B21\u8FD4\u56DE\u503C\u7684\u5F15\u7528\u5173\u7CFB\u6570\u3002",
|
|
88
|
+
descriptionEn: "Caps the reference-edge count of a single returned value."
|
|
73
89
|
},
|
|
74
90
|
{
|
|
75
91
|
key: "maxValueArrayLength",
|
|
@@ -78,7 +94,9 @@
|
|
|
78
94
|
min: 1,
|
|
79
95
|
max: Number.MAX_SAFE_INTEGER,
|
|
80
96
|
label: "\u6570\u7EC4\u6700\u5927\u58F0\u660E\u957F\u5EA6",
|
|
81
|
-
|
|
97
|
+
labelEn: "Max declared array length",
|
|
98
|
+
description: "\u9650\u5236\u8FD4\u56DE\u6570\u7EC4\u7684\u6700\u5927\u957F\u5EA6\u3002",
|
|
99
|
+
descriptionEn: "Caps the maximum length of a returned array."
|
|
82
100
|
},
|
|
83
101
|
{
|
|
84
102
|
key: "maxValueBigIntDigits",
|
|
@@ -87,7 +105,9 @@
|
|
|
87
105
|
min: 1,
|
|
88
106
|
max: Number.MAX_SAFE_INTEGER,
|
|
89
107
|
label: "BigInt \u6700\u5927\u5341\u8FDB\u5236\u4F4D\u6570",
|
|
90
|
-
|
|
108
|
+
labelEn: "Max BigInt decimal digits",
|
|
109
|
+
description: "\u9650\u5236\u8FD4\u56DE\u503C\u4E2D BigInt \u7684\u5341\u8FDB\u5236\u4F4D\u6570\u3002",
|
|
110
|
+
descriptionEn: "Caps the decimal digits of BigInt values in a returned value."
|
|
91
111
|
},
|
|
92
112
|
{
|
|
93
113
|
key: "maxNestedRunCodeDepth",
|
|
@@ -96,56 +116,72 @@
|
|
|
96
116
|
min: 1,
|
|
97
117
|
max: Number.MAX_SAFE_INTEGER,
|
|
98
118
|
label: "code.run \u6700\u5927\u9012\u5F52\u6DF1\u5EA6",
|
|
99
|
-
|
|
119
|
+
labelEn: "Max code.run recursion depth",
|
|
120
|
+
description: "\u9650\u5236 code.run \u7684\u5D4C\u5957\u5C42\u6570\u3002",
|
|
121
|
+
descriptionEn: "Caps how deeply code.run may nest."
|
|
100
122
|
},
|
|
101
123
|
{
|
|
102
124
|
key: "canonicalizeToolCalls",
|
|
103
125
|
type: "boolean",
|
|
104
126
|
default: true,
|
|
105
127
|
label: "\u89C4\u8303\u9876\u5C42 native \u8BEF\u8C03",
|
|
106
|
-
|
|
128
|
+
labelEn: "Canonicalize top-level native mis-calls",
|
|
129
|
+
description: "\u4FEE\u6B63\u53EF\u4EE5\u660E\u786E\u8BC6\u522B\u7684\u9876\u5C42 native \u8BEF\u8C03\u3002",
|
|
130
|
+
descriptionEn: "Repairs top-level native mis-calls that can be identified unambiguously."
|
|
107
131
|
},
|
|
108
132
|
{
|
|
109
133
|
key: "looseTopLevelRedeclarations",
|
|
110
134
|
type: "boolean",
|
|
111
135
|
default: true,
|
|
112
136
|
label: "\u5BBD\u677E\u9876\u5C42\u91CD\u58F0\u660E",
|
|
113
|
-
|
|
137
|
+
labelEn: "Loose top-level redeclarations",
|
|
138
|
+
description: "\u5141\u8BB8\u9876\u5C42 const/let \u91CD\u58F0\u660E\u5DF2\u6709\u53D8\u91CF\u3002",
|
|
139
|
+
descriptionEn: "Allows top-level const/let to redeclare existing variables."
|
|
114
140
|
},
|
|
115
141
|
{
|
|
116
142
|
key: "durableReplay",
|
|
117
143
|
type: "boolean",
|
|
118
144
|
default: true,
|
|
119
145
|
label: "\u6301\u4E45\u91CD\u653E",
|
|
120
|
-
|
|
146
|
+
labelEn: "Durable replay",
|
|
147
|
+
description: "worker \u91CD\u542F\u540E\u6062\u590D\u53EF\u4EE5\u91CD\u5EFA\u7684 REPL \u72B6\u6001\u3002",
|
|
148
|
+
descriptionEn: "Rebuilds recoverable REPL state after a worker restart."
|
|
121
149
|
},
|
|
122
150
|
{
|
|
123
151
|
key: "autoRewriteImports",
|
|
124
152
|
type: "boolean",
|
|
125
153
|
default: true,
|
|
126
154
|
label: "\u81EA\u52A8\u6539\u5199 import",
|
|
127
|
-
|
|
155
|
+
labelEn: "Auto-rewrite import",
|
|
156
|
+
description: "\u5141\u8BB8\u5728 run_code \u4E2D\u4F7F\u7528\u9759\u6001 import\u3002",
|
|
157
|
+
descriptionEn: "Allows static import declarations inside run_code."
|
|
128
158
|
},
|
|
129
159
|
{
|
|
130
160
|
key: "autoStripExports",
|
|
131
161
|
type: "boolean",
|
|
132
162
|
default: true,
|
|
133
163
|
label: "\u81EA\u52A8\u5265\u79BB export",
|
|
134
|
-
|
|
164
|
+
labelEn: "Auto-strip export",
|
|
165
|
+
description: "\u5141\u8BB8\u5728 run_code \u4E2D\u4F7F\u7528\u9876\u5C42 export\u3002",
|
|
166
|
+
descriptionEn: "Allows top-level export modifiers inside run_code."
|
|
135
167
|
},
|
|
136
168
|
{
|
|
137
169
|
key: "autoSplitRedeclarations",
|
|
138
170
|
type: "boolean",
|
|
139
171
|
default: true,
|
|
140
172
|
label: "\u81EA\u52A8\u62C6\u5206\u6DF7\u5408\u91CD\u58F0\u660E",
|
|
141
|
-
|
|
173
|
+
labelEn: "Auto-split mixed redeclarations",
|
|
174
|
+
description: "\u5141\u8BB8\u9876\u5C42\u89E3\u6784\u58F0\u660E\u540C\u65F6\u5305\u542B\u65B0\u65E7\u53D8\u91CF\u3002",
|
|
175
|
+
descriptionEn: "Allows top-level destructuring declarations that mix new and existing variables."
|
|
142
176
|
},
|
|
143
177
|
{
|
|
144
178
|
key: "tipsEnabled",
|
|
145
179
|
type: "boolean",
|
|
146
180
|
default: true,
|
|
147
181
|
label: "\u542F\u7528\u6062\u590D\u63D0\u793A",
|
|
148
|
-
|
|
182
|
+
labelEn: "Enable recovery tips",
|
|
183
|
+
description: "\u5728\u7B26\u5408\u6761\u4EF6\u7684\u5931\u8D25\u540E\u663E\u793A\u6062\u590D\u63D0\u793A\u3002",
|
|
184
|
+
descriptionEn: "Shows recovery tips after qualifying failures."
|
|
149
185
|
},
|
|
150
186
|
{
|
|
151
187
|
key: "tipCooldownMessages",
|
|
@@ -154,7 +190,9 @@
|
|
|
154
190
|
min: 1,
|
|
155
191
|
max: Number.MAX_SAFE_INTEGER,
|
|
156
192
|
label: "\u6062\u590D\u63D0\u793A\u51B7\u5374\u6B65\u6570",
|
|
157
|
-
|
|
193
|
+
labelEn: "Recovery tip cooldown (messages)",
|
|
194
|
+
description: "\u540C\u7C7B\u6062\u590D\u63D0\u793A\u4E4B\u95F4\u7684\u6700\u5C0F\u95F4\u9694\u3002",
|
|
195
|
+
descriptionEn: "The minimum gap between recovery tips of the same kind."
|
|
158
196
|
},
|
|
159
197
|
{
|
|
160
198
|
key: "tipEscalationFailures",
|
|
@@ -163,7 +201,9 @@
|
|
|
163
201
|
min: 1,
|
|
164
202
|
max: Number.MAX_SAFE_INTEGER,
|
|
165
203
|
label: "\u6062\u590D\u63D0\u793A\u5347\u7EA7\u5931\u8D25\u6B21\u6570",
|
|
166
|
-
|
|
204
|
+
labelEn: "Recovery tip escalation failures",
|
|
205
|
+
description: "\u8FDE\u7EED\u5931\u8D25\u8FBE\u5230\u6B64\u6B21\u6570\u540E\u663E\u793A\u66F4\u8BE6\u7EC6\u7684\u6062\u590D\u63D0\u793A\u3002",
|
|
206
|
+
descriptionEn: "After this many consecutive failures, a more detailed recovery tip is shown."
|
|
167
207
|
}
|
|
168
208
|
]);
|
|
169
209
|
var CONFIG_DEFAULTS = Object.freeze(
|
|
@@ -183,6 +223,55 @@
|
|
|
183
223
|
@media(max-width:560px){.ptcPlusHeader{padding:12px}.ptcPlusFields{margin:0 12px}.ptcPlusRow{align-items:flex-start;flex-direction:column;gap:6px;padding:10px 0}.ptcPlusInput{width:100%}.ptcPlusFooter{align-items:stretch;flex-direction:column}.ptcPlusButton{width:100%}}
|
|
184
224
|
@media(prefers-reduced-motion:reduce){.ptcPlusHeader,.ptcPlusChevron,.ptcPlusBody,.ptcPlusButton{transition:none}}
|
|
185
225
|
`;
|
|
226
|
+
var LOCALE_NS = "settings.ptcPlus";
|
|
227
|
+
var CHROME_COPY = Object.freeze({
|
|
228
|
+
zh: Object.freeze({
|
|
229
|
+
"card.description": "PTC \u6A21\u5F0F\u7684\u4F1A\u8BDD\u7EA7 TypeScript REPL\u3002",
|
|
230
|
+
"status.enabled": "\u5DF2\u542F\u7528",
|
|
231
|
+
"status.disabled": "\u5DF2\u505C\u7528",
|
|
232
|
+
"action.expand": "\u5C55\u5F00 PTC Plus \u8BBE\u7F6E",
|
|
233
|
+
"action.collapse": "\u6536\u8D77 PTC Plus \u8BBE\u7F6E",
|
|
234
|
+
"state.syncing": "\u6B63\u5728\u540C\u6B65\u8BBE\u7F6E...",
|
|
235
|
+
"state.unavailable": "\u5F53\u524D DSH \u5B9E\u4F8B\u672A\u63D0\u4F9B\u8BBE\u7F6E\u670D\u52A1",
|
|
236
|
+
"footer.live": "\u8BBE\u7F6E\u4F1A\u5728\u4FEE\u6539\u540E\u7ACB\u5373\u751F\u6548",
|
|
237
|
+
"footer.readOnly": "\u5F53\u524D\u8BBE\u7F6E\u4E3A\u53EA\u8BFB",
|
|
238
|
+
"status.applied": "\u8BBE\u7F6E\u5DF2\u7ACB\u5373\u751F\u6548",
|
|
239
|
+
"status.conflict": "\u8BBE\u7F6E\u672A\u751F\u6548\uFF0C\u8BF7\u68C0\u67E5\u8BBE\u7F6E\u51B2\u7A81",
|
|
240
|
+
"status.failed": "\u8BBE\u7F6E\u5931\u8D25\uFF1A{error}",
|
|
241
|
+
"indicator.title": "PTC Plus \u5DF2\u542F\u7528"
|
|
242
|
+
}),
|
|
243
|
+
en: Object.freeze({
|
|
244
|
+
"card.description": "The session-bound TypeScript REPL for PTC mode.",
|
|
245
|
+
"status.enabled": "Enabled",
|
|
246
|
+
"status.disabled": "Disabled",
|
|
247
|
+
"action.expand": "Expand PTC Plus settings",
|
|
248
|
+
"action.collapse": "Collapse PTC Plus settings",
|
|
249
|
+
"state.syncing": "Syncing settings...",
|
|
250
|
+
"state.unavailable": "This DSH instance does not provide a settings service",
|
|
251
|
+
"footer.live": "Changes take effect immediately.",
|
|
252
|
+
"footer.readOnly": "These settings are read-only.",
|
|
253
|
+
"status.applied": "Setting applied immediately.",
|
|
254
|
+
"status.conflict": "The setting did not take effect; check for conflicting settings.",
|
|
255
|
+
"status.failed": "Could not save: {error}",
|
|
256
|
+
"indicator.title": "PTC Plus is active"
|
|
257
|
+
})
|
|
258
|
+
});
|
|
259
|
+
function fieldCopy(field, locale) {
|
|
260
|
+
const copy = { [`${field.key}.label`]: locale === "en" ? field.labelEn : field.label };
|
|
261
|
+
const description = locale === "en" ? field.descriptionEn : field.description;
|
|
262
|
+
if (description !== "") copy[`${field.key}.description`] = description;
|
|
263
|
+
return copy;
|
|
264
|
+
}
|
|
265
|
+
var SETTINGS_COPY = Object.freeze(Object.fromEntries(
|
|
266
|
+
["zh", "en"].map((locale) => [locale, Object.freeze({
|
|
267
|
+
...CHROME_COPY[locale],
|
|
268
|
+
...Object.assign({}, ...CONFIG_FIELDS.map((field) => fieldCopy(field, locale)))
|
|
269
|
+
})])
|
|
270
|
+
));
|
|
271
|
+
function sessionUsesPtcPreset(session) {
|
|
272
|
+
const preset = session?.projectionValues?.agentPreset ?? session?.agentPreset;
|
|
273
|
+
return preset === "ptc" || preset === "code";
|
|
274
|
+
}
|
|
186
275
|
window.__ModuleLoader__.load({
|
|
187
276
|
// Replaced by the bundle entry with the package name from package.json.
|
|
188
277
|
id: "dsh-ptc-plus",
|
|
@@ -190,8 +279,7 @@
|
|
|
190
279
|
const React = require2("react");
|
|
191
280
|
const {
|
|
192
281
|
IconCheckOutline14,
|
|
193
|
-
IconChevronDownOutline14
|
|
194
|
-
IconSettingsOutline16
|
|
282
|
+
IconChevronDownOutline14
|
|
195
283
|
} = require2("@deepseek-ai/dsh-client-ui-primitives");
|
|
196
284
|
const module = { exports: {} };
|
|
197
285
|
const h = React.createElement;
|
|
@@ -204,7 +292,7 @@
|
|
|
204
292
|
document.head.append(style);
|
|
205
293
|
return () => style.remove();
|
|
206
294
|
}
|
|
207
|
-
function fieldInput(field, value, disabled, onChange) {
|
|
295
|
+
function fieldInput(field, value, disabled, onChange, label) {
|
|
208
296
|
if (field.type === "boolean") {
|
|
209
297
|
return h("input", {
|
|
210
298
|
type: "checkbox",
|
|
@@ -212,7 +300,7 @@
|
|
|
212
300
|
className: "ptcPlusCheck",
|
|
213
301
|
checked: value === true,
|
|
214
302
|
disabled,
|
|
215
|
-
"aria-label":
|
|
303
|
+
"aria-label": label,
|
|
216
304
|
onChange: (event) => onChange(field, event.target.checked)
|
|
217
305
|
});
|
|
218
306
|
}
|
|
@@ -224,7 +312,7 @@
|
|
|
224
312
|
max: field.max,
|
|
225
313
|
step: 1,
|
|
226
314
|
disabled,
|
|
227
|
-
"aria-label":
|
|
315
|
+
"aria-label": label,
|
|
228
316
|
onChange: (event) => {
|
|
229
317
|
const input = event.target.value;
|
|
230
318
|
const parsed = input === "" ? "" : Number(input);
|
|
@@ -234,10 +322,11 @@
|
|
|
234
322
|
}
|
|
235
323
|
function apply(ctx) {
|
|
236
324
|
const preferenceScope = ctx.settingsScope.bind({ namespace: SETTINGS_NAMESPACE });
|
|
325
|
+
ctx.effect(() => ctx.locale.register(LOCALE_NS, SETTINGS_COPY), "ptc-plus: settings dictionaries");
|
|
237
326
|
ctx.effect(installStyles, "ptc-plus: client styles");
|
|
238
|
-
function PTCPlusSettingsCard() {
|
|
327
|
+
function PTCPlusSettingsCard({ t }) {
|
|
239
328
|
const [open, setOpen] = React.useState(false);
|
|
240
|
-
const [status, setStatus] = React.useState(
|
|
329
|
+
const [status, setStatus] = React.useState(null);
|
|
241
330
|
const [pending, setPending] = React.useState(() => /* @__PURE__ */ new Set());
|
|
242
331
|
const writeTail = React.useRef(Promise.resolve());
|
|
243
332
|
const subscribe = React.useCallback((listener) => preferenceScope.subscribe(listener), []);
|
|
@@ -254,17 +343,20 @@
|
|
|
254
343
|
if (field.key !== "enabled" && before.value?.enabled !== true) return;
|
|
255
344
|
if (before.value?.[field.key] === nextValue) return;
|
|
256
345
|
setPending((current) => new Set(current).add(field.key));
|
|
257
|
-
setStatus(
|
|
346
|
+
setStatus(null);
|
|
258
347
|
try {
|
|
259
348
|
await preferenceScope.set(field.key, nextValue);
|
|
260
349
|
const after = preferenceScope.getSnapshot();
|
|
261
350
|
if (after.status !== "ready" || after.value?.[field.key] !== nextValue) {
|
|
262
|
-
setStatus("
|
|
351
|
+
setStatus({ key: "status.conflict" });
|
|
263
352
|
} else {
|
|
264
|
-
setStatus("
|
|
353
|
+
setStatus({ key: "status.applied" });
|
|
265
354
|
}
|
|
266
355
|
} catch (error) {
|
|
267
|
-
setStatus(
|
|
356
|
+
setStatus({
|
|
357
|
+
key: "status.failed",
|
|
358
|
+
params: { error: error instanceof Error ? error.message : String(error) }
|
|
359
|
+
});
|
|
268
360
|
} finally {
|
|
269
361
|
setPending((current) => {
|
|
270
362
|
const next = new Set(current);
|
|
@@ -286,18 +378,17 @@
|
|
|
286
378
|
type: "button",
|
|
287
379
|
className: "ptcPlusHeader",
|
|
288
380
|
"aria-expanded": open,
|
|
289
|
-
"aria-label": open ? "
|
|
381
|
+
"aria-label": t(open ? "action.collapse" : "action.expand"),
|
|
290
382
|
"aria-controls": "ptc-plus-settings-body",
|
|
291
383
|
onClick: () => setOpen((current) => !current)
|
|
292
384
|
},
|
|
293
|
-
h(IconSettingsOutline16, { size: 16 }),
|
|
294
385
|
h(
|
|
295
386
|
"span",
|
|
296
387
|
{ className: "ptcPlusHeadText" },
|
|
297
388
|
h("span", { className: "ptcPlusName" }, "PTC Plus"),
|
|
298
|
-
h("span", { className: "ptcPlusDescription" }, "
|
|
389
|
+
h("span", { className: "ptcPlusDescription" }, t("card.description"))
|
|
299
390
|
),
|
|
300
|
-
h("span", { className: "ptcPlusStatus", "data-enabled": enabled }, enabled ? "
|
|
391
|
+
h("span", { className: "ptcPlusStatus", "data-enabled": enabled }, t(enabled ? "status.enabled" : "status.disabled")),
|
|
301
392
|
h("span", { className: "ptcPlusChevron", "data-open": open, "aria-hidden": true }, h(IconChevronDownOutline14, { size: 14 }))
|
|
302
393
|
),
|
|
303
394
|
h(
|
|
@@ -306,22 +397,22 @@
|
|
|
306
397
|
h("div", { className: "ptcPlusBodyInner" }, h(
|
|
307
398
|
"div",
|
|
308
399
|
{ className: "ptcPlusFields" },
|
|
309
|
-
snapshot.status === "loading" ? h("p", { className: "ptcPlusMessage" }, "
|
|
400
|
+
snapshot.status === "loading" ? h("p", { className: "ptcPlusMessage" }, t("state.syncing")) : snapshot.status === "unavailable" ? h("p", { className: "ptcPlusMessage" }, t("state.unavailable")) : [
|
|
310
401
|
...CONFIG_FIELDS.map((field) => h(
|
|
311
402
|
"div",
|
|
312
403
|
{ key: field.key, className: "ptcPlusRow" },
|
|
313
404
|
h(
|
|
314
405
|
"div",
|
|
315
406
|
{ className: "ptcPlusMain" },
|
|
316
|
-
h("div", { className: "ptcPlusLabel" }, field.label),
|
|
317
|
-
field.description === "" ? null : h("div", { className: "ptcPlusDetail" }, field.description)
|
|
407
|
+
h("div", { className: "ptcPlusLabel" }, t(`${field.key}.label`)),
|
|
408
|
+
field.description === "" ? null : h("div", { className: "ptcPlusDetail" }, t(`${field.key}.description`))
|
|
318
409
|
),
|
|
319
|
-
fieldInput(field, value[field.key], fieldDisabled(field), persist)
|
|
410
|
+
fieldInput(field, value[field.key], fieldDisabled(field), persist, t(`${field.key}.label`))
|
|
320
411
|
)),
|
|
321
412
|
h(
|
|
322
413
|
"div",
|
|
323
414
|
{ key: "footer", className: "ptcPlusFooter" },
|
|
324
|
-
h("span", { className: "ptcPlusMessage", role: "status" }, status
|
|
415
|
+
h("span", { className: "ptcPlusMessage", role: "status" }, status === null ? t(snapshot.writable ? "footer.live" : "footer.readOnly") : t(status.key, status.params))
|
|
325
416
|
)
|
|
326
417
|
]
|
|
327
418
|
))
|
|
@@ -330,10 +421,11 @@
|
|
|
330
421
|
}
|
|
331
422
|
ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
|
|
332
423
|
name: "settings.plugin.item",
|
|
333
|
-
key: SETTINGS_NAMESPACE
|
|
424
|
+
key: SETTINGS_NAMESPACE,
|
|
425
|
+
locale: LOCALE_NS
|
|
334
426
|
}, PTCPlusSettingsCard));
|
|
335
427
|
ctx.inject(["slots", "sessions"], (scope) => {
|
|
336
|
-
function PTCPlusSessionIndicator({ sessionId }) {
|
|
428
|
+
function PTCPlusSessionIndicator({ sessionId, t }) {
|
|
337
429
|
const sessions = React.useSyncExternalStore(
|
|
338
430
|
(listener) => scope.sessions.list.subscribe(listener),
|
|
339
431
|
() => scope.sessions.list.getSnapshot(),
|
|
@@ -344,10 +436,10 @@
|
|
|
344
436
|
() => preferenceScope.getSnapshot(),
|
|
345
437
|
() => preferenceScope.getSnapshot()
|
|
346
438
|
);
|
|
347
|
-
if (sessions.byId?.[sessionId]
|
|
439
|
+
if (!sessionUsesPtcPreset(sessions.byId?.[sessionId]) || settings.status !== "ready" || settings.value?.enabled !== true) return null;
|
|
348
440
|
return h(
|
|
349
441
|
"span",
|
|
350
|
-
{ className: "ptcPlusActive", title: "
|
|
442
|
+
{ className: "ptcPlusActive", title: t("indicator.title") },
|
|
351
443
|
h(IconCheckOutline14, { size: 14 }),
|
|
352
444
|
"PTC Plus"
|
|
353
445
|
);
|
|
@@ -355,11 +447,12 @@
|
|
|
355
447
|
scope.slots.inject("conversation.session.header.actions", () => scope.slots.register({
|
|
356
448
|
name: "conversation.session.header.actions",
|
|
357
449
|
id: "ptc-plus-active",
|
|
358
|
-
order: -9
|
|
450
|
+
order: -9,
|
|
451
|
+
locale: LOCALE_NS
|
|
359
452
|
}, PTCPlusSessionIndicator));
|
|
360
453
|
});
|
|
361
454
|
}
|
|
362
|
-
module.exports = { apply, inject: ["settingsScope", "slots", "sessions"] };
|
|
455
|
+
module.exports = { apply, inject: ["settingsScope", "slots", "sessions", "locale"] };
|
|
363
456
|
return module.exports;
|
|
364
457
|
}
|
|
365
458
|
});
|