zcode-pro 0.18.0 → 0.20.0
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 +1 -0
- package/README.md +1 -0
- package/bin/zcode-pro.mjs +32 -9
- package/dist/inject.js +684 -130
- package/package.json +1 -1
- package/src/host/helper.mjs +613 -50
- package/src/host/main.mjs +8 -4
- package/src/host/setup.mjs +45 -42
- package/src/host/taskIndex.mjs +258 -0
- package/src/inject/core.js +67 -19
- package/src/inject/features/file-menu.js +9 -2
- package/src/inject/features/settings-dialog.js +266 -63
- package/src/inject/features/styles.js +1 -1
- package/src/inject/features/task-order.js +1 -1
- package/src/inject/features/title-gen.js +178 -0
- package/src/inject/features/title-lock.js +73 -1
- package/src/inject/features/toolbar-icons.js +38 -4
- package/src/inject/features/ws-running.js +1 -1
- package/src/inject/index.js +2 -0
- package/src/inject/provider-fields.js +71 -0
- package/src/inject/ui.js +20 -5
package/dist/inject.js
CHANGED
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
tabFeatures: "\u529F\u80FD",
|
|
36
36
|
tabStyles: "\u6837\u5F0F",
|
|
37
37
|
tabProxy: "\u4EE3\u7406",
|
|
38
|
+
tabBehavior: "\u884C\u4E3A",
|
|
38
39
|
tabAgents: "\u5168\u5C40\u63D0\u793A\u8BCD",
|
|
39
40
|
agentsDesc: "\u5199\u5165 ~/.zcode/AGENTS.md\uFF0C\u4F5C\u4E3A\u9ED8\u8BA4\u6307\u4EE4\u7528\u4E8E\u6240\u6709\u9879\u76EE\u7684\u6BCF\u6B21\u4F1A\u8BDD\uFF1B\u4FDD\u5B58\u540E\u4ECE\u65B0\u4F1A\u8BDD\u8D77\u751F\u6548\uFF0C\u9879\u76EE\u5185\u7684 AGENTS.md \u53EF\u8865\u5145\u6216\u8986\u76D6\u3002\u5185\u5BB9\u8D85\u8FC7 100KB \u4F1A\u88AB\u5E94\u7528\u622A\u65AD\u3002",
|
|
40
41
|
agentsPlaceholder: "\u586B\u5199\u5E0C\u671B\u6240\u6709\u9879\u76EE\u9ED8\u8BA4\u9075\u5FAA\u7684\u6307\u4EE4\uFF1B\u6E05\u7A7A\u5E76\u4FDD\u5B58\u5373\u79FB\u9664\u5168\u5C40\u63D0\u793A\u8BCD",
|
|
@@ -58,12 +59,16 @@
|
|
|
58
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",
|
|
59
60
|
tabSync: "\u540C\u6B65",
|
|
60
61
|
tabDebug: "\u8C03\u8BD5",
|
|
61
|
-
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\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",
|
|
62
|
+
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",
|
|
62
63
|
syncUrlPlaceholder: "https://dav.jianguoyun.com/dav/",
|
|
63
64
|
syncDir: "\u4E0A\u4F20\u76EE\u5F55",
|
|
64
65
|
syncDirPlaceholder: "zcode-pro",
|
|
65
66
|
syncLogin: "\u767B\u5F55",
|
|
66
67
|
syncPassword: "\u5BC6\u7801",
|
|
68
|
+
syncHistoryLimit: "\u5386\u53F2\u7248\u672C",
|
|
69
|
+
syncHistoryLimitUnit: "\u4E2A",
|
|
70
|
+
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",
|
|
71
|
+
syncPruned: "\u5DF2\u6E05\u7406 {n} \u4E2A\u66F4\u65E9\u7684\u5386\u53F2\u7248\u672C",
|
|
67
72
|
syncSave: "\u4FDD\u5B58",
|
|
68
73
|
syncSaved: "\u540C\u6B65\u914D\u7F6E\u5DF2\u4FDD\u5B58",
|
|
69
74
|
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",
|
|
@@ -84,8 +89,8 @@
|
|
|
84
89
|
syncConfirmTitle: "\u4ECE\u4E91\u7AEF\u4E0B\u8F7D",
|
|
85
90
|
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",
|
|
86
91
|
syncConfirmGo: "\u786E\u8BA4\u5BFC\u5165",
|
|
87
|
-
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\
|
|
88
|
-
syncVerDeleteLatestNote: "\u6CE8\u610F\uFF1A\u8FD9\u662F\u201C\u6700\u65B0\u201D\u6587\u4EF6\uFF0C\u65E7\u7248 zcode-pro \u7684\
|
|
92
|
+
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",
|
|
93
|
+
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",
|
|
89
94
|
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",
|
|
90
95
|
syncTest: "\u6D4B\u8BD5",
|
|
91
96
|
syncTesting: "\u6D4B\u8BD5\u4E2D\u2026",
|
|
@@ -109,8 +114,8 @@
|
|
|
109
114
|
syncVerDeleted: "\u5DF2\u5220\u9664\u4E91\u7AEF\u5907\u4EFD",
|
|
110
115
|
syncVerSaved: "\u5DF2\u4FDD\u5B58\u5230",
|
|
111
116
|
devMode: "\u5F00\u53D1\u6A21\u5F0F",
|
|
112
|
-
devModeRowDesc: "\u5F00\u542F\u540E\u51FA\u73B0\
|
|
113
|
-
devModeDesc: "\u5F00\u53D1\u8C03\u8BD5\u7528\uFF1A\u6539\u5B8C zcode-pro \u4EE3\u7801\u540E\u4E0D\u5FC5\u91CD\u542F ZCode\uFF0C\u70B9\
|
|
117
|
+
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",
|
|
118
|
+
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",
|
|
114
119
|
devReload: "\u91CD\u8F7D ZCode Pro",
|
|
115
120
|
devReloading: "\u91CD\u8F7D\u4E2D\u2026",
|
|
116
121
|
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",
|
|
@@ -131,7 +136,7 @@
|
|
|
131
136
|
lineHeightName: "\u56DE\u7B54\u884C\u9AD8",
|
|
132
137
|
lineHeightDesc: "\u56DE\u7B54\u6B63\u6587\u7684\u884C\u9AD8\uFF08\u500D\u6570\uFF09\u3002",
|
|
133
138
|
thinkingLineHeightName: "\u601D\u8003\u884C\u9AD8",
|
|
134
|
-
thinkingLineHeightDesc: "\
|
|
139
|
+
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",
|
|
135
140
|
userLineHeightName: "\u63D0\u95EE\u884C\u9AD8",
|
|
136
141
|
userLineHeightDesc: "\u63D0\u95EE\u5185\u5BB9\u7684\u884C\u9AD8\uFF08\u500D\u6570\uFF09\u3002",
|
|
137
142
|
contentWidthName: "\u5185\u5BB9\u5BBD\u5EA6",
|
|
@@ -146,6 +151,30 @@
|
|
|
146
151
|
featureSessionSwitchDesc: "alt+z \u5728\u5F53\u524D\u4E0E\u4E0A\u6B21\u4F1A\u8BDD\u95F4\u6765\u56DE\u5207\u6362\uFF1B\u6309\u4F4F alt \u518D\u6309 x/c \u5F39\u51FA\u6700\u8FD1\u4F1A\u8BDD\u5217\u8868\u524D\u540E\u9009\u62E9\uFF0C\u677E\u5F00 alt \u5207\u6362\uFF08\u7C7B alt+tab\uFF09\u3002",
|
|
147
152
|
featureTitleLock: "\u91CD\u547D\u540D\u4F1A\u8BDD\u540D\u9501\u5B9A",
|
|
148
153
|
featureTitleLockDesc: "\u624B\u52A8\u91CD\u547D\u540D\u8FC7\u7684\u4F1A\u8BDD\u4E0D\u518D\u88AB\u81EA\u52A8\u6807\u9898\u8986\u76D6\uFF1A\u4F1A\u8BDD\u6709\u65B0\u56DE\u7B54\u540E\u754C\u9762\u53EF\u80FD\u6539\u663E\u81EA\u52A8\u6807\u9898\uFF0C\u91CD\u542F\u540E\u53C8\u53D8\u56DE\uFF0C\u672C\u529F\u80FD\u8BA9\u4FA7\u680F\u59CB\u7EC8\u663E\u793A\u91CD\u547D\u540D\u540E\u7684\u540D\u5B57\u3002",
|
|
154
|
+
tabTitleGen: "\u4EFB\u52A1\u540D\u63D0\u793A\u8BCD",
|
|
155
|
+
titleGenShortDesc: "\u65B0\u4F1A\u8BDD\u5F00\u59CB\u4F5C\u7B54\u65F6\uFF0C\u6309\u6240\u9009\u4F9B\u5E94\u5546\u4E0E\u63D0\u793A\u8BCD\u751F\u6210\u4EFB\u52A1\u540D\u5E76\u6309\u624B\u52A8\u91CD\u547D\u540D\u4FDD\u5B58\uFF0C\u5B98\u65B9\u81EA\u52A8\u6807\u9898\u4E0D\u518D\u8986\u76D6\u3002",
|
|
156
|
+
titleGenEnabled: "\u542F\u7528",
|
|
157
|
+
titleGenProvider: "\u4F9B\u5E94\u5546",
|
|
158
|
+
titleGenProviderNone: "\u4E0D\u8DDF\u968F\uFF08\u81EA\u586B\u5730\u5740\uFF09",
|
|
159
|
+
titleGenProviderSession: "\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD",
|
|
160
|
+
titleGenProviderDeleted: "\uFF08\u5DF2\u5220\u9664\uFF09",
|
|
161
|
+
titleGenModel: "\u6A21\u578B",
|
|
162
|
+
titleGenModelHint: "\u4ECE\u5217\u8868\u9009\u62E9\uFF0C\u6216\u76F4\u63A5\u586B\u5199\u6A21\u578B id",
|
|
163
|
+
titleGenModelEmpty: "\uFF08\u672A\u9009\u62E9\uFF09",
|
|
164
|
+
titleGenModelSessionHint: "\u4ECE\u5217\u8868\u9009\u62E9\u6A21\u578B\uFF1B\u5217\u8868\u7B2C\u4E00\u9879\u4E3A\u8DDF\u968F\u4F1A\u8BDD\u5F53\u524D\u6A21\u578B",
|
|
165
|
+
titleGenModelFollowSession: "\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD\u5F53\u524D\u6A21\u578B",
|
|
166
|
+
titleGenModelManualHint: "\u8F93\u5165\u6A21\u578B id",
|
|
167
|
+
titleGenBaseUrl: "\u63A5\u53E3\u5730\u5740",
|
|
168
|
+
titleGenApiKey: "API Key",
|
|
169
|
+
titleGenFormat: "\u534F\u8BAE",
|
|
170
|
+
titleGenPrompt: "\u63D0\u793A\u8BCD",
|
|
171
|
+
titleGenPromptPlaceholder: "\u7559\u7A7A\u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u63D0\u793A\u8BCD\uFF08\u70B9\u51FB\u4E0B\u65B9\u6309\u94AE\u53EF\u67E5\u770B\uFF09",
|
|
172
|
+
titleGenPromptReset: "\u4F7F\u7528\u9ED8\u8BA4\u63D0\u793A\u8BCD",
|
|
173
|
+
titleGenSample: "\u6D4B\u8BD5\u6D88\u606F",
|
|
174
|
+
titleGenTest: "\u6D4B\u8BD5\u751F\u6210",
|
|
175
|
+
titleGenTesting: "\u751F\u6210\u4E2D\u2026",
|
|
176
|
+
titleGenTestOk: "\u751F\u6210\u7ED3\u679C\uFF1A",
|
|
177
|
+
titleGenTestFailed: "\u751F\u6210\u5931\u8D25",
|
|
149
178
|
featureWsRunning: "\u6298\u53E0\u9879\u76EE\u8FD0\u884C\u63D0\u793A\uFF08\u5B9E\u9A8C\u6027\uFF09",
|
|
150
179
|
featureWsRunningDesc: "\u6298\u53E0\u7684\u9879\u76EE\u91CC\u4ECD\u6709\u4F1A\u8BDD\u5728\u8FD0\u884C\u65F6\uFF0C\u9879\u76EE\u56FE\u6807\u65CB\u8F6C\u63D0\u793A\uFF1B\u5168\u90E8\u7ED3\u675F\u6216\u5C55\u5F00\u9879\u76EE\u540E\u6062\u590D\u3002\u671F\u95F4\u6BCF 60 \u79D2\u5728\u540E\u53F0\u77ED\u6682\u5C55\u5F00\u8BE5\u9879\u76EE\u590D\u6838\u8FD0\u884C\u72B6\u6001\u518D\u6536\u8D77\uFF0C\u4F1A\u8BDD\u884C\u4E0D\u663E\u793A\uFF0C\u4EC5\u9879\u76EE\u4F4D\u7F6E\u53EF\u80FD\u6709\u7EA6\u56DB\u5206\u4E4B\u4E00\u79D2\u7684\u8F7B\u5FAE\u9AD8\u5EA6\u8D77\u4F0F\u3002",
|
|
151
180
|
tabPerformance: "\u6027\u80FD",
|
|
@@ -220,10 +249,6 @@
|
|
|
220
249
|
visionMoveDown: "\u4E0B\u79FB",
|
|
221
250
|
visionName: "\u540D\u79F0",
|
|
222
251
|
visionUseProvider: "\u4F9B\u5E94\u5546",
|
|
223
|
-
visionUseProviderHint: "\u4E0B\u62C9\u9009\u62E9\u6216\u624B\u52A8\u8F93\u5165\uFF1Asession=\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD\u4F9B\u5E94\u5546\uFF0C\u6216\u4F9B\u5E94\u5546\u540D/ID\uFF1B\u8BBE\u7F6E\u540E baseUrl/API Key/\u683C\u5F0F\u81EA\u52A8\u53D6\u8BE5\u4F9B\u5E94\u5546",
|
|
224
|
-
visionUseProviderNone: "\u4E0D\u8DDF\u968F\uFF08\u81EA\u586B\u5730\u5740\uFF09",
|
|
225
|
-
visionUseProviderSession: "\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD\uFF08session\uFF09",
|
|
226
|
-
visionUseProviderUnknown: "\u672A\u627E\u5230\u8BE5\u4F9B\u5E94\u5546\uFF0C\u8BC6\u522B\u65F6\u4F1A\u62A5\u9519\uFF1B\u8BF7\u4ECE\u4E0B\u62C9\u9009\u62E9\uFF0C\u6216\u8F93\u5165 session",
|
|
227
252
|
visionSkipAfterFailures: "\u8FDE\u7EED\u5931\u8D25\u6B21\u6570",
|
|
228
253
|
visionSkipAfterFailuresHint: "\u67D0\u4EE3\u7406\u8FDE\u7EED\u5931\u8D25\u6EE1\u6B21\u6570\u540E\u6682\u65F6\u8DF3\u8FC7\u5B83\uFF0C\u76F4\u63A5\u8BD5\u4E0B\u4E00\u4E2A\uFF1B0 = \u4E0D\u8DF3\u8FC7",
|
|
229
254
|
visionSkipMinutes: "\u8DF3\u8FC7\u5206\u949F\u6570",
|
|
@@ -332,7 +357,6 @@
|
|
|
332
357
|
upgradeDone: "\u5DF2\u66F4\u65B0\u5230 {v}",
|
|
333
358
|
upgradeFinished: "\u5347\u7EA7\u5B8C\u6210",
|
|
334
359
|
upgradeCheckFailed: "\u68C0\u67E5\u66F4\u65B0\u5931\u8D25",
|
|
335
|
-
version: "\u7248\u672C",
|
|
336
360
|
close: "\u5173\u95ED",
|
|
337
361
|
cancel: "\u53D6\u6D88",
|
|
338
362
|
pathLabel: "\u8DEF\u5F84",
|
|
@@ -376,6 +400,7 @@
|
|
|
376
400
|
tabFeatures: "Features",
|
|
377
401
|
tabStyles: "Styles",
|
|
378
402
|
tabProxy: "Proxy",
|
|
403
|
+
tabBehavior: "Behavior",
|
|
379
404
|
tabAgents: "Global Prompt",
|
|
380
405
|
agentsDesc: "Written to ~/.zcode/AGENTS.md and used as default instructions in every session across all projects. Takes effect for new sessions; per-project AGENTS.md can extend or override it. Content over 100 KB is truncated by the app.",
|
|
381
406
|
agentsPlaceholder: "Instructions followed by all projects by default; save empty to remove the global prompt",
|
|
@@ -399,12 +424,16 @@
|
|
|
399
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.",
|
|
400
425
|
tabSync: "Sync",
|
|
401
426
|
tabDebug: "Debug",
|
|
402
|
-
syncDesc:
|
|
427
|
+
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.',
|
|
403
428
|
syncUrlPlaceholder: "https://dav.example.com/dav/",
|
|
404
|
-
syncDir: "
|
|
429
|
+
syncDir: "Folder",
|
|
405
430
|
syncDirPlaceholder: "zcode-pro",
|
|
406
431
|
syncLogin: "Login",
|
|
407
432
|
syncPassword: "Password",
|
|
433
|
+
syncHistoryLimit: "History",
|
|
434
|
+
syncHistoryLimitUnit: "versions",
|
|
435
|
+
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.",
|
|
436
|
+
syncPruned: "removed {n} older history versions",
|
|
408
437
|
syncSave: "Save",
|
|
409
438
|
syncSaved: "Sync settings saved.",
|
|
410
439
|
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.",
|
|
@@ -487,6 +516,30 @@
|
|
|
487
516
|
featureSessionSwitchDesc: "alt+z toggles between the current and the last session; hold alt and press x/c to move the highlight across recently used sessions, release alt to switch (like alt+tab).",
|
|
488
517
|
featureTitleLock: "Keep renamed session titles",
|
|
489
518
|
featureTitleLockDesc: "Sessions you renamed keep their custom title: after new replies the app may show an auto-generated title instead, which reverts after a restart; this keeps the renamed title in the sidebar.",
|
|
519
|
+
tabTitleGen: "Task name prompt",
|
|
520
|
+
titleGenShortDesc: "When a new session starts answering, generates the task name with the chosen provider and prompt and saves it as a manual rename the built-in title never overrides.",
|
|
521
|
+
titleGenEnabled: "Enable",
|
|
522
|
+
titleGenProvider: "Provider",
|
|
523
|
+
titleGenProviderNone: "Custom endpoint (no provider)",
|
|
524
|
+
titleGenProviderSession: "Follow current session",
|
|
525
|
+
titleGenProviderDeleted: " (deleted)",
|
|
526
|
+
titleGenModel: "Model",
|
|
527
|
+
titleGenModelHint: "Pick from the list, or type a model id",
|
|
528
|
+
titleGenModelEmpty: "(not set)",
|
|
529
|
+
titleGenModelSessionHint: "Pick from the list; the first entry follows the session model",
|
|
530
|
+
titleGenModelFollowSession: "Follow the session model",
|
|
531
|
+
titleGenModelManualHint: "Type a model id",
|
|
532
|
+
titleGenBaseUrl: "Base URL",
|
|
533
|
+
titleGenApiKey: "API Key",
|
|
534
|
+
titleGenFormat: "Protocol",
|
|
535
|
+
titleGenPrompt: "Prompt",
|
|
536
|
+
titleGenPromptPlaceholder: "Leave empty for the built-in default prompt (button below shows it)",
|
|
537
|
+
titleGenPromptReset: "Use default prompt",
|
|
538
|
+
titleGenSample: "Test message",
|
|
539
|
+
titleGenTest: "Test",
|
|
540
|
+
titleGenTesting: "Generating\u2026",
|
|
541
|
+
titleGenTestOk: "Result: ",
|
|
542
|
+
titleGenTestFailed: "Generation failed",
|
|
490
543
|
featureWsRunning: "Running indicator on collapsed projects (experimental)",
|
|
491
544
|
featureWsRunningDesc: "Spins a collapsed project's icon while any of its sessions is still running; stops when they all finish or the project is expanded. While spinning, the project is briefly re-expanded in the background every 60 s to re-check and then collapsed \u2014 rows stay hidden, with only a subtle quarter-second height ripple at the project.",
|
|
492
545
|
tabPerformance: "Performance",
|
|
@@ -561,10 +614,6 @@
|
|
|
561
614
|
visionMoveDown: "Down",
|
|
562
615
|
visionName: "Name",
|
|
563
616
|
visionUseProvider: "Provider",
|
|
564
|
-
visionUseProviderHint: "Pick from the list or type: session = follow the current session provider, or a provider name/ID; baseUrl/API key/format follow that provider",
|
|
565
|
-
visionUseProviderNone: "Not following (enter base URL)",
|
|
566
|
-
visionUseProviderSession: "Follow session provider (session)",
|
|
567
|
-
visionUseProviderUnknown: "Unknown provider; recognition will fail. Pick from the list or type session",
|
|
568
617
|
visionSkipAfterFailures: "Skip after failures",
|
|
569
618
|
visionSkipAfterFailuresHint: "After this many consecutive failures a proxy is skipped and the next one is tried; 0 = never skip",
|
|
570
619
|
visionSkipMinutes: "Skip minutes",
|
|
@@ -673,7 +722,6 @@
|
|
|
673
722
|
upgradeDone: "Updated to {v}",
|
|
674
723
|
upgradeFinished: "Update finished",
|
|
675
724
|
upgradeCheckFailed: "Update check failed",
|
|
676
|
-
version: "Version",
|
|
677
725
|
close: "Close",
|
|
678
726
|
cancel: "Cancel",
|
|
679
727
|
pathLabel: "Path",
|
|
@@ -870,7 +918,7 @@
|
|
|
870
918
|
var overlayClassBare = "fixed inset-0 isolate z-50 flex items-center justify-center duration-100 p-4 platform-linux-desktop:top-12";
|
|
871
919
|
var contentClass = "w-full sm:max-w-md rounded-2xl border-none bg-popover/98 p-5 text-ui-base/relaxed text-foreground ring-border shadow-2xl";
|
|
872
920
|
var dialogStack = [];
|
|
873
|
-
function openDialog({ title, description, onMount, onClose, width = "sm:max-w-md", overlay = "dim", draggable = false, posKey = "", dismissOnOutside = true }) {
|
|
921
|
+
function openDialog({ title, description, onMount, onClose, width = "sm:max-w-md", overlay = "dim", draggable = false, posKey = "", dismissOnOutside = true, bodyClass = "" }) {
|
|
874
922
|
const L = t();
|
|
875
923
|
const prevActive = document.activeElement;
|
|
876
924
|
let cleanupDrag = null;
|
|
@@ -914,7 +962,7 @@
|
|
|
914
962
|
titleEl,
|
|
915
963
|
...description ? [h("p", { class: "mt-2 text-ui-sm/relaxed text-foreground-subtle" }, description)] : []
|
|
916
964
|
);
|
|
917
|
-
const body = h("div", { class: "
|
|
965
|
+
const body = h("div", { class: "zcodepro-dialog-body " + (bodyClass || "mt-4") });
|
|
918
966
|
content.append(body);
|
|
919
967
|
let restorePos = null;
|
|
920
968
|
if (draggable) {
|
|
@@ -1176,7 +1224,7 @@
|
|
|
1176
1224
|
"data-state": checked ? "on" : "off"
|
|
1177
1225
|
}, knob);
|
|
1178
1226
|
const extraEl = extra ? h("div", {
|
|
1179
|
-
class: "flex shrink-0 items-center
|
|
1227
|
+
class: "flex shrink-0 items-center",
|
|
1180
1228
|
onClick: (e) => {
|
|
1181
1229
|
e.stopPropagation();
|
|
1182
1230
|
},
|
|
@@ -1190,7 +1238,7 @@
|
|
|
1190
1238
|
const row = h(
|
|
1191
1239
|
"div",
|
|
1192
1240
|
{
|
|
1193
|
-
class: `flex cursor-pointer items-
|
|
1241
|
+
class: `flex cursor-pointer items-center gap-2 rounded-lg ${desc ? "p-2" : "p-1.5"} transition-colors hover:bg-surface-hover`,
|
|
1194
1242
|
onClick: () => {
|
|
1195
1243
|
onToggle();
|
|
1196
1244
|
}
|
|
@@ -1278,13 +1326,14 @@
|
|
|
1278
1326
|
align-items: center;
|
|
1279
1327
|
justify-content: center;
|
|
1280
1328
|
height: 24px;
|
|
1281
|
-
padding: 0
|
|
1329
|
+
padding: 0 8px;
|
|
1282
1330
|
border: none;
|
|
1283
1331
|
border-radius: 9999px;
|
|
1284
1332
|
background: transparent;
|
|
1285
1333
|
cursor: pointer;
|
|
1286
1334
|
font-size: 12px;
|
|
1287
1335
|
line-height: 1;
|
|
1336
|
+
white-space: nowrap;
|
|
1288
1337
|
color: var(--color-muted-foreground, #888);
|
|
1289
1338
|
transition: color 0.15s ease, background-color 0.15s ease;
|
|
1290
1339
|
}
|
|
@@ -1373,6 +1422,8 @@
|
|
|
1373
1422
|
.zcodepro-textarea:disabled { opacity: 0.5; }
|
|
1374
1423
|
/* \u5C0F\u578B\u6587\u672C\u57DF\uFF08\u89C6\u89C9\u4EE3\u7406\u63D0\u793A\u8BCD\u7B49\uFF09\uFF1A11rem \u6700\u5C0F\u9AD8\u5EA6\u53EA\u5C5E\u4E8E\u5168\u5C40\u63D0\u793A\u8BCD\u5927\u7F16\u8F91\u6846\uFF0C\u8FD9\u91CC\u6309 rows \u5B9A\u9AD8 */
|
|
1375
1424
|
.zcodepro-textarea.zcodepro-textarea-sm { min-height: 0; }
|
|
1425
|
+
/* \u5168\u5C40\u63D0\u793A\u8BCD\u5927\u7F16\u8F91\u6846\uFF1A\u9ED8\u8BA4/\u6700\u5927\u9AD8\u5EA6\u90FD\u6BD4\u9ED8\u8BA4\u6587\u672C\u57DF\u66F4\u9AD8 */
|
|
1426
|
+
.zcodepro-textarea.zcodepro-textarea-lg { min-height: 16rem; max-height: 40rem; }
|
|
1376
1427
|
/* \u884C\u9AD8\u6ED1\u6746\uFF08\u6837\u5F0F\u8C03\u6574\u6807\u7B7E\u9875\uFF09 */
|
|
1377
1428
|
.zcodepro-range {
|
|
1378
1429
|
-webkit-appearance: none;
|
|
@@ -1558,6 +1609,14 @@
|
|
|
1558
1609
|
}
|
|
1559
1610
|
/* \u539F\u4FA7\u680F\u83DC\u5355\u6574\u4F53\u9690\u85CF\uFF08toolbar-icons \u5F00\u542F\u65F6\uFF09 */
|
|
1560
1611
|
.zcodepro-tb-hidden { display: none !important; }
|
|
1612
|
+
/* \u539F\u751F\u9876\u680F\u65B0\u5EFA\u4EFB\u52A1\u6309\u94AE\uFF08\u6587\u4EF6\u67E5\u770B\u7B49\u5B50\u9875\u5C55\u5F00\u7684\u90A3\u4E2A\uFF09\uFF1A\u5E38\u9A7B DOM\u3001\u9760\u52A8\u753B\u5BB9\u5668
|
|
1613
|
+
\u5728 w-7/w-0 \u95F4\u5207\u6362\u663E\u9690\u3002\u529F\u80FD\u5F00\u542F\u671F\u95F4\u6574\u4F53\u9489\u6B7B\u6536\u8D77\u6001\u2014\u2014\u65B0\u5EFA\u5165\u53E3\u7EDF\u4E00\u7531\u6211\u4EEC
|
|
1614
|
+
\u7684\u6309\u94AE\u884C\u63D0\u4F9B\uFF0C\u4E5F\u5C31\u4E0D\u518D\u9700\u8981\u968F\u5B50\u9875\u8FDB\u51FA\u52A8\u6001\u663E\u9690\u81EA\u5DF1\u7684\u65B0\u5EFA\u6309\u94AE */
|
|
1615
|
+
.zcodepro-tb-hidden-native div[class*="transition-[opacity,width]"] {
|
|
1616
|
+
width: 0 !important;
|
|
1617
|
+
opacity: 0 !important;
|
|
1618
|
+
pointer-events: none !important;
|
|
1619
|
+
}
|
|
1561
1620
|
/* \u5DF2\u7F6E\u9876\u5206\u533A\u53EF\u6298\u53E0\uFF08pinned-collapse.js\uFF09\uFF1A\u6807\u9898\u6574\u884C\u53EF\u70B9\uFF0C\u6298\u53E0\u65F6\u85CF\u8D77\u4EFB\u52A1\u5217\u8868\uFF0C
|
|
1562
1621
|
chevron \u65CB\u5411\u4E0E\u201C\u9879\u76EE\u201D\u5206\u533A\u4E00\u81F4\uFF08\u6536\u8D77\u6307\u5411\u53F3\u4FA7\uFF09 */
|
|
1563
1622
|
.zcodepro-pin-head {
|
|
@@ -2212,6 +2271,12 @@
|
|
|
2212
2271
|
const path = resolveTargetPath(content);
|
|
2213
2272
|
if (!path) return;
|
|
2214
2273
|
const L = t();
|
|
2274
|
+
const fire = (endpoint, label) => {
|
|
2275
|
+
rpc(endpoint, { method: "POST", body: { path } }).then((r) => {
|
|
2276
|
+
if (r && r.ok === false) showToast(`${label}\u5931\u8D25\uFF1A${r.error || "\u672A\u77E5\u9519\u8BEF"}`, "error");
|
|
2277
|
+
}).catch(() => {
|
|
2278
|
+
});
|
|
2279
|
+
};
|
|
2215
2280
|
const noApps = items.find((el) => NO_APPS_TEXTS.some((x) => itemText(el) === x)) || content.querySelector('[data-disabled][role="menuitem"]');
|
|
2216
2281
|
const openAnchor = noApps && content.contains(noApps) ? noApps : copyAbs;
|
|
2217
2282
|
appendMenuItem(content, copyAbs, openAnchor, {
|
|
@@ -2219,10 +2284,7 @@
|
|
|
2219
2284
|
label: L.fileOpenDefault,
|
|
2220
2285
|
icon: ICON_OPEN_DEFAULT,
|
|
2221
2286
|
onPick: () => {
|
|
2222
|
-
|
|
2223
|
-
void rpc("/open-path", { method: "POST", body: { path } });
|
|
2224
|
-
} catch {
|
|
2225
|
-
}
|
|
2287
|
+
void fire("/open-path", L.fileOpenDefault);
|
|
2226
2288
|
}
|
|
2227
2289
|
});
|
|
2228
2290
|
appendMenuItem(content, copyAbs, copyAbs, {
|
|
@@ -2230,10 +2292,7 @@
|
|
|
2230
2292
|
label: L.fileReveal,
|
|
2231
2293
|
icon: ICON_REVEAL,
|
|
2232
2294
|
onPick: () => {
|
|
2233
|
-
|
|
2234
|
-
void rpc("/reveal-path", { method: "POST", body: { path } });
|
|
2235
|
-
} catch {
|
|
2236
|
-
}
|
|
2295
|
+
void fire("/reveal-path", L.fileReveal);
|
|
2237
2296
|
}
|
|
2238
2297
|
});
|
|
2239
2298
|
})();
|
|
@@ -2445,6 +2504,56 @@
|
|
|
2445
2504
|
}, true);
|
|
2446
2505
|
}
|
|
2447
2506
|
|
|
2507
|
+
// src/inject/provider-fields.js
|
|
2508
|
+
var PROVIDER_FIELD_CLS = "h-8 w-full 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";
|
|
2509
|
+
function comboField(current2, options, onChange, { disabled = false, placeholder = "", staleLabel = "\uFF08\u624B\u52A8\u8F93\u5165\uFF09", emptyLabel = "" } = {}) {
|
|
2510
|
+
const sel = h("select", { class: PROVIDER_FIELD_CLS, disabled: disabled || void 0 });
|
|
2511
|
+
const input = h("input", { type: "text", value: current2, placeholder, class: PROVIDER_FIELD_CLS, disabled: disabled || void 0 });
|
|
2512
|
+
const sync3 = () => {
|
|
2513
|
+
const cur = input.value;
|
|
2514
|
+
const opts = [...options];
|
|
2515
|
+
if (cur && !opts.some((o) => o.value === cur)) opts.push({ value: cur, label: `${cur}${staleLabel}` });
|
|
2516
|
+
if (!cur && !opts.some((o) => o.value === "")) opts.unshift({ value: "", label: emptyLabel });
|
|
2517
|
+
sel.replaceChildren(...opts.map((o) => h("option", { value: o.value, title: o.value }, o.label)));
|
|
2518
|
+
sel.value = cur;
|
|
2519
|
+
};
|
|
2520
|
+
sel.addEventListener("change", () => {
|
|
2521
|
+
input.value = sel.value;
|
|
2522
|
+
onChange(sel.value, "select");
|
|
2523
|
+
});
|
|
2524
|
+
input.addEventListener("input", () => onChange(input.value, "type"));
|
|
2525
|
+
input.addEventListener("blur", () => sync3());
|
|
2526
|
+
sync3();
|
|
2527
|
+
return h("div", { class: "flex flex-col gap-1" }, sel, input);
|
|
2528
|
+
}
|
|
2529
|
+
function providerOptionsOf(providers, L) {
|
|
2530
|
+
return [
|
|
2531
|
+
{ value: "", label: L.titleGenProviderNone },
|
|
2532
|
+
{ value: "session", label: L.titleGenProviderSession },
|
|
2533
|
+
...providers.map((p) => ({ value: p.id, label: p.name }))
|
|
2534
|
+
];
|
|
2535
|
+
}
|
|
2536
|
+
function modelOptionsOf(providerValue, providers, { followSession = false, followSessionLabel = "" } = {}) {
|
|
2537
|
+
const v = (providerValue || "").trim();
|
|
2538
|
+
const cur = providers.find((p) => p.id === v);
|
|
2539
|
+
if (cur) return cur.models.map((m) => ({ value: m, label: m }));
|
|
2540
|
+
if (v === "session") {
|
|
2541
|
+
const head = followSession && followSessionLabel ? [{ value: "", label: followSessionLabel }] : [];
|
|
2542
|
+
return [...head, ...[...new Set(providers.flatMap((p) => p.models))].map((m) => ({ value: m, label: m }))];
|
|
2543
|
+
}
|
|
2544
|
+
return [];
|
|
2545
|
+
}
|
|
2546
|
+
function modelPlaceholderOf(providerValue, L) {
|
|
2547
|
+
const v = (providerValue || "").trim();
|
|
2548
|
+
if (v === "session") return L.titleGenModelSessionHint;
|
|
2549
|
+
if (v === "") return L.titleGenModelManualHint;
|
|
2550
|
+
return L.titleGenModelHint;
|
|
2551
|
+
}
|
|
2552
|
+
function isManualConn(providerValue, providers) {
|
|
2553
|
+
const v = (providerValue || "").trim();
|
|
2554
|
+
return v === "" || v !== "session" && !providers.some((p) => p.id === v);
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2448
2557
|
// src/inject/features/styles.js
|
|
2449
2558
|
var STYLE_DEFAULTS = {
|
|
2450
2559
|
rowGap: 20,
|
|
@@ -2850,8 +2959,10 @@
|
|
|
2850
2959
|
openDialog({
|
|
2851
2960
|
title: L.settingsTitle,
|
|
2852
2961
|
// 宽度类必须用宿主样式表已有的工具类(注入的类名不会生成 CSS):
|
|
2853
|
-
// sm:max-w-3xl 不存在会失去约束拉满全屏;max-w-
|
|
2854
|
-
|
|
2962
|
+
// sm:max-w-3xl 不存在会失去约束拉满全屏;max-w-3xl=48rem 存在——英文界面
|
|
2963
|
+
// 标签栏较长,42rem 会挤出一块空白并触发横向滚动
|
|
2964
|
+
width: "max-w-3xl",
|
|
2965
|
+
bodyClass: "mt-1",
|
|
2855
2966
|
overlay: "none",
|
|
2856
2967
|
draggable: true,
|
|
2857
2968
|
posKey: "settings",
|
|
@@ -2912,7 +3023,9 @@
|
|
|
2912
3023
|
const config = await getConfig(true);
|
|
2913
3024
|
const agentsRes = await rpc("/agents");
|
|
2914
3025
|
const visionRes = await rpc("/vision");
|
|
2915
|
-
const
|
|
3026
|
+
const titleGenRes = await rpc("/title-gen");
|
|
3027
|
+
const titleGenProvidersRes = await rpc("/title-gen/providers");
|
|
3028
|
+
const titleGenProviders = titleGenProvidersRes.ok && Array.isArray(titleGenProvidersRes.providers) ? titleGenProvidersRes.providers : [];
|
|
2916
3029
|
const rtkRes = await rpc("/rtk");
|
|
2917
3030
|
const headroomRes = await rpc("/headroom");
|
|
2918
3031
|
const setFeature = async (key, value) => {
|
|
@@ -2934,7 +3047,7 @@
|
|
|
2934
3047
|
"data-zcodepro-status": "1"
|
|
2935
3048
|
},
|
|
2936
3049
|
h("span", { class: "inline-block size-2 rounded-full bg-emerald-500" }),
|
|
2937
|
-
h("span", { class: "text-foreground-subtle/70" }, `${
|
|
3050
|
+
h("span", { class: "text-foreground-subtle/70" }, `${health.version} \xB7 ${HELPER_URL}`)
|
|
2938
3051
|
);
|
|
2939
3052
|
const rows = h("div", { class: "divide-y divide-border rounded-xl border border-border" });
|
|
2940
3053
|
const refreshRows = () => {
|
|
@@ -3103,19 +3216,20 @@
|
|
|
3103
3216
|
);
|
|
3104
3217
|
const paneStyles = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3105
3218
|
const panePerf = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3106
|
-
const paneAgents = h("div", { role: "tabpanel", class: "mt-
|
|
3219
|
+
const paneAgents = h("div", { role: "tabpanel", class: "mt-2", style: "display:none" });
|
|
3107
3220
|
const paneProxy = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3108
3221
|
const paneSync = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3109
3222
|
const paneVision = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3110
3223
|
const paneRtk = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3111
3224
|
const paneHeadroom = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3225
|
+
const paneTitleGen = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3112
3226
|
const paneDebug = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3113
3227
|
const panes = { features: paneFeatures, styles: paneStyles, perf: panePerf, agents: paneAgents, proxy: paneProxy, sync: paneSync, vision: paneVision, headroom: paneHeadroom, rtk: paneRtk, debug: paneDebug };
|
|
3114
3228
|
const tabDefs = [
|
|
3115
3229
|
["features", L.tabFeatures],
|
|
3230
|
+
["agents", L.tabBehavior],
|
|
3116
3231
|
["styles", L.tabStyles],
|
|
3117
3232
|
["perf", L.tabPerformance],
|
|
3118
|
-
["agents", L.tabAgents],
|
|
3119
3233
|
["proxy", L.tabProxy],
|
|
3120
3234
|
["sync", L.tabSync],
|
|
3121
3235
|
["vision", L.tabVision],
|
|
@@ -3125,7 +3239,7 @@
|
|
|
3125
3239
|
// 普通用户不可见
|
|
3126
3240
|
...config.devMode === true || config.devActive === true ? [["debug", L.tabDebug]] : []
|
|
3127
3241
|
];
|
|
3128
|
-
const tablist = h("div", { role: "tablist", "aria-orientation": "horizontal", class: "zcodepro-tablist mt-
|
|
3242
|
+
const tablist = h("div", { role: "tablist", "aria-orientation": "horizontal", class: "zcodepro-tablist mt-1" });
|
|
3129
3243
|
const renderTabs = () => tablist.replaceChildren(...tabDefs.map(([id, label]) => h("button", {
|
|
3130
3244
|
type: "button",
|
|
3131
3245
|
role: "tab",
|
|
@@ -3334,7 +3448,7 @@
|
|
|
3334
3448
|
)
|
|
3335
3449
|
);
|
|
3336
3450
|
const agentsArea = h("textarea", {
|
|
3337
|
-
class: "zcodepro-textarea",
|
|
3451
|
+
class: "zcodepro-textarea zcodepro-textarea-lg",
|
|
3338
3452
|
placeholder: L.agentsPlaceholder,
|
|
3339
3453
|
spellcheck: "false"
|
|
3340
3454
|
});
|
|
@@ -3365,12 +3479,36 @@
|
|
|
3365
3479
|
agentsSaveBtn.disabled = false;
|
|
3366
3480
|
}
|
|
3367
3481
|
};
|
|
3368
|
-
|
|
3482
|
+
const agentsPromptPane = h("div", { class: "mt-4" });
|
|
3483
|
+
agentsPromptPane.append(
|
|
3369
3484
|
h("p", { class: "text-ui-sm/relaxed text-foreground-subtle" }, L.agentsDesc),
|
|
3370
3485
|
...agentsFailed ? [h("p", { class: "mt-2 text-ui-sm text-destructive" }, L.agentsLoadFailed + ": " + errText(agentsRes))] : [],
|
|
3371
3486
|
h("div", { class: "mt-3" }, agentsArea),
|
|
3372
3487
|
h("div", { class: "mt-3 flex justify-end" }, agentsSaveBtn)
|
|
3373
3488
|
);
|
|
3489
|
+
let agentsSubTab = "prompt";
|
|
3490
|
+
const agentsSubPanes = { prompt: agentsPromptPane, titleGen: paneTitleGen };
|
|
3491
|
+
const agentsSubList = h("div", { role: "tablist", "aria-orientation": "horizontal", class: "zcodepro-tablist" });
|
|
3492
|
+
const renderAgentsSubTabs = () => {
|
|
3493
|
+
agentsSubList.replaceChildren(...[
|
|
3494
|
+
["prompt", L.tabAgents],
|
|
3495
|
+
["titleGen", L.tabTitleGen]
|
|
3496
|
+
].map(([id, label]) => h("button", {
|
|
3497
|
+
type: "button",
|
|
3498
|
+
role: "tab",
|
|
3499
|
+
class: "zcodepro-tab",
|
|
3500
|
+
"aria-selected": String(agentsSubTab === id),
|
|
3501
|
+
"data-state": agentsSubTab === id ? "active" : "inactive",
|
|
3502
|
+
onClick: () => {
|
|
3503
|
+
agentsSubTab = id;
|
|
3504
|
+
for (const [pid, pane] of Object.entries(agentsSubPanes)) pane.style.display = pid === id ? "" : "none";
|
|
3505
|
+
renderAgentsSubTabs();
|
|
3506
|
+
}
|
|
3507
|
+
}, label)));
|
|
3508
|
+
};
|
|
3509
|
+
for (const [pid, pane] of Object.entries(agentsSubPanes)) pane.style.display = pid === agentsSubTab ? "" : "none";
|
|
3510
|
+
renderAgentsSubTabs();
|
|
3511
|
+
paneAgents.append(agentsSubList, agentsPromptPane, paneTitleGen);
|
|
3374
3512
|
const savedProxy = typeof config.proxy === "string" ? config.proxy : "";
|
|
3375
3513
|
const proxyInputCls = "h-8 w-full 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";
|
|
3376
3514
|
const proxyInput = h("input", { type: "text", value: savedProxy, placeholder: L.proxyPlaceholder, spellcheck: "false", class: proxyInputCls + " min-w-0 flex-1" });
|
|
@@ -3524,17 +3662,34 @@
|
|
|
3524
3662
|
)
|
|
3525
3663
|
);
|
|
3526
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 };
|
|
3527
|
-
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);
|
|
3528
3668
|
const syncFormRow = (labelText, node) => h(
|
|
3529
3669
|
"div",
|
|
3530
3670
|
{ class: "flex items-center gap-3 px-2 py-1.5" },
|
|
3531
|
-
|
|
3671
|
+
syncLabel(labelText),
|
|
3532
3672
|
node
|
|
3533
3673
|
);
|
|
3534
3674
|
const syncUrlInput = h("input", { type: "text", value: savedSync.url || "", placeholder: L.syncUrlPlaceholder, spellcheck: "false", autocomplete: "off", class: syncInputCls + " min-w-0 flex-1" });
|
|
3535
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" });
|
|
3536
3676
|
const syncLoginInput = h("input", { type: "text", value: savedSync.login || "", spellcheck: "false", autocomplete: "off", class: syncInputCls + " min-w-0 flex-1" });
|
|
3537
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
|
+
};
|
|
3538
3693
|
let syncFormOriginal = null;
|
|
3539
3694
|
const syncSaveBtn = btnSmall(L.syncSave, () => {
|
|
3540
3695
|
void saveSyncForm();
|
|
@@ -3543,15 +3698,16 @@
|
|
|
3543
3698
|
url: syncUrlInput.value.trim(),
|
|
3544
3699
|
dir: syncDirInput.value.trim(),
|
|
3545
3700
|
login: syncLoginInput.value.trim(),
|
|
3546
|
-
password: syncPasswordInput.value
|
|
3701
|
+
password: syncPasswordInput.value,
|
|
3702
|
+
historyLimit: syncHistoryValue()
|
|
3547
3703
|
});
|
|
3548
3704
|
const syncCheckDirty = () => {
|
|
3549
3705
|
const c = syncFormValues();
|
|
3550
|
-
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;
|
|
3551
3707
|
};
|
|
3552
3708
|
syncFormOriginal = syncFormValues();
|
|
3553
3709
|
syncSaveBtn.disabled = true;
|
|
3554
|
-
for (const el of [syncUrlInput, syncDirInput, syncLoginInput, syncPasswordInput]) {
|
|
3710
|
+
for (const el of [syncUrlInput, syncDirInput, syncLoginInput, syncPasswordInput, syncHistoryInput]) {
|
|
3555
3711
|
el.addEventListener("input", syncCheckDirty);
|
|
3556
3712
|
}
|
|
3557
3713
|
const saveSyncForm = async () => {
|
|
@@ -3562,12 +3718,14 @@
|
|
|
3562
3718
|
url: res.sync.url,
|
|
3563
3719
|
dir: res.sync.dir,
|
|
3564
3720
|
login: res.sync.login,
|
|
3565
|
-
password: res.sync.password
|
|
3721
|
+
password: res.sync.password,
|
|
3722
|
+
historyLimit: Number.isInteger(res.sync.historyLimit) ? res.sync.historyLimit : 10
|
|
3566
3723
|
};
|
|
3567
3724
|
syncUrlInput.value = res.sync.url;
|
|
3568
3725
|
syncDirInput.value = res.sync.dir;
|
|
3569
3726
|
syncLoginInput.value = res.sync.login;
|
|
3570
3727
|
syncPasswordInput.value = res.sync.password;
|
|
3728
|
+
syncHistoryInput.value = syncFormOriginal.historyLimit;
|
|
3571
3729
|
showToast(L.syncSaved);
|
|
3572
3730
|
} else {
|
|
3573
3731
|
showToast(L.failed + ": " + errText(res), "error");
|
|
@@ -3863,7 +4021,7 @@
|
|
|
3863
4021
|
return;
|
|
3864
4022
|
}
|
|
3865
4023
|
renderSyncStatus(res.sync || {});
|
|
3866
|
-
showToast(L.syncUploaded, "success");
|
|
4024
|
+
showToast(res.pruned ? L.syncUploaded + (isZhLocale() ? "\uFF1B" : "; ") + L.syncPruned.replace("{n}", res.pruned) : L.syncUploaded, "success");
|
|
3867
4025
|
};
|
|
3868
4026
|
paneSync.append(
|
|
3869
4027
|
h("p", { class: "text-ui-sm/relaxed text-foreground-subtle" }, L.syncDesc),
|
|
@@ -3871,12 +4029,27 @@
|
|
|
3871
4029
|
"div",
|
|
3872
4030
|
{ class: "mt-3 rounded-xl border border-border p-1" },
|
|
3873
4031
|
syncFormRow("URL", syncUrlInput),
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
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
|
+
),
|
|
3877
4041
|
h(
|
|
3878
4042
|
"div",
|
|
3879
|
-
{ 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" },
|
|
3880
4053
|
h(
|
|
3881
4054
|
"div",
|
|
3882
4055
|
{ class: "min-w-0" },
|
|
@@ -3966,7 +4139,6 @@
|
|
|
3966
4139
|
skipMinutes: 30,
|
|
3967
4140
|
forceIntercept: true
|
|
3968
4141
|
};
|
|
3969
|
-
const visionProviders = visionProvidersRes.ok && Array.isArray(visionProvidersRes.providers) ? visionProvidersRes.providers : [];
|
|
3970
4142
|
let visionCfg = visionRes.ok && visionRes.config && typeof visionRes.config === "object" ? structuredClone(visionRes.config) : null;
|
|
3971
4143
|
let visionSaveTimer = null;
|
|
3972
4144
|
const persistVision = async () => {
|
|
@@ -4158,53 +4330,45 @@
|
|
|
4158
4330
|
h(
|
|
4159
4331
|
"div",
|
|
4160
4332
|
{ class: "mt-2 grid grid-cols-1 gap-2 sm:grid-cols-2" },
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
const cur = (p.useProvider || "").trim();
|
|
4169
|
-
const opts = [h("option", { value: "" }, L.visionUseProviderNone), h("option", { value: "session" }, L.visionUseProviderSession)];
|
|
4170
|
-
for (const pr of visionProviders) {
|
|
4171
|
-
opts.push(h("option", { value: pr.id }, pr.name && pr.name !== pr.id ? `${pr.name}\uFF08${pr.id}\uFF09` : pr.id));
|
|
4172
|
-
}
|
|
4173
|
-
if (cur && !opts.some((o) => o.value === cur)) opts.push(h("option", { value: cur }, `${cur}\uFF08${L.visionUseProvider}\uFF09`));
|
|
4174
|
-
sel.replaceChildren(...opts);
|
|
4175
|
-
sel.value = cur;
|
|
4176
|
-
};
|
|
4177
|
-
sel.addEventListener("change", () => {
|
|
4178
|
-
input.value = sel.value;
|
|
4179
|
-
p.useProvider = sel.value.trim();
|
|
4180
|
-
warn.style.display = "none";
|
|
4333
|
+
// 供应商与模型走 provider-fields 共用逻辑:跟随会话时模型下拉为
|
|
4334
|
+
// 全部供应商模型汇总,具体供应商为其模型列表;已删 id 标注“已删除”
|
|
4335
|
+
field(L.visionUseProvider, comboField(
|
|
4336
|
+
p.useProvider || "",
|
|
4337
|
+
providerOptionsOf(titleGenProviders, L),
|
|
4338
|
+
(v, src) => {
|
|
4339
|
+
p.useProvider = v;
|
|
4181
4340
|
saveVisionSoon();
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4341
|
+
if (src === "select") renderVision();
|
|
4342
|
+
},
|
|
4343
|
+
{ placeholder: L.titleGenProviderSession, staleLabel: L.titleGenProviderDeleted }
|
|
4344
|
+
)),
|
|
4345
|
+
// 跟随会话时模型下拉头部有“跟随当前会话当前模型”(值为空,
|
|
4346
|
+
// 插件 ≥1.6.1 在调用时解析为会话当前模型);具体供应商为其模型列表
|
|
4347
|
+
field(L.visionModel, comboField(
|
|
4348
|
+
p.model || "",
|
|
4349
|
+
modelOptionsOf(p.useProvider, titleGenProviders, {
|
|
4350
|
+
followSession: (p.useProvider || "").trim() === "session",
|
|
4351
|
+
followSessionLabel: L.titleGenModelFollowSession
|
|
4352
|
+
}),
|
|
4353
|
+
(v) => {
|
|
4354
|
+
p.model = v;
|
|
4185
4355
|
saveVisionSoon();
|
|
4186
|
-
}
|
|
4187
|
-
|
|
4188
|
-
p.useProvider
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
p.
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
saveVisionSoon();
|
|
4203
|
-
})),
|
|
4204
|
-
field(L.visionApiKey + " \xB7 " + L.visionApiKeyHint, textIn(p.apiKey, (v) => {
|
|
4205
|
-
p.apiKey = v;
|
|
4206
|
-
saveVisionSoon();
|
|
4207
|
-
}, { type: "password" }))
|
|
4356
|
+
},
|
|
4357
|
+
{
|
|
4358
|
+
placeholder: modelPlaceholderOf(p.useProvider, L),
|
|
4359
|
+
emptyLabel: (p.useProvider || "").trim() === "session" ? L.titleGenModelFollowSession : L.titleGenModelEmpty
|
|
4360
|
+
}
|
|
4361
|
+
)),
|
|
4362
|
+
...isManualConn(p.useProvider, titleGenProviders) ? [
|
|
4363
|
+
field(L.visionBaseUrl, textIn(p.baseUrl, (v) => {
|
|
4364
|
+
p.baseUrl = v;
|
|
4365
|
+
saveVisionSoon();
|
|
4366
|
+
})),
|
|
4367
|
+
field(L.visionApiKey + " \xB7 " + L.visionApiKeyHint, textIn(p.apiKey, (v) => {
|
|
4368
|
+
p.apiKey = v;
|
|
4369
|
+
saveVisionSoon();
|
|
4370
|
+
}, { type: "password" }))
|
|
4371
|
+
] : []
|
|
4208
4372
|
),
|
|
4209
4373
|
(() => {
|
|
4210
4374
|
const n = h("textarea", { class: "zcodepro-textarea zcodepro-textarea-sm", rows: "3", placeholder: L.visionPrompt });
|
|
@@ -4945,13 +5109,190 @@
|
|
|
4945
5109
|
);
|
|
4946
5110
|
};
|
|
4947
5111
|
renderHeadroomPane();
|
|
5112
|
+
let titleGenCfg = titleGenRes.ok && titleGenRes.titleGen && typeof titleGenRes.titleGen === "object" ? structuredClone(titleGenRes.titleGen) : null;
|
|
5113
|
+
const titleGenDefaultPrompt = titleGenRes.ok && typeof titleGenRes.defaultPrompt === "string" ? titleGenRes.defaultPrompt : "";
|
|
5114
|
+
let titleGenSaveTimer = null;
|
|
5115
|
+
const persistTitleGen = async () => {
|
|
5116
|
+
const res = await rpc("/title-gen", { method: "POST", body: { titleGen: titleGenCfg } });
|
|
5117
|
+
clearConfigCache();
|
|
5118
|
+
if (!res.ok) showToast(L.failed + ": " + errText(res), "error");
|
|
5119
|
+
return res.ok;
|
|
5120
|
+
};
|
|
5121
|
+
const saveTitleGenSoon = () => {
|
|
5122
|
+
clearTimeout(titleGenSaveTimer);
|
|
5123
|
+
titleGenSaveTimer = setTimeout(() => {
|
|
5124
|
+
void persistTitleGen();
|
|
5125
|
+
}, 500);
|
|
5126
|
+
};
|
|
5127
|
+
const renderTitleGenPane = () => {
|
|
5128
|
+
if (!titleGenCfg) {
|
|
5129
|
+
paneTitleGen.replaceChildren(
|
|
5130
|
+
h("p", { class: "text-ui-sm/relaxed text-foreground-subtle" }, L.titleGenShortDesc),
|
|
5131
|
+
h("p", { class: "mt-2 text-ui-sm text-destructive" }, L.visionLoadFailed + ": " + errText(titleGenRes))
|
|
5132
|
+
);
|
|
5133
|
+
return;
|
|
5134
|
+
}
|
|
5135
|
+
const inputCls = "h-8 w-full 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";
|
|
5136
|
+
const field = (labelText, node) => h(
|
|
5137
|
+
"label",
|
|
5138
|
+
{ class: "block min-w-0" },
|
|
5139
|
+
h("span", { class: "mb-1 block text-ui-xs font-medium text-foreground-subtle" }, labelText),
|
|
5140
|
+
node
|
|
5141
|
+
);
|
|
5142
|
+
const showInlineConn = isManualConn(titleGenCfg.provider, titleGenProviders);
|
|
5143
|
+
const providerCombo = comboField(
|
|
5144
|
+
titleGenCfg.provider || "",
|
|
5145
|
+
providerOptionsOf(titleGenProviders, L),
|
|
5146
|
+
(v, src) => {
|
|
5147
|
+
titleGenCfg.provider = v;
|
|
5148
|
+
if (src === "select") {
|
|
5149
|
+
void persistTitleGen();
|
|
5150
|
+
renderTitleGenPane();
|
|
5151
|
+
} else saveTitleGenSoon();
|
|
5152
|
+
},
|
|
5153
|
+
{ placeholder: L.titleGenProviderSession, staleLabel: L.titleGenProviderDeleted }
|
|
5154
|
+
);
|
|
5155
|
+
const modelCombo = comboField(
|
|
5156
|
+
titleGenCfg.model || "",
|
|
5157
|
+
// 跟随会话时选项表头部有“跟随当前会话当前模型”(值为空,生成时用
|
|
5158
|
+
// 会话当前模型),选了具体模型后也能再切回它
|
|
5159
|
+
modelOptionsOf(titleGenCfg.provider, titleGenProviders, {
|
|
5160
|
+
followSession: true,
|
|
5161
|
+
followSessionLabel: L.titleGenModelFollowSession
|
|
5162
|
+
}),
|
|
5163
|
+
(v) => {
|
|
5164
|
+
titleGenCfg.model = v;
|
|
5165
|
+
saveTitleGenSoon();
|
|
5166
|
+
},
|
|
5167
|
+
{
|
|
5168
|
+
placeholder: modelPlaceholderOf(titleGenCfg.provider, L),
|
|
5169
|
+
emptyLabel: (titleGenCfg.provider || "").trim() === "session" ? L.titleGenModelFollowSession : L.titleGenModelEmpty
|
|
5170
|
+
}
|
|
5171
|
+
);
|
|
5172
|
+
const textIn = (value, onInput, { type = "text", placeholder = "" } = {}) => {
|
|
5173
|
+
const n = h("input", { type, value: value || "", placeholder, class: inputCls });
|
|
5174
|
+
n.addEventListener("input", () => onInput(n.value));
|
|
5175
|
+
return n;
|
|
5176
|
+
};
|
|
5177
|
+
const formatSel = h(
|
|
5178
|
+
"select",
|
|
5179
|
+
{ class: inputCls },
|
|
5180
|
+
h("option", { value: "anthropic" }, "anthropic"),
|
|
5181
|
+
h("option", { value: "openai" }, "openai")
|
|
5182
|
+
);
|
|
5183
|
+
formatSel.value = titleGenCfg.format === "openai" ? "openai" : "anthropic";
|
|
5184
|
+
formatSel.addEventListener("change", () => {
|
|
5185
|
+
titleGenCfg.format = formatSel.value;
|
|
5186
|
+
void persistTitleGen();
|
|
5187
|
+
});
|
|
5188
|
+
const inlineConnCard = h(
|
|
5189
|
+
"div",
|
|
5190
|
+
{
|
|
5191
|
+
class: "mt-2 grid grid-cols-1 gap-2 rounded-xl border border-border p-2 sm:grid-cols-3",
|
|
5192
|
+
style: showInlineConn ? "" : "display:none"
|
|
5193
|
+
},
|
|
5194
|
+
field(L.titleGenBaseUrl, textIn(titleGenCfg.baseUrl, (v) => {
|
|
5195
|
+
titleGenCfg.baseUrl = v;
|
|
5196
|
+
saveTitleGenSoon();
|
|
5197
|
+
}, { placeholder: "https://\u2026" })),
|
|
5198
|
+
field(L.titleGenApiKey, textIn(titleGenCfg.apiKey, (v) => {
|
|
5199
|
+
titleGenCfg.apiKey = v;
|
|
5200
|
+
saveTitleGenSoon();
|
|
5201
|
+
}, { type: "password" })),
|
|
5202
|
+
field(L.titleGenFormat, formatSel)
|
|
5203
|
+
);
|
|
5204
|
+
const promptArea = h("textarea", {
|
|
5205
|
+
class: "zcodepro-textarea zcodepro-textarea-sm",
|
|
5206
|
+
rows: "8",
|
|
5207
|
+
placeholder: L.titleGenPromptPlaceholder
|
|
5208
|
+
});
|
|
5209
|
+
promptArea.value = titleGenCfg.prompt || "";
|
|
5210
|
+
promptArea.addEventListener("input", () => {
|
|
5211
|
+
titleGenCfg.prompt = promptArea.value;
|
|
5212
|
+
saveTitleGenSoon();
|
|
5213
|
+
});
|
|
5214
|
+
const sampleText = isZhLocale() ? "\u5E2E\u6211\u770B\u4E0B\u8FD9\u4E2A\u62A5\u9519\u662F\u4EC0\u4E48\u539F\u56E0\uFF1ANullPointerException at com.example.OrderService.calculate(OrderService.java:87)" : "Why does my Spring Boot app throw NullPointerException intermittently in OrderService.calculate?";
|
|
5215
|
+
const sampleInput = h("input", {
|
|
5216
|
+
type: "text",
|
|
5217
|
+
class: inputCls + " min-w-0 flex-1",
|
|
5218
|
+
value: sampleText
|
|
5219
|
+
});
|
|
5220
|
+
let testBtn;
|
|
5221
|
+
const testState = h("span", { class: "min-w-0 flex-1 truncate text-ui-xs/relaxed text-foreground-subtle" });
|
|
5222
|
+
testBtn = btnSmall(L.titleGenTest, async () => {
|
|
5223
|
+
testBtn.disabled = true;
|
|
5224
|
+
testBtn.textContent = L.titleGenTesting;
|
|
5225
|
+
testState.textContent = L.titleGenTesting;
|
|
5226
|
+
const res = await rpc("/title-gen/run", {
|
|
5227
|
+
method: "POST",
|
|
5228
|
+
body: { text: sampleInput.value, test: true }
|
|
5229
|
+
});
|
|
5230
|
+
testBtn.disabled = false;
|
|
5231
|
+
testBtn.textContent = L.titleGenTest;
|
|
5232
|
+
if (res && res.ok) {
|
|
5233
|
+
testState.textContent = L.titleGenTestOk + res.title;
|
|
5234
|
+
showToast(res.title, "success");
|
|
5235
|
+
} else {
|
|
5236
|
+
testState.textContent = res && errText(res) || L.titleGenTestFailed;
|
|
5237
|
+
testState.className = "min-w-0 flex-1 truncate text-ui-xs/relaxed text-destructive";
|
|
5238
|
+
showToast(L.titleGenTestFailed + ": " + (res ? errText(res) : ""), "error");
|
|
5239
|
+
}
|
|
5240
|
+
}, "shrink-0");
|
|
5241
|
+
paneTitleGen.replaceChildren(
|
|
5242
|
+
// 信息卡:一句话简介在左,启用开关右对齐
|
|
5243
|
+
h(
|
|
5244
|
+
"div",
|
|
5245
|
+
{ class: "mt-3 flex items-center justify-between gap-2 rounded-xl border border-border p-2" },
|
|
5246
|
+
h("span", { class: "min-w-0 text-ui-sm/relaxed text-foreground-subtle" }, L.titleGenShortDesc),
|
|
5247
|
+
h("div", { class: "shrink-0" }, settingRow(L.titleGenEnabled, "", titleGenCfg.enabled === true, async () => {
|
|
5248
|
+
titleGenCfg.enabled = !(titleGenCfg.enabled === true);
|
|
5249
|
+
await persistTitleGen();
|
|
5250
|
+
renderTitleGenPane();
|
|
5251
|
+
}))
|
|
5252
|
+
),
|
|
5253
|
+
// 供应商 + 模型
|
|
5254
|
+
h(
|
|
5255
|
+
"div",
|
|
5256
|
+
{ class: "mt-2 grid grid-cols-1 gap-2 rounded-xl border border-border p-2 sm:grid-cols-2" },
|
|
5257
|
+
field(L.titleGenProvider, providerCombo),
|
|
5258
|
+
field(L.titleGenModel, modelCombo)
|
|
5259
|
+
),
|
|
5260
|
+
inlineConnCard,
|
|
5261
|
+
// 提示词 + 载入默认
|
|
5262
|
+
h(
|
|
5263
|
+
"div",
|
|
5264
|
+
{ class: "mt-2 rounded-xl border border-border p-2" },
|
|
5265
|
+
h(
|
|
5266
|
+
"div",
|
|
5267
|
+
{ class: "mb-1 flex items-center justify-between gap-2" },
|
|
5268
|
+
h("span", { class: "text-ui-xs font-medium text-foreground-subtle" }, L.titleGenPrompt),
|
|
5269
|
+
btnSmall(L.titleGenPromptReset, () => {
|
|
5270
|
+
promptArea.value = titleGenDefaultPrompt;
|
|
5271
|
+
titleGenCfg.prompt = titleGenDefaultPrompt;
|
|
5272
|
+
void persistTitleGen();
|
|
5273
|
+
promptArea.focus();
|
|
5274
|
+
})
|
|
5275
|
+
),
|
|
5276
|
+
promptArea
|
|
5277
|
+
),
|
|
5278
|
+
// 测试
|
|
5279
|
+
h(
|
|
5280
|
+
"div",
|
|
5281
|
+
{ class: "mt-2 flex items-center gap-2 rounded-xl border border-border p-2" },
|
|
5282
|
+
sampleInput,
|
|
5283
|
+
testBtn
|
|
5284
|
+
),
|
|
5285
|
+
testState
|
|
5286
|
+
);
|
|
5287
|
+
};
|
|
5288
|
+
renderTitleGenPane();
|
|
4948
5289
|
body.append(
|
|
4949
5290
|
statusLine,
|
|
4950
5291
|
tablist,
|
|
4951
5292
|
paneFeatures,
|
|
5293
|
+
paneAgents,
|
|
4952
5294
|
paneStyles,
|
|
4953
5295
|
panePerf,
|
|
4954
|
-
paneAgents,
|
|
4955
5296
|
paneProxy,
|
|
4956
5297
|
paneSync,
|
|
4957
5298
|
paneVision,
|
|
@@ -5424,15 +5765,68 @@
|
|
|
5424
5765
|
const map = await fetchPinned();
|
|
5425
5766
|
if (map) scan2();
|
|
5426
5767
|
}
|
|
5768
|
+
function setRowTitle(key, text) {
|
|
5769
|
+
for (const item of findRows(key)) {
|
|
5770
|
+
for (const el of titleElsOf(item)) writeTitle(el, text);
|
|
5771
|
+
}
|
|
5772
|
+
}
|
|
5773
|
+
function refreshPinnedTitles() {
|
|
5774
|
+
return fetchPinned().then((m) => {
|
|
5775
|
+
if (m) scan2();
|
|
5776
|
+
});
|
|
5777
|
+
}
|
|
5778
|
+
var RENAME_CTX_VALID_MS = 15e3;
|
|
5779
|
+
var renameCtx = null;
|
|
5780
|
+
var renamePrefilled = /* @__PURE__ */ new WeakSet();
|
|
5781
|
+
function setNativeValue(el, text) {
|
|
5782
|
+
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
5783
|
+
Object.getOwnPropertyDescriptor(el.constructor.prototype, "value").set.call(el, text);
|
|
5784
|
+
} else {
|
|
5785
|
+
el.textContent = text;
|
|
5786
|
+
}
|
|
5787
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
5788
|
+
}
|
|
5789
|
+
function prefillRenameDialog() {
|
|
5790
|
+
if (!renameCtx || !renameCtx.armed || Date.now() - renameCtx.at > RENAME_CTX_VALID_MS) {
|
|
5791
|
+
renameCtx = null;
|
|
5792
|
+
return;
|
|
5793
|
+
}
|
|
5794
|
+
if (!enabled2 || !pinned) return;
|
|
5795
|
+
const want = pinned.get(sessIdOf(renameCtx.key));
|
|
5796
|
+
if (want === void 0) return;
|
|
5797
|
+
for (const el of document.querySelectorAll('[role="dialog"] input, [role="dialog"] textarea, [role="dialog"] [contenteditable="true"]')) {
|
|
5798
|
+
if (renamePrefilled.has(el) || !el.getClientRects().length) continue;
|
|
5799
|
+
if (el.closest(TASK_SEL) || el.closest(".zcodepro-overlay")) continue;
|
|
5800
|
+
const cur = String(el.value ?? el.textContent ?? "").trim();
|
|
5801
|
+
if (!cur) continue;
|
|
5802
|
+
renamePrefilled.add(el);
|
|
5803
|
+
if (cur !== String(want).trim()) setNativeValue(el, String(want));
|
|
5804
|
+
renameCtx = null;
|
|
5805
|
+
return;
|
|
5806
|
+
}
|
|
5807
|
+
}
|
|
5427
5808
|
function startTitleLock() {
|
|
5428
5809
|
if (installed2 || typeof document === "undefined") return;
|
|
5429
5810
|
installed2 = true;
|
|
5430
5811
|
void bootstrap();
|
|
5431
5812
|
new MutationObserver((muts) => {
|
|
5813
|
+
if (renameCtx) prefillRenameDialog();
|
|
5432
5814
|
if (!taskRowMutations2(muts)) return;
|
|
5433
5815
|
refreshMapSoon();
|
|
5434
5816
|
scheduleScan2();
|
|
5435
5817
|
}).observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ["class"], characterData: true });
|
|
5818
|
+
document.addEventListener("contextmenu", (e) => {
|
|
5819
|
+
const row = e.target instanceof Element && e.target.closest(TASK_SEL);
|
|
5820
|
+
renameCtx = row ? { key: row.getAttribute("data-task-item-key") || "", at: 0, armed: false } : null;
|
|
5821
|
+
}, true);
|
|
5822
|
+
document.addEventListener("click", (e) => {
|
|
5823
|
+
if (!renameCtx || renameCtx.armed) return;
|
|
5824
|
+
const item = e.target instanceof Element && e.target.closest('[role="menuitem"], [data-radix-collection-item]');
|
|
5825
|
+
if (item && /重命名|rename/i.test(item.textContent || "")) {
|
|
5826
|
+
renameCtx.armed = true;
|
|
5827
|
+
renameCtx.at = Date.now();
|
|
5828
|
+
}
|
|
5829
|
+
}, true);
|
|
5436
5830
|
scheduleBootRetry();
|
|
5437
5831
|
setInterval(() => {
|
|
5438
5832
|
if (!document.hidden) scan2();
|
|
@@ -5459,8 +5853,152 @@
|
|
|
5459
5853
|
});
|
|
5460
5854
|
}
|
|
5461
5855
|
|
|
5462
|
-
// src/inject/features/
|
|
5856
|
+
// src/inject/features/title-gen.js
|
|
5857
|
+
var CONV2 = '[class*="@md/conversation"]';
|
|
5858
|
+
var USER_ROW = '[class*="user-row"]';
|
|
5859
|
+
var SCAN_DEBOUNCE_MS3 = 300;
|
|
5860
|
+
var SCAN_FALLBACK_MS3 = 5e3;
|
|
5861
|
+
var SELECT_WAIT_MS = 2e3;
|
|
5862
|
+
var MSG_WAIT_MS = 1e4;
|
|
5863
|
+
var QUIET_FALLBACK_MS = 12e4;
|
|
5864
|
+
var COLLECT_MAX_MS = 6e5;
|
|
5463
5865
|
var installed3 = false;
|
|
5866
|
+
var knownKeys = /* @__PURE__ */ new Set();
|
|
5867
|
+
var attempted = /* @__PURE__ */ new Set();
|
|
5868
|
+
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
5869
|
+
function sessIdOf2(key) {
|
|
5870
|
+
const i = key.indexOf(":sess_");
|
|
5871
|
+
return i > 0 ? key.slice(i + 1) : "";
|
|
5872
|
+
}
|
|
5873
|
+
function currentKey() {
|
|
5874
|
+
for (const el of document.querySelectorAll("[data-task-item-key]")) {
|
|
5875
|
+
if ((el.className + "").includes("bg-selected")) return el.getAttribute("data-task-item-key") || "";
|
|
5876
|
+
}
|
|
5877
|
+
return "";
|
|
5878
|
+
}
|
|
5879
|
+
function userTexts() {
|
|
5880
|
+
return [...document.querySelectorAll(`${CONV2} ${USER_ROW}`)].map((r) => {
|
|
5881
|
+
const el = r.querySelector(".whitespace-pre-wrap");
|
|
5882
|
+
return ((el ? el.textContent : r.innerText) || "").trim();
|
|
5883
|
+
}).filter(Boolean);
|
|
5884
|
+
}
|
|
5885
|
+
async function onNewTaskRow(key) {
|
|
5886
|
+
const selDeadline = Date.now() + SELECT_WAIT_MS;
|
|
5887
|
+
while (currentKey() !== key && Date.now() < selDeadline) await sleep(200);
|
|
5888
|
+
if (currentKey() !== key) return;
|
|
5889
|
+
const cfg = await getConfig().catch(() => null);
|
|
5890
|
+
if (!cfg || !cfg.titleGen || cfg.titleGen.enabled !== true) return;
|
|
5891
|
+
const sessId = sessIdOf2(key);
|
|
5892
|
+
if (!sessId || attempted.has(sessId)) return;
|
|
5893
|
+
attempted.add(sessId);
|
|
5894
|
+
let texts = [];
|
|
5895
|
+
const msgDeadline = Date.now() + MSG_WAIT_MS;
|
|
5896
|
+
while (Date.now() < msgDeadline) {
|
|
5897
|
+
texts = userTexts();
|
|
5898
|
+
if (texts.length) break;
|
|
5899
|
+
await sleep(400);
|
|
5900
|
+
}
|
|
5901
|
+
if (!texts.length) return;
|
|
5902
|
+
let assistantSeen = false;
|
|
5903
|
+
const convObserver = new MutationObserver((muts) => {
|
|
5904
|
+
if (currentKey() !== key) return;
|
|
5905
|
+
for (const m of muts) {
|
|
5906
|
+
const t2 = m.type === "characterData" ? m.target.parentElement : m.target;
|
|
5907
|
+
if (t2 instanceof Element && t2.closest(USER_ROW)) continue;
|
|
5908
|
+
for (const n of [t2, ...m.addedNodes]) {
|
|
5909
|
+
if (n instanceof Element && n.closest && n.closest(CONV2)) {
|
|
5910
|
+
assistantSeen = true;
|
|
5911
|
+
return;
|
|
5912
|
+
}
|
|
5913
|
+
}
|
|
5914
|
+
}
|
|
5915
|
+
});
|
|
5916
|
+
convObserver.observe(document.body, { childList: true, subtree: true, characterData: true });
|
|
5917
|
+
const startAt = Date.now();
|
|
5918
|
+
let lastCount = texts.length;
|
|
5919
|
+
let lastChange = Date.now();
|
|
5920
|
+
try {
|
|
5921
|
+
while (Date.now() - startAt < COLLECT_MAX_MS) {
|
|
5922
|
+
await sleep(500);
|
|
5923
|
+
if (currentKey() !== key) {
|
|
5924
|
+
lastChange = Date.now();
|
|
5925
|
+
continue;
|
|
5926
|
+
}
|
|
5927
|
+
texts = userTexts();
|
|
5928
|
+
if (texts.length !== lastCount) {
|
|
5929
|
+
lastCount = texts.length;
|
|
5930
|
+
lastChange = Date.now();
|
|
5931
|
+
}
|
|
5932
|
+
if (assistantSeen) break;
|
|
5933
|
+
if (Date.now() - lastChange >= QUIET_FALLBACK_MS) break;
|
|
5934
|
+
}
|
|
5935
|
+
} finally {
|
|
5936
|
+
convObserver.disconnect();
|
|
5937
|
+
}
|
|
5938
|
+
if (!texts.length) return;
|
|
5939
|
+
const callTitleGen = () => rpc("/title-gen/run", { method: "POST", body: { sessId, text: texts.join("\n") } }).catch(() => null);
|
|
5940
|
+
let res = await callTitleGen();
|
|
5941
|
+
for (const delay of [5e3, 2e4]) {
|
|
5942
|
+
if (res && res.ok) break;
|
|
5943
|
+
await sleep(delay);
|
|
5944
|
+
res = await callTitleGen();
|
|
5945
|
+
}
|
|
5946
|
+
if (res && res.ok && res.written && res.title) {
|
|
5947
|
+
setRowTitle(key, res.title);
|
|
5948
|
+
void refreshPinnedTitles();
|
|
5949
|
+
}
|
|
5950
|
+
}
|
|
5951
|
+
function scanForNewRows() {
|
|
5952
|
+
for (const el of document.querySelectorAll("[data-task-item-key]")) {
|
|
5953
|
+
const key = el.getAttribute("data-task-item-key") || "";
|
|
5954
|
+
if (!key || knownKeys.has(key)) continue;
|
|
5955
|
+
knownKeys.add(key);
|
|
5956
|
+
void onNewTaskRow(key);
|
|
5957
|
+
}
|
|
5958
|
+
}
|
|
5959
|
+
var TASK_SEL2 = "[data-task-item-key]";
|
|
5960
|
+
var inTaskRow3 = (node) => !!(node instanceof Element && node.closest && node.closest(TASK_SEL2));
|
|
5961
|
+
function taskRowMutations3(muts) {
|
|
5962
|
+
for (const m of muts) {
|
|
5963
|
+
if (m.type === "attributes") {
|
|
5964
|
+
if (inTaskRow3(m.target)) return true;
|
|
5965
|
+
} else if (m.type === "characterData") {
|
|
5966
|
+
if (m.target.parentElement && inTaskRow3(m.target.parentElement)) return true;
|
|
5967
|
+
} else if (inTaskRow3(m.target)) {
|
|
5968
|
+
return true;
|
|
5969
|
+
} else {
|
|
5970
|
+
for (const n of m.addedNodes) {
|
|
5971
|
+
if (n instanceof Element && (n.matches(TASK_SEL2) || !!n.querySelector(TASK_SEL2))) return true;
|
|
5972
|
+
}
|
|
5973
|
+
}
|
|
5974
|
+
}
|
|
5975
|
+
return false;
|
|
5976
|
+
}
|
|
5977
|
+
var scanDebounce3 = 0;
|
|
5978
|
+
function scheduleScan3() {
|
|
5979
|
+
if (scanDebounce3) return;
|
|
5980
|
+
scanDebounce3 = setTimeout(() => {
|
|
5981
|
+
scanDebounce3 = 0;
|
|
5982
|
+
scanForNewRows();
|
|
5983
|
+
}, SCAN_DEBOUNCE_MS3);
|
|
5984
|
+
}
|
|
5985
|
+
function startTitleGen() {
|
|
5986
|
+
if (installed3 || typeof document === "undefined") return;
|
|
5987
|
+
installed3 = true;
|
|
5988
|
+
scanForNewRows();
|
|
5989
|
+
new MutationObserver((muts) => {
|
|
5990
|
+
if (taskRowMutations3(muts)) scheduleScan3();
|
|
5991
|
+
}).observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ["class"], characterData: true });
|
|
5992
|
+
setInterval(() => {
|
|
5993
|
+
if (!document.hidden) scanForNewRows();
|
|
5994
|
+
}, SCAN_FALLBACK_MS3);
|
|
5995
|
+
document.addEventListener("visibilitychange", () => {
|
|
5996
|
+
if (!document.hidden) scanForNewRows();
|
|
5997
|
+
});
|
|
5998
|
+
}
|
|
5999
|
+
|
|
6000
|
+
// src/inject/features/pinned-expand.js
|
|
6001
|
+
var installed4 = false;
|
|
5464
6002
|
var keepCollapsed = false;
|
|
5465
6003
|
var CONFIG_POLL_MIN_MS = 5e3;
|
|
5466
6004
|
var CONFIG_POLL_MAX_MS = 6e4;
|
|
@@ -5487,8 +6025,8 @@
|
|
|
5487
6025
|
}, pollMs);
|
|
5488
6026
|
}
|
|
5489
6027
|
function startPinnedExpandSuppression() {
|
|
5490
|
-
if (
|
|
5491
|
-
|
|
6028
|
+
if (installed4 || typeof document === "undefined") return;
|
|
6029
|
+
installed4 = true;
|
|
5492
6030
|
void refreshConfig();
|
|
5493
6031
|
pollConfig();
|
|
5494
6032
|
document.addEventListener("visibilitychange", () => {
|
|
@@ -5567,10 +6105,10 @@
|
|
|
5567
6105
|
}
|
|
5568
6106
|
|
|
5569
6107
|
// src/inject/features/ws-running.js
|
|
5570
|
-
var
|
|
6108
|
+
var installed5 = false;
|
|
5571
6109
|
var enabled3 = true;
|
|
5572
|
-
var
|
|
5573
|
-
var
|
|
6110
|
+
var SCAN_DEBOUNCE_MS4 = 150;
|
|
6111
|
+
var SCAN_FALLBACK_MS4 = 5e3;
|
|
5574
6112
|
var PEEK_FIRST_MS = 2e4;
|
|
5575
6113
|
var PEEK_REPEAT_MS = 6e4;
|
|
5576
6114
|
var PEEK_SETTLE_MS = 160;
|
|
@@ -5578,7 +6116,7 @@
|
|
|
5578
6116
|
var PEEK_UNMOUNT_WAIT_MS = 800;
|
|
5579
6117
|
var CONFIG_POLL_MIN_MS2 = 5e3;
|
|
5580
6118
|
var CONFIG_POLL_MAX_MS2 = 6e4;
|
|
5581
|
-
var
|
|
6119
|
+
var TASK_SEL3 = "[data-task-item-key]";
|
|
5582
6120
|
var WS_SEL = '[data-testid^="workspace-item-"]';
|
|
5583
6121
|
var runningByWs = /* @__PURE__ */ new Map();
|
|
5584
6122
|
var peekTimers = /* @__PURE__ */ new Map();
|
|
@@ -5601,10 +6139,10 @@
|
|
|
5601
6139
|
return [...holder.children].some((c) => c.tagName === "svg" && (c.getAttribute("class") || "").includes("lucide-loader"));
|
|
5602
6140
|
}
|
|
5603
6141
|
function domRowsOf(ws) {
|
|
5604
|
-
return [...document.querySelectorAll(
|
|
6142
|
+
return [...document.querySelectorAll(TASK_SEL3)].filter((e) => workspaceOf2(e.getAttribute("data-task-item-key") || "") === ws);
|
|
5605
6143
|
}
|
|
5606
6144
|
function currentTaskRow2() {
|
|
5607
|
-
for (const el of document.querySelectorAll(
|
|
6145
|
+
for (const el of document.querySelectorAll(TASK_SEL3)) {
|
|
5608
6146
|
if ((el.className + "").includes("bg-selected")) return el;
|
|
5609
6147
|
}
|
|
5610
6148
|
return null;
|
|
@@ -5620,12 +6158,12 @@
|
|
|
5620
6158
|
const backKey = cur ? cur.getAttribute("data-task-item-key") : "";
|
|
5621
6159
|
synthClick(head);
|
|
5622
6160
|
if (!backKey) return;
|
|
5623
|
-
const back = cur && cur.isConnected ? cur : document.querySelector(`${
|
|
6161
|
+
const back = cur && cur.isConnected ? cur : document.querySelector(`${TASK_SEL3}[data-task-item-key="${CSS.escape(backKey)}"]`);
|
|
5624
6162
|
if (back) synthClick(back);
|
|
5625
6163
|
}
|
|
5626
6164
|
function scan3() {
|
|
5627
6165
|
wsWithRows = /* @__PURE__ */ new Set();
|
|
5628
|
-
for (const el of document.querySelectorAll(
|
|
6166
|
+
for (const el of document.querySelectorAll(TASK_SEL3)) {
|
|
5629
6167
|
const key = el.getAttribute("data-task-item-key") || "";
|
|
5630
6168
|
const ws = workspaceOf2(key);
|
|
5631
6169
|
if (!ws) continue;
|
|
@@ -5651,8 +6189,8 @@
|
|
|
5651
6189
|
if (m.type !== "childList") continue;
|
|
5652
6190
|
for (const n of m.removedNodes) {
|
|
5653
6191
|
if (!(n instanceof Element)) continue;
|
|
5654
|
-
if (n.matches(
|
|
5655
|
-
else for (const r of n.querySelectorAll(
|
|
6192
|
+
if (n.matches(TASK_SEL3)) removed.push(n);
|
|
6193
|
+
else for (const r of n.querySelectorAll(TASK_SEL3)) removed.push(r);
|
|
5656
6194
|
}
|
|
5657
6195
|
}
|
|
5658
6196
|
if (!removed.length) return;
|
|
@@ -5835,7 +6373,7 @@
|
|
|
5835
6373
|
var PEEK_EXEMPT_CLASS = "zcodepro-peek-exempt";
|
|
5836
6374
|
var cssAttr = (v) => String(v).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
5837
6375
|
function installPeekHider(ws) {
|
|
5838
|
-
const rowSel3 = `${
|
|
6376
|
+
const rowSel3 = `${TASK_SEL3}[data-task-item-key^="${cssAttr(ws + ":")}"]`;
|
|
5839
6377
|
for (const r of document.querySelectorAll(rowSel3)) r.classList.add(PEEK_EXEMPT_CLASS);
|
|
5840
6378
|
const style = document.createElement("style");
|
|
5841
6379
|
style.textContent = `${rowSel3}:not(.${PEEK_EXEMPT_CLASS}){display:none!important}`;
|
|
@@ -5847,7 +6385,7 @@
|
|
|
5847
6385
|
for (const r of document.querySelectorAll("." + PEEK_EXEMPT_CLASS)) r.classList.remove(PEEK_EXEMPT_CLASS);
|
|
5848
6386
|
}
|
|
5849
6387
|
function waitForRowsGone(ws) {
|
|
5850
|
-
const sel = `${
|
|
6388
|
+
const sel = `${TASK_SEL3}[data-task-item-key^="${cssAttr(ws + ":")}"]:not(.${PEEK_EXEMPT_CLASS})`;
|
|
5851
6389
|
return new Promise((resolve) => {
|
|
5852
6390
|
const t0 = Date.now();
|
|
5853
6391
|
const timer = setInterval(() => {
|
|
@@ -5869,12 +6407,12 @@
|
|
|
5869
6407
|
}
|
|
5870
6408
|
function relevant(muts) {
|
|
5871
6409
|
for (const m of muts) {
|
|
5872
|
-
if (inSel(m.target,
|
|
6410
|
+
if (inSel(m.target, TASK_SEL3) || inSel(m.target, WS_SEL)) return true;
|
|
5873
6411
|
for (const n of m.addedNodes) {
|
|
5874
|
-
if (n instanceof Element && (n.matches(
|
|
6412
|
+
if (n instanceof Element && (n.matches(TASK_SEL3) || n.matches(WS_SEL) || n.querySelector(TASK_SEL3) || n.querySelector(WS_SEL))) return true;
|
|
5875
6413
|
}
|
|
5876
6414
|
for (const n of m.removedNodes) {
|
|
5877
|
-
if (n instanceof Element && (n.matches(
|
|
6415
|
+
if (n instanceof Element && (n.matches(TASK_SEL3) || n.matches(WS_SEL) || n.querySelector(TASK_SEL3))) return true;
|
|
5878
6416
|
}
|
|
5879
6417
|
}
|
|
5880
6418
|
return false;
|
|
@@ -5905,27 +6443,27 @@
|
|
|
5905
6443
|
pollConfig2();
|
|
5906
6444
|
}, pollMs2);
|
|
5907
6445
|
}
|
|
5908
|
-
var
|
|
6446
|
+
var scanDebounce4 = 0;
|
|
5909
6447
|
function startWsRunningSpin() {
|
|
5910
|
-
if (
|
|
5911
|
-
|
|
6448
|
+
if (installed5 || typeof document === "undefined") return;
|
|
6449
|
+
installed5 = true;
|
|
5912
6450
|
void refreshConfig2();
|
|
5913
6451
|
pollConfig2();
|
|
5914
6452
|
const observer2 = new MutationObserver((muts) => {
|
|
5915
6453
|
if (!relevant(muts)) return;
|
|
5916
6454
|
handleRemovals(muts);
|
|
5917
|
-
if (!
|
|
5918
|
-
|
|
5919
|
-
|
|
6455
|
+
if (!scanDebounce4) {
|
|
6456
|
+
scanDebounce4 = setTimeout(() => {
|
|
6457
|
+
scanDebounce4 = 0;
|
|
5920
6458
|
scan3();
|
|
5921
|
-
},
|
|
6459
|
+
}, SCAN_DEBOUNCE_MS4);
|
|
5922
6460
|
}
|
|
5923
6461
|
});
|
|
5924
6462
|
observer2.observe(document.body, { childList: true, subtree: true });
|
|
5925
6463
|
scan3();
|
|
5926
6464
|
setInterval(() => {
|
|
5927
6465
|
if (!document.hidden && enabled3) scan3();
|
|
5928
|
-
},
|
|
6466
|
+
}, SCAN_FALLBACK_MS4);
|
|
5929
6467
|
document.addEventListener("visibilitychange", () => {
|
|
5930
6468
|
if (!document.hidden) scan3();
|
|
5931
6469
|
});
|
|
@@ -6089,7 +6627,7 @@
|
|
|
6089
6627
|
// src/inject/features/toolbar-icons.js
|
|
6090
6628
|
var HIDE_CLASS = "zcodepro-tb-hidden";
|
|
6091
6629
|
var SYNC_DEBOUNCE_MS = 150;
|
|
6092
|
-
var
|
|
6630
|
+
var SCAN_FALLBACK_MS5 = 5e3;
|
|
6093
6631
|
var ROW_SEL = "[data-task-item-key]";
|
|
6094
6632
|
var MENU_SEL = '[data-testid="task-new-button"], [data-testid="automations-open"], [data-testid="plugin-store-sidebar-open"], [data-slot="command"], [data-testid="desktop-top-nav-back"]';
|
|
6095
6633
|
var enabled4 = true;
|
|
@@ -6161,6 +6699,7 @@
|
|
|
6161
6699
|
menu.classList.add(HIDE_CLASS);
|
|
6162
6700
|
origs = next;
|
|
6163
6701
|
rowEl?.remove();
|
|
6702
|
+
navRow.classList.add("zcodepro-tb-hidden-native");
|
|
6164
6703
|
const L = t();
|
|
6165
6704
|
const mk = (kind, orig, nameSel, fallback) => h("button", {
|
|
6166
6705
|
type: "button",
|
|
@@ -6186,7 +6725,9 @@
|
|
|
6186
6725
|
const pIcon = iconOf(next.plugin);
|
|
6187
6726
|
if (pIcon) pluginBtn.append(pIcon);
|
|
6188
6727
|
rowEl = h("div", { class: "zcodepro-tb-row" }, newBtn, searchBtn, autoBtn, pluginBtn);
|
|
6189
|
-
navRow.
|
|
6728
|
+
const updBtn = [...navRow.querySelectorAll("button")].find((b) => /bg-(success|emerald)/.test(b.className || ""));
|
|
6729
|
+
if (updBtn) updBtn.before(rowEl);
|
|
6730
|
+
else navRow.append(rowEl);
|
|
6190
6731
|
return true;
|
|
6191
6732
|
}
|
|
6192
6733
|
function sidebarCollapsed() {
|
|
@@ -6216,10 +6757,18 @@
|
|
|
6216
6757
|
if (sidebarCollapsed() || sidebarTooNarrow()) {
|
|
6217
6758
|
if (rowEl) rowEl.style.display = "none";
|
|
6218
6759
|
menu.classList.remove(HIDE_CLASS);
|
|
6760
|
+
document.querySelectorAll(".zcodepro-tb-hidden-native").forEach((el) => el.classList.remove("zcodepro-tb-hidden-native"));
|
|
6219
6761
|
return;
|
|
6220
6762
|
}
|
|
6221
6763
|
const alive = origs && origs.menu === menu && origs.newTask.isConnected && origs.search.isConnected && origs.auto.isConnected && origs.plugin.isConnected && rowEl && rowEl.isConnected;
|
|
6222
|
-
if (!alive && !rebuild())
|
|
6764
|
+
if (!alive && !rebuild()) {
|
|
6765
|
+
if (rowEl) rowEl.style.display = "none";
|
|
6766
|
+
setTimeout(scheduleSync, 400);
|
|
6767
|
+
setTimeout(scheduleSync, 1200);
|
|
6768
|
+
return;
|
|
6769
|
+
}
|
|
6770
|
+
const navRow = document.querySelector('[data-testid="desktop-top-nav-back"]')?.parentElement;
|
|
6771
|
+
if (navRow) navRow.classList.add("zcodepro-tb-hidden-native");
|
|
6223
6772
|
menu.classList.add(HIDE_CLASS);
|
|
6224
6773
|
if (rowEl) rowEl.style.display = "";
|
|
6225
6774
|
syncActive();
|
|
@@ -6255,6 +6804,7 @@
|
|
|
6255
6804
|
rowEl = null;
|
|
6256
6805
|
if (origs) {
|
|
6257
6806
|
origs.menu.classList.remove(HIDE_CLASS);
|
|
6807
|
+
document.querySelectorAll(".zcodepro-tb-hidden-native").forEach((el) => el.classList.remove("zcodepro-tb-hidden-native"));
|
|
6258
6808
|
origs = null;
|
|
6259
6809
|
}
|
|
6260
6810
|
}
|
|
@@ -6275,7 +6825,7 @@
|
|
|
6275
6825
|
}).observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ["class", "aria-pressed"] });
|
|
6276
6826
|
setInterval(() => {
|
|
6277
6827
|
if (!document.hidden) sync();
|
|
6278
|
-
},
|
|
6828
|
+
}, SCAN_FALLBACK_MS5);
|
|
6279
6829
|
document.addEventListener("visibilitychange", () => {
|
|
6280
6830
|
if (!document.hidden) sync();
|
|
6281
6831
|
});
|
|
@@ -6286,7 +6836,7 @@
|
|
|
6286
6836
|
var HEAD_CLASS = "zcodepro-pin-head";
|
|
6287
6837
|
var STORE_KEY = "zcodepro:pinned-collapsed";
|
|
6288
6838
|
var SYNC_DEBOUNCE_MS2 = 300;
|
|
6289
|
-
var
|
|
6839
|
+
var SCAN_FALLBACK_MS6 = 5e3;
|
|
6290
6840
|
var enabled5 = true;
|
|
6291
6841
|
var syncTimer2 = 0;
|
|
6292
6842
|
function findPinnedHeader() {
|
|
@@ -6405,7 +6955,7 @@
|
|
|
6405
6955
|
}).observe(document.body, { childList: true, subtree: true });
|
|
6406
6956
|
setInterval(() => {
|
|
6407
6957
|
if (!document.hidden) sync2();
|
|
6408
|
-
},
|
|
6958
|
+
}, SCAN_FALLBACK_MS6);
|
|
6409
6959
|
document.addEventListener("visibilitychange", () => {
|
|
6410
6960
|
if (!document.hidden) sync2();
|
|
6411
6961
|
});
|
|
@@ -6486,6 +7036,10 @@
|
|
|
6486
7036
|
startTitleLock();
|
|
6487
7037
|
} catch {
|
|
6488
7038
|
}
|
|
7039
|
+
try {
|
|
7040
|
+
startTitleGen();
|
|
7041
|
+
} catch {
|
|
7042
|
+
}
|
|
6489
7043
|
try {
|
|
6490
7044
|
startImageMenu();
|
|
6491
7045
|
} catch {
|