zcode-pro 0.19.0 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/zcode-pro.mjs +32 -9
- package/dist/inject.js +229 -127
- package/package.json +1 -1
- package/src/host/helper.mjs +325 -35
- package/src/host/main.mjs +8 -4
- package/src/host/setup.mjs +45 -42
- package/src/host/taskIndex.mjs +186 -6
- package/src/inject/core.js +23 -15
- package/src/inject/features/settings-dialog.js +85 -49
- package/src/inject/features/styles.js +1 -1
- package/src/inject/features/task-order.js +1 -1
- package/src/inject/features/title-gen.js +10 -1
- package/src/inject/features/title-lock.js +59 -1
- package/src/inject/features/ws-running.js +1 -1
- package/src/inject/provider-fields.js +2 -2
package/dist/inject.js
CHANGED
|
@@ -59,12 +59,17 @@
|
|
|
59
59
|
proxyScopeSyncDesc: "WebDAV \u4E0A\u4F20\u4E0E\u4E0B\u8F7D\u8D70\u4EE3\u7406\u3002\u9ED8\u8BA4\u5173\u95ED\uFF1A\u575A\u679C\u4E91\u7B49\u56FD\u5185\u7F51\u76D8\u76F4\u8FDE\u5373\u53EF\uFF0C\u4EE3\u7406\u505C\u4E86\u540C\u6B65\u4F1A\u8DDF\u7740\u5931\u8D25\u3002",
|
|
60
60
|
tabSync: "\u540C\u6B65",
|
|
61
61
|
tabDebug: "\u8C03\u8BD5",
|
|
62
|
-
|
|
62
|
+
testNoSessionHint: "\u9009\u62E9\u201C\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD[\u5F53\u524D\u6A21\u578B]\u201D\u65F6\uFF0C\u9009\u62E9\u4E0A\u6B21\u4F1A\u8BDD\u4E2D\u4F7F\u7528\u7684\u4F9B\u5E94\u5546[\u6A21\u578B]",
|
|
63
|
+
syncDesc: "\u624B\u52A8\u628A ZCode Pro \u8BBE\u7F6E\u4E0E\u6A21\u578B\u8BBE\u7F6E\u5907\u4EFD\u5230 WebDAV\uFF0C\u6216\u5728\u65B0\u7535\u8111\u4E0A\u6062\u590D\u3002\u4E24\u9879\u5404\u81EA\u72EC\u7ACB\u6210\u6587\u4EF6\uFF0C\u53EF\u53EA\u4E0A\u4F20\u6216\u53EA\u8986\u76D6\u5176\u4E2D\u4E00\u9879\uFF1B\u6BCF\u6B21\u4E0A\u4F20\u4F1A\u989D\u5916\u4FDD\u7559\u4E00\u4EFD\u5E26\u65F6\u95F4\u6233\u7684\u5386\u53F2\u7248\u672C\uFF08\u4FDD\u7559\u591A\u5C11\u4E2A\u89C1\u201C\u5386\u53F2\u7248\u672C\u201D\u4E00\u884C\uFF0C\u4E0A\u4F20\u540E\u81EA\u52A8\u5220\u9664\u8D85\u51FA\u7684\u6700\u65E7\u7248\u672C\uFF09\uFF0C\u4E0B\u8F7D\u65F6\u4EFB\u9009\u4E00\u4E2A\u7248\u672C\u6062\u590D\uFF1B\u4EC5\u5728\u70B9\u51FB\u6309\u94AE\u65F6\u4F20\u8F93\uFF0C\u4E0D\u505A\u81EA\u52A8\u540C\u6B65\u3002",
|
|
63
64
|
syncUrlPlaceholder: "https://dav.jianguoyun.com/dav/",
|
|
64
65
|
syncDir: "\u4E0A\u4F20\u76EE\u5F55",
|
|
65
66
|
syncDirPlaceholder: "zcode-pro",
|
|
66
67
|
syncLogin: "\u767B\u5F55",
|
|
67
68
|
syncPassword: "\u5BC6\u7801",
|
|
69
|
+
syncHistoryLimit: "\u5386\u53F2\u7248\u672C",
|
|
70
|
+
syncHistoryLimitUnit: "\u4E2A",
|
|
71
|
+
syncHistoryLimitHint: "\u4E91\u7AEF\u6700\u591A\u4FDD\u7559\u6700\u8FD1\u51E0\u6B21\u4E0A\u4F20\u7559\u4E0B\u7684\u5386\u53F2\u7248\u672C\uFF0C\u4E0A\u4F20\u6210\u529F\u540E\u81EA\u52A8\u5220\u9664\u66F4\u65E9\u7684\uFF1B\u56FA\u5B9A\u540D\u6700\u65B0\u7248\u4E0D\u53D7\u5F71\u54CD\uFF1B0 = \u4E0D\u4FDD\u7559\u5386\u53F2\u7248\u672C",
|
|
72
|
+
syncPruned: "\u5DF2\u6E05\u7406 {n} \u4E2A\u66F4\u65E9\u7684\u5386\u53F2\u7248\u672C",
|
|
68
73
|
syncSave: "\u4FDD\u5B58",
|
|
69
74
|
syncSaved: "\u540C\u6B65\u914D\u7F6E\u5DF2\u4FDD\u5B58",
|
|
70
75
|
syncFormHint: "\u540C\u6B65\u6587\u4EF6\u5B58\u5230\u201C\u4E0A\u4F20\u76EE\u5F55\u201D\uFF08\u9ED8\u8BA4 zcode-pro\uFF0C\u53EF\u591A\u7EA7\uFF0C\u81EA\u52A8\u521B\u5EFA\uFF09\uFF1Azcodepro.json \u4E0E model.json \u59CB\u7EC8\u662F\u6700\u65B0\u4E00\u7248\uFF0C\u65C1\u8FB9\u53E6\u4FDD\u7559\u5E26\u65F6\u95F4\u6233\u7684\u5386\u53F2\u7248\u672C\u3002",
|
|
@@ -85,8 +90,8 @@
|
|
|
85
90
|
syncConfirmTitle: "\u4ECE\u4E91\u7AEF\u4E0B\u8F7D",
|
|
86
91
|
syncConfirmDesc: "\u5C06\u7528\u6240\u9009\u6587\u4EF6\u8986\u76D6\u672C\u673A\u5BF9\u5E94\u7684\u4E00\u9879\uFF08\u8986\u76D6\u524D\u4F1A\u5728\u539F\u6587\u4EF6\u65C1\u7559\u4E0B .zcodepro-backup \u5907\u4EFD\uFF09\uFF1B\u672C\u673A\u7684\u540C\u6B65\u914D\u7F6E\u4E0E\u767B\u5F55\u51ED\u636E\u4E0D\u53D7\u5F71\u54CD\u3002\u6A21\u578B\u8BBE\u7F6E\u6062\u590D\u540E\u5EFA\u8BAE\u91CD\u542F ZCode \u751F\u6548\u3002\u786E\u8BA4\u5BFC\u5165\uFF1F",
|
|
87
92
|
syncConfirmGo: "\u786E\u8BA4\u5BFC\u5165",
|
|
88
|
-
syncPickDesc: "\u56FA\u5B9A\u540D\u6587\u4EF6\u59CB\u7EC8\u662F\u6700\u65B0\u4E00\u7248\uFF0C\u5E26\u65F6\u95F4\u6233\u7684\u662F\u6BCF\u6B21\u4E0A\u4F20\u7559\u4E0B\u7684\u5386\u53F2\u7248\u672C\uFF1B\
|
|
89
|
-
syncVerDeleteLatestNote: "\u6CE8\u610F\uFF1A\u8FD9\u662F\u201C\u6700\u65B0\u201D\u6587\u4EF6\uFF0C\u65E7\u7248 zcode-pro \u7684\
|
|
93
|
+
syncPickDesc: "\u56FA\u5B9A\u540D\u6587\u4EF6\u59CB\u7EC8\u662F\u6700\u65B0\u4E00\u7248\uFF0C\u5E26\u65F6\u95F4\u6233\u7684\u662F\u6BCF\u6B21\u4E0A\u4F20\u7559\u4E0B\u7684\u5386\u53F2\u7248\u672C\uFF1B\u201C\u5BFC\u5165\u201D\u7528\u6240\u9009\u6587\u4EF6\u8986\u76D6\u672C\u673A\u5BF9\u5E94\u7684\u4E00\u9879\u3002",
|
|
94
|
+
syncVerDeleteLatestNote: "\u6CE8\u610F\uFF1A\u8FD9\u662F\u201C\u6700\u65B0\u201D\u6587\u4EF6\uFF0C\u65E7\u7248 zcode-pro \u7684\u201C\u4ECE\u4E91\u7AEF\u4E0B\u8F7D\u201D\u4F9D\u8D56\u5B83\uFF0C\u5220\u9664\u540E\u65E7\u7248\u673A\u5668\u5C06\u65E0\u6CD5\u4E0B\u8F7D\uFF1B\u5E26\u65F6\u95F4\u6233\u7684\u5386\u53F2\u7248\u672C\u4E0D\u53D7\u5F71\u54CD\u3002",
|
|
90
95
|
syncHint: "\u540C\u6B65\u767B\u5F55\u51ED\u636E\u4EC5\u4FDD\u5B58\u5728\u672C\u673A zcodepro.json\uFF1B\u6A21\u578B\u8BBE\u7F6E\u5305\u542B\u81EA\u5B9A\u4E49\u4F9B\u5E94\u5546\u7684 API Key\uFF0C\u53EA\u4F1A\u4E0A\u4F20\u5230\u4F60\u81EA\u5DF1\u7684 WebDAV\u3002",
|
|
91
96
|
syncTest: "\u6D4B\u8BD5",
|
|
92
97
|
syncTesting: "\u6D4B\u8BD5\u4E2D\u2026",
|
|
@@ -110,8 +115,8 @@
|
|
|
110
115
|
syncVerDeleted: "\u5DF2\u5220\u9664\u4E91\u7AEF\u5907\u4EFD",
|
|
111
116
|
syncVerSaved: "\u5DF2\u4FDD\u5B58\u5230",
|
|
112
117
|
devMode: "\u5F00\u53D1\u6A21\u5F0F",
|
|
113
|
-
devModeRowDesc: "\u5F00\u542F\u540E\u51FA\u73B0\
|
|
114
|
-
devModeDesc: "\u5F00\u53D1\u8C03\u8BD5\u7528\uFF1A\u6539\u5B8C zcode-pro \u4EE3\u7801\u540E\u4E0D\u5FC5\u91CD\u542F ZCode\uFF0C\u70B9\
|
|
118
|
+
devModeRowDesc: "\u5F00\u542F\u540E\u51FA\u73B0\u201C\u91CD\u8F7D ZCode Pro\u201D\u6309\u94AE\uFF1B\u4E5F\u53EF\u7ED9\u542F\u52A8\u5668\u8BBE\u73AF\u5883\u53D8\u91CF ZCODEPRO_DEV=1 \u542F\u7528\u3002\u6B64\u6807\u7B7E\u9875\u4EC5\u5728\u5F00\u53D1\u6A21\u5F0F\u751F\u6548\u65F6\u663E\u793A\u3002",
|
|
119
|
+
devModeDesc: "\u5F00\u53D1\u8C03\u8BD5\u7528\uFF1A\u6539\u5B8C zcode-pro \u4EE3\u7801\u540E\u4E0D\u5FC5\u91CD\u542F ZCode\uFF0C\u70B9\u201C\u91CD\u8F7D ZCode Pro\u201D\u5373\u53EF\u52A0\u8F7D\u65B0\u4EE3\u7801\u3002\u6D41\u7A0B\u4E3A\u81EA\u52A8\u6784\u5EFA\uFF08\u9700\u5728\u6E90\u7801\u76EE\u5F55\u8FD0\u884C\uFF09\u2192 \u4EE5\u65B0\u8FDB\u7A0B\u91CD\u542F ZCode Pro\uFF08\u672C\u5730\u52A9\u624B\u4E0E\u6CE8\u5165\u811A\u672C\u90FD\u6362\u65B0\uFF09\u2192 \u6240\u6709 ZCode \u7A97\u53E3\u81EA\u52A8\u5237\u65B0\u5E76\u91CD\u65B0\u6CE8\u5165\uFF1BZCode \u672C\u4F53\u4E0E\u5DF2\u6253\u5F00\u7684\u4F1A\u8BDD\u4E0D\u53D7\u5F71\u54CD\u3002",
|
|
115
120
|
devReload: "\u91CD\u8F7D ZCode Pro",
|
|
116
121
|
devReloading: "\u91CD\u8F7D\u4E2D\u2026",
|
|
117
122
|
devReloadDesc: "\u70B9\u51FB\u540E\u7EA6 2-3 \u79D2\u5185\u6240\u6709 ZCode \u7A97\u53E3\u81EA\u52A8\u5237\u65B0\u4E00\u6B21\u5E76\u52A0\u8F7D\u65B0\u811A\u672C\u3002",
|
|
@@ -132,7 +137,7 @@
|
|
|
132
137
|
lineHeightName: "\u56DE\u7B54\u884C\u9AD8",
|
|
133
138
|
lineHeightDesc: "\u56DE\u7B54\u6B63\u6587\u7684\u884C\u9AD8\uFF08\u500D\u6570\uFF09\u3002",
|
|
134
139
|
thinkingLineHeightName: "\u601D\u8003\u884C\u9AD8",
|
|
135
|
-
thinkingLineHeightDesc: "\
|
|
140
|
+
thinkingLineHeightDesc: "\u201C\u5DF2\u5DE5\u4F5C/\u5DE5\u4F5C\u4E2D\u201D\u8FC7\u7A0B\u8BB0\u5F55\uFF08\u8BFB\u53D6/\u7F16\u8F91/\u67E5\u9605/\u7EC8\u7AEF\u6761\u76EE\u4E0E\u601D\u8003\u5185\u5BB9\uFF09\u7684\u884C\u9AD8\uFF08\u500D\u6570\uFF09\u3002",
|
|
136
141
|
userLineHeightName: "\u63D0\u95EE\u884C\u9AD8",
|
|
137
142
|
userLineHeightDesc: "\u63D0\u95EE\u5185\u5BB9\u7684\u884C\u9AD8\uFF08\u500D\u6570\uFF09\u3002",
|
|
138
143
|
contentWidthName: "\u5185\u5BB9\u5BBD\u5EA6",
|
|
@@ -250,11 +255,10 @@
|
|
|
250
255
|
visionSkipMinutes: "\u8DF3\u8FC7\u5206\u949F\u6570",
|
|
251
256
|
visionSkipMinutesHint: "\u8DF3\u8FC7\u591A\u4E45\u540E\u81EA\u52A8\u6062\u590D\u5C1D\u8BD5\uFF1B\u671F\u95F4\u4EFB\u4E00\u6B21\u6210\u529F\u5373\u6E05\u96F6\u8BA1\u6570",
|
|
252
257
|
visionResetChain: "\u6062\u590D\u9ED8\u8BA4\u94FE",
|
|
253
|
-
visionResetChainConfirm: "\u5C06\u94FE\u6A21\u5F0F\u4E0E\u4EE3\u7406\u5217\u8868\u6062\u590D\u4E3A\u9ED8\u8BA4\
|
|
254
|
-
visionBaseUrl: "\u63A5\u53E3\u5730\u5740
|
|
258
|
+
visionResetChainConfirm: "\u5C06\u94FE\u6A21\u5F0F\u4E0E\u4EE3\u7406\u5217\u8868\u6062\u590D\u4E3A\u9ED8\u8BA4\u5355\u7EA7\uFF08session\uFF1A\u8DDF\u968F\u4F1A\u8BDD\u4E0E\u5176\u5F53\u524D\u6A21\u578B\uFF09\uFF0C\u5F53\u524D\u5BF9\u4EE3\u7406\u7684\u4FEE\u6539\u4F1A\u4E22\u5931\u3002\u7EE7\u7EED\uFF1F",
|
|
259
|
+
visionBaseUrl: "\u63A5\u53E3\u5730\u5740",
|
|
255
260
|
visionModel: "\u6A21\u578B",
|
|
256
261
|
visionApiKey: "API Key",
|
|
257
|
-
visionApiKeyHint: "\u7559\u7A7A\u81EA\u52A8\u53D6 GLM \u8BA2\u9605 key",
|
|
258
262
|
visionPrompt: "\u8BC6\u522B\u63D0\u793A\u8BCD\uFF08pipeline \u540E\u7EED\u6B65\u53EF\u7528 {prev} \u5F15\u7528\u4E0A\u4E00\u6B65\uFF09",
|
|
259
263
|
visionTest: "\u6D4B\u8BD5",
|
|
260
264
|
visionTesting: "\u6D4B\u8BD5\u4E2D\u2026",
|
|
@@ -420,12 +424,17 @@
|
|
|
420
424
|
proxyScopeSyncDesc: "WebDAV upload and download go through the proxy. Off by default: domestic WebDAV providers work fine direct, and a stopped proxy breaks sync.",
|
|
421
425
|
tabSync: "Sync",
|
|
422
426
|
tabDebug: "Debug",
|
|
423
|
-
|
|
427
|
+
testNoSessionHint: "With \u201Cfollow current session [current model]\u201D selected, the provider [model] of the last session is used.",
|
|
428
|
+
syncDesc: 'Manually back up ZCode Pro settings and model settings to WebDAV, or restore them on a new computer. The two items are stored as separate files, so you can upload or overwrite either one alone; every upload also keeps a timestamped history version (how many to keep is set in the "History" row; older ones are removed automatically after upload) and download lets you pick any of them. Data moves only when you click, never automatically.',
|
|
424
429
|
syncUrlPlaceholder: "https://dav.example.com/dav/",
|
|
425
|
-
syncDir: "
|
|
430
|
+
syncDir: "Folder",
|
|
426
431
|
syncDirPlaceholder: "zcode-pro",
|
|
427
432
|
syncLogin: "Login",
|
|
428
433
|
syncPassword: "Password",
|
|
434
|
+
syncHistoryLimit: "History",
|
|
435
|
+
syncHistoryLimitUnit: "versions",
|
|
436
|
+
syncHistoryLimitHint: "How many recent uploads keep their history versions on the server; older ones are removed automatically after a successful upload. The fixed-name latest file is never removed. 0 = keep no history versions.",
|
|
437
|
+
syncPruned: "removed {n} older history versions",
|
|
429
438
|
syncSave: "Save",
|
|
430
439
|
syncSaved: "Sync settings saved.",
|
|
431
440
|
syncFormHint: "Sync files go inside the folder (default zcode-pro, multi-level allowed, created automatically): zcodepro.json and model.json are always the latest version; timestamped history versions are kept alongside.",
|
|
@@ -611,11 +620,10 @@
|
|
|
611
620
|
visionSkipMinutes: "Skip minutes",
|
|
612
621
|
visionSkipMinutesHint: "How long a skipped proxy rests before being retried; any success resets the counter",
|
|
613
622
|
visionResetChain: "Reset default chain",
|
|
614
|
-
visionResetChainConfirm: "Reset chain mode and the proxy list to the default
|
|
615
|
-
visionBaseUrl: "
|
|
623
|
+
visionResetChainConfirm: "Reset chain mode and the proxy list to the default single-level chain (session: follow session and its current model)? Current proxy edits will be lost. Continue?",
|
|
624
|
+
visionBaseUrl: "API URL",
|
|
616
625
|
visionModel: "Model",
|
|
617
626
|
visionApiKey: "API Key",
|
|
618
|
-
visionApiKeyHint: "Leave empty to reuse the GLM subscription key",
|
|
619
627
|
visionPrompt: "Recognition prompt ({prev} = previous step in pipeline)",
|
|
620
628
|
visionTest: "Test",
|
|
621
629
|
visionTesting: "Testing\u2026",
|
|
@@ -3654,17 +3662,34 @@
|
|
|
3654
3662
|
)
|
|
3655
3663
|
);
|
|
3656
3664
|
const savedSync = config.sync && typeof config.sync === "object" ? config.sync : { url: "", dir: "zcode-pro", login: "", password: "", include: { zcodepro: true, model: true }, lastPushAt: null, lastPullAt: null };
|
|
3657
|
-
const
|
|
3665
|
+
const syncInputBase = "h-8 rounded-lg border border-border bg-input px-2.5 text-ui-sm text-foreground outline-none transition-shadow placeholder:text-foreground-subtle focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40";
|
|
3666
|
+
const syncInputCls = syncInputBase + " w-full";
|
|
3667
|
+
const syncLabel = (text) => h("span", { class: "w-20 shrink-0 text-ui-sm font-medium text-foreground" }, text);
|
|
3658
3668
|
const syncFormRow = (labelText, node) => h(
|
|
3659
3669
|
"div",
|
|
3660
3670
|
{ class: "flex items-center gap-3 px-2 py-1.5" },
|
|
3661
|
-
|
|
3671
|
+
syncLabel(labelText),
|
|
3662
3672
|
node
|
|
3663
3673
|
);
|
|
3664
3674
|
const syncUrlInput = h("input", { type: "text", value: savedSync.url || "", placeholder: L.syncUrlPlaceholder, spellcheck: "false", autocomplete: "off", class: syncInputCls + " min-w-0 flex-1" });
|
|
3665
3675
|
const syncDirInput = h("input", { type: "text", value: savedSync.dir || "zcode-pro", placeholder: L.syncDirPlaceholder, spellcheck: "false", autocomplete: "off", class: syncInputCls + " min-w-0 flex-1" });
|
|
3666
3676
|
const syncLoginInput = h("input", { type: "text", value: savedSync.login || "", spellcheck: "false", autocomplete: "off", class: syncInputCls + " min-w-0 flex-1" });
|
|
3667
3677
|
const syncPasswordInput = h("input", { type: "password", value: savedSync.password || "", autocomplete: "new-password", class: syncInputCls + " min-w-0 flex-1" });
|
|
3678
|
+
const syncHistoryInput = h("input", {
|
|
3679
|
+
type: "number",
|
|
3680
|
+
min: "0",
|
|
3681
|
+
max: "100",
|
|
3682
|
+
step: "1",
|
|
3683
|
+
value: Number.isInteger(savedSync.historyLimit) ? savedSync.historyLimit : 10,
|
|
3684
|
+
title: L.syncHistoryLimitHint,
|
|
3685
|
+
class: syncInputBase + " w-20 shrink-0 text-center"
|
|
3686
|
+
});
|
|
3687
|
+
const syncHistoryValue = () => {
|
|
3688
|
+
const s = syncHistoryInput.value.trim();
|
|
3689
|
+
if (!s) return 10;
|
|
3690
|
+
const n = Number(s);
|
|
3691
|
+
return Number.isFinite(n) ? Math.min(100, Math.max(0, Math.round(n))) : 10;
|
|
3692
|
+
};
|
|
3668
3693
|
let syncFormOriginal = null;
|
|
3669
3694
|
const syncSaveBtn = btnSmall(L.syncSave, () => {
|
|
3670
3695
|
void saveSyncForm();
|
|
@@ -3673,15 +3698,16 @@
|
|
|
3673
3698
|
url: syncUrlInput.value.trim(),
|
|
3674
3699
|
dir: syncDirInput.value.trim(),
|
|
3675
3700
|
login: syncLoginInput.value.trim(),
|
|
3676
|
-
password: syncPasswordInput.value
|
|
3701
|
+
password: syncPasswordInput.value,
|
|
3702
|
+
historyLimit: syncHistoryValue()
|
|
3677
3703
|
});
|
|
3678
3704
|
const syncCheckDirty = () => {
|
|
3679
3705
|
const c = syncFormValues();
|
|
3680
|
-
syncSaveBtn.disabled = c.url === syncFormOriginal.url && c.dir === syncFormOriginal.dir && c.login === syncFormOriginal.login && c.password === syncFormOriginal.password;
|
|
3706
|
+
syncSaveBtn.disabled = c.url === syncFormOriginal.url && c.dir === syncFormOriginal.dir && c.login === syncFormOriginal.login && c.password === syncFormOriginal.password && c.historyLimit === syncFormOriginal.historyLimit;
|
|
3681
3707
|
};
|
|
3682
3708
|
syncFormOriginal = syncFormValues();
|
|
3683
3709
|
syncSaveBtn.disabled = true;
|
|
3684
|
-
for (const el of [syncUrlInput, syncDirInput, syncLoginInput, syncPasswordInput]) {
|
|
3710
|
+
for (const el of [syncUrlInput, syncDirInput, syncLoginInput, syncPasswordInput, syncHistoryInput]) {
|
|
3685
3711
|
el.addEventListener("input", syncCheckDirty);
|
|
3686
3712
|
}
|
|
3687
3713
|
const saveSyncForm = async () => {
|
|
@@ -3692,12 +3718,14 @@
|
|
|
3692
3718
|
url: res.sync.url,
|
|
3693
3719
|
dir: res.sync.dir,
|
|
3694
3720
|
login: res.sync.login,
|
|
3695
|
-
password: res.sync.password
|
|
3721
|
+
password: res.sync.password,
|
|
3722
|
+
historyLimit: Number.isInteger(res.sync.historyLimit) ? res.sync.historyLimit : 10
|
|
3696
3723
|
};
|
|
3697
3724
|
syncUrlInput.value = res.sync.url;
|
|
3698
3725
|
syncDirInput.value = res.sync.dir;
|
|
3699
3726
|
syncLoginInput.value = res.sync.login;
|
|
3700
3727
|
syncPasswordInput.value = res.sync.password;
|
|
3728
|
+
syncHistoryInput.value = syncFormOriginal.historyLimit;
|
|
3701
3729
|
showToast(L.syncSaved);
|
|
3702
3730
|
} else {
|
|
3703
3731
|
showToast(L.failed + ": " + errText(res), "error");
|
|
@@ -3993,7 +4021,7 @@
|
|
|
3993
4021
|
return;
|
|
3994
4022
|
}
|
|
3995
4023
|
renderSyncStatus(res.sync || {});
|
|
3996
|
-
showToast(L.syncUploaded, "success");
|
|
4024
|
+
showToast(res.pruned ? L.syncUploaded + (isZhLocale() ? "\uFF1B" : "; ") + L.syncPruned.replace("{n}", res.pruned) : L.syncUploaded, "success");
|
|
3997
4025
|
};
|
|
3998
4026
|
paneSync.append(
|
|
3999
4027
|
h("p", { class: "text-ui-sm/relaxed text-foreground-subtle" }, L.syncDesc),
|
|
@@ -4001,12 +4029,27 @@
|
|
|
4001
4029
|
"div",
|
|
4002
4030
|
{ class: "mt-3 rounded-xl border border-border p-1" },
|
|
4003
4031
|
syncFormRow("URL", syncUrlInput),
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4032
|
+
// 登录与密码一行、上传目录与历史版本一行:短字段成对排,少占纵向空间
|
|
4033
|
+
h(
|
|
4034
|
+
"div",
|
|
4035
|
+
{ class: "flex items-center gap-3 px-2 py-1.5" },
|
|
4036
|
+
syncLabel(L.syncLogin),
|
|
4037
|
+
syncLoginInput,
|
|
4038
|
+
syncLabel(L.syncPassword),
|
|
4039
|
+
syncPasswordInput
|
|
4040
|
+
),
|
|
4007
4041
|
h(
|
|
4008
4042
|
"div",
|
|
4009
|
-
{ class: "flex items-
|
|
4043
|
+
{ class: "flex items-center gap-3 px-2 py-1.5" },
|
|
4044
|
+
syncLabel(L.syncDir),
|
|
4045
|
+
syncDirInput,
|
|
4046
|
+
syncLabel(L.syncHistoryLimit),
|
|
4047
|
+
syncHistoryInput,
|
|
4048
|
+
h("span", { class: "shrink-0 text-ui-xs text-foreground-subtle" }, L.syncHistoryLimitUnit)
|
|
4049
|
+
),
|
|
4050
|
+
h(
|
|
4051
|
+
"div",
|
|
4052
|
+
{ class: "flex items-center justify-between gap-2 px-2 py-1.5" },
|
|
4010
4053
|
h(
|
|
4011
4054
|
"div",
|
|
4012
4055
|
{ class: "min-w-0" },
|
|
@@ -4083,16 +4126,15 @@
|
|
|
4083
4126
|
const VISION_DEFAULT_CFG = {
|
|
4084
4127
|
enabled: true,
|
|
4085
4128
|
chainMode: "fallback",
|
|
4086
|
-
chain: ["
|
|
4129
|
+
chain: ["session"],
|
|
4087
4130
|
proxies: [
|
|
4088
|
-
{ name: "
|
|
4089
|
-
{ name: "glm-flash", baseUrl: "https://open.bigmodel.cn/api/anthropic", model: "glm-5.3-flash", apiKey: "", format: "anthropic", prompt: VISION_DEFAULT_PROMPT }
|
|
4131
|
+
{ name: "session", useProvider: "session", model: "", prompt: VISION_DEFAULT_PROMPT }
|
|
4090
4132
|
],
|
|
4091
4133
|
pollMs: 3e3,
|
|
4092
4134
|
apiTimeoutMs: 12e4,
|
|
4093
4135
|
// 视觉上游冷启动可能近 2 分钟,与插件 DEFAULT_CONFIG 一致
|
|
4094
4136
|
compressThresholdKB: 1024,
|
|
4095
|
-
skipAfterFailures:
|
|
4137
|
+
skipAfterFailures: 2,
|
|
4096
4138
|
skipMinutes: 30,
|
|
4097
4139
|
forceIntercept: true
|
|
4098
4140
|
};
|
|
@@ -4236,26 +4278,22 @@
|
|
|
4236
4278
|
n
|
|
4237
4279
|
);
|
|
4238
4280
|
};
|
|
4239
|
-
const cards = visionCfg.proxies.map((p, i) =>
|
|
4240
|
-
|
|
4241
|
-
{ class: "mt-2 rounded-xl border border-border p-2" },
|
|
4242
|
-
h(
|
|
4281
|
+
const cards = visionCfg.proxies.map((p, i) => {
|
|
4282
|
+
const manualConnCard = isManualConn(p.useProvider, titleGenProviders) ? [h(
|
|
4243
4283
|
"div",
|
|
4244
|
-
{ class: "
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
})(),
|
|
4255
|
-
(() => {
|
|
4284
|
+
{ class: "mt-2 grid grid-cols-1 gap-2 rounded-xl border border-border p-2 sm:grid-cols-3" },
|
|
4285
|
+
field(L.visionBaseUrl, textIn(p.baseUrl, (v) => {
|
|
4286
|
+
p.baseUrl = v;
|
|
4287
|
+
saveVisionSoon();
|
|
4288
|
+
})),
|
|
4289
|
+
field(L.visionApiKey, textIn(p.apiKey, (v) => {
|
|
4290
|
+
p.apiKey = v;
|
|
4291
|
+
saveVisionSoon();
|
|
4292
|
+
}, { type: "password" })),
|
|
4293
|
+
field(L.titleGenFormat, (() => {
|
|
4256
4294
|
const sel = h(
|
|
4257
4295
|
"select",
|
|
4258
|
-
{ class: "h-
|
|
4296
|
+
{ class: "h-8 w-full rounded-lg border border-border bg-input px-2 text-ui-sm text-foreground outline-none" },
|
|
4259
4297
|
h("option", { value: "anthropic" }, "anthropic"),
|
|
4260
4298
|
h("option", { value: "openai" }, "openai")
|
|
4261
4299
|
);
|
|
@@ -4265,78 +4303,85 @@
|
|
|
4265
4303
|
void persistVision();
|
|
4266
4304
|
});
|
|
4267
4305
|
return sel;
|
|
4268
|
-
})()
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
)
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
placeholder:
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
p.
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4306
|
+
})())
|
|
4307
|
+
)] : [];
|
|
4308
|
+
return h("div", { class: "mt-2 rounded-xl border border-border p-2" }, [
|
|
4309
|
+
h(
|
|
4310
|
+
"div",
|
|
4311
|
+
{ class: "flex flex-wrap items-center gap-2" },
|
|
4312
|
+
h("span", { class: "shrink-0 rounded-md bg-surface px-1.5 py-0.5 text-ui-xs tabular-nums text-foreground-subtle" }, String(i + 1)),
|
|
4313
|
+
// 名称输入框用 flex-1 占剩余宽度,与序号同行;textIn 的 w-full 会把序号挤成单独一行
|
|
4314
|
+
(() => {
|
|
4315
|
+
const n = h("input", { type: "text", value: p.name || "", placeholder: L.visionName, class: visionInputCls + " min-w-0 flex-1" });
|
|
4316
|
+
n.addEventListener("input", () => {
|
|
4317
|
+
p.name = n.value;
|
|
4318
|
+
saveVisionSoon();
|
|
4319
|
+
});
|
|
4320
|
+
return n;
|
|
4321
|
+
})(),
|
|
4322
|
+
smallBtn(L.visionMoveUp, () => {
|
|
4323
|
+
if (i <= 0) return;
|
|
4324
|
+
visionCfg.proxies.splice(i - 1, 0, visionCfg.proxies.splice(i, 1)[0]);
|
|
4325
|
+
void persistVision();
|
|
4326
|
+
renderVision();
|
|
4327
|
+
}, i === 0 ? "pointer-events-none opacity-40" : ""),
|
|
4328
|
+
smallBtn(L.visionMoveDown, () => {
|
|
4329
|
+
if (i >= visionCfg.proxies.length - 1) return;
|
|
4330
|
+
visionCfg.proxies.splice(i + 1, 0, visionCfg.proxies.splice(i, 1)[0]);
|
|
4331
|
+
void persistVision();
|
|
4332
|
+
renderVision();
|
|
4333
|
+
}, i === visionCfg.proxies.length - 1 ? "pointer-events-none opacity-40" : ""),
|
|
4334
|
+
smallBtn(L.visionRemove, () => {
|
|
4335
|
+
visionCfg.proxies.splice(i, 1);
|
|
4336
|
+
void persistVision();
|
|
4337
|
+
renderVision();
|
|
4338
|
+
})
|
|
4339
|
+
),
|
|
4340
|
+
h(
|
|
4341
|
+
"div",
|
|
4342
|
+
{ class: "mt-2 grid grid-cols-1 gap-2 sm:grid-cols-2" },
|
|
4343
|
+
// 供应商与模型走 provider-fields 共用逻辑:跟随会话时模型下拉为
|
|
4344
|
+
// 全部供应商模型汇总,具体供应商为其模型列表;已删 id 标注“已删除”
|
|
4345
|
+
field(L.visionUseProvider, comboField(
|
|
4346
|
+
p.useProvider || "",
|
|
4347
|
+
providerOptionsOf(titleGenProviders, L),
|
|
4348
|
+
(v, src) => {
|
|
4349
|
+
p.useProvider = v;
|
|
4350
|
+
saveVisionSoon();
|
|
4351
|
+
if (src === "select") renderVision();
|
|
4352
|
+
},
|
|
4353
|
+
{ placeholder: L.titleGenProviderSession, staleLabel: L.titleGenProviderDeleted }
|
|
4354
|
+
)),
|
|
4355
|
+
// 跟随会话时模型下拉头部有“跟随当前会话当前模型”(值为空,
|
|
4356
|
+
// 插件 ≥1.6.1 在调用时解析为会话当前模型);具体供应商为其模型列表
|
|
4357
|
+
field(L.visionModel, comboField(
|
|
4358
|
+
p.model || "",
|
|
4359
|
+
modelOptionsOf(p.useProvider, titleGenProviders, {
|
|
4360
|
+
followSession: (p.useProvider || "").trim() === "session",
|
|
4361
|
+
followSessionLabel: L.titleGenModelFollowSession
|
|
4362
|
+
}),
|
|
4363
|
+
(v) => {
|
|
4364
|
+
p.model = v;
|
|
4365
|
+
saveVisionSoon();
|
|
4366
|
+
},
|
|
4367
|
+
{
|
|
4368
|
+
placeholder: modelPlaceholderOf(p.useProvider, L),
|
|
4369
|
+
emptyLabel: (p.useProvider || "").trim() === "session" ? L.titleGenModelFollowSession : L.titleGenModelEmpty
|
|
4370
|
+
}
|
|
4371
|
+
))
|
|
4372
|
+
),
|
|
4373
|
+
...manualConnCard,
|
|
4374
|
+
(() => {
|
|
4375
|
+
const n = h("textarea", { class: "zcodepro-textarea zcodepro-textarea-sm", rows: "3", placeholder: L.visionPrompt });
|
|
4376
|
+
n.value = p.prompt || "";
|
|
4377
|
+
n.addEventListener("input", () => {
|
|
4378
|
+
p.prompt = n.value;
|
|
4326
4379
|
saveVisionSoon();
|
|
4327
|
-
}
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
n.value = p.prompt || "";
|
|
4333
|
-
n.addEventListener("input", () => {
|
|
4334
|
-
p.prompt = n.value;
|
|
4335
|
-
saveVisionSoon();
|
|
4336
|
-
});
|
|
4337
|
-
return field(L.visionPrompt, n);
|
|
4338
|
-
})()
|
|
4339
|
-
));
|
|
4380
|
+
});
|
|
4381
|
+
return field(L.visionPrompt, n);
|
|
4382
|
+
})()
|
|
4383
|
+
]);
|
|
4384
|
+
});
|
|
4340
4385
|
let testBtn;
|
|
4341
4386
|
testBtn = smallBtn(L.visionTest, async () => {
|
|
4342
4387
|
testBtn.disabled = true;
|
|
@@ -4347,7 +4392,6 @@
|
|
|
4347
4392
|
testBtn.disabled = false;
|
|
4348
4393
|
testBtn.textContent = L.visionTest;
|
|
4349
4394
|
visionTestPre.textContent = res.output || res.error || "";
|
|
4350
|
-
if (!res.ok) showToast(L.visionTestFailed + ": " + errText(res), "error");
|
|
4351
4395
|
});
|
|
4352
4396
|
paneVision.replaceChildren(
|
|
4353
4397
|
h("p", { class: "text-ui-sm/relaxed text-foreground-subtle" }, L.visionDesc),
|
|
@@ -4412,7 +4456,7 @@
|
|
|
4412
4456
|
n
|
|
4413
4457
|
);
|
|
4414
4458
|
})(),
|
|
4415
|
-
numIn(visionCfg.skipAfterFailures, { min: 0, dflt:
|
|
4459
|
+
numIn(visionCfg.skipAfterFailures, { min: 0, dflt: 2, title: L.visionSkipAfterFailuresHint, label: L.visionSkipAfterFailures, commit: (v) => {
|
|
4416
4460
|
visionCfg.skipAfterFailures = v;
|
|
4417
4461
|
} }),
|
|
4418
4462
|
numIn(visionCfg.skipMinutes, { min: 1, dflt: 30, title: L.visionSkipMinutesHint, label: L.visionSkipMinutes, commit: (v) => {
|
|
@@ -4427,7 +4471,7 @@
|
|
|
4427
4471
|
"div",
|
|
4428
4472
|
{ class: "flex items-center gap-1.5" },
|
|
4429
4473
|
smallBtn("+ " + L.visionAddProxy, () => {
|
|
4430
|
-
visionCfg.proxies.push({ name: "", baseUrl: "https://open.bigmodel.cn/api/anthropic", model: "glm-5.3-flash", apiKey: "", format: "anthropic", prompt:
|
|
4474
|
+
visionCfg.proxies.push({ name: "", baseUrl: "https://open.bigmodel.cn/api/anthropic", model: "glm-5.3-flash", apiKey: "", format: "anthropic", prompt: VISION_DEFAULT_PROMPT });
|
|
4431
4475
|
renderVision();
|
|
4432
4476
|
}),
|
|
4433
4477
|
smallBtn(L.visionResetChain, () => {
|
|
@@ -4438,7 +4482,12 @@
|
|
|
4438
4482
|
renderVision();
|
|
4439
4483
|
})
|
|
4440
4484
|
),
|
|
4441
|
-
|
|
4485
|
+
h(
|
|
4486
|
+
"div",
|
|
4487
|
+
{ class: "flex min-w-0 items-center justify-end gap-2" },
|
|
4488
|
+
h("span", { class: "min-w-0 text-right text-ui-xs/relaxed text-foreground-subtle" }, L.testNoSessionHint),
|
|
4489
|
+
testBtn
|
|
4490
|
+
)
|
|
4442
4491
|
),
|
|
4443
4492
|
visionTestPre
|
|
4444
4493
|
);
|
|
@@ -5188,11 +5237,9 @@
|
|
|
5188
5237
|
testBtn.textContent = L.titleGenTest;
|
|
5189
5238
|
if (res && res.ok) {
|
|
5190
5239
|
testState.textContent = L.titleGenTestOk + res.title;
|
|
5191
|
-
showToast(res.title, "success");
|
|
5192
5240
|
} else {
|
|
5193
5241
|
testState.textContent = res && errText(res) || L.titleGenTestFailed;
|
|
5194
5242
|
testState.className = "min-w-0 flex-1 truncate text-ui-xs/relaxed text-destructive";
|
|
5195
|
-
showToast(L.titleGenTestFailed + ": " + (res ? errText(res) : ""), "error");
|
|
5196
5243
|
}
|
|
5197
5244
|
}, "shrink-0");
|
|
5198
5245
|
paneTitleGen.replaceChildren(
|
|
@@ -5232,12 +5279,18 @@
|
|
|
5232
5279
|
),
|
|
5233
5280
|
promptArea
|
|
5234
5281
|
),
|
|
5235
|
-
//
|
|
5282
|
+
// 测试(两行:输入框整行;说明 + 按钮一行。结果只显示在本区下方,
|
|
5283
|
+
// 不弹窗;从没对话过时的引导见 testState 错误文案)
|
|
5236
5284
|
h(
|
|
5237
5285
|
"div",
|
|
5238
|
-
{ class: "mt-2
|
|
5286
|
+
{ class: "mt-2 rounded-xl border border-border p-2" },
|
|
5239
5287
|
sampleInput,
|
|
5240
|
-
|
|
5288
|
+
h(
|
|
5289
|
+
"div",
|
|
5290
|
+
{ class: "mt-2 flex items-center justify-between gap-2" },
|
|
5291
|
+
h("span", { class: "min-w-0 text-ui-xs/relaxed text-foreground-subtle" }, L.testNoSessionHint),
|
|
5292
|
+
testBtn
|
|
5293
|
+
)
|
|
5241
5294
|
),
|
|
5242
5295
|
testState
|
|
5243
5296
|
);
|
|
@@ -5732,15 +5785,58 @@
|
|
|
5732
5785
|
if (m) scan2();
|
|
5733
5786
|
});
|
|
5734
5787
|
}
|
|
5788
|
+
var RENAME_CTX_VALID_MS = 15e3;
|
|
5789
|
+
var renameCtx = null;
|
|
5790
|
+
var renamePrefilled = /* @__PURE__ */ new WeakSet();
|
|
5791
|
+
function setNativeValue(el, text) {
|
|
5792
|
+
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
5793
|
+
Object.getOwnPropertyDescriptor(el.constructor.prototype, "value").set.call(el, text);
|
|
5794
|
+
} else {
|
|
5795
|
+
el.textContent = text;
|
|
5796
|
+
}
|
|
5797
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
5798
|
+
}
|
|
5799
|
+
function prefillRenameDialog() {
|
|
5800
|
+
if (!renameCtx || !renameCtx.armed || Date.now() - renameCtx.at > RENAME_CTX_VALID_MS) {
|
|
5801
|
+
renameCtx = null;
|
|
5802
|
+
return;
|
|
5803
|
+
}
|
|
5804
|
+
if (!enabled2 || !pinned) return;
|
|
5805
|
+
const want = pinned.get(sessIdOf(renameCtx.key));
|
|
5806
|
+
if (want === void 0) return;
|
|
5807
|
+
for (const el of document.querySelectorAll('[role="dialog"] input, [role="dialog"] textarea, [role="dialog"] [contenteditable="true"]')) {
|
|
5808
|
+
if (renamePrefilled.has(el) || !el.getClientRects().length) continue;
|
|
5809
|
+
if (el.closest(TASK_SEL) || el.closest(".zcodepro-overlay")) continue;
|
|
5810
|
+
const cur = String(el.value ?? el.textContent ?? "").trim();
|
|
5811
|
+
if (!cur) continue;
|
|
5812
|
+
renamePrefilled.add(el);
|
|
5813
|
+
if (cur !== String(want).trim()) setNativeValue(el, String(want));
|
|
5814
|
+
renameCtx = null;
|
|
5815
|
+
return;
|
|
5816
|
+
}
|
|
5817
|
+
}
|
|
5735
5818
|
function startTitleLock() {
|
|
5736
5819
|
if (installed2 || typeof document === "undefined") return;
|
|
5737
5820
|
installed2 = true;
|
|
5738
5821
|
void bootstrap();
|
|
5739
5822
|
new MutationObserver((muts) => {
|
|
5823
|
+
if (renameCtx) prefillRenameDialog();
|
|
5740
5824
|
if (!taskRowMutations2(muts)) return;
|
|
5741
5825
|
refreshMapSoon();
|
|
5742
5826
|
scheduleScan2();
|
|
5743
5827
|
}).observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ["class"], characterData: true });
|
|
5828
|
+
document.addEventListener("contextmenu", (e) => {
|
|
5829
|
+
const row = e.target instanceof Element && e.target.closest(TASK_SEL);
|
|
5830
|
+
renameCtx = row ? { key: row.getAttribute("data-task-item-key") || "", at: 0, armed: false } : null;
|
|
5831
|
+
}, true);
|
|
5832
|
+
document.addEventListener("click", (e) => {
|
|
5833
|
+
if (!renameCtx || renameCtx.armed) return;
|
|
5834
|
+
const item = e.target instanceof Element && e.target.closest('[role="menuitem"], [data-radix-collection-item]');
|
|
5835
|
+
if (item && /重命名|rename/i.test(item.textContent || "")) {
|
|
5836
|
+
renameCtx.armed = true;
|
|
5837
|
+
renameCtx.at = Date.now();
|
|
5838
|
+
}
|
|
5839
|
+
}, true);
|
|
5744
5840
|
scheduleBootRetry();
|
|
5745
5841
|
setInterval(() => {
|
|
5746
5842
|
if (!document.hidden) scan2();
|
|
@@ -5850,7 +5946,13 @@
|
|
|
5850
5946
|
convObserver.disconnect();
|
|
5851
5947
|
}
|
|
5852
5948
|
if (!texts.length) return;
|
|
5853
|
-
const
|
|
5949
|
+
const callTitleGen = () => rpc("/title-gen/run", { method: "POST", body: { sessId, text: texts.join("\n") } }).catch(() => null);
|
|
5950
|
+
let res = await callTitleGen();
|
|
5951
|
+
for (const delay of [5e3, 2e4]) {
|
|
5952
|
+
if (res && res.ok) break;
|
|
5953
|
+
await sleep(delay);
|
|
5954
|
+
res = await callTitleGen();
|
|
5955
|
+
}
|
|
5854
5956
|
if (res && res.ok && res.written && res.title) {
|
|
5855
5957
|
setRowTitle(key, res.title);
|
|
5856
5958
|
void refreshPinnedTitles();
|