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