dsh-ptc-plus 0.2.3 → 0.3.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.en.md +171 -0
- package/README.md +94 -67
- package/assets/dsh-ptc-plus-banner-en.webp +0 -0
- package/assets/ptc-plus-repair-en.png +0 -0
- package/assets/ptc-plus-settings-en.png +0 -0
- package/assets/ptc-plus-settings-zh.png +0 -0
- package/client.js +1211 -128
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +20 -4
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0022-stage-npm-releases-with-oidc.md +31 -0
- package/docs/architecture.md +10 -9
- package/docs/client-ui.md +30 -12
- package/docs/installation.md +13 -5
- package/docs/publishing.md +25 -1
- package/docs/runtime-reference.md +18 -12
- package/docs/value-wire.md +1 -1
- package/index.js +43 -12
- package/internal/cell-analysis.js +20 -3
- package/internal/cell-rewriter.js +36 -2
- package/internal/config-spec.js +192 -82
- package/internal/direct-surface-owner.js +77 -23
- package/internal/edit-transport-owner.js +10 -1
- package/internal/failure-reporting.js +15 -0
- package/internal/rejected-cell-editor.js +21 -12
- package/internal/repl-memory-projection.js +277 -0
- package/internal/run-code-description.js +34 -0
- package/internal/runtime-bridge-owner.js +63 -15
- package/internal/runtime-config.js +2 -0
- package/internal/session-cell-executor.js +14 -4
- package/internal/session-events.js +7 -0
- package/internal/session-journal.js +3 -2
- package/internal/session-log-view.js +2 -1
- package/internal/session-runtime.js +19 -2
- package/internal/session-state.js +83 -4
- package/internal/settings-compat.js +31 -0
- package/package.json +20 -13
- package/src/client-activity.js +472 -0
- package/src/client.js +536 -38
- package/README.zh.md +0 -144
- package/assets/ptc-plus-settings.png +0 -0
- /package/assets/{dsh-ptc-plus-banner.webp → dsh-ptc-plus-banner-zh.webp} +0 -0
- /package/assets/{ptc-plus-repair.png → ptc-plus-repair-zh.png} +0 -0
package/client.js
CHANGED
|
@@ -8,14 +8,99 @@
|
|
|
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: ""
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
key: "enhancedToolView",
|
|
17
|
+
type: "boolean",
|
|
18
|
+
default: true,
|
|
19
|
+
label: "\u4F7F\u7528 PTC Plus \u589E\u5F3A\u5DE5\u5177\u5361\u7247",
|
|
20
|
+
labelEn: "Use enhanced PTC Plus tool cards",
|
|
21
|
+
description: "\u5F00\u542F\u65F6\u4F7F\u7528\u589E\u5F3A\u5DE5\u5177\u5361\u7247\uFF1B\u5173\u95ED\u540E\u4F7F\u7528 DSH \u539F\u751F\u5DE5\u5177\u5361\u7247\u3002",
|
|
22
|
+
descriptionEn: "Uses enhanced tool cards when enabled and DSH native tool cards when disabled."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
key: "autoDescribeRunCode",
|
|
26
|
+
type: "boolean",
|
|
27
|
+
default: true,
|
|
28
|
+
label: "\u5141\u8BB8\u6267\u884C\u7F3A\u5C11\u6458\u8981\u7684 run_code",
|
|
29
|
+
labelEn: "Allow run_code execution without a summary",
|
|
30
|
+
description: "\u5141\u8BB8 run_code \u7F3A\u5C11\u5916\u5C42 description\uFF1B\u5173\u95ED\u540E\u6062\u590D DSH \u6821\u9A8C\u3002\u6A21\u578B\u8BF7\u6C42\u548C\u539F\u59CB\u8C03\u7528\u53C2\u6570\u4FDD\u6301\u4E0D\u53D8\u3002",
|
|
31
|
+
descriptionEn: "Allows run_code to omit its outer description; disabling restores DSH validation. Model requests and original call arguments remain unchanged."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: "canonicalizeToolCalls",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
default: true,
|
|
37
|
+
label: "\u4FEE\u590D\u53EF\u8BC6\u522B\u7684\u9876\u5C42 native \u5DE5\u5177\u8BEF\u8C03\u7528",
|
|
38
|
+
labelEn: "Repair recognizable top-level native tool mis-calls",
|
|
39
|
+
description: "\u4EC5\u5F53\u5F53\u524D schema \u80FD\u552F\u4E00\u786E\u8BA4\u76EE\u6807\u5DE5\u5177\u4E14\u53C2\u6570\u6709\u6548\u65F6\uFF0C\u624D\u628A\u9876\u5C42 native \u5DE5\u5177\u8BEF\u8C03\u7528\u4FEE\u590D\u4E3A\u5BF9\u5E94\u7684 run_code \u8C03\u7528\u3002",
|
|
40
|
+
descriptionEn: "Repairs a top-level native tool mis-call as the corresponding run_code call only when the current schema uniquely identifies the tool and validates its arguments."
|
|
12
41
|
},
|
|
13
42
|
{
|
|
14
43
|
key: "cordisToolsEnabled",
|
|
15
44
|
type: "boolean",
|
|
16
45
|
default: false,
|
|
17
|
-
label: "\u5728 PTC \u6A21\u5F0F\u4E2D\u542F\u7528 Cordis \u5DE5\u5177",
|
|
18
|
-
|
|
46
|
+
label: "\u5728 PTC \u6A21\u5F0F\u4E2D\u542F\u7528\u5B98\u65B9 Cordis \u5DE5\u5177",
|
|
47
|
+
labelEn: "Enable official Cordis tools in PTC mode",
|
|
48
|
+
description: "\u5F00\u542F\u540E\uFF0CPTC agent \u53EF\u4F7F\u7528\u5B98\u65B9 Cordis \u5DE5\u5177\u3001\u914D\u5957\u6307\u5F15\u548C\u5F00\u53D1 Skill\uFF1B\u5173\u95ED\u540E\u79FB\u9664\u8FD9\u4E9B\u80FD\u529B\u3002Cordis \u5DE5\u5177\u4EE5 DSH \u8FDB\u7A0B\u6743\u9650\u8FD0\u884C\u3002",
|
|
49
|
+
descriptionEn: "When enabled, PTC agents can use the official Cordis tools, guidance, and development Skill; disabling removes them. Cordis tools run with the DSH process permissions."
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: "looseTopLevelRedeclarations",
|
|
53
|
+
type: "boolean",
|
|
54
|
+
default: true,
|
|
55
|
+
label: "\u5141\u8BB8\u9876\u5C42\u53D8\u91CF\u91CD\u58F0\u660E",
|
|
56
|
+
labelEn: "Allow top-level variable redeclarations",
|
|
57
|
+
description: "\u5141\u8BB8\u9876\u5C42 const \u6216 let \u58F0\u660E\u66FF\u6362\u5DF2\u6709\u53D8\u91CF\uFF1B\u5173\u95ED\u540E\uFF0C\u91CD\u58F0\u660E\u4F1A\u5728\u6267\u884C\u524D\u88AB\u62D2\u7EDD\u3002",
|
|
58
|
+
descriptionEn: "Allows top-level const or let declarations to replace existing variables; disabling rejects redeclarations before execution."
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
key: "autoRewriteImports",
|
|
62
|
+
type: "boolean",
|
|
63
|
+
default: true,
|
|
64
|
+
label: "\u652F\u6301\u9759\u6001 import \u58F0\u660E",
|
|
65
|
+
labelEn: "Support static import declarations",
|
|
66
|
+
description: "\u5141\u8BB8\u5728 run_code \u4E2D\u4F7F\u7528\u9759\u6001 import\uFF0C\u5E76\u4FDD\u7559\u6A21\u5757\u89E3\u6790\u548C\u53EA\u8BFB binding \u8BED\u4E49\u3002",
|
|
67
|
+
descriptionEn: "Allows static import declarations in run_code while preserving module resolution and read-only binding semantics."
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
key: "autoStripExports",
|
|
71
|
+
type: "boolean",
|
|
72
|
+
default: true,
|
|
73
|
+
label: "\u652F\u6301\u9876\u5C42 export \u4FEE\u9970\u7B26",
|
|
74
|
+
labelEn: "Support top-level export modifiers",
|
|
75
|
+
description: "\u5141\u8BB8\u5728 run_code \u4E2D\u4F7F\u7528\u9876\u5C42 export\uFF0C\u5E76\u4FDD\u7559\u5BF9\u5E94\u7684\u672C\u5730\u58F0\u660E\u6216\u6A21\u5757\u526F\u4F5C\u7528\u3002",
|
|
76
|
+
descriptionEn: "Allows top-level export syntax in run_code while preserving the corresponding local declaration or module side effect."
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
key: "autoSplitRedeclarations",
|
|
80
|
+
type: "boolean",
|
|
81
|
+
default: true,
|
|
82
|
+
label: "\u652F\u6301\u6DF7\u5408\u89E3\u6784\u91CD\u58F0\u660E",
|
|
83
|
+
labelEn: "Support mixed destructuring redeclarations",
|
|
84
|
+
description: "\u5141\u8BB8\u9876\u5C42\u89E3\u6784\u58F0\u660E\u540C\u65F6\u5305\u542B\u65B0\u53D8\u91CF\u548C\u5DF2\u6709\u53D8\u91CF\u3002",
|
|
85
|
+
descriptionEn: "Allows top-level destructuring declarations to contain both new and existing variables."
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: "durableReplay",
|
|
89
|
+
type: "boolean",
|
|
90
|
+
default: true,
|
|
91
|
+
label: "\u542F\u7528\u6301\u4E45 REPL \u6062\u590D",
|
|
92
|
+
labelEn: "Enable durable REPL recovery",
|
|
93
|
+
description: "worker \u91CD\u542F\u540E\u4ECE session journal \u91CD\u5EFA\u53EF\u6062\u590D\u7684 REPL \u72B6\u6001\u3002",
|
|
94
|
+
descriptionEn: "Rebuilds recoverable REPL state from the session journal after a worker restart."
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
key: "tipsEnabled",
|
|
98
|
+
type: "boolean",
|
|
99
|
+
default: true,
|
|
100
|
+
label: "\u542F\u7528\u5931\u8D25\u6062\u590D\u63D0\u793A",
|
|
101
|
+
labelEn: "Enable failure recovery tips",
|
|
102
|
+
description: "\u5728\u7B26\u5408\u6761\u4EF6\u7684\u5931\u8D25\u540E\u663E\u793A\u6709\u51B7\u5374\u95F4\u9694\u7684\u6062\u590D\u63D0\u793A\u3002",
|
|
103
|
+
descriptionEn: "Shows recovery tips with a cooldown after qualifying failures."
|
|
19
104
|
},
|
|
20
105
|
{
|
|
21
106
|
key: "computeMs",
|
|
@@ -23,8 +108,10 @@
|
|
|
23
108
|
default: 6e4,
|
|
24
109
|
min: 1,
|
|
25
110
|
max: Number.MAX_SAFE_INTEGER,
|
|
26
|
-
label: "\u5355 cell
|
|
27
|
-
|
|
111
|
+
label: "\u5355 cell CPU \u65F6\u95F4\u4E0A\u9650 (ms)",
|
|
112
|
+
labelEn: "CPU time limit per cell (ms)",
|
|
113
|
+
description: "\u540C\u6B65\u8BA1\u7B97\u8D85\u8FC7\u8BE5\u4E0A\u9650\u65F6\u4E2D\u65AD\u5F53\u524D cell\u3002",
|
|
114
|
+
descriptionEn: "Interrupts the current cell when synchronous computation exceeds this limit."
|
|
28
115
|
},
|
|
29
116
|
{
|
|
30
117
|
key: "maxWallMs",
|
|
@@ -32,26 +119,43 @@
|
|
|
32
119
|
default: 6e5,
|
|
33
120
|
min: 1,
|
|
34
121
|
max: MAX_TIMER_DELAY_MS,
|
|
35
|
-
label: "\u5355 cell \
|
|
36
|
-
|
|
122
|
+
label: "\u5355 cell \u603B\u8017\u65F6\u4E0A\u9650 (ms)",
|
|
123
|
+
labelEn: "Elapsed time limit per cell (ms)",
|
|
124
|
+
description: "\u9650\u5236\u5B8C\u6574 cell \u6267\u884C\u7684\u8017\u65F6\uFF0C\u5305\u62EC\u5F02\u6B65\u7B49\u5F85\u3002",
|
|
125
|
+
descriptionEn: "Limits the complete cell execution time, including asynchronous waits."
|
|
37
126
|
},
|
|
38
127
|
{
|
|
39
|
-
key: "
|
|
128
|
+
key: "maxOldGenerationSizeMb",
|
|
40
129
|
type: "integer",
|
|
41
|
-
default:
|
|
130
|
+
default: 512,
|
|
42
131
|
min: 1,
|
|
43
132
|
max: Number.MAX_SAFE_INTEGER,
|
|
44
|
-
label: "\
|
|
45
|
-
|
|
133
|
+
label: "\u6BCF\u4E2A worker \u65E7\u751F\u4EE3\u5185\u5B58\u4E0A\u9650 (MiB)",
|
|
134
|
+
labelEn: "Old-generation memory limit per worker (MiB)",
|
|
135
|
+
description: "\u9650\u5236\u6BCF\u4E2A worker \u7684 V8 \u65E7\u751F\u4EE3\uFF1B\u6D3B\u52A8 worker \u5B58\u5728\u65F6\u4E0D\u80FD\u4FEE\u6539\u3002",
|
|
136
|
+
descriptionEn: "Limits the V8 old generation for each worker; this setting cannot change while a worker is active."
|
|
46
137
|
},
|
|
47
138
|
{
|
|
48
|
-
key: "
|
|
139
|
+
key: "maxNestedRunCodeDepth",
|
|
49
140
|
type: "integer",
|
|
50
|
-
default:
|
|
141
|
+
default: 8,
|
|
51
142
|
min: 1,
|
|
52
143
|
max: Number.MAX_SAFE_INTEGER,
|
|
53
|
-
label: "
|
|
54
|
-
|
|
144
|
+
label: "code.run \u5D4C\u5957\u5C42\u6570\u4E0A\u9650",
|
|
145
|
+
labelEn: "code.run nesting depth limit",
|
|
146
|
+
description: "\u9650\u5236\u5355\u4E2A\u9876\u5C42 cell \u4E2D code.run \u7684\u6700\u5927\u5D4C\u5957\u5C42\u6570\u3002",
|
|
147
|
+
descriptionEn: "Limits the maximum code.run nesting depth within one top-level cell."
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
key: "maxOutputBytes",
|
|
151
|
+
type: "integer",
|
|
152
|
+
default: 64 * 1024 * 1024,
|
|
153
|
+
min: 1,
|
|
154
|
+
max: Number.MAX_SAFE_INTEGER,
|
|
155
|
+
label: "\u5355 cell \u8F93\u51FA\u4E0A\u9650 (bytes)",
|
|
156
|
+
labelEn: "Output limit per cell (bytes)",
|
|
157
|
+
description: "\u9650\u5236\u5355\u4E2A cell \u7684\u65E5\u5FD7\u548C\u8FD4\u56DE\u7ED3\u679C\u7684\u5408\u8BA1\u5927\u5C0F\u3002",
|
|
158
|
+
descriptionEn: "Limits the combined size of one cell's logs and returned result."
|
|
55
159
|
},
|
|
56
160
|
{
|
|
57
161
|
key: "maxValueNodes",
|
|
@@ -59,8 +163,10 @@
|
|
|
59
163
|
default: 1e5,
|
|
60
164
|
min: 1,
|
|
61
165
|
max: Number.MAX_SAFE_INTEGER,
|
|
62
|
-
label: "
|
|
63
|
-
|
|
166
|
+
label: "\u8FD4\u56DE\u503C\u8282\u70B9\u6570\u4E0A\u9650",
|
|
167
|
+
labelEn: "Returned-value node limit",
|
|
168
|
+
description: "\u9650\u5236\u5355\u6B21\u8FD4\u56DE\u503C\u7684 Value Graph \u8282\u70B9\u6570\u3002",
|
|
169
|
+
descriptionEn: "Limits the Value Graph node count for one returned value."
|
|
64
170
|
},
|
|
65
171
|
{
|
|
66
172
|
key: "maxValueEdges",
|
|
@@ -68,8 +174,10 @@
|
|
|
68
174
|
default: 1e6,
|
|
69
175
|
min: 1,
|
|
70
176
|
max: Number.MAX_SAFE_INTEGER,
|
|
71
|
-
label: "
|
|
72
|
-
|
|
177
|
+
label: "\u8FD4\u56DE\u503C\u5F15\u7528\u8FB9\u6570\u4E0A\u9650",
|
|
178
|
+
labelEn: "Returned-value reference-edge limit",
|
|
179
|
+
description: "\u9650\u5236\u5355\u6B21\u8FD4\u56DE\u503C\u7684 Value Graph \u5F15\u7528\u8FB9\u6570\u3002",
|
|
180
|
+
descriptionEn: "Limits the Value Graph reference-edge count for one returned value."
|
|
73
181
|
},
|
|
74
182
|
{
|
|
75
183
|
key: "maxValueArrayLength",
|
|
@@ -77,8 +185,10 @@
|
|
|
77
185
|
default: 1e6,
|
|
78
186
|
min: 1,
|
|
79
187
|
max: Number.MAX_SAFE_INTEGER,
|
|
80
|
-
label: "\u6570\u7EC4\
|
|
81
|
-
|
|
188
|
+
label: "\u8FD4\u56DE\u6570\u7EC4\u957F\u5EA6\u4E0A\u9650",
|
|
189
|
+
labelEn: "Returned-array length limit",
|
|
190
|
+
description: "\u9650\u5236\u8FD4\u56DE\u6570\u7EC4\u7684\u6700\u5927\u58F0\u660E\u957F\u5EA6\u3002",
|
|
191
|
+
descriptionEn: "Limits the maximum declared length of a returned array."
|
|
82
192
|
},
|
|
83
193
|
{
|
|
84
194
|
key: "maxValueBigIntDigits",
|
|
@@ -86,66 +196,10 @@
|
|
|
86
196
|
default: 1e5,
|
|
87
197
|
min: 1,
|
|
88
198
|
max: Number.MAX_SAFE_INTEGER,
|
|
89
|
-
label: "BigInt \
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
key: "maxNestedRunCodeDepth",
|
|
94
|
-
type: "integer",
|
|
95
|
-
default: 8,
|
|
96
|
-
min: 1,
|
|
97
|
-
max: Number.MAX_SAFE_INTEGER,
|
|
98
|
-
label: "code.run \u6700\u5927\u9012\u5F52\u6DF1\u5EA6",
|
|
99
|
-
description: "\u9650\u5236 code.run \u7684\u5D4C\u5957\u5C42\u6570\u3002"
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
key: "canonicalizeToolCalls",
|
|
103
|
-
type: "boolean",
|
|
104
|
-
default: true,
|
|
105
|
-
label: "\u89C4\u8303\u9876\u5C42 native \u8BEF\u8C03",
|
|
106
|
-
description: "\u4FEE\u6B63\u53EF\u4EE5\u660E\u786E\u8BC6\u522B\u7684\u9876\u5C42 native \u8BEF\u8C03\u3002"
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
key: "looseTopLevelRedeclarations",
|
|
110
|
-
type: "boolean",
|
|
111
|
-
default: true,
|
|
112
|
-
label: "\u5BBD\u677E\u9876\u5C42\u91CD\u58F0\u660E",
|
|
113
|
-
description: "\u5141\u8BB8\u9876\u5C42 const/let \u91CD\u58F0\u660E\u5DF2\u6709\u53D8\u91CF\u3002"
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
key: "durableReplay",
|
|
117
|
-
type: "boolean",
|
|
118
|
-
default: true,
|
|
119
|
-
label: "\u6301\u4E45\u91CD\u653E",
|
|
120
|
-
description: "worker \u91CD\u542F\u540E\u6062\u590D\u53EF\u4EE5\u91CD\u5EFA\u7684 REPL \u72B6\u6001\u3002"
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
key: "autoRewriteImports",
|
|
124
|
-
type: "boolean",
|
|
125
|
-
default: true,
|
|
126
|
-
label: "\u81EA\u52A8\u6539\u5199 import",
|
|
127
|
-
description: "\u5141\u8BB8\u5728 run_code \u4E2D\u4F7F\u7528\u9759\u6001 import\u3002"
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
key: "autoStripExports",
|
|
131
|
-
type: "boolean",
|
|
132
|
-
default: true,
|
|
133
|
-
label: "\u81EA\u52A8\u5265\u79BB export",
|
|
134
|
-
description: "\u5141\u8BB8\u5728 run_code \u4E2D\u4F7F\u7528\u9876\u5C42 export\u3002"
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
key: "autoSplitRedeclarations",
|
|
138
|
-
type: "boolean",
|
|
139
|
-
default: true,
|
|
140
|
-
label: "\u81EA\u52A8\u62C6\u5206\u6DF7\u5408\u91CD\u58F0\u660E",
|
|
141
|
-
description: "\u5141\u8BB8\u9876\u5C42\u89E3\u6784\u58F0\u660E\u540C\u65F6\u5305\u542B\u65B0\u65E7\u53D8\u91CF\u3002"
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
key: "tipsEnabled",
|
|
145
|
-
type: "boolean",
|
|
146
|
-
default: true,
|
|
147
|
-
label: "\u542F\u7528\u6062\u590D\u63D0\u793A",
|
|
148
|
-
description: "\u5728\u7B26\u5408\u6761\u4EF6\u7684\u5931\u8D25\u540E\u663E\u793A\u6062\u590D\u63D0\u793A\u3002"
|
|
199
|
+
label: "\u8FD4\u56DE\u503C BigInt \u5341\u8FDB\u5236\u4F4D\u6570\u4E0A\u9650",
|
|
200
|
+
labelEn: "Returned-value BigInt decimal-digit limit",
|
|
201
|
+
description: "\u9650\u5236\u8FD4\u56DE\u503C\u4E2D BigInt \u7684\u5341\u8FDB\u5236\u4F4D\u6570\u3002",
|
|
202
|
+
descriptionEn: "Limits the decimal-digit count of BigInt values in one returned value."
|
|
149
203
|
},
|
|
150
204
|
{
|
|
151
205
|
key: "tipCooldownMessages",
|
|
@@ -153,8 +207,10 @@
|
|
|
153
207
|
default: 3,
|
|
154
208
|
min: 1,
|
|
155
209
|
max: Number.MAX_SAFE_INTEGER,
|
|
156
|
-
label: "\u6062\u590D\u63D0\u793A\
|
|
157
|
-
|
|
210
|
+
label: "\u540C\u7C7B\u6062\u590D\u63D0\u793A\u95F4\u9694 (messages)",
|
|
211
|
+
labelEn: "Same-kind recovery tip interval (messages)",
|
|
212
|
+
description: "\u540C\u7C7B\u6062\u590D\u63D0\u793A\u4E4B\u95F4\u7684\u6700\u5C0F\u95F4\u9694\u3002",
|
|
213
|
+
descriptionEn: "The minimum gap between recovery tips of the same kind."
|
|
158
214
|
},
|
|
159
215
|
{
|
|
160
216
|
key: "tipEscalationFailures",
|
|
@@ -162,14 +218,501 @@
|
|
|
162
218
|
default: 2,
|
|
163
219
|
min: 1,
|
|
164
220
|
max: Number.MAX_SAFE_INTEGER,
|
|
165
|
-
label: "\u6062\u590D\u63D0\u793A\
|
|
166
|
-
|
|
221
|
+
label: "\u8BE6\u7EC6\u6062\u590D\u63D0\u793A\u9608\u503C (failures)",
|
|
222
|
+
labelEn: "Detailed recovery tip threshold (failures)",
|
|
223
|
+
description: "\u8FDE\u7EED\u5931\u8D25\u8FBE\u5230\u6B64\u6B21\u6570\u540E\u663E\u793A\u66F4\u8BE6\u7EC6\u7684\u6062\u590D\u63D0\u793A\u3002",
|
|
224
|
+
descriptionEn: "After this many consecutive failures, a more detailed recovery tip is shown."
|
|
225
|
+
}
|
|
226
|
+
]);
|
|
227
|
+
var CONFIG_GROUPS = Object.freeze([
|
|
228
|
+
{
|
|
229
|
+
key: "core",
|
|
230
|
+
label: "\u5E38\u7528\u4E0E\u517C\u5BB9\u6027",
|
|
231
|
+
labelEn: "Common and compatibility",
|
|
232
|
+
fields: Object.freeze(["enabled", "enhancedToolView", "autoDescribeRunCode", "canonicalizeToolCalls"])
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
key: "optional",
|
|
236
|
+
label: "\u53EF\u9009\u80FD\u529B",
|
|
237
|
+
labelEn: "Optional capabilities",
|
|
238
|
+
fields: Object.freeze(["cordisToolsEnabled"])
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
key: "advanced",
|
|
242
|
+
label: "\u9AD8\u7EA7\u884C\u4E3A",
|
|
243
|
+
labelEn: "Advanced behavior",
|
|
244
|
+
fields: Object.freeze([
|
|
245
|
+
"looseTopLevelRedeclarations",
|
|
246
|
+
"autoRewriteImports",
|
|
247
|
+
"autoStripExports",
|
|
248
|
+
"autoSplitRedeclarations",
|
|
249
|
+
"durableReplay",
|
|
250
|
+
"tipsEnabled"
|
|
251
|
+
])
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
key: "limits",
|
|
255
|
+
label: "\u8D44\u6E90\u9650\u5236",
|
|
256
|
+
labelEn: "Resource limits",
|
|
257
|
+
fields: Object.freeze([
|
|
258
|
+
"computeMs",
|
|
259
|
+
"maxWallMs",
|
|
260
|
+
"maxOldGenerationSizeMb",
|
|
261
|
+
"maxNestedRunCodeDepth",
|
|
262
|
+
"maxOutputBytes",
|
|
263
|
+
"maxValueNodes",
|
|
264
|
+
"maxValueEdges",
|
|
265
|
+
"maxValueArrayLength",
|
|
266
|
+
"maxValueBigIntDigits",
|
|
267
|
+
"tipCooldownMessages",
|
|
268
|
+
"tipEscalationFailures"
|
|
269
|
+
])
|
|
167
270
|
}
|
|
168
271
|
]);
|
|
169
272
|
var CONFIG_DEFAULTS = Object.freeze(
|
|
170
273
|
Object.fromEntries(CONFIG_FIELDS.map((field) => [field.key, field.default]))
|
|
171
274
|
);
|
|
172
275
|
|
|
276
|
+
// src/client-activity.js
|
|
277
|
+
var JOURNAL_VERSIONS = /* @__PURE__ */ new Set([1, 2, 3]);
|
|
278
|
+
var JOURNAL_STATUSES = /* @__PURE__ */ new Set(["durable", "volatile", "discarded", "noop"]);
|
|
279
|
+
var BINDING_MODES = /* @__PURE__ */ new Set(["loose", "strict"]);
|
|
280
|
+
var JOURNAL_FIELDS = /* @__PURE__ */ new Set([
|
|
281
|
+
"version",
|
|
282
|
+
"bindingMode",
|
|
283
|
+
"rewritePolicy",
|
|
284
|
+
"status",
|
|
285
|
+
"calls",
|
|
286
|
+
"operations",
|
|
287
|
+
"confirms",
|
|
288
|
+
"diagnostics",
|
|
289
|
+
"completion",
|
|
290
|
+
"volatileReason"
|
|
291
|
+
]);
|
|
292
|
+
var LEGACY_JOURNAL_FIELDS = new Set([...JOURNAL_FIELDS].filter((key) => key !== "rewritePolicy"));
|
|
293
|
+
var REWRITE_POLICY_FIELDS = /* @__PURE__ */ new Set([
|
|
294
|
+
"autoRewriteImports",
|
|
295
|
+
"autoStripExports",
|
|
296
|
+
"autoSplitRedeclarations"
|
|
297
|
+
]);
|
|
298
|
+
var CALL_SUCCESS_FIELDS = /* @__PURE__ */ new Set(["global", "member", "args", "ok", "value", "settle"]);
|
|
299
|
+
var CALL_ERROR_FIELDS = /* @__PURE__ */ new Set(["global", "member", "args", "ok", "error", "settle"]);
|
|
300
|
+
var OPERATION_FIELDS = /* @__PURE__ */ new Set(["action", "name"]);
|
|
301
|
+
var RETURN_FIELDS = /* @__PURE__ */ new Set(["kind", "hasValue", "value"]);
|
|
302
|
+
var THROW_FIELDS = /* @__PURE__ */ new Set(["kind", "error"]);
|
|
303
|
+
var ERROR_FIELDS = /* @__PURE__ */ new Set(["kind", "message"]);
|
|
304
|
+
var DIAGNOSTIC_FIELDS = /* @__PURE__ */ new Set([
|
|
305
|
+
"code",
|
|
306
|
+
"severity",
|
|
307
|
+
"phase",
|
|
308
|
+
"message",
|
|
309
|
+
"stateEffect",
|
|
310
|
+
"dispatchState",
|
|
311
|
+
"source",
|
|
312
|
+
"cause",
|
|
313
|
+
"help"
|
|
314
|
+
]);
|
|
315
|
+
var SOURCE_FIELDS = /* @__PURE__ */ new Set(["cell", "start", "end"]);
|
|
316
|
+
var POSITION_FIELDS = /* @__PURE__ */ new Set(["line", "column"]);
|
|
317
|
+
var CAUSE_FIELDS = /* @__PURE__ */ new Set(["code", "message"]);
|
|
318
|
+
var SEVERITIES = /* @__PURE__ */ new Set(["error", "warning", "note"]);
|
|
319
|
+
var PHASES = /* @__PURE__ */ new Set(["parse", "preflight", "execute", "tool-dispatch", "replay", "recover"]);
|
|
320
|
+
var STATE_EFFECTS = /* @__PURE__ */ new Set(["unchanged", "partially-applied", "rolled-back", "unknown"]);
|
|
321
|
+
var DISPATCH_STATES = /* @__PURE__ */ new Set(["not-dispatched", "dispatched", "completed", "unknown"]);
|
|
322
|
+
var REWRITE_FIELDS = /* @__PURE__ */ new Set(["kind", "description", "source"]);
|
|
323
|
+
var REWRITE_KINDS = /* @__PURE__ */ new Set(["import", "redeclaration", "export"]);
|
|
324
|
+
var REWRITE_POLICY_BY_KIND = Object.freeze({
|
|
325
|
+
import: "autoRewriteImports",
|
|
326
|
+
redeclaration: "autoSplitRedeclarations",
|
|
327
|
+
export: "autoStripExports"
|
|
328
|
+
});
|
|
329
|
+
var EDIT_TARGET_FIELDS = /* @__PURE__ */ new Set(["targetCallSeq"]);
|
|
330
|
+
var DERIVED_RUN_FIELDS = /* @__PURE__ */ new Set(["code", "description"]);
|
|
331
|
+
var RECOVERY_BOUNDARY_FIELDS = /* @__PURE__ */ new Set(["failedCallSeq", "frontierCallSeq"]);
|
|
332
|
+
var VALUE_ENVELOPE_FIELDS = /* @__PURE__ */ new Set(["codec", "root", "nodes"]);
|
|
333
|
+
var VALUE_OBJECT_FIELDS = /* @__PURE__ */ new Set(["type", "prototype", "entries"]);
|
|
334
|
+
var VALUE_ARRAY_FIELDS = /* @__PURE__ */ new Set(["type", "length", "entries"]);
|
|
335
|
+
var VALUE_UNDEFINED_FIELDS = /* @__PURE__ */ new Set(["tag"]);
|
|
336
|
+
var VALUE_NUMBER_FIELDS = /* @__PURE__ */ new Set(["tag", "value"]);
|
|
337
|
+
var VALUE_BIGINT_FIELDS = /* @__PURE__ */ new Set(["tag", "value"]);
|
|
338
|
+
var VALUE_REFERENCE_FIELDS = /* @__PURE__ */ new Set(["tag", "index"]);
|
|
339
|
+
var MAX_VALUE_NODES = 1e5;
|
|
340
|
+
var MAX_VALUE_EDGES = 1e6;
|
|
341
|
+
var MAX_ARRAY_LENGTH = 1e6;
|
|
342
|
+
var MAX_BIGINT_DIGITS = 1e5;
|
|
343
|
+
var MAX_STRING_BYTES = 64 * 1024 * 1024;
|
|
344
|
+
var textEncoder = new TextEncoder();
|
|
345
|
+
function isRecord(value) {
|
|
346
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
347
|
+
}
|
|
348
|
+
function hasClosedFields(value, allowed, required = []) {
|
|
349
|
+
if (!isRecord(value)) return false;
|
|
350
|
+
const keys = Reflect.ownKeys(value);
|
|
351
|
+
if (keys.some((key) => typeof key !== "string" || !allowed.has(key) || !Object.prototype.propertyIsEnumerable.call(value, key))) return false;
|
|
352
|
+
return [...required].every((key) => Object.hasOwn(value, key));
|
|
353
|
+
}
|
|
354
|
+
function hasExactFields(value, fields) {
|
|
355
|
+
return hasClosedFields(value, fields, fields) && Reflect.ownKeys(value).length === fields.size;
|
|
356
|
+
}
|
|
357
|
+
function hasExactOrderedFields(value, fields) {
|
|
358
|
+
if (!isRecord(value)) return false;
|
|
359
|
+
const keys = Reflect.ownKeys(value);
|
|
360
|
+
const ordered = [...fields];
|
|
361
|
+
return keys.length === ordered.length && keys.every((key, index) => key === ordered[index] && Object.prototype.propertyIsEnumerable.call(value, key));
|
|
362
|
+
}
|
|
363
|
+
function isLine(value) {
|
|
364
|
+
return typeof value === "string" && value.length > 0 && !/[\r\n]/.test(value);
|
|
365
|
+
}
|
|
366
|
+
function isSafeSequence(value) {
|
|
367
|
+
return Number.isSafeInteger(value) && value >= 0;
|
|
368
|
+
}
|
|
369
|
+
function isValidPosition(value) {
|
|
370
|
+
return hasExactFields(value, POSITION_FIELDS) && Number.isSafeInteger(value.line) && value.line >= 1 && Number.isSafeInteger(value.column) && value.column >= 1;
|
|
371
|
+
}
|
|
372
|
+
function isValidDiagnosticCause(value, depth) {
|
|
373
|
+
if (depth > 16 || !isRecord(value)) return false;
|
|
374
|
+
if (Object.hasOwn(value, "severity")) return isValidDiagnostic(value, depth + 1);
|
|
375
|
+
return hasClosedFields(value, CAUSE_FIELDS, ["message"]) && (value.code === void 0 || isLine(value.code)) && isLine(value.message);
|
|
376
|
+
}
|
|
377
|
+
function isValidDiagnostic(value, depth = 0) {
|
|
378
|
+
if (!hasClosedFields(value, DIAGNOSTIC_FIELDS, [
|
|
379
|
+
"code",
|
|
380
|
+
"severity",
|
|
381
|
+
"phase",
|
|
382
|
+
"message",
|
|
383
|
+
"stateEffect"
|
|
384
|
+
])) return false;
|
|
385
|
+
if (typeof value.code !== "string" || !/^[A-Z][A-Z0-9-]{2,31}$/.test(value.code) || !SEVERITIES.has(value.severity) || !PHASES.has(value.phase) || !STATE_EFFECTS.has(value.stateEffect) || !isLine(value.message)) return false;
|
|
386
|
+
if (value.dispatchState !== void 0 && !DISPATCH_STATES.has(value.dispatchState)) return false;
|
|
387
|
+
if (value.source !== void 0) {
|
|
388
|
+
if (!hasClosedFields(value.source, SOURCE_FIELDS, ["cell", "start"]) || !isLine(value.source.cell) || !isValidPosition(value.source.start) || value.source.end !== void 0 && !isValidPosition(value.source.end)) return false;
|
|
389
|
+
if (value.source.end !== void 0 && (value.source.end.line < value.source.start.line || value.source.end.line === value.source.start.line && value.source.end.column < value.source.start.column)) return false;
|
|
390
|
+
}
|
|
391
|
+
if (value.cause !== void 0 && !isValidDiagnosticCause(value.cause, depth)) return false;
|
|
392
|
+
return value.help === void 0 || Array.isArray(value.help) && value.help.length <= 3 && value.help.every(isLine);
|
|
393
|
+
}
|
|
394
|
+
function isArrayIndexKey(value) {
|
|
395
|
+
if (!/^(0|[1-9][0-9]*)$/.test(value)) return false;
|
|
396
|
+
const parsed = Number(value);
|
|
397
|
+
return Number.isInteger(parsed) && parsed >= 0 && parsed < 4294967295 && String(parsed) === value;
|
|
398
|
+
}
|
|
399
|
+
function accountText(value, state) {
|
|
400
|
+
state.textBytes += textEncoder.encode(value).byteLength;
|
|
401
|
+
return state.textBytes <= MAX_STRING_BYTES;
|
|
402
|
+
}
|
|
403
|
+
function isValidValueAtom(value, state) {
|
|
404
|
+
if (value === null || typeof value === "boolean") return true;
|
|
405
|
+
if (typeof value === "string") return accountText(value, state);
|
|
406
|
+
if (typeof value === "number") return Number.isFinite(value) && !Object.is(value, -0);
|
|
407
|
+
if (!isRecord(value) || typeof value.tag !== "string") return false;
|
|
408
|
+
if (value.tag === "undefined") return hasExactOrderedFields(value, VALUE_UNDEFINED_FIELDS);
|
|
409
|
+
if (value.tag === "number") {
|
|
410
|
+
return hasExactOrderedFields(value, VALUE_NUMBER_FIELDS) && ["nan", "infinity", "-infinity", "-0"].includes(value.value);
|
|
411
|
+
}
|
|
412
|
+
if (value.tag === "bigint") {
|
|
413
|
+
if (!hasExactOrderedFields(value, VALUE_BIGINT_FIELDS) || typeof value.value !== "string" || !/^(0|-[1-9][0-9]*|[1-9][0-9]*)$/.test(value.value)) return false;
|
|
414
|
+
const digits = value.value[0] === "-" ? value.value.length - 1 : value.value.length;
|
|
415
|
+
return digits <= MAX_BIGINT_DIGITS && accountText(value.value, state);
|
|
416
|
+
}
|
|
417
|
+
if (value.tag !== "reference" || !hasExactOrderedFields(value, VALUE_REFERENCE_FIELDS) || !isSafeSequence(value.index) || value.index >= state.nodeCount) return false;
|
|
418
|
+
if (!state.discovered.has(value.index)) {
|
|
419
|
+
if (value.index !== state.discovered.size) return false;
|
|
420
|
+
state.discovered.add(value.index);
|
|
421
|
+
}
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
function isValidValueWire(value) {
|
|
425
|
+
if (!hasExactOrderedFields(value, VALUE_ENVELOPE_FIELDS) || value.codec !== "ptc-value-graph/v1" || !Array.isArray(value.nodes) || value.nodes.length > MAX_VALUE_NODES) return false;
|
|
426
|
+
const state = {
|
|
427
|
+
nodeCount: value.nodes.length,
|
|
428
|
+
discovered: /* @__PURE__ */ new Set(),
|
|
429
|
+
edges: 0,
|
|
430
|
+
textBytes: 0
|
|
431
|
+
};
|
|
432
|
+
if (!isValidValueAtom(value.root, state)) return false;
|
|
433
|
+
for (const [nodeIndex, node] of value.nodes.entries()) {
|
|
434
|
+
if (!state.discovered.has(nodeIndex) || !isRecord(node)) return false;
|
|
435
|
+
if (node.type === "array") {
|
|
436
|
+
if (!hasExactOrderedFields(node, VALUE_ARRAY_FIELDS) || !Number.isSafeInteger(node.length) || node.length < 0 || node.length > MAX_ARRAY_LENGTH || !Array.isArray(node.entries)) return false;
|
|
437
|
+
let previous = -1;
|
|
438
|
+
for (const entry of node.entries) {
|
|
439
|
+
if (!Array.isArray(entry) || entry.length !== 2 || !Number.isSafeInteger(entry[0]) || entry[0] <= previous || entry[0] < 0 || entry[0] >= node.length) return false;
|
|
440
|
+
previous = entry[0];
|
|
441
|
+
state.edges += 1;
|
|
442
|
+
if (state.edges > MAX_VALUE_EDGES || !isValidValueAtom(entry[1], state)) return false;
|
|
443
|
+
}
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
if (node.type !== "object" || !hasExactOrderedFields(node, VALUE_OBJECT_FIELDS) || !["object", "null"].includes(node.prototype) || !Array.isArray(node.entries)) return false;
|
|
447
|
+
const keys = /* @__PURE__ */ new Set();
|
|
448
|
+
let previousArrayIndex = -1;
|
|
449
|
+
let sawOtherKey = false;
|
|
450
|
+
for (const entry of node.entries) {
|
|
451
|
+
if (!Array.isArray(entry) || entry.length !== 2 || typeof entry[0] !== "string" || keys.has(entry[0]) || !accountText(entry[0], state)) return false;
|
|
452
|
+
keys.add(entry[0]);
|
|
453
|
+
if (isArrayIndexKey(entry[0])) {
|
|
454
|
+
const current = Number(entry[0]);
|
|
455
|
+
if (sawOtherKey || current <= previousArrayIndex) return false;
|
|
456
|
+
previousArrayIndex = current;
|
|
457
|
+
} else {
|
|
458
|
+
sawOtherKey = true;
|
|
459
|
+
}
|
|
460
|
+
state.edges += 1;
|
|
461
|
+
if (state.edges > MAX_VALUE_EDGES || !isValidValueAtom(entry[1], state)) return false;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return state.discovered.size === value.nodes.length;
|
|
465
|
+
}
|
|
466
|
+
function isValidRewritePolicy(value) {
|
|
467
|
+
return hasExactFields(value, REWRITE_POLICY_FIELDS) && [...REWRITE_POLICY_FIELDS].every((key) => typeof value[key] === "boolean");
|
|
468
|
+
}
|
|
469
|
+
function isValidCall(value) {
|
|
470
|
+
if (!isRecord(value) || value.ok !== true && value.ok !== false) return false;
|
|
471
|
+
const fields = value.ok ? CALL_SUCCESS_FIELDS : CALL_ERROR_FIELDS;
|
|
472
|
+
if (!hasExactFields(value, fields) || typeof value.global !== "string" || typeof value.member !== "string" || !isValidValueWire(value.args) || !isSafeSequence(value.settle)) return false;
|
|
473
|
+
return value.ok ? isValidValueWire(value.value) : typeof value.error === "string";
|
|
474
|
+
}
|
|
475
|
+
function isValidOperation(value) {
|
|
476
|
+
if (!hasClosedFields(value, OPERATION_FIELDS, ["action"]) || !["save", "restore", "delete"].includes(value.action)) return false;
|
|
477
|
+
if (value.action === "restore" && value.name === void 0) return true;
|
|
478
|
+
return typeof value.name === "string" && /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(value.name);
|
|
479
|
+
}
|
|
480
|
+
function isValidCompletion(value) {
|
|
481
|
+
if (!isRecord(value) || !["return", "throw"].includes(value.kind)) return false;
|
|
482
|
+
if (value.kind === "return") {
|
|
483
|
+
if (!hasClosedFields(value, RETURN_FIELDS, ["kind", "hasValue"]) || typeof value.hasValue !== "boolean") return false;
|
|
484
|
+
return value.hasValue ? Object.hasOwn(value, "value") && isValidValueWire(value.value) : !Object.hasOwn(value, "value");
|
|
485
|
+
}
|
|
486
|
+
return hasExactFields(value, THROW_FIELDS) && hasExactFields(value.error, ERROR_FIELDS) && typeof value.error.kind === "string" && typeof value.error.message === "string";
|
|
487
|
+
}
|
|
488
|
+
function isValidConfirms(value, version) {
|
|
489
|
+
if (value === void 0) return true;
|
|
490
|
+
if (!Array.isArray(value) || new Set(value).size !== value.length) return false;
|
|
491
|
+
if (version === 1) return value.length === 0;
|
|
492
|
+
return value.every(isSafeSequence);
|
|
493
|
+
}
|
|
494
|
+
function isReadableJournalUnchecked(value) {
|
|
495
|
+
if (!isRecord(value) || !JOURNAL_VERSIONS.has(value.version) || !JOURNAL_STATUSES.has(value.status)) {
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
const fields = value.version === 1 ? LEGACY_JOURNAL_FIELDS : JOURNAL_FIELDS;
|
|
499
|
+
const required = ["version", "bindingMode", "status", "calls", "operations", "diagnostics"];
|
|
500
|
+
if (value.version !== 1) required.push("rewritePolicy");
|
|
501
|
+
if (!hasClosedFields(value, fields, required) || !BINDING_MODES.has(value.bindingMode) || value.version !== 1 && !isValidRewritePolicy(value.rewritePolicy) || !Array.isArray(value.calls) || !value.calls.every(isValidCall) || !Array.isArray(value.operations) || !value.operations.every(isValidOperation) || !isValidConfirms(value.confirms, value.version) || !Array.isArray(value.diagnostics) || !value.diagnostics.every(isValidDiagnostic)) return false;
|
|
502
|
+
const settlementOrder = value.calls.map((call) => call.settle).sort((left, right) => left - right);
|
|
503
|
+
if (settlementOrder.some((settle, index) => settle !== index)) return false;
|
|
504
|
+
const requiresCompletion = value.status === "durable" || value.status === "volatile";
|
|
505
|
+
if (requiresCompletion && !isValidCompletion(value.completion) || !requiresCompletion && value.completion !== void 0 && !isValidCompletion(value.completion)) return false;
|
|
506
|
+
if ((value.status === "discarded" || value.status === "noop") && (value.calls.length !== 0 || value.operations.length !== 0)) return false;
|
|
507
|
+
if (value.volatileReason !== void 0 && (typeof value.volatileReason !== "string" || value.status !== "volatile" && value.status !== "discarded")) return false;
|
|
508
|
+
return true;
|
|
509
|
+
}
|
|
510
|
+
function isReadableJournal(value) {
|
|
511
|
+
try {
|
|
512
|
+
return isReadableJournalUnchecked(value);
|
|
513
|
+
} catch {
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
function isCountableJournal(value) {
|
|
518
|
+
return isReadableJournal(value) && JOURNAL_STATUSES.has(value.status) && Array.isArray(value.calls) && Array.isArray(value.operations) && Array.isArray(value.diagnostics);
|
|
519
|
+
}
|
|
520
|
+
function isValidRewrites(value, journal) {
|
|
521
|
+
try {
|
|
522
|
+
return journal.status !== "noop" && isValidRewritePolicy(journal.rewritePolicy) && Array.isArray(value) && value.every((rewrite) => hasClosedFields(rewrite, REWRITE_FIELDS, ["kind", "description"]) && REWRITE_KINDS.has(rewrite.kind) && journal.rewritePolicy[REWRITE_POLICY_BY_KIND[rewrite.kind]] === true && typeof rewrite.description === "string" && rewrite.description.length > 0 && (rewrite.source === void 0 || typeof rewrite.source === "string"));
|
|
523
|
+
} catch {
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
function isValidEditTarget(value) {
|
|
528
|
+
try {
|
|
529
|
+
return hasExactFields(value, EDIT_TARGET_FIELDS) && isSafeSequence(value.targetCallSeq);
|
|
530
|
+
} catch {
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function isValidDerivedRun(value) {
|
|
535
|
+
try {
|
|
536
|
+
return hasExactFields(value, DERIVED_RUN_FIELDS) && typeof value.code === "string" && typeof value.description === "string";
|
|
537
|
+
} catch {
|
|
538
|
+
return false;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
function isValidRecoveryBoundaries(value) {
|
|
542
|
+
try {
|
|
543
|
+
return Array.isArray(value) && value.every((boundary) => hasExactFields(boundary, RECOVERY_BOUNDARY_FIELDS) && isSafeSequence(boundary.failedCallSeq) && (boundary.frontierCallSeq === null || isSafeSequence(boundary.frontierCallSeq)));
|
|
544
|
+
} catch {
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
function isValidEditRelation(meta, args, journal) {
|
|
549
|
+
try {
|
|
550
|
+
if (!isRecord(meta) || !isRecord(args) || !isValidEditTarget(meta.dshPtcPlusEdit) || !isValidDerivedRun(meta.dshPtcPlusDerivedRun) || journal.status === "noop") return false;
|
|
551
|
+
if (Object.hasOwn(meta, "dshPtcPlusRecoveryBoundaries") && !isValidRecoveryBoundaries(meta.dshPtcPlusRecoveryBoundaries)) return false;
|
|
552
|
+
return !Object.hasOwn(args, "expected_target_call_seq") || args.expected_target_call_seq === meta.dshPtcPlusEdit.targetCallSeq;
|
|
553
|
+
} catch {
|
|
554
|
+
return false;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
function rawArguments(block, settled) {
|
|
558
|
+
const call = settled ? block.call : block;
|
|
559
|
+
return typeof call?.argsRaw === "string" ? call.argsRaw : typeof call?.arguments === "string" ? call.arguments : "";
|
|
560
|
+
}
|
|
561
|
+
function parseArguments(raw) {
|
|
562
|
+
try {
|
|
563
|
+
const value = JSON.parse(raw);
|
|
564
|
+
return isRecord(value) ? value : void 0;
|
|
565
|
+
} catch {
|
|
566
|
+
return void 0;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
function resultText(block) {
|
|
570
|
+
if (!Array.isArray(block.content)) return "";
|
|
571
|
+
try {
|
|
572
|
+
const parts = block.content.map((item) => item?.type === "text" && typeof item.text === "string" ? item.text : JSON.stringify(item, null, 2));
|
|
573
|
+
if (parts.length === 0 && isRecord(block.error)) {
|
|
574
|
+
return [block.error.name, block.error.code].filter((value) => typeof value === "string").join(": ");
|
|
575
|
+
}
|
|
576
|
+
return parts.filter((value) => typeof value === "string").join("\n");
|
|
577
|
+
} catch {
|
|
578
|
+
return "";
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
var MIXED_REDECLARATION = "split a mixed top-level declaration while preserving native pattern initialization";
|
|
582
|
+
var GENERATED_RUN_CODE_DESCRIPTION_KEY = "dshPtcPlusRunCodeDescription";
|
|
583
|
+
function rewriteFeature(rewrites, predicate, key) {
|
|
584
|
+
const matching = rewrites.filter(predicate);
|
|
585
|
+
if (matching.length === 0) return void 0;
|
|
586
|
+
const sources = [...new Set(matching.map((rewrite) => rewrite.source).filter((source) => source !== void 0))];
|
|
587
|
+
return { key, detail: sources.join(", ") };
|
|
588
|
+
}
|
|
589
|
+
function operationFeatures(operations) {
|
|
590
|
+
const keys = {
|
|
591
|
+
save: "feature.stateSaved",
|
|
592
|
+
restore: "feature.stateRestored",
|
|
593
|
+
delete: "feature.stateDeleted"
|
|
594
|
+
};
|
|
595
|
+
return operations.map((operation) => ({
|
|
596
|
+
key: keys[operation.action],
|
|
597
|
+
detail: operation.name ?? ""
|
|
598
|
+
}));
|
|
599
|
+
}
|
|
600
|
+
function uniqueFeatures(features) {
|
|
601
|
+
const seen = /* @__PURE__ */ new Set();
|
|
602
|
+
return features.filter((feature) => {
|
|
603
|
+
if (feature === void 0) return false;
|
|
604
|
+
const identity = `${feature.key}\0${feature.detail}`;
|
|
605
|
+
if (seen.has(identity)) return false;
|
|
606
|
+
seen.add(identity);
|
|
607
|
+
return true;
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
function isDurableRecoveryDiagnostic(diagnostic) {
|
|
611
|
+
return diagnostic.code === "PTC-R002" && diagnostic.severity === "warning" && diagnostic.phase === "recover" && diagnostic.stateEffect === "rolled-back";
|
|
612
|
+
}
|
|
613
|
+
function derivePtcToolView(block, toolName = void 0) {
|
|
614
|
+
const settled = isRecord(block) && block.kind === "tool-result";
|
|
615
|
+
const argsRaw = isRecord(block) ? rawArguments(block, settled) : "";
|
|
616
|
+
const args = parseArguments(argsRaw);
|
|
617
|
+
const code = typeof args?.code === "string" ? args.code : argsRaw;
|
|
618
|
+
const explicitDescription = typeof args?.description === "string" && args.description.length > 0 ? args.description : void 0;
|
|
619
|
+
const generatedDescription = settled && isRecord(block.meta) && typeof block.meta[GENERATED_RUN_CODE_DESCRIPTION_KEY] === "string" && block.meta[GENERATED_RUN_CODE_DESCRIPTION_KEY].length > 0 ? block.meta[GENERATED_RUN_CODE_DESCRIPTION_KEY] : void 0;
|
|
620
|
+
const description = (explicitDescription ?? generatedDescription)?.split(/\r?\n/, 1)[0] ?? "";
|
|
621
|
+
const output = settled ? resultText(block) : "";
|
|
622
|
+
const state = !settled ? "running" : block.error?.code === "interrupted" ? "stopped" : block.isError === true ? "error" : "ok";
|
|
623
|
+
const journal = settled && isRecord(block.meta) && isCountableJournal(block.meta.dshPtcPlus) ? block.meta.dshPtcPlus : void 0;
|
|
624
|
+
if (journal === void 0) {
|
|
625
|
+
return Object.freeze({ state, description, code, output, ptc: false, features: Object.freeze([]) });
|
|
626
|
+
}
|
|
627
|
+
const rewrites = isValidRewrites(block.meta.dshPtcPlusRewrites, journal) ? block.meta.dshPtcPlusRewrites : [];
|
|
628
|
+
const resolvedToolName = typeof toolName === "string" ? toolName : typeof block.call?.name === "string" ? block.call.name : "";
|
|
629
|
+
const recordedToolName = typeof block.call?.name === "string" ? block.call.name : void 0;
|
|
630
|
+
const safeEdit = resolvedToolName === "edit_run_code" && (recordedToolName === void 0 || recordedToolName === "edit_run_code") && isValidEditRelation(block.meta, args, journal);
|
|
631
|
+
const features = uniqueFeatures([
|
|
632
|
+
safeEdit ? { key: "feature.safeEdit", detail: "" } : void 0,
|
|
633
|
+
rewriteFeature(rewrites, (rewrite) => rewrite.kind === "import", "autoRewriteImports.label"),
|
|
634
|
+
rewriteFeature(rewrites, (rewrite) => rewrite.kind === "export", "autoStripExports.label"),
|
|
635
|
+
rewriteFeature(rewrites, (rewrite) => rewrite.kind === "redeclaration" && rewrite.description === MIXED_REDECLARATION, "autoSplitRedeclarations.label"),
|
|
636
|
+
journal.calls.some((call) => call.global === "code" && call.member === "run" && call.ok === true) ? { key: "feature.codeRun", detail: "" } : void 0,
|
|
637
|
+
journal.diagnostics.some(isDurableRecoveryDiagnostic) ? { key: "durableReplay.label", detail: "" } : void 0,
|
|
638
|
+
...operationFeatures(journal.operations)
|
|
639
|
+
]);
|
|
640
|
+
return Object.freeze({ state, description, code, output, ptc: true, features: Object.freeze(features) });
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// internal/record-utils.js
|
|
644
|
+
function isRecord2(value) {
|
|
645
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// internal/repl-memory-projection.js
|
|
649
|
+
var BINDING_KINDS = /* @__PURE__ */ new Set(["variable", "function", "class", "import"]);
|
|
650
|
+
var MAX_BINDINGS = 128;
|
|
651
|
+
var MAX_BINDING_NAME_LENGTH = 128;
|
|
652
|
+
var MAX_DEFINITION_SOURCE_LENGTH = 1024;
|
|
653
|
+
var MAX_DEFINITION_SOURCE_TOTAL_LENGTH = 16 * 1024;
|
|
654
|
+
var SNAPSHOT_FIELDS = /* @__PURE__ */ new Set(["available", "entries", "total", "omitted"]);
|
|
655
|
+
var ENTRY_FIELDS = /* @__PURE__ */ new Set(["name", "kind", "definition"]);
|
|
656
|
+
var DEFINITION_FIELDS = /* @__PURE__ */ new Set(["source", "line", "column"]);
|
|
657
|
+
function exactFields(value, fields) {
|
|
658
|
+
if (!isRecord2(value)) return false;
|
|
659
|
+
const keys = Reflect.ownKeys(value);
|
|
660
|
+
return keys.length === fields.size && keys.every((key) => typeof key === "string" && fields.has(key) && Object.prototype.propertyIsEnumerable.call(value, key));
|
|
661
|
+
}
|
|
662
|
+
var EMPTY_REPL_MEMORY = Object.freeze({
|
|
663
|
+
available: false,
|
|
664
|
+
entries: Object.freeze([]),
|
|
665
|
+
total: 0,
|
|
666
|
+
omitted: 0
|
|
667
|
+
});
|
|
668
|
+
function unavailableReplMemorySnapshot() {
|
|
669
|
+
return EMPTY_REPL_MEMORY;
|
|
670
|
+
}
|
|
671
|
+
function normalizeDefinition(value) {
|
|
672
|
+
if (!exactFields(value, DEFINITION_FIELDS) || typeof value.source !== "string" || value.source.length === 0 || value.source.length > MAX_DEFINITION_SOURCE_LENGTH || !Number.isSafeInteger(value.line) || value.line < 1 || !Number.isSafeInteger(value.column) || value.column < 1) {
|
|
673
|
+
throw new Error("invalid dsh-ptc-plus REPL binding definition");
|
|
674
|
+
}
|
|
675
|
+
return Object.freeze({ source: value.source, line: value.line, column: value.column });
|
|
676
|
+
}
|
|
677
|
+
function normalizeBinding(value) {
|
|
678
|
+
if (!exactFields(value, ENTRY_FIELDS) || typeof value.name !== "string" || value.name.length === 0 || value.name.length > MAX_BINDING_NAME_LENGTH || !BINDING_KINDS.has(value.kind)) {
|
|
679
|
+
throw new Error("invalid dsh-ptc-plus REPL memory binding");
|
|
680
|
+
}
|
|
681
|
+
return Object.freeze({
|
|
682
|
+
name: value.name,
|
|
683
|
+
kind: value.kind,
|
|
684
|
+
definition: normalizeDefinition(value.definition)
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
function normalizeReplMemorySnapshot(value) {
|
|
688
|
+
if (!exactFields(value, SNAPSHOT_FIELDS) || typeof value.available !== "boolean" || !Array.isArray(value.entries) || value.entries.length > MAX_BINDINGS || !Number.isSafeInteger(value.total) || value.total < 0 || !Number.isSafeInteger(value.omitted) || value.omitted < 0 || value.total !== value.entries.length + value.omitted) {
|
|
689
|
+
throw new Error("invalid dsh-ptc-plus REPL memory snapshot");
|
|
690
|
+
}
|
|
691
|
+
if (!value.available && (value.total !== 0 || value.entries.length !== 0)) {
|
|
692
|
+
throw new Error("unavailable dsh-ptc-plus REPL memory snapshot must be empty");
|
|
693
|
+
}
|
|
694
|
+
const names = /* @__PURE__ */ new Set();
|
|
695
|
+
let sourceLength = 0;
|
|
696
|
+
const entries = value.entries.map((entry) => {
|
|
697
|
+
const normalized = normalizeBinding(entry);
|
|
698
|
+
if (names.has(normalized.name)) {
|
|
699
|
+
throw new Error("invalid dsh-ptc-plus REPL memory binding");
|
|
700
|
+
}
|
|
701
|
+
sourceLength += normalized.definition.source.length;
|
|
702
|
+
if (sourceLength > MAX_DEFINITION_SOURCE_TOTAL_LENGTH) {
|
|
703
|
+
throw new Error("dsh-ptc-plus REPL binding definitions exceed the presentation budget");
|
|
704
|
+
}
|
|
705
|
+
names.add(normalized.name);
|
|
706
|
+
return normalized;
|
|
707
|
+
});
|
|
708
|
+
return Object.freeze({
|
|
709
|
+
available: value.available,
|
|
710
|
+
entries: Object.freeze(entries),
|
|
711
|
+
total: value.total,
|
|
712
|
+
omitted: value.omitted
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
|
|
173
716
|
// src/client.js
|
|
174
717
|
var CLIENT_STYLE_ID = "ptc-plus-client-style";
|
|
175
718
|
var CLIENT_CSS = `
|
|
@@ -178,20 +721,140 @@
|
|
|
178
721
|
.ptcPlusHeader:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06))}.ptcPlusHeader:focus-visible,.ptcPlusButton:focus-visible,.ptcPlusInput:focus-visible{outline:2px solid var(--dsw-alias-interactive-primary,#4d6bfe);outline-offset:-2px}
|
|
179
722
|
.ptcPlusHeadText{display:flex;flex:1;min-width:0;flex-direction:column;align-items:flex-start;gap:1px}.ptcPlusName{font-size:14px;font-weight:600;line-height:20px}.ptcPlusDescription{color:var(--dsw-alias-label-tertiary,#74777d);font-size:12px;line-height:18px;overflow-wrap:anywhere}.ptcPlusStatus{display:inline-flex;align-items:center;flex:none;padding:2px 8px;border-radius:999px;font-size:11px;font-weight:500;line-height:16px}.ptcPlusStatus[data-enabled=true]{color:var(--dsw-alias-state-success-primary,#16794f);background:var(--dsw-alias-state-success-tertiary,#e7f7ef)}.ptcPlusStatus[data-enabled=false]{color:var(--dsw-alias-label-tertiary,#74777d);background:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06))}
|
|
180
723
|
.ptcPlusChevron{display:flex;color:var(--dsw-alias-label-tertiary,#74777d);transition:transform .18s ease}.ptcPlusChevron[data-open=true]{transform:rotate(180deg)}.ptcPlusBody{display:grid;grid-template-rows:0fr;transition:grid-template-rows .2s ease}.ptcPlusBody[data-open=true]{grid-template-rows:1fr}.ptcPlusBodyInner{min-height:0;overflow:hidden}.ptcPlusFields{margin:0 16px;padding:8px 0 12px;border-top:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1))}
|
|
181
|
-
.ptcPlusRow{display:flex;align-items:center;gap:12px;min-height:48px;border-top:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1))}.ptcPlusRow:first-child{border-top:0}.ptcPlusMain{flex:1;min-width:0}.ptcPlusLabel{font-size:14px;font-weight:500;line-height:20px}.ptcPlusDetail,.ptcPlusMessage{color:var(--dsw-alias-label-tertiary,#74777d);font-size:12px;line-height:18px;overflow-wrap:anywhere}.ptcPlusInput{box-sizing:border-box;min-width:72px;width:140px;padding:5px 8px;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1));border-radius:6px;background:var(--dsw-alias-bg-layer-1,#fff);color:inherit;font:12px/18px ui-monospace,SFMono-Regular,Consolas,monospace}.ptcPlusCheck{width:18px;height:18px;accent-color:var(--dsw-alias-interactive-primary,#4d6bfe)}
|
|
182
|
-
.ptcPlusFooter{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:8px}.ptcPlusButton{min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1));border-radius:6px;background:transparent;color:inherit;cursor:pointer;font:500 13px/20px inherit;transition:background-color .16s ease,border-color .16s ease}.ptcPlusButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06))}.ptcPlusButton:disabled,.ptcPlusInput:disabled,.ptcPlusCheck:disabled{cursor:not-allowed;opacity:.55}
|
|
183
|
-
|
|
184
|
-
|
|
724
|
+
.ptcPlusGroup+.ptcPlusGroup{margin-top:14px}.ptcPlusGroupTitle{margin:0;padding:8px 0 5px;color:var(--dsw-alias-label-secondary,#52565d);font-size:11px;font-weight:600;letter-spacing:0;line-height:16px}.ptcPlusRow{display:flex;align-items:center;gap:12px;min-height:48px;border-top:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1))}.ptcPlusRow:first-child{border-top:0}.ptcPlusMain{flex:1;min-width:0}.ptcPlusLabel{font-size:14px;font-weight:500;line-height:20px}.ptcPlusDetail,.ptcPlusMessage{color:var(--dsw-alias-label-tertiary,#74777d);font-size:12px;line-height:18px;overflow-wrap:anywhere}.ptcPlusInput{box-sizing:border-box;min-width:72px;width:140px;padding:5px 8px;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1));border-radius:6px;background:var(--dsw-alias-bg-layer-1,#fff);color:inherit;font:12px/18px ui-monospace,SFMono-Regular,Consolas,monospace}.ptcPlusCheck{width:18px;height:18px;accent-color:var(--dsw-alias-interactive-primary,#4d6bfe)}
|
|
725
|
+
.ptcPlusFooter{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:8px}.ptcPlusButton{min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1));border-radius:6px;background:transparent;color:inherit;cursor:pointer;font:500 13px/20px inherit;transition:background-color .16s ease,border-color .16s ease}.ptcPlusButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06))}.ptcPlusButton:disabled,.ptcPlusInput:disabled,.ptcPlusCheck:disabled{cursor:not-allowed;opacity:.55}
|
|
726
|
+
.ptcPlusActiveShell{display:inline-flex;align-items:center}.ptcPlusActive{appearance:none;display:inline-flex;height:24px;align-items:center;gap:5px;padding:0 8px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary,#16794f) 32%,transparent);border-radius:6px;background:var(--dsw-alias-state-success-tertiary,#e7f7ef);color:var(--dsw-alias-state-success-primary,#16794f);cursor:help;font:600 12px/18px inherit;white-space:nowrap;transition:background-color .14s ease,border-color .14s ease}.ptcPlusActive:hover,.ptcPlusActive[aria-expanded=true]{border-color:color-mix(in srgb,var(--dsw-alias-state-success-primary,#16794f) 48%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-success-primary,#16794f) 16%,var(--dsw-alias-bg-layer-3,#fff))}.ptcPlusActive:focus-visible{outline:2px solid var(--dsw-alias-state-success-primary,#16794f);outline-offset:2px}.ptcPlusReplPopover{position:fixed;z-index:2147483000;inset:auto;display:none;box-sizing:border-box;margin:0;padding:0;border:0;overflow:visible;background:transparent;color:var(--dsw-alias-label-primary,#18191c)}.ptcPlusReplPopover:popover-open,.ptcPlusReplPopover[data-open=true]{display:block}.ptcPlusReplPopover::backdrop{background:transparent}.ptcPlusReplCard{display:flex;max-height:inherit;overflow:hidden;flex-direction:column;border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary,#16794f) 22%,var(--dsw-alias-border-l2,rgba(0,0,0,.1)));border-top:3px solid var(--dsw-alias-state-success-primary,#16794f);border-radius:8px;background:var(--dsw-alias-bg-layer-3,#fff);box-shadow:0 14px 36px rgba(16,24,40,.2),0 3px 10px rgba(16,24,40,.1);color:var(--dsw-alias-label-primary,#18191c);white-space:normal}.ptcPlusReplHead{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;column-gap:8px;padding:11px 13px 10px;border-bottom:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1));background:color-mix(in srgb,var(--dsw-alias-state-success-primary,#16794f) 7%,var(--dsw-alias-bg-layer-3,#fff))}.ptcPlusReplStatusDot{grid-row:1/3;width:8px;height:8px;border-radius:50%;background:var(--dsw-alias-state-success-primary,#16794f);box-shadow:0 0 0 3px color-mix(in srgb,var(--dsw-alias-state-success-primary,#16794f) 14%,transparent)}.ptcPlusReplTitle,.ptcPlusReplSummary{display:block;min-width:0}.ptcPlusReplTitle{font-size:13px;font-weight:600;line-height:19px}.ptcPlusReplSummary{color:var(--dsw-alias-label-tertiary,#74777d);font-size:11px;line-height:16px}.ptcPlusReplList{min-height:0;margin:0;padding:5px 0;overflow:auto;overscroll-behavior:contain;list-style:none;scrollbar-gutter:stable}.ptcPlusReplBinding{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:4px 10px;padding:7px 12px}.ptcPlusReplBinding:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06))}.ptcPlusReplIdentity{display:flex;min-width:0;align-items:center;gap:7px}.ptcPlusReplName{min-width:0;overflow:hidden;font:12px/18px ui-monospace,SFMono-Regular,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}.ptcPlusReplKind{flex:none;padding:1px 6px;border:1px solid color-mix(in srgb,currentColor 22%,transparent);border-radius:999px;background:color-mix(in srgb,currentColor 10%,transparent);font-size:10px;font-weight:600;line-height:15px}.ptcPlusReplKind[data-kind=variable]{color:var(--dsw-alias-interactive-primary,#315fbd)}.ptcPlusReplKind[data-kind=function]{color:#7651b5}.ptcPlusReplKind[data-kind=class]{color:var(--dsw-alias-state-warning-primary,#946200)}.ptcPlusReplKind[data-kind=import]{color:#14766f}.ptcPlusReplPreview{grid-column:1;min-width:0;overflow:hidden;color:var(--dsw-alias-label-tertiary,#74777d);font:11px/16px ui-monospace,SFMono-Regular,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}.ptcPlusReplInspect{grid-column:2;grid-row:1/3;display:inline-flex;align-items:center;gap:4px;padding:3px 5px;border:0;border-radius:4px;background:transparent;color:var(--dsw-alias-label-secondary,#52565d);cursor:pointer;font:500 11px/17px inherit;white-space:nowrap}.ptcPlusReplInspect:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06));color:var(--dsw-alias-interactive-primary,#4d6bfe)}.ptcPlusReplInspect:focus-visible{outline:2px solid var(--dsw-alias-interactive-primary,#4d6bfe);outline-offset:1px}.ptcPlusReplDefinition{grid-column:1/-1;min-width:0;margin-top:4px;padding:8px;border-left:2px solid var(--dsw-alias-interactive-primary,#4d6bfe);background:var(--dsw-alias-bg-layer-2,rgba(38,49,72,.03))}.ptcPlusReplLocation{display:block;margin-bottom:5px;color:var(--dsw-alias-label-tertiary,#74777d);font-size:10px;line-height:15px}.ptcPlusReplCode{max-height:180px;margin:0;overflow:auto;color:inherit;font:11px/16px ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}.ptcPlusReplEmpty,.ptcPlusReplMore{display:block;color:var(--dsw-alias-label-tertiary,#74777d)}.ptcPlusReplEmpty{padding:18px 13px;font-size:12px;line-height:18px}.ptcPlusReplMore{padding:8px 13px;border-top:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1));background:var(--dsw-alias-bg-layer-2,rgba(38,49,72,.03));font-size:11px;line-height:17px}
|
|
727
|
+
.ptcPlusReplList{max-height:min(52vh,480px)}.ptcPlusReplBinding{grid-template-columns:minmax(0,1fr) 24px;gap:3px 8px;min-height:36px;padding:5px 12px;content-visibility:auto;contain-intrinsic-size:36px;cursor:pointer;transition:background-color .16s ease}.ptcPlusReplBinding:focus-visible{outline:2px solid var(--dsw-alias-interactive-primary,#4d6bfe);outline-offset:-2px}.ptcPlusReplBinding[data-expanded=true]{background:color-mix(in srgb,var(--dsw-alias-interactive-primary,#4d6bfe) 5%,transparent)}.ptcPlusReplName{grid-column:1}.ptcPlusReplName[data-kind=variable]{color:var(--dsw-alias-interactive-primary,#315fbd)}.ptcPlusReplName[data-kind=function]{color:#7651b5}.ptcPlusReplName[data-kind=class]{color:var(--dsw-alias-state-warning-primary,#946200)}.ptcPlusReplName[data-kind=import]{color:#14766f}.ptcPlusReplPreview{grid-column:1}.ptcPlusReplChevron{grid-column:2;grid-row:1/3;display:flex;align-items:center;justify-content:center;color:var(--dsw-alias-label-tertiary,#74777d);transition:transform .2s ease}.ptcPlusReplChevron[data-open=true]{transform:rotate(180deg)}.ptcPlusReplDefinitionWrap{grid-column:1/-1;display:grid;grid-template-rows:0fr;min-width:0;transition:grid-template-rows .24s cubic-bezier(.2,.7,.2,1)}.ptcPlusReplDefinitionWrap[data-open=true]{grid-template-rows:1fr}.ptcPlusReplDefinitionInner{min-height:0;overflow:hidden}
|
|
728
|
+
.ptcPlusTool{display:flex;min-width:0;flex-direction:column}.ptcPlusToolPreview{display:flex;min-width:0;flex:1 1 auto;flex-direction:row;align-items:center;overflow:hidden;margin-left:7px}.ptcPlusToolPreview .ptcPlusFeatures{flex:0 1 auto;flex-wrap:nowrap;overflow:hidden;margin:0 0 0 7px}.ptcPlusToolSummaryLine{box-sizing:border-box;display:flex;min-width:0;min-height:20px;flex:1 1 auto;align-items:center;gap:7px;padding:0;color:inherit;line-height:20px}.ptcPlusToolSummary{box-sizing:border-box;display:flex;min-width:0;min-height:32px;align-items:center;gap:7px;padding:0;color:inherit;line-height:20px}.ptcPlusToolSummary[data-expandable=true]{cursor:pointer}.ptcPlusToolSummary[data-expandable=true]:hover .ptcPlusToolTitle{color:var(--dsw-alias-interactive-primary,#4d6bfe)}.ptcPlusToolSummary:focus-visible{outline:2px solid var(--dsw-alias-interactive-primary,#4d6bfe);outline-offset:2px}.ptcPlusToolLeading{display:flex;width:16px;height:20px;flex:none;align-items:center;justify-content:center;color:var(--dsw-alias-label-tertiary,#74777d)}.ptcPlusToolChevron{transition:transform .16s ease}.ptcPlusToolChevron[data-open=true]{transform:rotate(180deg)}.ptcPlusToolTitle{display:flex;height:20px;flex:none;align-items:center;font-size:13px;font-weight:500;line-height:20px}.ptcPlusToolState{display:flex;height:20px;flex:none;align-items:center;color:var(--dsw-alias-label-tertiary,#74777d);font-size:11px;line-height:20px}.ptcPlusToolSummaryLine[data-state=running] .ptcPlusToolState,.ptcPlusToolSummary[data-state=running] .ptcPlusToolState{color:var(--dsw-alias-interactive-primary,#4d6bfe)}.ptcPlusToolSummaryLine[data-state=error] .ptcPlusToolState,.ptcPlusToolSummary[data-state=error] .ptcPlusToolState{color:var(--dsw-alias-state-danger-primary,#c43d3d)}.ptcPlusToolSummaryLine[data-state=stopped] .ptcPlusToolState,.ptcPlusToolSummary[data-state=stopped] .ptcPlusToolState{color:var(--dsw-alias-state-warning-primary,#a15c00)}.ptcPlusToolSep{width:3px;height:3px;flex:none;border-radius:50%;background:var(--dsw-alias-label-tertiary,#74777d)}.ptcPlusToolDescription{display:flex;min-width:0;min-height:20px;flex:1 1 auto;align-items:center;overflow:hidden;color:var(--dsw-alias-label-secondary,#52565d);font-size:13px;line-height:20px;text-overflow:ellipsis;white-space:nowrap}.ptcPlusToolPreview .ptcPlusFeature{flex:none;max-width:180px;white-space:nowrap}.ptcPlusToolPreview .ptcPlusFeatureDetail{max-width:120px}.ptcPlusToolSummaryLine[data-state=error] .ptcPlusToolDescription,.ptcPlusToolSummary[data-state=error] .ptcPlusToolDescription{color:var(--dsw-alias-state-danger-primary,#c43d3d)}.ptcPlusToolSummaryLine[data-state=stopped] .ptcPlusToolDescription,.ptcPlusToolSummary[data-state=stopped] .ptcPlusToolDescription{color:var(--dsw-alias-state-warning-primary,#a15c00)}
|
|
729
|
+
.ptcPlusFeatures{display:flex;min-width:0;flex-wrap:wrap;gap:3px 14px;margin:0 0 5px 23px}.ptcPlusFeature{display:inline-flex;min-width:0;align-items:center;gap:5px;color:var(--dsw-alias-label-secondary,#52565d);font-size:11px;line-height:17px}.ptcPlusFeature::before{width:4px;height:4px;flex:none;border-radius:50%;background:var(--dsw-alias-interactive-primary,#4d6bfe);content:''}.ptcPlusFeatureName{font-weight:500}.ptcPlusFeatureDetail{min-width:0;overflow:hidden;color:var(--dsw-alias-label-tertiary,#74777d);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}
|
|
730
|
+
.ptcPlusToolBody{margin:4px 0 8px 23px;border-left:2px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1));background:var(--dsw-alias-bg-layer-2,rgba(38,49,72,.03))}.ptcPlusToolSection{display:flex;min-width:0;flex-direction:column;gap:4px;padding:9px 11px}.ptcPlusToolSection+.ptcPlusToolSection{border-top:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1))}.ptcPlusToolSectionLabel{color:var(--dsw-alias-label-tertiary,#74777d);font-size:10px;font-weight:600;line-height:16px;text-transform:uppercase}.ptcPlusToolCode{max-height:320px;margin:0;overflow:auto;color:inherit;font:12px/18px ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}.ptcPlusIoCard{display:flex;flex-direction:column;border:1px solid var(--dsw-alias-border-l1,rgba(0,0,0,.1));border-radius:12px;background:var(--dsw-alias-markdown-code-block,rgba(38,49,72,.06));overflow:hidden}.ptcPlusIoText{max-height:320px;margin:0;padding:12px 16px;overflow:auto;color:var(--dsw-alias-label-secondary,#52565d);font:12px/18px ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}.ptcPlusIoText[data-error]{color:var(--dsw-alias-state-error-primary,#c43d3d)}.ptcPlusInspect{display:inline-flex;align-self:flex-start;align-items:center;gap:4px;margin:4px 0 2px 4px;padding:2px 8px;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1));border-radius:999px;background:var(--dsw-alias-bg-base,#fff);color:var(--dsw-alias-label-secondary,#52565d);cursor:pointer;opacity:0;font-size:11px;line-height:16px;transition:opacity .1s ease;display:inline-flex}.ptcPlusTool:hover .ptcPlusInspect,.ptcPlusInspect:focus-visible{opacity:1}.ptcPlusInspect:hover{background:var(--dsw-alias-interactive-bg-hover-solid,rgba(38,49,72,.06));color:var(--dsw-alias-label-primary,#18191c)}
|
|
731
|
+
@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%}.ptcPlusFeatures,.ptcPlusToolBody{margin-left:0}.ptcPlusToolSummary .ptcPlusToolDescription{white-space:normal;overflow-wrap:anywhere}}
|
|
732
|
+
@media(prefers-reduced-motion:reduce){.ptcPlusHeader,.ptcPlusChevron,.ptcPlusBody,.ptcPlusButton,.ptcPlusActive,.ptcPlusToolChevron,.ptcPlusReplChevron,.ptcPlusReplDefinitionWrap,.ptcPlusInspect{transition:none}}
|
|
733
|
+
/* The summary button owns disclosure; definition content is a separate grid item. */
|
|
734
|
+
.ptcPlusReplBinding{padding:0;cursor:default}.ptcPlusReplBindingTrigger{appearance:none;display:grid;width:100%;grid-column:1/-1;grid-template-columns:minmax(0,1fr) 24px;gap:3px 8px;min-height:36px;padding:5px 12px;border:0;background:transparent;color:inherit;text-align:left;cursor:pointer;font:inherit;transition:background-color .16s ease}.ptcPlusReplBindingTrigger:hover,.ptcPlusReplBindingTrigger[aria-expanded=true]{background:color-mix(in srgb,var(--dsw-alias-interactive-primary,#4d6bfe) 5%,transparent)}.ptcPlusReplBindingTrigger:focus-visible{outline:2px solid var(--dsw-alias-interactive-primary,#4d6bfe);outline-offset:-2px}
|
|
735
|
+
/* High-contrast TypeScript-like token colors adapt to the active text theme. */
|
|
736
|
+
.ptcPlusReplCard .ptcPlusReplName[data-kind=variable]{color:color-mix(in srgb,#005cc5 78%,var(--dsw-alias-label-primary,#18191c))}
|
|
737
|
+
.ptcPlusReplCard .ptcPlusReplName[data-kind=function]{color:color-mix(in srgb,#795e26 78%,var(--dsw-alias-label-primary,#18191c))}
|
|
738
|
+
.ptcPlusReplCard .ptcPlusReplName[data-kind=class]{color:color-mix(in srgb,#267f99 78%,var(--dsw-alias-label-primary,#18191c))}
|
|
739
|
+
.ptcPlusReplCard .ptcPlusReplName[data-kind=import]{color:color-mix(in srgb,#af00db 78%,var(--dsw-alias-label-primary,#18191c))}
|
|
740
|
+
/* Keep the session-header action on the same compact 32px rhythm as DSH chrome. */
|
|
741
|
+
.ptcPlusActiveShell{display:inline-flex;height:28px;align-items:center;justify-content:center;line-height:0;vertical-align:middle}.ptcPlusActive{box-sizing:border-box;height:28px;justify-content:center;gap:6px;padding:0 6px;border:0;background:transparent;font-family:inherit;font-size:13px;font-weight:500;line-height:18px}.ptcPlusActive::before{width:6px;height:6px;flex:none;border-radius:50%;background:currentColor;box-shadow:0 0 0 2px color-mix(in srgb,currentColor 18%,transparent);content:''}.ptcPlusActive:hover,.ptcPlusActive[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06))}.ptcPlusActiveLabel{display:inline-flex;height:18px;align-items:center;line-height:18px}
|
|
185
742
|
`;
|
|
743
|
+
var LOCALE_NS = "settings.ptcPlus";
|
|
744
|
+
var CHROME_COPY = Object.freeze({
|
|
745
|
+
zh: Object.freeze({
|
|
746
|
+
"card.description": "PTC \u6A21\u5F0F\u7684\u4F1A\u8BDD\u7EA7 TypeScript REPL\u3002",
|
|
747
|
+
"status.enabled": "\u5DF2\u542F\u7528",
|
|
748
|
+
"status.disabled": "\u5DF2\u505C\u7528",
|
|
749
|
+
"action.expand": "\u5C55\u5F00 PTC Plus \u8BBE\u7F6E",
|
|
750
|
+
"action.collapse": "\u6536\u8D77 PTC Plus \u8BBE\u7F6E",
|
|
751
|
+
"state.syncing": "\u6B63\u5728\u540C\u6B65\u8BBE\u7F6E...",
|
|
752
|
+
"state.unavailable": "\u5F53\u524D DSH \u5B9E\u4F8B\u672A\u63D0\u4F9B\u8BBE\u7F6E\u670D\u52A1",
|
|
753
|
+
"footer.live": "\u8BBE\u7F6E\u4F1A\u5728\u4FEE\u6539\u540E\u7ACB\u5373\u751F\u6548",
|
|
754
|
+
"footer.readOnly": "\u5F53\u524D\u8BBE\u7F6E\u4E3A\u53EA\u8BFB",
|
|
755
|
+
"status.applied": "\u8BBE\u7F6E\u5DF2\u7ACB\u5373\u751F\u6548",
|
|
756
|
+
"status.conflict": "\u8BBE\u7F6E\u672A\u751F\u6548\uFF0C\u8BF7\u68C0\u67E5\u8BBE\u7F6E\u51B2\u7A81",
|
|
757
|
+
"status.failed": "\u8BBE\u7F6E\u5931\u8D25\uFF1A{error}",
|
|
758
|
+
"indicator.title": "PTC Plus \u5DF2\u542F\u7528\uFF1B\u67E5\u770B\u5F53\u524D\u53EF\u590D\u7528\u7684 REPL \u7ED1\u5B9A",
|
|
759
|
+
"memory.title": "REPL \u53EF\u590D\u7528\u7ED1\u5B9A",
|
|
760
|
+
"memory.count": "{count} \u4E2A\u53EF\u590D\u7528\u7ED1\u5B9A",
|
|
761
|
+
"memory.empty": "\u5F53\u524D\u6CA1\u6709\u53EF\u590D\u7528\u7ED1\u5B9A",
|
|
762
|
+
"memory.unavailable": "\u5F53\u524D\u7ED1\u5B9A\u72B6\u6001\u5C1A\u4E0D\u53EF\u786E\u8BA4",
|
|
763
|
+
"memory.more": "\u53E6\u6709 {count} \u4E2A\u7ED1\u5B9A\u672A\u663E\u793A",
|
|
764
|
+
"memory.kind.variable": "\u53D8\u91CF",
|
|
765
|
+
"memory.kind.function": "\u51FD\u6570",
|
|
766
|
+
"memory.kind.class": "\u7C7B",
|
|
767
|
+
"memory.kind.import": "\u5BFC\u5165",
|
|
768
|
+
"memory.location": "\u7B2C {line} \u884C\uFF0C\u7B2C {column} \u5217",
|
|
769
|
+
"tool.code": "\u6267\u884C",
|
|
770
|
+
"tool.codeEdit": "\u4FEE\u6B63\u6267\u884C",
|
|
771
|
+
"tool.running": "\u6B63\u5728\u8FD0\u884C",
|
|
772
|
+
"tool.completed": "\u6267\u884C\u5B8C\u6210",
|
|
773
|
+
"tool.failed": "\u6267\u884C\u5931\u8D25",
|
|
774
|
+
"tool.stopped": "\u6267\u884C\u5DF2\u4E2D\u65AD",
|
|
775
|
+
"tool.source": "\u6E90\u7801",
|
|
776
|
+
"tool.result": "\u7ED3\u679C",
|
|
777
|
+
"tool.copy": "\u590D\u5236\u4EE3\u7801",
|
|
778
|
+
"tool.copied": "\u5DF2\u590D\u5236",
|
|
779
|
+
"tool.inspect": "\u68C0\u67E5\u8C03\u7528",
|
|
780
|
+
"feature.safeEdit": "\u5B89\u5168\u7F16\u8F91\u6267\u884C",
|
|
781
|
+
"feature.codeRun": "\u9694\u79BB\u6267\u884C code.run",
|
|
782
|
+
"feature.stateSaved": "\u4FDD\u5B58 REPL \u72B6\u6001",
|
|
783
|
+
"feature.stateRestored": "\u6062\u590D REPL \u72B6\u6001",
|
|
784
|
+
"feature.stateDeleted": "\u5220\u9664 REPL \u72B6\u6001"
|
|
785
|
+
}),
|
|
786
|
+
en: Object.freeze({
|
|
787
|
+
"card.description": "The session-bound TypeScript REPL for PTC mode.",
|
|
788
|
+
"status.enabled": "Enabled",
|
|
789
|
+
"status.disabled": "Disabled",
|
|
790
|
+
"action.expand": "Expand PTC Plus settings",
|
|
791
|
+
"action.collapse": "Collapse PTC Plus settings",
|
|
792
|
+
"state.syncing": "Syncing settings...",
|
|
793
|
+
"state.unavailable": "This DSH instance does not provide a settings service",
|
|
794
|
+
"footer.live": "Changes take effect immediately.",
|
|
795
|
+
"footer.readOnly": "These settings are read-only.",
|
|
796
|
+
"status.applied": "Setting applied immediately.",
|
|
797
|
+
"status.conflict": "The setting did not take effect; check for conflicting settings.",
|
|
798
|
+
"status.failed": "Could not save: {error}",
|
|
799
|
+
"indicator.title": "PTC Plus is active; view reusable REPL bindings",
|
|
800
|
+
"memory.title": "Reusable REPL bindings",
|
|
801
|
+
"memory.count": "{count} reusable bindings",
|
|
802
|
+
"memory.empty": "No reusable bindings",
|
|
803
|
+
"memory.unavailable": "Current binding state cannot be confirmed",
|
|
804
|
+
"memory.more": "{count} more bindings not shown",
|
|
805
|
+
"memory.kind.variable": "Variable",
|
|
806
|
+
"memory.kind.function": "Function",
|
|
807
|
+
"memory.kind.class": "Class",
|
|
808
|
+
"memory.kind.import": "Import",
|
|
809
|
+
"memory.location": "Line {line}, column {column}",
|
|
810
|
+
"tool.code": "Code",
|
|
811
|
+
"tool.codeEdit": "Code edit",
|
|
812
|
+
"tool.running": "Running",
|
|
813
|
+
"tool.completed": "Completed",
|
|
814
|
+
"tool.failed": "Failed",
|
|
815
|
+
"tool.stopped": "Stopped",
|
|
816
|
+
"tool.source": "Source",
|
|
817
|
+
"tool.result": "Result",
|
|
818
|
+
"tool.inspect": "Inspect call",
|
|
819
|
+
"feature.safeEdit": "Safe edit execution",
|
|
820
|
+
"feature.codeRun": "Isolated code.run execution",
|
|
821
|
+
"feature.stateSaved": "Saved REPL state",
|
|
822
|
+
"feature.stateRestored": "Restored REPL state",
|
|
823
|
+
"feature.stateDeleted": "Deleted REPL state",
|
|
824
|
+
"tool.copy": "Copy code",
|
|
825
|
+
"tool.copied": "Copied"
|
|
826
|
+
})
|
|
827
|
+
});
|
|
828
|
+
function fieldCopy(field, locale) {
|
|
829
|
+
const copy = { [`${field.key}.label`]: locale === "en" ? field.labelEn : field.label };
|
|
830
|
+
const description = locale === "en" ? field.descriptionEn : field.description;
|
|
831
|
+
if (description !== "") copy[`${field.key}.description`] = description;
|
|
832
|
+
return copy;
|
|
833
|
+
}
|
|
834
|
+
var SETTINGS_COPY = Object.freeze(Object.fromEntries(
|
|
835
|
+
["zh", "en"].map((locale) => [locale, Object.freeze({
|
|
836
|
+
...CHROME_COPY[locale],
|
|
837
|
+
...Object.assign({}, ...CONFIG_GROUPS.map((group) => ({
|
|
838
|
+
[`group.${group.key}`]: locale === "en" ? group.labelEn : group.label
|
|
839
|
+
}))),
|
|
840
|
+
...Object.assign({}, ...CONFIG_FIELDS.map((field) => fieldCopy(field, locale)))
|
|
841
|
+
})])
|
|
842
|
+
));
|
|
843
|
+
function sessionUsesPtcPreset(session) {
|
|
844
|
+
const preset = session?.projectionValues?.agentPreset ?? session?.agentPreset;
|
|
845
|
+
return preset === "ptc" || preset === "code";
|
|
846
|
+
}
|
|
186
847
|
window.__ModuleLoader__.load({
|
|
187
848
|
// Replaced by the bundle entry with the package name from package.json.
|
|
188
849
|
id: "dsh-ptc-plus",
|
|
189
850
|
factory: (require2) => {
|
|
190
851
|
const React = require2("react");
|
|
191
852
|
const {
|
|
853
|
+
CodeBlock,
|
|
854
|
+
DisclosureRow,
|
|
192
855
|
IconCheckOutline14,
|
|
193
856
|
IconChevronDownOutline14,
|
|
194
|
-
|
|
857
|
+
IconInspectOutline12
|
|
195
858
|
} = require2("@deepseek-ai/dsh-client-ui-primitives");
|
|
196
859
|
const module = { exports: {} };
|
|
197
860
|
const h = React.createElement;
|
|
@@ -204,7 +867,7 @@
|
|
|
204
867
|
document.head.append(style);
|
|
205
868
|
return () => style.remove();
|
|
206
869
|
}
|
|
207
|
-
function fieldInput(field, value, disabled, onChange) {
|
|
870
|
+
function fieldInput(field, value, disabled, onChange, label) {
|
|
208
871
|
if (field.type === "boolean") {
|
|
209
872
|
return h("input", {
|
|
210
873
|
type: "checkbox",
|
|
@@ -212,7 +875,7 @@
|
|
|
212
875
|
className: "ptcPlusCheck",
|
|
213
876
|
checked: value === true,
|
|
214
877
|
disabled,
|
|
215
|
-
"aria-label":
|
|
878
|
+
"aria-label": label,
|
|
216
879
|
onChange: (event) => onChange(field, event.target.checked)
|
|
217
880
|
});
|
|
218
881
|
}
|
|
@@ -224,7 +887,7 @@
|
|
|
224
887
|
max: field.max,
|
|
225
888
|
step: 1,
|
|
226
889
|
disabled,
|
|
227
|
-
"aria-label":
|
|
890
|
+
"aria-label": label,
|
|
228
891
|
onChange: (event) => {
|
|
229
892
|
const input = event.target.value;
|
|
230
893
|
const parsed = input === "" ? "" : Number(input);
|
|
@@ -234,10 +897,11 @@
|
|
|
234
897
|
}
|
|
235
898
|
function apply(ctx) {
|
|
236
899
|
const preferenceScope = ctx.settingsScope.bind({ namespace: SETTINGS_NAMESPACE });
|
|
900
|
+
ctx.effect(() => ctx.locale.register(LOCALE_NS, SETTINGS_COPY), "ptc-plus: settings dictionaries");
|
|
237
901
|
ctx.effect(installStyles, "ptc-plus: client styles");
|
|
238
|
-
function PTCPlusSettingsCard() {
|
|
902
|
+
function PTCPlusSettingsCard({ t }) {
|
|
239
903
|
const [open, setOpen] = React.useState(false);
|
|
240
|
-
const [status, setStatus] = React.useState(
|
|
904
|
+
const [status, setStatus] = React.useState(null);
|
|
241
905
|
const [pending, setPending] = React.useState(() => /* @__PURE__ */ new Set());
|
|
242
906
|
const writeTail = React.useRef(Promise.resolve());
|
|
243
907
|
const subscribe = React.useCallback((listener) => preferenceScope.subscribe(listener), []);
|
|
@@ -254,17 +918,20 @@
|
|
|
254
918
|
if (field.key !== "enabled" && before.value?.enabled !== true) return;
|
|
255
919
|
if (before.value?.[field.key] === nextValue) return;
|
|
256
920
|
setPending((current) => new Set(current).add(field.key));
|
|
257
|
-
setStatus(
|
|
921
|
+
setStatus(null);
|
|
258
922
|
try {
|
|
259
923
|
await preferenceScope.set(field.key, nextValue);
|
|
260
924
|
const after = preferenceScope.getSnapshot();
|
|
261
925
|
if (after.status !== "ready" || after.value?.[field.key] !== nextValue) {
|
|
262
|
-
setStatus("
|
|
926
|
+
setStatus({ key: "status.conflict" });
|
|
263
927
|
} else {
|
|
264
|
-
setStatus("
|
|
928
|
+
setStatus({ key: "status.applied" });
|
|
265
929
|
}
|
|
266
930
|
} catch (error) {
|
|
267
|
-
setStatus(
|
|
931
|
+
setStatus({
|
|
932
|
+
key: "status.failed",
|
|
933
|
+
params: { error: error instanceof Error ? error.message : String(error) }
|
|
934
|
+
});
|
|
268
935
|
} finally {
|
|
269
936
|
setPending((current) => {
|
|
270
937
|
const next = new Set(current);
|
|
@@ -277,6 +944,33 @@
|
|
|
277
944
|
});
|
|
278
945
|
};
|
|
279
946
|
const fieldDisabled = (field) => unavailable || pending.has(field.key) || field.key !== "enabled" && !enabled;
|
|
947
|
+
const settingGroups = CONFIG_GROUPS.map((group) => h(
|
|
948
|
+
"section",
|
|
949
|
+
{
|
|
950
|
+
key: group.key,
|
|
951
|
+
className: "ptcPlusGroup",
|
|
952
|
+
"aria-labelledby": `ptc-plus-settings-group-${group.key}`
|
|
953
|
+
},
|
|
954
|
+
h("h3", {
|
|
955
|
+
id: `ptc-plus-settings-group-${group.key}`,
|
|
956
|
+
className: "ptcPlusGroupTitle"
|
|
957
|
+
}, t(`group.${group.key}`)),
|
|
958
|
+
...group.fields.map((key) => {
|
|
959
|
+
const field = CONFIG_FIELDS.find((candidate) => candidate.key === key);
|
|
960
|
+
if (field === void 0) return null;
|
|
961
|
+
return h(
|
|
962
|
+
"div",
|
|
963
|
+
{ key: field.key, className: "ptcPlusRow" },
|
|
964
|
+
h(
|
|
965
|
+
"div",
|
|
966
|
+
{ className: "ptcPlusMain" },
|
|
967
|
+
h("div", { className: "ptcPlusLabel" }, t(`${field.key}.label`)),
|
|
968
|
+
field.description === "" ? null : h("div", { className: "ptcPlusDetail" }, t(`${field.key}.description`))
|
|
969
|
+
),
|
|
970
|
+
fieldInput(field, value[field.key], fieldDisabled(field), persist, t(`${field.key}.label`))
|
|
971
|
+
);
|
|
972
|
+
})
|
|
973
|
+
));
|
|
280
974
|
return h(
|
|
281
975
|
"li",
|
|
282
976
|
{ className: "ptcPlusCard" },
|
|
@@ -286,18 +980,17 @@
|
|
|
286
980
|
type: "button",
|
|
287
981
|
className: "ptcPlusHeader",
|
|
288
982
|
"aria-expanded": open,
|
|
289
|
-
"aria-label": open ? "
|
|
983
|
+
"aria-label": t(open ? "action.collapse" : "action.expand"),
|
|
290
984
|
"aria-controls": "ptc-plus-settings-body",
|
|
291
985
|
onClick: () => setOpen((current) => !current)
|
|
292
986
|
},
|
|
293
|
-
h(IconSettingsOutline16, { size: 16 }),
|
|
294
987
|
h(
|
|
295
988
|
"span",
|
|
296
989
|
{ className: "ptcPlusHeadText" },
|
|
297
990
|
h("span", { className: "ptcPlusName" }, "PTC Plus"),
|
|
298
|
-
h("span", { className: "ptcPlusDescription" }, "
|
|
991
|
+
h("span", { className: "ptcPlusDescription" }, t("card.description"))
|
|
299
992
|
),
|
|
300
|
-
h("span", { className: "ptcPlusStatus", "data-enabled": enabled }, enabled ? "
|
|
993
|
+
h("span", { className: "ptcPlusStatus", "data-enabled": enabled }, t(enabled ? "status.enabled" : "status.disabled")),
|
|
301
994
|
h("span", { className: "ptcPlusChevron", "data-open": open, "aria-hidden": true }, h(IconChevronDownOutline14, { size: 14 }))
|
|
302
995
|
),
|
|
303
996
|
h(
|
|
@@ -306,22 +999,12 @@
|
|
|
306
999
|
h("div", { className: "ptcPlusBodyInner" }, h(
|
|
307
1000
|
"div",
|
|
308
1001
|
{ className: "ptcPlusFields" },
|
|
309
|
-
snapshot.status === "loading" ? h("p", { className: "ptcPlusMessage" }, "
|
|
310
|
-
...
|
|
311
|
-
"div",
|
|
312
|
-
{ key: field.key, className: "ptcPlusRow" },
|
|
313
|
-
h(
|
|
314
|
-
"div",
|
|
315
|
-
{ className: "ptcPlusMain" },
|
|
316
|
-
h("div", { className: "ptcPlusLabel" }, field.label),
|
|
317
|
-
field.description === "" ? null : h("div", { className: "ptcPlusDetail" }, field.description)
|
|
318
|
-
),
|
|
319
|
-
fieldInput(field, value[field.key], fieldDisabled(field), persist)
|
|
320
|
-
)),
|
|
1002
|
+
snapshot.status === "loading" ? h("p", { className: "ptcPlusMessage" }, t("state.syncing")) : snapshot.status === "unavailable" ? h("p", { className: "ptcPlusMessage" }, t("state.unavailable")) : [
|
|
1003
|
+
...settingGroups,
|
|
321
1004
|
h(
|
|
322
1005
|
"div",
|
|
323
1006
|
{ key: "footer", className: "ptcPlusFooter" },
|
|
324
|
-
h("span", { className: "ptcPlusMessage", role: "status" }, status
|
|
1007
|
+
h("span", { className: "ptcPlusMessage", role: "status" }, status === null ? t(snapshot.writable ? "footer.live" : "footer.readOnly") : t(status.key, status.params))
|
|
325
1008
|
)
|
|
326
1009
|
]
|
|
327
1010
|
))
|
|
@@ -330,36 +1013,436 @@
|
|
|
330
1013
|
}
|
|
331
1014
|
ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
|
|
332
1015
|
name: "settings.plugin.item",
|
|
333
|
-
key: SETTINGS_NAMESPACE
|
|
1016
|
+
key: SETTINGS_NAMESPACE,
|
|
1017
|
+
locale: LOCALE_NS
|
|
334
1018
|
}, PTCPlusSettingsCard));
|
|
1019
|
+
function PTCPlusToolRow({ toolName, block, inspect, t }) {
|
|
1020
|
+
const [open, setOpen] = React.useState(false);
|
|
1021
|
+
const view = derivePtcToolView(block, toolName);
|
|
1022
|
+
const expandable = view.code !== "" || view.output !== "" || typeof inspect === "function";
|
|
1023
|
+
const stateKey = {
|
|
1024
|
+
running: "tool.running",
|
|
1025
|
+
ok: "tool.completed",
|
|
1026
|
+
error: "tool.failed",
|
|
1027
|
+
stopped: "tool.stopped"
|
|
1028
|
+
}[view.state];
|
|
1029
|
+
const outputSummary = view.state === "error" && view.output !== "" ? view.output.split(/\r?\n/, 1)[0] : "";
|
|
1030
|
+
const summary = outputSummary || view.description;
|
|
1031
|
+
const stateText = view.state === "ok" ? null : t(stateKey);
|
|
1032
|
+
const toggle = () => {
|
|
1033
|
+
if (expandable) setOpen((current) => !current);
|
|
1034
|
+
};
|
|
1035
|
+
const summaryText = summary === "" ? null : summary;
|
|
1036
|
+
const summaryLine = stateText === null && summaryText === null ? null : h(
|
|
1037
|
+
"div",
|
|
1038
|
+
{ className: "ptcPlusToolSummaryLine", "data-state": view.state, role: "status" },
|
|
1039
|
+
stateText === null ? null : h("span", { className: "ptcPlusToolState" }, stateText),
|
|
1040
|
+
summaryText === null ? null : h("span", { className: "ptcPlusToolSep", "aria-hidden": true }),
|
|
1041
|
+
summaryText === null ? null : h("span", { className: "ptcPlusToolDescription" }, summaryText)
|
|
1042
|
+
);
|
|
1043
|
+
const body = !open ? null : h(
|
|
1044
|
+
"div",
|
|
1045
|
+
{ className: "ptcPlusToolBody" },
|
|
1046
|
+
view.code === "" ? null : h(
|
|
1047
|
+
"div",
|
|
1048
|
+
{ className: "ptcPlusToolSection" },
|
|
1049
|
+
h("span", { className: "ptcPlusToolSectionLabel" }, t("tool.source")),
|
|
1050
|
+
typeof CodeBlock === "function" ? h(CodeBlock, {
|
|
1051
|
+
code: view.code,
|
|
1052
|
+
lang: "typescript",
|
|
1053
|
+
className: "ptcPlusToolCode",
|
|
1054
|
+
copyLabel: t("tool.copy"),
|
|
1055
|
+
copiedLabel: t("tool.copied")
|
|
1056
|
+
}) : h("pre", { className: "ptcPlusToolCode" }, view.code)
|
|
1057
|
+
),
|
|
1058
|
+
view.output === "" ? null : h(
|
|
1059
|
+
"div",
|
|
1060
|
+
{ className: "ptcPlusToolSection" },
|
|
1061
|
+
h("span", { className: "ptcPlusToolSectionLabel" }, t("tool.result")),
|
|
1062
|
+
h(
|
|
1063
|
+
"div",
|
|
1064
|
+
{ className: "ptcPlusIoCard" },
|
|
1065
|
+
h("pre", {
|
|
1066
|
+
className: "ptcPlusIoText",
|
|
1067
|
+
"data-error": view.state === "error" || void 0
|
|
1068
|
+
}, view.output)
|
|
1069
|
+
)
|
|
1070
|
+
),
|
|
1071
|
+
typeof inspect !== "function" ? null : h("button", {
|
|
1072
|
+
type: "button",
|
|
1073
|
+
className: "ptcPlusInspect",
|
|
1074
|
+
onClick: inspect
|
|
1075
|
+
}, h(IconInspectOutline12, { "aria-hidden": true }), t("tool.inspect"))
|
|
1076
|
+
);
|
|
1077
|
+
const features = view.features.length === 0 ? null : h(
|
|
1078
|
+
"div",
|
|
1079
|
+
{ className: "ptcPlusFeatures" },
|
|
1080
|
+
view.features.map((feature) => h(
|
|
1081
|
+
"span",
|
|
1082
|
+
{
|
|
1083
|
+
key: `${feature.key}:${feature.detail}`,
|
|
1084
|
+
className: "ptcPlusFeature"
|
|
1085
|
+
},
|
|
1086
|
+
h("span", { className: "ptcPlusFeatureName" }, t(feature.key)),
|
|
1087
|
+
feature.detail === "" ? null : h("span", { className: "ptcPlusFeatureDetail", title: feature.detail }, feature.detail)
|
|
1088
|
+
))
|
|
1089
|
+
);
|
|
1090
|
+
const collapsedContent = h("div", { className: "ptcPlusToolPreview" }, summaryLine, features);
|
|
1091
|
+
if (typeof DisclosureRow === "function") {
|
|
1092
|
+
return h(
|
|
1093
|
+
"div",
|
|
1094
|
+
{ className: "ptcPlusTool" },
|
|
1095
|
+
h(DisclosureRow, {
|
|
1096
|
+
icon: expandable ? h(IconChevronDownOutline14, { size: 14 }) : h(IconCheckOutline14, { size: 14 }),
|
|
1097
|
+
title: t(toolName === "edit_run_code" ? "tool.codeEdit" : "tool.code"),
|
|
1098
|
+
open,
|
|
1099
|
+
expandable,
|
|
1100
|
+
onToggle: toggle,
|
|
1101
|
+
expandOnRowClick: true,
|
|
1102
|
+
previewChevron: false,
|
|
1103
|
+
keepContentWhenOpen: true,
|
|
1104
|
+
collapsedContent,
|
|
1105
|
+
children: body
|
|
1106
|
+
})
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
return h(
|
|
1110
|
+
"div",
|
|
1111
|
+
{ className: "ptcPlusTool" },
|
|
1112
|
+
h(
|
|
1113
|
+
"div",
|
|
1114
|
+
{
|
|
1115
|
+
className: "ptcPlusToolSummary",
|
|
1116
|
+
"data-state": view.state,
|
|
1117
|
+
"data-expandable": expandable || void 0,
|
|
1118
|
+
role: expandable ? "button" : void 0,
|
|
1119
|
+
tabIndex: expandable ? 0 : void 0,
|
|
1120
|
+
"aria-expanded": expandable ? open : void 0,
|
|
1121
|
+
onClick: expandable ? toggle : void 0,
|
|
1122
|
+
onKeyDown: expandable ? (event) => {
|
|
1123
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
1124
|
+
event.preventDefault();
|
|
1125
|
+
toggle();
|
|
1126
|
+
} : void 0
|
|
1127
|
+
},
|
|
1128
|
+
h("span", { className: "ptcPlusToolLeading", "aria-hidden": true }, expandable ? h(IconChevronDownOutline14, { size: 14, className: "ptcPlusToolChevron", "data-open": open }) : h(IconCheckOutline14, { size: 14 })),
|
|
1129
|
+
h("span", { className: "ptcPlusToolTitle" }, t(
|
|
1130
|
+
toolName === "edit_run_code" ? "tool.codeEdit" : "tool.code"
|
|
1131
|
+
)),
|
|
1132
|
+
view.state === "ok" ? null : h("span", { className: "ptcPlusToolState", role: "status" }, t(stateKey)),
|
|
1133
|
+
h("span", { className: "ptcPlusToolSep", "aria-hidden": true }),
|
|
1134
|
+
h("span", { className: "ptcPlusToolDescription" }, summary)
|
|
1135
|
+
),
|
|
1136
|
+
features,
|
|
1137
|
+
body
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
ctx.slots.inject("tool.call.toolview", () => {
|
|
1141
|
+
let releaseRows;
|
|
1142
|
+
const release = () => {
|
|
1143
|
+
releaseRows?.();
|
|
1144
|
+
releaseRows = void 0;
|
|
1145
|
+
};
|
|
1146
|
+
const sync = () => {
|
|
1147
|
+
const snapshot = preferenceScope.getSnapshot();
|
|
1148
|
+
const enabled = snapshot.status === "ready" && snapshot.value?.enabled === true && snapshot.value?.enhancedToolView !== false;
|
|
1149
|
+
if (enabled === (releaseRows !== void 0)) return;
|
|
1150
|
+
release();
|
|
1151
|
+
if (!enabled) return;
|
|
1152
|
+
const disposers = [];
|
|
1153
|
+
try {
|
|
1154
|
+
disposers.push(ctx.slots.register({
|
|
1155
|
+
name: "tool.call.toolview",
|
|
1156
|
+
key: "run_code",
|
|
1157
|
+
locale: LOCALE_NS
|
|
1158
|
+
}, PTCPlusToolRow));
|
|
1159
|
+
disposers.push(ctx.slots.register({
|
|
1160
|
+
name: "tool.call.toolview",
|
|
1161
|
+
key: "edit_run_code",
|
|
1162
|
+
locale: LOCALE_NS
|
|
1163
|
+
}, PTCPlusToolRow));
|
|
1164
|
+
} catch (error) {
|
|
1165
|
+
disposers.reverse().forEach((dispose) => dispose());
|
|
1166
|
+
throw error;
|
|
1167
|
+
}
|
|
1168
|
+
releaseRows = () => disposers.reverse().forEach((dispose) => dispose());
|
|
1169
|
+
};
|
|
1170
|
+
sync();
|
|
1171
|
+
const unsubscribe = preferenceScope.subscribe(sync);
|
|
1172
|
+
return () => {
|
|
1173
|
+
unsubscribe();
|
|
1174
|
+
release();
|
|
1175
|
+
};
|
|
1176
|
+
});
|
|
335
1177
|
ctx.inject(["slots", "sessions"], (scope) => {
|
|
336
|
-
function
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
()
|
|
340
|
-
|
|
1178
|
+
function replPopoverIsOpen(popover) {
|
|
1179
|
+
if (popover?.dataset?.open === "true") return true;
|
|
1180
|
+
try {
|
|
1181
|
+
return popover?.matches?.(":popover-open") === true;
|
|
1182
|
+
} catch {
|
|
1183
|
+
return false;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
function placeReplPopover(trigger, popover) {
|
|
1187
|
+
if (trigger === null || popover === null) return;
|
|
1188
|
+
const margin = 12;
|
|
1189
|
+
const gap = 8;
|
|
1190
|
+
const viewportWidth = document.documentElement.clientWidth || window.innerWidth;
|
|
1191
|
+
const viewportHeight = document.documentElement.clientHeight || window.innerHeight;
|
|
1192
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
1193
|
+
const width = Math.min(344, Math.max(0, viewportWidth - margin * 2));
|
|
1194
|
+
const left = Math.min(
|
|
1195
|
+
Math.max(margin, triggerRect.right - width),
|
|
1196
|
+
Math.max(margin, viewportWidth - width - margin)
|
|
341
1197
|
);
|
|
1198
|
+
const below = Math.max(0, viewportHeight - triggerRect.bottom - gap - margin);
|
|
1199
|
+
const above = Math.max(0, triggerRect.top - gap - margin);
|
|
1200
|
+
const opensAbove = below < 260 && above > below;
|
|
1201
|
+
const availableHeight = Math.max(80, opensAbove ? above : below);
|
|
1202
|
+
popover.style.width = `${width}px`;
|
|
1203
|
+
popover.style.maxHeight = `${availableHeight}px`;
|
|
1204
|
+
popover.style.left = `${left}px`;
|
|
1205
|
+
popover.style.top = opensAbove ? `${Math.max(margin, triggerRect.top - gap - Math.min(popover.offsetHeight, availableHeight))}px` : `${Math.min(viewportHeight - margin, triggerRect.bottom + gap)}px`;
|
|
1206
|
+
}
|
|
1207
|
+
function ReplMemoryCard({ memory, t, id, titleId, popoverRef, onEnter, onLeave }) {
|
|
1208
|
+
const [expandedBinding, setExpandedBinding] = React.useState(null);
|
|
1209
|
+
return h(
|
|
1210
|
+
"div",
|
|
1211
|
+
{
|
|
1212
|
+
className: "ptcPlusReplPopover",
|
|
1213
|
+
id,
|
|
1214
|
+
ref: popoverRef,
|
|
1215
|
+
popover: "auto",
|
|
1216
|
+
role: "dialog",
|
|
1217
|
+
"aria-labelledby": titleId,
|
|
1218
|
+
onPointerEnter: onEnter,
|
|
1219
|
+
onPointerLeave: onLeave
|
|
1220
|
+
},
|
|
1221
|
+
h(
|
|
1222
|
+
"div",
|
|
1223
|
+
{ className: "ptcPlusReplCard" },
|
|
1224
|
+
h(
|
|
1225
|
+
"div",
|
|
1226
|
+
{ className: "ptcPlusReplHead" },
|
|
1227
|
+
h("span", { className: "ptcPlusReplStatusDot", "aria-hidden": true }),
|
|
1228
|
+
h("span", { className: "ptcPlusReplTitle", id: titleId }, t("memory.title")),
|
|
1229
|
+
memory.available ? h("span", { className: "ptcPlusReplSummary" }, t("memory.count", { count: memory.total })) : null
|
|
1230
|
+
),
|
|
1231
|
+
!memory.available ? h("span", { className: "ptcPlusReplEmpty" }, t("memory.unavailable")) : memory.entries.length === 0 ? h("span", { className: "ptcPlusReplEmpty" }, t("memory.empty")) : h("ul", { className: "ptcPlusReplList" }, memory.entries.map((binding, index) => {
|
|
1232
|
+
const expanded = expandedBinding === binding.name;
|
|
1233
|
+
const preview = binding.definition.source.replace(/\s+/g, " ").trim();
|
|
1234
|
+
const definitionId = `${id}-binding-${index}`;
|
|
1235
|
+
const toggle = () => setExpandedBinding((current) => current === binding.name ? null : binding.name);
|
|
1236
|
+
return h(
|
|
1237
|
+
"li",
|
|
1238
|
+
{
|
|
1239
|
+
className: "ptcPlusReplBinding",
|
|
1240
|
+
key: binding.name,
|
|
1241
|
+
"data-expanded": expanded
|
|
1242
|
+
},
|
|
1243
|
+
h(
|
|
1244
|
+
"button",
|
|
1245
|
+
{
|
|
1246
|
+
className: "ptcPlusReplBindingTrigger",
|
|
1247
|
+
type: "button",
|
|
1248
|
+
"aria-expanded": expanded,
|
|
1249
|
+
"aria-controls": expanded ? definitionId : void 0,
|
|
1250
|
+
onClick: toggle
|
|
1251
|
+
},
|
|
1252
|
+
h("span", {
|
|
1253
|
+
className: "ptcPlusReplName",
|
|
1254
|
+
"data-kind": binding.kind,
|
|
1255
|
+
title: `${binding.name} - ${t(`memory.kind.${binding.kind}`)}`
|
|
1256
|
+
}, binding.name),
|
|
1257
|
+
h("span", { className: "ptcPlusReplPreview", title: preview }, preview),
|
|
1258
|
+
h("span", {
|
|
1259
|
+
className: "ptcPlusReplChevron",
|
|
1260
|
+
"data-open": expanded,
|
|
1261
|
+
"aria-hidden": true
|
|
1262
|
+
}, h(IconChevronDownOutline14, { size: 14 }))
|
|
1263
|
+
),
|
|
1264
|
+
expanded ? h("div", {
|
|
1265
|
+
className: "ptcPlusReplDefinitionWrap",
|
|
1266
|
+
"data-open": true,
|
|
1267
|
+
id: definitionId,
|
|
1268
|
+
role: "region",
|
|
1269
|
+
"aria-label": binding.name
|
|
1270
|
+
}, h(
|
|
1271
|
+
"div",
|
|
1272
|
+
{ className: "ptcPlusReplDefinitionInner" },
|
|
1273
|
+
h(
|
|
1274
|
+
"div",
|
|
1275
|
+
{ className: "ptcPlusReplDefinition" },
|
|
1276
|
+
h("span", { className: "ptcPlusReplLocation" }, t("memory.location", {
|
|
1277
|
+
line: binding.definition.line,
|
|
1278
|
+
column: binding.definition.column
|
|
1279
|
+
})),
|
|
1280
|
+
typeof CodeBlock === "function" ? h(CodeBlock, {
|
|
1281
|
+
code: binding.definition.source,
|
|
1282
|
+
lang: "typescript",
|
|
1283
|
+
className: "ptcPlusReplCode",
|
|
1284
|
+
copyLabel: t("tool.copy"),
|
|
1285
|
+
copiedLabel: t("tool.copied")
|
|
1286
|
+
}) : h("pre", { className: "ptcPlusReplCode" }, binding.definition.source)
|
|
1287
|
+
)
|
|
1288
|
+
)) : null
|
|
1289
|
+
);
|
|
1290
|
+
})),
|
|
1291
|
+
memory.omitted === 0 ? null : h("span", { className: "ptcPlusReplMore" }, t("memory.more", { count: memory.omitted }))
|
|
1292
|
+
)
|
|
1293
|
+
);
|
|
1294
|
+
}
|
|
1295
|
+
function PTCPlusSessionIndicator({ sessionId, t, useSession, useProjection, useSessions }) {
|
|
1296
|
+
let conversation;
|
|
1297
|
+
try {
|
|
1298
|
+
conversation = typeof useSession === "function" ? useSession((snapshot) => snapshot) : void 0;
|
|
1299
|
+
} catch {
|
|
1300
|
+
conversation = void 0;
|
|
1301
|
+
}
|
|
1302
|
+
let projectionMemory;
|
|
1303
|
+
try {
|
|
1304
|
+
projectionMemory = typeof useProjection === "function" ? useProjection("ptcPlusRepl") : void 0;
|
|
1305
|
+
} catch {
|
|
1306
|
+
projectionMemory = void 0;
|
|
1307
|
+
}
|
|
1308
|
+
let sessions;
|
|
1309
|
+
try {
|
|
1310
|
+
sessions = typeof useSessions === "function" ? useSessions((snapshot) => snapshot) : React.useSyncExternalStore(
|
|
1311
|
+
(listener) => scope.sessions?.list?.subscribe?.(listener) ?? (() => {
|
|
1312
|
+
}),
|
|
1313
|
+
() => scope.sessions?.list?.getSnapshot?.() ?? {},
|
|
1314
|
+
() => scope.sessions?.list?.getSnapshot?.() ?? {}
|
|
1315
|
+
);
|
|
1316
|
+
} catch {
|
|
1317
|
+
sessions = {};
|
|
1318
|
+
}
|
|
342
1319
|
const settings = React.useSyncExternalStore(
|
|
343
1320
|
(listener) => preferenceScope.subscribe(listener),
|
|
344
1321
|
() => preferenceScope.getSnapshot(),
|
|
345
1322
|
() => preferenceScope.getSnapshot()
|
|
346
1323
|
);
|
|
347
|
-
|
|
1324
|
+
const triggerRef = React.useRef(null);
|
|
1325
|
+
const popoverRef = React.useRef(null);
|
|
1326
|
+
const closeTimer = React.useRef(void 0);
|
|
1327
|
+
const [expanded, setExpanded] = React.useState(false);
|
|
1328
|
+
const positionPopover = React.useCallback(() => {
|
|
1329
|
+
if (!replPopoverIsOpen(popoverRef.current)) return;
|
|
1330
|
+
placeReplPopover(triggerRef.current, popoverRef.current);
|
|
1331
|
+
}, []);
|
|
1332
|
+
const showPopover = React.useCallback(() => {
|
|
1333
|
+
if (closeTimer.current !== void 0) clearTimeout(closeTimer.current);
|
|
1334
|
+
const popover = popoverRef.current;
|
|
1335
|
+
if (popover === null) return;
|
|
1336
|
+
popover.style.visibility = "hidden";
|
|
1337
|
+
if (!replPopoverIsOpen(popover)) {
|
|
1338
|
+
if (typeof popover.showPopover === "function") {
|
|
1339
|
+
try {
|
|
1340
|
+
popover.showPopover();
|
|
1341
|
+
} catch {
|
|
1342
|
+
popover.dataset.open = "true";
|
|
1343
|
+
}
|
|
1344
|
+
} else {
|
|
1345
|
+
popover.dataset.open = "true";
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
placeReplPopover(triggerRef.current, popover);
|
|
1349
|
+
popover.style.visibility = "visible";
|
|
1350
|
+
setExpanded(true);
|
|
1351
|
+
}, []);
|
|
1352
|
+
const hidePopover = React.useCallback(() => {
|
|
1353
|
+
const popover = popoverRef.current;
|
|
1354
|
+
if (popover === null) return;
|
|
1355
|
+
if (popover.dataset.open === "true") delete popover.dataset.open;
|
|
1356
|
+
if (typeof popover.hidePopover === "function" && replPopoverIsOpen(popover)) {
|
|
1357
|
+
try {
|
|
1358
|
+
popover.hidePopover();
|
|
1359
|
+
} catch {
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
setExpanded(false);
|
|
1363
|
+
}, []);
|
|
1364
|
+
const scheduleHide = React.useCallback(() => {
|
|
1365
|
+
if (closeTimer.current !== void 0) clearTimeout(closeTimer.current);
|
|
1366
|
+
closeTimer.current = setTimeout(() => {
|
|
1367
|
+
closeTimer.current = void 0;
|
|
1368
|
+
if (document.activeElement === triggerRef.current || popoverRef.current?.contains(document.activeElement)) return;
|
|
1369
|
+
hidePopover();
|
|
1370
|
+
}, 120);
|
|
1371
|
+
}, [hidePopover]);
|
|
1372
|
+
React.useEffect(() => {
|
|
1373
|
+
const syncPopoverState = (event) => {
|
|
1374
|
+
if (event.target !== popoverRef.current) return;
|
|
1375
|
+
setExpanded(replPopoverIsOpen(popoverRef.current));
|
|
1376
|
+
};
|
|
1377
|
+
window.addEventListener("resize", positionPopover);
|
|
1378
|
+
document.addEventListener("scroll", positionPopover, true);
|
|
1379
|
+
document.addEventListener("toggle", syncPopoverState, true);
|
|
1380
|
+
return () => {
|
|
1381
|
+
if (closeTimer.current !== void 0) clearTimeout(closeTimer.current);
|
|
1382
|
+
window.removeEventListener("resize", positionPopover);
|
|
1383
|
+
document.removeEventListener("scroll", positionPopover, true);
|
|
1384
|
+
document.removeEventListener("toggle", syncPopoverState, true);
|
|
1385
|
+
const popover = popoverRef.current;
|
|
1386
|
+
if (popover?.dataset?.open === "true") delete popover.dataset.open;
|
|
1387
|
+
if (typeof popover?.hidePopover === "function" && replPopoverIsOpen(popover)) {
|
|
1388
|
+
try {
|
|
1389
|
+
popover.hidePopover();
|
|
1390
|
+
} catch {
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
1394
|
+
}, [hidePopover, positionPopover]);
|
|
1395
|
+
const resolvedSessionId = sessionId ?? conversation?.sessionId;
|
|
1396
|
+
const session = sessions?.byId?.[resolvedSessionId] ?? conversation;
|
|
1397
|
+
if (!sessionUsesPtcPreset(session) || settings.status !== "ready" || settings.value?.enabled !== true) return null;
|
|
1398
|
+
let memory;
|
|
1399
|
+
try {
|
|
1400
|
+
memory = normalizeReplMemorySnapshot(projectionMemory ?? session?.projectionValues?.ptcPlusRepl);
|
|
1401
|
+
} catch {
|
|
1402
|
+
memory = unavailableReplMemorySnapshot();
|
|
1403
|
+
}
|
|
1404
|
+
const popoverId = `ptc-plus-repl-${String(resolvedSessionId).replace(/[^A-Za-z0-9_-]/g, "-")}`;
|
|
1405
|
+
const titleId = `${popoverId}-title`;
|
|
348
1406
|
return h(
|
|
349
1407
|
"span",
|
|
350
|
-
{ className: "
|
|
351
|
-
h(
|
|
352
|
-
|
|
1408
|
+
{ className: "ptcPlusActiveShell" },
|
|
1409
|
+
h("button", {
|
|
1410
|
+
type: "button",
|
|
1411
|
+
className: "ptcPlusActive",
|
|
1412
|
+
ref: triggerRef,
|
|
1413
|
+
"aria-label": t("indicator.title"),
|
|
1414
|
+
"aria-controls": popoverId,
|
|
1415
|
+
"aria-expanded": expanded,
|
|
1416
|
+
"aria-haspopup": "dialog",
|
|
1417
|
+
onPointerEnter: showPopover,
|
|
1418
|
+
onPointerLeave: scheduleHide,
|
|
1419
|
+
onFocus: showPopover,
|
|
1420
|
+
onBlur: scheduleHide,
|
|
1421
|
+
onClick: showPopover,
|
|
1422
|
+
onKeyDown: (event) => {
|
|
1423
|
+
if (event.key === "Escape") hidePopover();
|
|
1424
|
+
}
|
|
1425
|
+
}, h("span", { className: "ptcPlusActiveLabel" }, "PTC Plus")),
|
|
1426
|
+
h(ReplMemoryCard, {
|
|
1427
|
+
memory,
|
|
1428
|
+
t,
|
|
1429
|
+
id: popoverId,
|
|
1430
|
+
titleId,
|
|
1431
|
+
popoverRef,
|
|
1432
|
+
onEnter: showPopover,
|
|
1433
|
+
onLeave: scheduleHide
|
|
1434
|
+
})
|
|
353
1435
|
);
|
|
354
1436
|
}
|
|
355
1437
|
scope.slots.inject("conversation.session.header.actions", () => scope.slots.register({
|
|
356
1438
|
name: "conversation.session.header.actions",
|
|
357
1439
|
id: "ptc-plus-active",
|
|
358
|
-
order: -9
|
|
1440
|
+
order: -9,
|
|
1441
|
+
locale: LOCALE_NS
|
|
359
1442
|
}, PTCPlusSessionIndicator));
|
|
360
1443
|
});
|
|
361
1444
|
}
|
|
362
|
-
module.exports = { apply, inject: ["settingsScope", "slots", "sessions"] };
|
|
1445
|
+
module.exports = { apply, inject: ["settingsScope", "slots", "sessions", "locale"] };
|
|
363
1446
|
return module.exports;
|
|
364
1447
|
}
|
|
365
1448
|
});
|