zcode-pro 0.18.0 → 0.19.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/dist/inject.js +573 -111
- package/package.json +1 -1
- package/src/host/helper.mjs +457 -34
- package/src/host/taskIndex.mjs +83 -0
- package/src/inject/core.js +50 -10
- package/src/inject/features/file-menu.js +9 -2
- package/src/inject/features/settings-dialog.js +224 -48
- package/src/inject/features/title-gen.js +169 -0
- package/src/inject/features/title-lock.js +14 -0
- package/src/inject/features/toolbar-icons.js +38 -4
- 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",
|
|
@@ -146,6 +147,30 @@
|
|
|
146
147
|
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
148
|
featureTitleLock: "\u91CD\u547D\u540D\u4F1A\u8BDD\u540D\u9501\u5B9A",
|
|
148
149
|
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",
|
|
150
|
+
tabTitleGen: "\u4EFB\u52A1\u540D\u63D0\u793A\u8BCD",
|
|
151
|
+
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",
|
|
152
|
+
titleGenEnabled: "\u542F\u7528",
|
|
153
|
+
titleGenProvider: "\u4F9B\u5E94\u5546",
|
|
154
|
+
titleGenProviderNone: "\u4E0D\u8DDF\u968F\uFF08\u81EA\u586B\u5730\u5740\uFF09",
|
|
155
|
+
titleGenProviderSession: "\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD",
|
|
156
|
+
titleGenProviderDeleted: "\uFF08\u5DF2\u5220\u9664\uFF09",
|
|
157
|
+
titleGenModel: "\u6A21\u578B",
|
|
158
|
+
titleGenModelHint: "\u4ECE\u5217\u8868\u9009\u62E9\uFF0C\u6216\u76F4\u63A5\u586B\u5199\u6A21\u578B id",
|
|
159
|
+
titleGenModelEmpty: "\uFF08\u672A\u9009\u62E9\uFF09",
|
|
160
|
+
titleGenModelSessionHint: "\u4ECE\u5217\u8868\u9009\u62E9\u6A21\u578B\uFF1B\u5217\u8868\u7B2C\u4E00\u9879\u4E3A\u8DDF\u968F\u4F1A\u8BDD\u5F53\u524D\u6A21\u578B",
|
|
161
|
+
titleGenModelFollowSession: "\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD\u5F53\u524D\u6A21\u578B",
|
|
162
|
+
titleGenModelManualHint: "\u8F93\u5165\u6A21\u578B id",
|
|
163
|
+
titleGenBaseUrl: "\u63A5\u53E3\u5730\u5740",
|
|
164
|
+
titleGenApiKey: "API Key",
|
|
165
|
+
titleGenFormat: "\u534F\u8BAE",
|
|
166
|
+
titleGenPrompt: "\u63D0\u793A\u8BCD",
|
|
167
|
+
titleGenPromptPlaceholder: "\u7559\u7A7A\u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u63D0\u793A\u8BCD\uFF08\u70B9\u51FB\u4E0B\u65B9\u6309\u94AE\u53EF\u67E5\u770B\uFF09",
|
|
168
|
+
titleGenPromptReset: "\u4F7F\u7528\u9ED8\u8BA4\u63D0\u793A\u8BCD",
|
|
169
|
+
titleGenSample: "\u6D4B\u8BD5\u6D88\u606F",
|
|
170
|
+
titleGenTest: "\u6D4B\u8BD5\u751F\u6210",
|
|
171
|
+
titleGenTesting: "\u751F\u6210\u4E2D\u2026",
|
|
172
|
+
titleGenTestOk: "\u751F\u6210\u7ED3\u679C\uFF1A",
|
|
173
|
+
titleGenTestFailed: "\u751F\u6210\u5931\u8D25",
|
|
149
174
|
featureWsRunning: "\u6298\u53E0\u9879\u76EE\u8FD0\u884C\u63D0\u793A\uFF08\u5B9E\u9A8C\u6027\uFF09",
|
|
150
175
|
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
176
|
tabPerformance: "\u6027\u80FD",
|
|
@@ -220,10 +245,6 @@
|
|
|
220
245
|
visionMoveDown: "\u4E0B\u79FB",
|
|
221
246
|
visionName: "\u540D\u79F0",
|
|
222
247
|
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
248
|
visionSkipAfterFailures: "\u8FDE\u7EED\u5931\u8D25\u6B21\u6570",
|
|
228
249
|
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
250
|
visionSkipMinutes: "\u8DF3\u8FC7\u5206\u949F\u6570",
|
|
@@ -332,7 +353,6 @@
|
|
|
332
353
|
upgradeDone: "\u5DF2\u66F4\u65B0\u5230 {v}",
|
|
333
354
|
upgradeFinished: "\u5347\u7EA7\u5B8C\u6210",
|
|
334
355
|
upgradeCheckFailed: "\u68C0\u67E5\u66F4\u65B0\u5931\u8D25",
|
|
335
|
-
version: "\u7248\u672C",
|
|
336
356
|
close: "\u5173\u95ED",
|
|
337
357
|
cancel: "\u53D6\u6D88",
|
|
338
358
|
pathLabel: "\u8DEF\u5F84",
|
|
@@ -376,6 +396,7 @@
|
|
|
376
396
|
tabFeatures: "Features",
|
|
377
397
|
tabStyles: "Styles",
|
|
378
398
|
tabProxy: "Proxy",
|
|
399
|
+
tabBehavior: "Behavior",
|
|
379
400
|
tabAgents: "Global Prompt",
|
|
380
401
|
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
402
|
agentsPlaceholder: "Instructions followed by all projects by default; save empty to remove the global prompt",
|
|
@@ -487,6 +508,30 @@
|
|
|
487
508
|
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
509
|
featureTitleLock: "Keep renamed session titles",
|
|
489
510
|
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.",
|
|
511
|
+
tabTitleGen: "Task name prompt",
|
|
512
|
+
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.",
|
|
513
|
+
titleGenEnabled: "Enable",
|
|
514
|
+
titleGenProvider: "Provider",
|
|
515
|
+
titleGenProviderNone: "Custom endpoint (no provider)",
|
|
516
|
+
titleGenProviderSession: "Follow current session",
|
|
517
|
+
titleGenProviderDeleted: " (deleted)",
|
|
518
|
+
titleGenModel: "Model",
|
|
519
|
+
titleGenModelHint: "Pick from the list, or type a model id",
|
|
520
|
+
titleGenModelEmpty: "(not set)",
|
|
521
|
+
titleGenModelSessionHint: "Pick from the list; the first entry follows the session model",
|
|
522
|
+
titleGenModelFollowSession: "Follow the session model",
|
|
523
|
+
titleGenModelManualHint: "Type a model id",
|
|
524
|
+
titleGenBaseUrl: "Base URL",
|
|
525
|
+
titleGenApiKey: "API Key",
|
|
526
|
+
titleGenFormat: "Protocol",
|
|
527
|
+
titleGenPrompt: "Prompt",
|
|
528
|
+
titleGenPromptPlaceholder: "Leave empty for the built-in default prompt (button below shows it)",
|
|
529
|
+
titleGenPromptReset: "Use default prompt",
|
|
530
|
+
titleGenSample: "Test message",
|
|
531
|
+
titleGenTest: "Test",
|
|
532
|
+
titleGenTesting: "Generating\u2026",
|
|
533
|
+
titleGenTestOk: "Result: ",
|
|
534
|
+
titleGenTestFailed: "Generation failed",
|
|
490
535
|
featureWsRunning: "Running indicator on collapsed projects (experimental)",
|
|
491
536
|
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
537
|
tabPerformance: "Performance",
|
|
@@ -561,10 +606,6 @@
|
|
|
561
606
|
visionMoveDown: "Down",
|
|
562
607
|
visionName: "Name",
|
|
563
608
|
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
609
|
visionSkipAfterFailures: "Skip after failures",
|
|
569
610
|
visionSkipAfterFailuresHint: "After this many consecutive failures a proxy is skipped and the next one is tried; 0 = never skip",
|
|
570
611
|
visionSkipMinutes: "Skip minutes",
|
|
@@ -673,7 +714,6 @@
|
|
|
673
714
|
upgradeDone: "Updated to {v}",
|
|
674
715
|
upgradeFinished: "Update finished",
|
|
675
716
|
upgradeCheckFailed: "Update check failed",
|
|
676
|
-
version: "Version",
|
|
677
717
|
close: "Close",
|
|
678
718
|
cancel: "Cancel",
|
|
679
719
|
pathLabel: "Path",
|
|
@@ -870,7 +910,7 @@
|
|
|
870
910
|
var overlayClassBare = "fixed inset-0 isolate z-50 flex items-center justify-center duration-100 p-4 platform-linux-desktop:top-12";
|
|
871
911
|
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
912
|
var dialogStack = [];
|
|
873
|
-
function openDialog({ title, description, onMount, onClose, width = "sm:max-w-md", overlay = "dim", draggable = false, posKey = "", dismissOnOutside = true }) {
|
|
913
|
+
function openDialog({ title, description, onMount, onClose, width = "sm:max-w-md", overlay = "dim", draggable = false, posKey = "", dismissOnOutside = true, bodyClass = "" }) {
|
|
874
914
|
const L = t();
|
|
875
915
|
const prevActive = document.activeElement;
|
|
876
916
|
let cleanupDrag = null;
|
|
@@ -914,7 +954,7 @@
|
|
|
914
954
|
titleEl,
|
|
915
955
|
...description ? [h("p", { class: "mt-2 text-ui-sm/relaxed text-foreground-subtle" }, description)] : []
|
|
916
956
|
);
|
|
917
|
-
const body = h("div", { class: "
|
|
957
|
+
const body = h("div", { class: "zcodepro-dialog-body " + (bodyClass || "mt-4") });
|
|
918
958
|
content.append(body);
|
|
919
959
|
let restorePos = null;
|
|
920
960
|
if (draggable) {
|
|
@@ -1176,7 +1216,7 @@
|
|
|
1176
1216
|
"data-state": checked ? "on" : "off"
|
|
1177
1217
|
}, knob);
|
|
1178
1218
|
const extraEl = extra ? h("div", {
|
|
1179
|
-
class: "flex shrink-0 items-center
|
|
1219
|
+
class: "flex shrink-0 items-center",
|
|
1180
1220
|
onClick: (e) => {
|
|
1181
1221
|
e.stopPropagation();
|
|
1182
1222
|
},
|
|
@@ -1190,7 +1230,7 @@
|
|
|
1190
1230
|
const row = h(
|
|
1191
1231
|
"div",
|
|
1192
1232
|
{
|
|
1193
|
-
class: `flex cursor-pointer items-
|
|
1233
|
+
class: `flex cursor-pointer items-center gap-2 rounded-lg ${desc ? "p-2" : "p-1.5"} transition-colors hover:bg-surface-hover`,
|
|
1194
1234
|
onClick: () => {
|
|
1195
1235
|
onToggle();
|
|
1196
1236
|
}
|
|
@@ -1278,13 +1318,14 @@
|
|
|
1278
1318
|
align-items: center;
|
|
1279
1319
|
justify-content: center;
|
|
1280
1320
|
height: 24px;
|
|
1281
|
-
padding: 0
|
|
1321
|
+
padding: 0 8px;
|
|
1282
1322
|
border: none;
|
|
1283
1323
|
border-radius: 9999px;
|
|
1284
1324
|
background: transparent;
|
|
1285
1325
|
cursor: pointer;
|
|
1286
1326
|
font-size: 12px;
|
|
1287
1327
|
line-height: 1;
|
|
1328
|
+
white-space: nowrap;
|
|
1288
1329
|
color: var(--color-muted-foreground, #888);
|
|
1289
1330
|
transition: color 0.15s ease, background-color 0.15s ease;
|
|
1290
1331
|
}
|
|
@@ -1373,6 +1414,8 @@
|
|
|
1373
1414
|
.zcodepro-textarea:disabled { opacity: 0.5; }
|
|
1374
1415
|
/* \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
1416
|
.zcodepro-textarea.zcodepro-textarea-sm { min-height: 0; }
|
|
1417
|
+
/* \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 */
|
|
1418
|
+
.zcodepro-textarea.zcodepro-textarea-lg { min-height: 16rem; max-height: 40rem; }
|
|
1376
1419
|
/* \u884C\u9AD8\u6ED1\u6746\uFF08\u6837\u5F0F\u8C03\u6574\u6807\u7B7E\u9875\uFF09 */
|
|
1377
1420
|
.zcodepro-range {
|
|
1378
1421
|
-webkit-appearance: none;
|
|
@@ -1558,6 +1601,14 @@
|
|
|
1558
1601
|
}
|
|
1559
1602
|
/* \u539F\u4FA7\u680F\u83DC\u5355\u6574\u4F53\u9690\u85CF\uFF08toolbar-icons \u5F00\u542F\u65F6\uFF09 */
|
|
1560
1603
|
.zcodepro-tb-hidden { display: none !important; }
|
|
1604
|
+
/* \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
|
|
1605
|
+
\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
|
|
1606
|
+
\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 */
|
|
1607
|
+
.zcodepro-tb-hidden-native div[class*="transition-[opacity,width]"] {
|
|
1608
|
+
width: 0 !important;
|
|
1609
|
+
opacity: 0 !important;
|
|
1610
|
+
pointer-events: none !important;
|
|
1611
|
+
}
|
|
1561
1612
|
/* \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
1613
|
chevron \u65CB\u5411\u4E0E\u201C\u9879\u76EE\u201D\u5206\u533A\u4E00\u81F4\uFF08\u6536\u8D77\u6307\u5411\u53F3\u4FA7\uFF09 */
|
|
1563
1614
|
.zcodepro-pin-head {
|
|
@@ -2212,6 +2263,12 @@
|
|
|
2212
2263
|
const path = resolveTargetPath(content);
|
|
2213
2264
|
if (!path) return;
|
|
2214
2265
|
const L = t();
|
|
2266
|
+
const fire = (endpoint, label) => {
|
|
2267
|
+
rpc(endpoint, { method: "POST", body: { path } }).then((r) => {
|
|
2268
|
+
if (r && r.ok === false) showToast(`${label}\u5931\u8D25\uFF1A${r.error || "\u672A\u77E5\u9519\u8BEF"}`, "error");
|
|
2269
|
+
}).catch(() => {
|
|
2270
|
+
});
|
|
2271
|
+
};
|
|
2215
2272
|
const noApps = items.find((el) => NO_APPS_TEXTS.some((x) => itemText(el) === x)) || content.querySelector('[data-disabled][role="menuitem"]');
|
|
2216
2273
|
const openAnchor = noApps && content.contains(noApps) ? noApps : copyAbs;
|
|
2217
2274
|
appendMenuItem(content, copyAbs, openAnchor, {
|
|
@@ -2219,10 +2276,7 @@
|
|
|
2219
2276
|
label: L.fileOpenDefault,
|
|
2220
2277
|
icon: ICON_OPEN_DEFAULT,
|
|
2221
2278
|
onPick: () => {
|
|
2222
|
-
|
|
2223
|
-
void rpc("/open-path", { method: "POST", body: { path } });
|
|
2224
|
-
} catch {
|
|
2225
|
-
}
|
|
2279
|
+
void fire("/open-path", L.fileOpenDefault);
|
|
2226
2280
|
}
|
|
2227
2281
|
});
|
|
2228
2282
|
appendMenuItem(content, copyAbs, copyAbs, {
|
|
@@ -2230,10 +2284,7 @@
|
|
|
2230
2284
|
label: L.fileReveal,
|
|
2231
2285
|
icon: ICON_REVEAL,
|
|
2232
2286
|
onPick: () => {
|
|
2233
|
-
|
|
2234
|
-
void rpc("/reveal-path", { method: "POST", body: { path } });
|
|
2235
|
-
} catch {
|
|
2236
|
-
}
|
|
2287
|
+
void fire("/reveal-path", L.fileReveal);
|
|
2237
2288
|
}
|
|
2238
2289
|
});
|
|
2239
2290
|
})();
|
|
@@ -2445,6 +2496,56 @@
|
|
|
2445
2496
|
}, true);
|
|
2446
2497
|
}
|
|
2447
2498
|
|
|
2499
|
+
// src/inject/provider-fields.js
|
|
2500
|
+
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";
|
|
2501
|
+
function comboField(current2, options, onChange, { disabled = false, placeholder = "", staleLabel = "\uFF08\u624B\u52A8\u8F93\u5165\uFF09", emptyLabel = "" } = {}) {
|
|
2502
|
+
const sel = h("select", { class: PROVIDER_FIELD_CLS, disabled: disabled || void 0 });
|
|
2503
|
+
const input = h("input", { type: "text", value: current2, placeholder, class: PROVIDER_FIELD_CLS, disabled: disabled || void 0 });
|
|
2504
|
+
const sync3 = () => {
|
|
2505
|
+
const cur = input.value;
|
|
2506
|
+
const opts = [...options];
|
|
2507
|
+
if (cur && !opts.some((o) => o.value === cur)) opts.push({ value: cur, label: `${cur}${staleLabel}` });
|
|
2508
|
+
if (!cur && !opts.some((o) => o.value === "")) opts.unshift({ value: "", label: emptyLabel });
|
|
2509
|
+
sel.replaceChildren(...opts.map((o) => h("option", { value: o.value, title: o.value }, o.label)));
|
|
2510
|
+
sel.value = cur;
|
|
2511
|
+
};
|
|
2512
|
+
sel.addEventListener("change", () => {
|
|
2513
|
+
input.value = sel.value;
|
|
2514
|
+
onChange(sel.value, "select");
|
|
2515
|
+
});
|
|
2516
|
+
input.addEventListener("input", () => onChange(input.value, "type"));
|
|
2517
|
+
input.addEventListener("blur", () => sync3());
|
|
2518
|
+
sync3();
|
|
2519
|
+
return h("div", { class: "flex flex-col gap-1" }, sel, input);
|
|
2520
|
+
}
|
|
2521
|
+
function providerOptionsOf(providers, L) {
|
|
2522
|
+
return [
|
|
2523
|
+
{ value: "", label: L.titleGenProviderNone },
|
|
2524
|
+
{ value: "session", label: L.titleGenProviderSession },
|
|
2525
|
+
...providers.map((p) => ({ value: p.id, label: p.name }))
|
|
2526
|
+
];
|
|
2527
|
+
}
|
|
2528
|
+
function modelOptionsOf(providerValue, providers, { followSession = false, followSessionLabel = "" } = {}) {
|
|
2529
|
+
const v = (providerValue || "").trim();
|
|
2530
|
+
const cur = providers.find((p) => p.id === v);
|
|
2531
|
+
if (cur) return cur.models.map((m) => ({ value: m, label: m }));
|
|
2532
|
+
if (v === "session") {
|
|
2533
|
+
const head = followSession && followSessionLabel ? [{ value: "", label: followSessionLabel }] : [];
|
|
2534
|
+
return [...head, ...[...new Set(providers.flatMap((p) => p.models))].map((m) => ({ value: m, label: m }))];
|
|
2535
|
+
}
|
|
2536
|
+
return [];
|
|
2537
|
+
}
|
|
2538
|
+
function modelPlaceholderOf(providerValue, L) {
|
|
2539
|
+
const v = (providerValue || "").trim();
|
|
2540
|
+
if (v === "session") return L.titleGenModelSessionHint;
|
|
2541
|
+
if (v === "") return L.titleGenModelManualHint;
|
|
2542
|
+
return L.titleGenModelHint;
|
|
2543
|
+
}
|
|
2544
|
+
function isManualConn(providerValue, providers) {
|
|
2545
|
+
const v = (providerValue || "").trim();
|
|
2546
|
+
return v === "" || v !== "session" && !providers.some((p) => p.id === v);
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2448
2549
|
// src/inject/features/styles.js
|
|
2449
2550
|
var STYLE_DEFAULTS = {
|
|
2450
2551
|
rowGap: 20,
|
|
@@ -2850,8 +2951,10 @@
|
|
|
2850
2951
|
openDialog({
|
|
2851
2952
|
title: L.settingsTitle,
|
|
2852
2953
|
// 宽度类必须用宿主样式表已有的工具类(注入的类名不会生成 CSS):
|
|
2853
|
-
// sm:max-w-3xl 不存在会失去约束拉满全屏;max-w-
|
|
2854
|
-
|
|
2954
|
+
// sm:max-w-3xl 不存在会失去约束拉满全屏;max-w-3xl=48rem 存在——英文界面
|
|
2955
|
+
// 标签栏较长,42rem 会挤出一块空白并触发横向滚动
|
|
2956
|
+
width: "max-w-3xl",
|
|
2957
|
+
bodyClass: "mt-1",
|
|
2855
2958
|
overlay: "none",
|
|
2856
2959
|
draggable: true,
|
|
2857
2960
|
posKey: "settings",
|
|
@@ -2912,7 +3015,9 @@
|
|
|
2912
3015
|
const config = await getConfig(true);
|
|
2913
3016
|
const agentsRes = await rpc("/agents");
|
|
2914
3017
|
const visionRes = await rpc("/vision");
|
|
2915
|
-
const
|
|
3018
|
+
const titleGenRes = await rpc("/title-gen");
|
|
3019
|
+
const titleGenProvidersRes = await rpc("/title-gen/providers");
|
|
3020
|
+
const titleGenProviders = titleGenProvidersRes.ok && Array.isArray(titleGenProvidersRes.providers) ? titleGenProvidersRes.providers : [];
|
|
2916
3021
|
const rtkRes = await rpc("/rtk");
|
|
2917
3022
|
const headroomRes = await rpc("/headroom");
|
|
2918
3023
|
const setFeature = async (key, value) => {
|
|
@@ -2934,7 +3039,7 @@
|
|
|
2934
3039
|
"data-zcodepro-status": "1"
|
|
2935
3040
|
},
|
|
2936
3041
|
h("span", { class: "inline-block size-2 rounded-full bg-emerald-500" }),
|
|
2937
|
-
h("span", { class: "text-foreground-subtle/70" }, `${
|
|
3042
|
+
h("span", { class: "text-foreground-subtle/70" }, `${health.version} \xB7 ${HELPER_URL}`)
|
|
2938
3043
|
);
|
|
2939
3044
|
const rows = h("div", { class: "divide-y divide-border rounded-xl border border-border" });
|
|
2940
3045
|
const refreshRows = () => {
|
|
@@ -3103,19 +3208,20 @@
|
|
|
3103
3208
|
);
|
|
3104
3209
|
const paneStyles = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3105
3210
|
const panePerf = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3106
|
-
const paneAgents = h("div", { role: "tabpanel", class: "mt-
|
|
3211
|
+
const paneAgents = h("div", { role: "tabpanel", class: "mt-2", style: "display:none" });
|
|
3107
3212
|
const paneProxy = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3108
3213
|
const paneSync = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3109
3214
|
const paneVision = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3110
3215
|
const paneRtk = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3111
3216
|
const paneHeadroom = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3217
|
+
const paneTitleGen = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3112
3218
|
const paneDebug = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
3113
3219
|
const panes = { features: paneFeatures, styles: paneStyles, perf: panePerf, agents: paneAgents, proxy: paneProxy, sync: paneSync, vision: paneVision, headroom: paneHeadroom, rtk: paneRtk, debug: paneDebug };
|
|
3114
3220
|
const tabDefs = [
|
|
3115
3221
|
["features", L.tabFeatures],
|
|
3222
|
+
["agents", L.tabBehavior],
|
|
3116
3223
|
["styles", L.tabStyles],
|
|
3117
3224
|
["perf", L.tabPerformance],
|
|
3118
|
-
["agents", L.tabAgents],
|
|
3119
3225
|
["proxy", L.tabProxy],
|
|
3120
3226
|
["sync", L.tabSync],
|
|
3121
3227
|
["vision", L.tabVision],
|
|
@@ -3125,7 +3231,7 @@
|
|
|
3125
3231
|
// 普通用户不可见
|
|
3126
3232
|
...config.devMode === true || config.devActive === true ? [["debug", L.tabDebug]] : []
|
|
3127
3233
|
];
|
|
3128
|
-
const tablist = h("div", { role: "tablist", "aria-orientation": "horizontal", class: "zcodepro-tablist mt-
|
|
3234
|
+
const tablist = h("div", { role: "tablist", "aria-orientation": "horizontal", class: "zcodepro-tablist mt-1" });
|
|
3129
3235
|
const renderTabs = () => tablist.replaceChildren(...tabDefs.map(([id, label]) => h("button", {
|
|
3130
3236
|
type: "button",
|
|
3131
3237
|
role: "tab",
|
|
@@ -3334,7 +3440,7 @@
|
|
|
3334
3440
|
)
|
|
3335
3441
|
);
|
|
3336
3442
|
const agentsArea = h("textarea", {
|
|
3337
|
-
class: "zcodepro-textarea",
|
|
3443
|
+
class: "zcodepro-textarea zcodepro-textarea-lg",
|
|
3338
3444
|
placeholder: L.agentsPlaceholder,
|
|
3339
3445
|
spellcheck: "false"
|
|
3340
3446
|
});
|
|
@@ -3365,12 +3471,36 @@
|
|
|
3365
3471
|
agentsSaveBtn.disabled = false;
|
|
3366
3472
|
}
|
|
3367
3473
|
};
|
|
3368
|
-
|
|
3474
|
+
const agentsPromptPane = h("div", { class: "mt-4" });
|
|
3475
|
+
agentsPromptPane.append(
|
|
3369
3476
|
h("p", { class: "text-ui-sm/relaxed text-foreground-subtle" }, L.agentsDesc),
|
|
3370
3477
|
...agentsFailed ? [h("p", { class: "mt-2 text-ui-sm text-destructive" }, L.agentsLoadFailed + ": " + errText(agentsRes))] : [],
|
|
3371
3478
|
h("div", { class: "mt-3" }, agentsArea),
|
|
3372
3479
|
h("div", { class: "mt-3 flex justify-end" }, agentsSaveBtn)
|
|
3373
3480
|
);
|
|
3481
|
+
let agentsSubTab = "prompt";
|
|
3482
|
+
const agentsSubPanes = { prompt: agentsPromptPane, titleGen: paneTitleGen };
|
|
3483
|
+
const agentsSubList = h("div", { role: "tablist", "aria-orientation": "horizontal", class: "zcodepro-tablist" });
|
|
3484
|
+
const renderAgentsSubTabs = () => {
|
|
3485
|
+
agentsSubList.replaceChildren(...[
|
|
3486
|
+
["prompt", L.tabAgents],
|
|
3487
|
+
["titleGen", L.tabTitleGen]
|
|
3488
|
+
].map(([id, label]) => h("button", {
|
|
3489
|
+
type: "button",
|
|
3490
|
+
role: "tab",
|
|
3491
|
+
class: "zcodepro-tab",
|
|
3492
|
+
"aria-selected": String(agentsSubTab === id),
|
|
3493
|
+
"data-state": agentsSubTab === id ? "active" : "inactive",
|
|
3494
|
+
onClick: () => {
|
|
3495
|
+
agentsSubTab = id;
|
|
3496
|
+
for (const [pid, pane] of Object.entries(agentsSubPanes)) pane.style.display = pid === id ? "" : "none";
|
|
3497
|
+
renderAgentsSubTabs();
|
|
3498
|
+
}
|
|
3499
|
+
}, label)));
|
|
3500
|
+
};
|
|
3501
|
+
for (const [pid, pane] of Object.entries(agentsSubPanes)) pane.style.display = pid === agentsSubTab ? "" : "none";
|
|
3502
|
+
renderAgentsSubTabs();
|
|
3503
|
+
paneAgents.append(agentsSubList, agentsPromptPane, paneTitleGen);
|
|
3374
3504
|
const savedProxy = typeof config.proxy === "string" ? config.proxy : "";
|
|
3375
3505
|
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
3506
|
const proxyInput = h("input", { type: "text", value: savedProxy, placeholder: L.proxyPlaceholder, spellcheck: "false", class: proxyInputCls + " min-w-0 flex-1" });
|
|
@@ -3966,7 +4096,6 @@
|
|
|
3966
4096
|
skipMinutes: 30,
|
|
3967
4097
|
forceIntercept: true
|
|
3968
4098
|
};
|
|
3969
|
-
const visionProviders = visionProvidersRes.ok && Array.isArray(visionProvidersRes.providers) ? visionProvidersRes.providers : [];
|
|
3970
4099
|
let visionCfg = visionRes.ok && visionRes.config && typeof visionRes.config === "object" ? structuredClone(visionRes.config) : null;
|
|
3971
4100
|
let visionSaveTimer = null;
|
|
3972
4101
|
const persistVision = async () => {
|
|
@@ -4158,53 +4287,45 @@
|
|
|
4158
4287
|
h(
|
|
4159
4288
|
"div",
|
|
4160
4289
|
{ 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";
|
|
4290
|
+
// 供应商与模型走 provider-fields 共用逻辑:跟随会话时模型下拉为
|
|
4291
|
+
// 全部供应商模型汇总,具体供应商为其模型列表;已删 id 标注「已删除」
|
|
4292
|
+
field(L.visionUseProvider, comboField(
|
|
4293
|
+
p.useProvider || "",
|
|
4294
|
+
providerOptionsOf(titleGenProviders, L),
|
|
4295
|
+
(v, src) => {
|
|
4296
|
+
p.useProvider = v;
|
|
4181
4297
|
saveVisionSoon();
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4298
|
+
if (src === "select") renderVision();
|
|
4299
|
+
},
|
|
4300
|
+
{ placeholder: L.titleGenProviderSession, staleLabel: L.titleGenProviderDeleted }
|
|
4301
|
+
)),
|
|
4302
|
+
// 跟随会话时模型下拉头部有「跟随当前会话当前模型」(值为空,
|
|
4303
|
+
// 插件 ≥1.6.1 在调用时解析为会话当前模型);具体供应商为其模型列表
|
|
4304
|
+
field(L.visionModel, comboField(
|
|
4305
|
+
p.model || "",
|
|
4306
|
+
modelOptionsOf(p.useProvider, titleGenProviders, {
|
|
4307
|
+
followSession: (p.useProvider || "").trim() === "session",
|
|
4308
|
+
followSessionLabel: L.titleGenModelFollowSession
|
|
4309
|
+
}),
|
|
4310
|
+
(v) => {
|
|
4311
|
+
p.model = v;
|
|
4185
4312
|
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" }))
|
|
4313
|
+
},
|
|
4314
|
+
{
|
|
4315
|
+
placeholder: modelPlaceholderOf(p.useProvider, L),
|
|
4316
|
+
emptyLabel: (p.useProvider || "").trim() === "session" ? L.titleGenModelFollowSession : L.titleGenModelEmpty
|
|
4317
|
+
}
|
|
4318
|
+
)),
|
|
4319
|
+
...isManualConn(p.useProvider, titleGenProviders) ? [
|
|
4320
|
+
field(L.visionBaseUrl, textIn(p.baseUrl, (v) => {
|
|
4321
|
+
p.baseUrl = v;
|
|
4322
|
+
saveVisionSoon();
|
|
4323
|
+
})),
|
|
4324
|
+
field(L.visionApiKey + " \xB7 " + L.visionApiKeyHint, textIn(p.apiKey, (v) => {
|
|
4325
|
+
p.apiKey = v;
|
|
4326
|
+
saveVisionSoon();
|
|
4327
|
+
}, { type: "password" }))
|
|
4328
|
+
] : []
|
|
4208
4329
|
),
|
|
4209
4330
|
(() => {
|
|
4210
4331
|
const n = h("textarea", { class: "zcodepro-textarea zcodepro-textarea-sm", rows: "3", placeholder: L.visionPrompt });
|
|
@@ -4945,13 +5066,190 @@
|
|
|
4945
5066
|
);
|
|
4946
5067
|
};
|
|
4947
5068
|
renderHeadroomPane();
|
|
5069
|
+
let titleGenCfg = titleGenRes.ok && titleGenRes.titleGen && typeof titleGenRes.titleGen === "object" ? structuredClone(titleGenRes.titleGen) : null;
|
|
5070
|
+
const titleGenDefaultPrompt = titleGenRes.ok && typeof titleGenRes.defaultPrompt === "string" ? titleGenRes.defaultPrompt : "";
|
|
5071
|
+
let titleGenSaveTimer = null;
|
|
5072
|
+
const persistTitleGen = async () => {
|
|
5073
|
+
const res = await rpc("/title-gen", { method: "POST", body: { titleGen: titleGenCfg } });
|
|
5074
|
+
clearConfigCache();
|
|
5075
|
+
if (!res.ok) showToast(L.failed + ": " + errText(res), "error");
|
|
5076
|
+
return res.ok;
|
|
5077
|
+
};
|
|
5078
|
+
const saveTitleGenSoon = () => {
|
|
5079
|
+
clearTimeout(titleGenSaveTimer);
|
|
5080
|
+
titleGenSaveTimer = setTimeout(() => {
|
|
5081
|
+
void persistTitleGen();
|
|
5082
|
+
}, 500);
|
|
5083
|
+
};
|
|
5084
|
+
const renderTitleGenPane = () => {
|
|
5085
|
+
if (!titleGenCfg) {
|
|
5086
|
+
paneTitleGen.replaceChildren(
|
|
5087
|
+
h("p", { class: "text-ui-sm/relaxed text-foreground-subtle" }, L.titleGenShortDesc),
|
|
5088
|
+
h("p", { class: "mt-2 text-ui-sm text-destructive" }, L.visionLoadFailed + ": " + errText(titleGenRes))
|
|
5089
|
+
);
|
|
5090
|
+
return;
|
|
5091
|
+
}
|
|
5092
|
+
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";
|
|
5093
|
+
const field = (labelText, node) => h(
|
|
5094
|
+
"label",
|
|
5095
|
+
{ class: "block min-w-0" },
|
|
5096
|
+
h("span", { class: "mb-1 block text-ui-xs font-medium text-foreground-subtle" }, labelText),
|
|
5097
|
+
node
|
|
5098
|
+
);
|
|
5099
|
+
const showInlineConn = isManualConn(titleGenCfg.provider, titleGenProviders);
|
|
5100
|
+
const providerCombo = comboField(
|
|
5101
|
+
titleGenCfg.provider || "",
|
|
5102
|
+
providerOptionsOf(titleGenProviders, L),
|
|
5103
|
+
(v, src) => {
|
|
5104
|
+
titleGenCfg.provider = v;
|
|
5105
|
+
if (src === "select") {
|
|
5106
|
+
void persistTitleGen();
|
|
5107
|
+
renderTitleGenPane();
|
|
5108
|
+
} else saveTitleGenSoon();
|
|
5109
|
+
},
|
|
5110
|
+
{ placeholder: L.titleGenProviderSession, staleLabel: L.titleGenProviderDeleted }
|
|
5111
|
+
);
|
|
5112
|
+
const modelCombo = comboField(
|
|
5113
|
+
titleGenCfg.model || "",
|
|
5114
|
+
// 跟随会话时选项表头部有“跟随当前会话当前模型”(值为空,生成时用
|
|
5115
|
+
// 会话当前模型),选了具体模型后也能再切回它
|
|
5116
|
+
modelOptionsOf(titleGenCfg.provider, titleGenProviders, {
|
|
5117
|
+
followSession: true,
|
|
5118
|
+
followSessionLabel: L.titleGenModelFollowSession
|
|
5119
|
+
}),
|
|
5120
|
+
(v) => {
|
|
5121
|
+
titleGenCfg.model = v;
|
|
5122
|
+
saveTitleGenSoon();
|
|
5123
|
+
},
|
|
5124
|
+
{
|
|
5125
|
+
placeholder: modelPlaceholderOf(titleGenCfg.provider, L),
|
|
5126
|
+
emptyLabel: (titleGenCfg.provider || "").trim() === "session" ? L.titleGenModelFollowSession : L.titleGenModelEmpty
|
|
5127
|
+
}
|
|
5128
|
+
);
|
|
5129
|
+
const textIn = (value, onInput, { type = "text", placeholder = "" } = {}) => {
|
|
5130
|
+
const n = h("input", { type, value: value || "", placeholder, class: inputCls });
|
|
5131
|
+
n.addEventListener("input", () => onInput(n.value));
|
|
5132
|
+
return n;
|
|
5133
|
+
};
|
|
5134
|
+
const formatSel = h(
|
|
5135
|
+
"select",
|
|
5136
|
+
{ class: inputCls },
|
|
5137
|
+
h("option", { value: "anthropic" }, "anthropic"),
|
|
5138
|
+
h("option", { value: "openai" }, "openai")
|
|
5139
|
+
);
|
|
5140
|
+
formatSel.value = titleGenCfg.format === "openai" ? "openai" : "anthropic";
|
|
5141
|
+
formatSel.addEventListener("change", () => {
|
|
5142
|
+
titleGenCfg.format = formatSel.value;
|
|
5143
|
+
void persistTitleGen();
|
|
5144
|
+
});
|
|
5145
|
+
const inlineConnCard = h(
|
|
5146
|
+
"div",
|
|
5147
|
+
{
|
|
5148
|
+
class: "mt-2 grid grid-cols-1 gap-2 rounded-xl border border-border p-2 sm:grid-cols-3",
|
|
5149
|
+
style: showInlineConn ? "" : "display:none"
|
|
5150
|
+
},
|
|
5151
|
+
field(L.titleGenBaseUrl, textIn(titleGenCfg.baseUrl, (v) => {
|
|
5152
|
+
titleGenCfg.baseUrl = v;
|
|
5153
|
+
saveTitleGenSoon();
|
|
5154
|
+
}, { placeholder: "https://\u2026" })),
|
|
5155
|
+
field(L.titleGenApiKey, textIn(titleGenCfg.apiKey, (v) => {
|
|
5156
|
+
titleGenCfg.apiKey = v;
|
|
5157
|
+
saveTitleGenSoon();
|
|
5158
|
+
}, { type: "password" })),
|
|
5159
|
+
field(L.titleGenFormat, formatSel)
|
|
5160
|
+
);
|
|
5161
|
+
const promptArea = h("textarea", {
|
|
5162
|
+
class: "zcodepro-textarea zcodepro-textarea-sm",
|
|
5163
|
+
rows: "8",
|
|
5164
|
+
placeholder: L.titleGenPromptPlaceholder
|
|
5165
|
+
});
|
|
5166
|
+
promptArea.value = titleGenCfg.prompt || "";
|
|
5167
|
+
promptArea.addEventListener("input", () => {
|
|
5168
|
+
titleGenCfg.prompt = promptArea.value;
|
|
5169
|
+
saveTitleGenSoon();
|
|
5170
|
+
});
|
|
5171
|
+
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?";
|
|
5172
|
+
const sampleInput = h("input", {
|
|
5173
|
+
type: "text",
|
|
5174
|
+
class: inputCls + " min-w-0 flex-1",
|
|
5175
|
+
value: sampleText
|
|
5176
|
+
});
|
|
5177
|
+
let testBtn;
|
|
5178
|
+
const testState = h("span", { class: "min-w-0 flex-1 truncate text-ui-xs/relaxed text-foreground-subtle" });
|
|
5179
|
+
testBtn = btnSmall(L.titleGenTest, async () => {
|
|
5180
|
+
testBtn.disabled = true;
|
|
5181
|
+
testBtn.textContent = L.titleGenTesting;
|
|
5182
|
+
testState.textContent = L.titleGenTesting;
|
|
5183
|
+
const res = await rpc("/title-gen/run", {
|
|
5184
|
+
method: "POST",
|
|
5185
|
+
body: { text: sampleInput.value, test: true }
|
|
5186
|
+
});
|
|
5187
|
+
testBtn.disabled = false;
|
|
5188
|
+
testBtn.textContent = L.titleGenTest;
|
|
5189
|
+
if (res && res.ok) {
|
|
5190
|
+
testState.textContent = L.titleGenTestOk + res.title;
|
|
5191
|
+
showToast(res.title, "success");
|
|
5192
|
+
} else {
|
|
5193
|
+
testState.textContent = res && errText(res) || L.titleGenTestFailed;
|
|
5194
|
+
testState.className = "min-w-0 flex-1 truncate text-ui-xs/relaxed text-destructive";
|
|
5195
|
+
showToast(L.titleGenTestFailed + ": " + (res ? errText(res) : ""), "error");
|
|
5196
|
+
}
|
|
5197
|
+
}, "shrink-0");
|
|
5198
|
+
paneTitleGen.replaceChildren(
|
|
5199
|
+
// 信息卡:一句话简介在左,启用开关右对齐
|
|
5200
|
+
h(
|
|
5201
|
+
"div",
|
|
5202
|
+
{ class: "mt-3 flex items-center justify-between gap-2 rounded-xl border border-border p-2" },
|
|
5203
|
+
h("span", { class: "min-w-0 text-ui-sm/relaxed text-foreground-subtle" }, L.titleGenShortDesc),
|
|
5204
|
+
h("div", { class: "shrink-0" }, settingRow(L.titleGenEnabled, "", titleGenCfg.enabled === true, async () => {
|
|
5205
|
+
titleGenCfg.enabled = !(titleGenCfg.enabled === true);
|
|
5206
|
+
await persistTitleGen();
|
|
5207
|
+
renderTitleGenPane();
|
|
5208
|
+
}))
|
|
5209
|
+
),
|
|
5210
|
+
// 供应商 + 模型
|
|
5211
|
+
h(
|
|
5212
|
+
"div",
|
|
5213
|
+
{ class: "mt-2 grid grid-cols-1 gap-2 rounded-xl border border-border p-2 sm:grid-cols-2" },
|
|
5214
|
+
field(L.titleGenProvider, providerCombo),
|
|
5215
|
+
field(L.titleGenModel, modelCombo)
|
|
5216
|
+
),
|
|
5217
|
+
inlineConnCard,
|
|
5218
|
+
// 提示词 + 载入默认
|
|
5219
|
+
h(
|
|
5220
|
+
"div",
|
|
5221
|
+
{ class: "mt-2 rounded-xl border border-border p-2" },
|
|
5222
|
+
h(
|
|
5223
|
+
"div",
|
|
5224
|
+
{ class: "mb-1 flex items-center justify-between gap-2" },
|
|
5225
|
+
h("span", { class: "text-ui-xs font-medium text-foreground-subtle" }, L.titleGenPrompt),
|
|
5226
|
+
btnSmall(L.titleGenPromptReset, () => {
|
|
5227
|
+
promptArea.value = titleGenDefaultPrompt;
|
|
5228
|
+
titleGenCfg.prompt = titleGenDefaultPrompt;
|
|
5229
|
+
void persistTitleGen();
|
|
5230
|
+
promptArea.focus();
|
|
5231
|
+
})
|
|
5232
|
+
),
|
|
5233
|
+
promptArea
|
|
5234
|
+
),
|
|
5235
|
+
// 测试
|
|
5236
|
+
h(
|
|
5237
|
+
"div",
|
|
5238
|
+
{ class: "mt-2 flex items-center gap-2 rounded-xl border border-border p-2" },
|
|
5239
|
+
sampleInput,
|
|
5240
|
+
testBtn
|
|
5241
|
+
),
|
|
5242
|
+
testState
|
|
5243
|
+
);
|
|
5244
|
+
};
|
|
5245
|
+
renderTitleGenPane();
|
|
4948
5246
|
body.append(
|
|
4949
5247
|
statusLine,
|
|
4950
5248
|
tablist,
|
|
4951
5249
|
paneFeatures,
|
|
5250
|
+
paneAgents,
|
|
4952
5251
|
paneStyles,
|
|
4953
5252
|
panePerf,
|
|
4954
|
-
paneAgents,
|
|
4955
5253
|
paneProxy,
|
|
4956
5254
|
paneSync,
|
|
4957
5255
|
paneVision,
|
|
@@ -5424,6 +5722,16 @@
|
|
|
5424
5722
|
const map = await fetchPinned();
|
|
5425
5723
|
if (map) scan2();
|
|
5426
5724
|
}
|
|
5725
|
+
function setRowTitle(key, text) {
|
|
5726
|
+
for (const item of findRows(key)) {
|
|
5727
|
+
for (const el of titleElsOf(item)) writeTitle(el, text);
|
|
5728
|
+
}
|
|
5729
|
+
}
|
|
5730
|
+
function refreshPinnedTitles() {
|
|
5731
|
+
return fetchPinned().then((m) => {
|
|
5732
|
+
if (m) scan2();
|
|
5733
|
+
});
|
|
5734
|
+
}
|
|
5427
5735
|
function startTitleLock() {
|
|
5428
5736
|
if (installed2 || typeof document === "undefined") return;
|
|
5429
5737
|
installed2 = true;
|
|
@@ -5459,8 +5767,146 @@
|
|
|
5459
5767
|
});
|
|
5460
5768
|
}
|
|
5461
5769
|
|
|
5462
|
-
// src/inject/features/
|
|
5770
|
+
// src/inject/features/title-gen.js
|
|
5771
|
+
var CONV2 = '[class*="@md/conversation"]';
|
|
5772
|
+
var USER_ROW = '[class*="user-row"]';
|
|
5773
|
+
var SCAN_DEBOUNCE_MS3 = 300;
|
|
5774
|
+
var SCAN_FALLBACK_MS3 = 5e3;
|
|
5775
|
+
var SELECT_WAIT_MS = 2e3;
|
|
5776
|
+
var MSG_WAIT_MS = 1e4;
|
|
5777
|
+
var QUIET_FALLBACK_MS = 12e4;
|
|
5778
|
+
var COLLECT_MAX_MS = 6e5;
|
|
5463
5779
|
var installed3 = false;
|
|
5780
|
+
var knownKeys = /* @__PURE__ */ new Set();
|
|
5781
|
+
var attempted = /* @__PURE__ */ new Set();
|
|
5782
|
+
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
5783
|
+
function sessIdOf2(key) {
|
|
5784
|
+
const i = key.indexOf(":sess_");
|
|
5785
|
+
return i > 0 ? key.slice(i + 1) : "";
|
|
5786
|
+
}
|
|
5787
|
+
function currentKey() {
|
|
5788
|
+
for (const el of document.querySelectorAll("[data-task-item-key]")) {
|
|
5789
|
+
if ((el.className + "").includes("bg-selected")) return el.getAttribute("data-task-item-key") || "";
|
|
5790
|
+
}
|
|
5791
|
+
return "";
|
|
5792
|
+
}
|
|
5793
|
+
function userTexts() {
|
|
5794
|
+
return [...document.querySelectorAll(`${CONV2} ${USER_ROW}`)].map((r) => {
|
|
5795
|
+
const el = r.querySelector(".whitespace-pre-wrap");
|
|
5796
|
+
return ((el ? el.textContent : r.innerText) || "").trim();
|
|
5797
|
+
}).filter(Boolean);
|
|
5798
|
+
}
|
|
5799
|
+
async function onNewTaskRow(key) {
|
|
5800
|
+
const selDeadline = Date.now() + SELECT_WAIT_MS;
|
|
5801
|
+
while (currentKey() !== key && Date.now() < selDeadline) await sleep(200);
|
|
5802
|
+
if (currentKey() !== key) return;
|
|
5803
|
+
const cfg = await getConfig().catch(() => null);
|
|
5804
|
+
if (!cfg || !cfg.titleGen || cfg.titleGen.enabled !== true) return;
|
|
5805
|
+
const sessId = sessIdOf2(key);
|
|
5806
|
+
if (!sessId || attempted.has(sessId)) return;
|
|
5807
|
+
attempted.add(sessId);
|
|
5808
|
+
let texts = [];
|
|
5809
|
+
const msgDeadline = Date.now() + MSG_WAIT_MS;
|
|
5810
|
+
while (Date.now() < msgDeadline) {
|
|
5811
|
+
texts = userTexts();
|
|
5812
|
+
if (texts.length) break;
|
|
5813
|
+
await sleep(400);
|
|
5814
|
+
}
|
|
5815
|
+
if (!texts.length) return;
|
|
5816
|
+
let assistantSeen = false;
|
|
5817
|
+
const convObserver = new MutationObserver((muts) => {
|
|
5818
|
+
if (currentKey() !== key) return;
|
|
5819
|
+
for (const m of muts) {
|
|
5820
|
+
const t2 = m.type === "characterData" ? m.target.parentElement : m.target;
|
|
5821
|
+
if (t2 instanceof Element && t2.closest(USER_ROW)) continue;
|
|
5822
|
+
for (const n of [t2, ...m.addedNodes]) {
|
|
5823
|
+
if (n instanceof Element && n.closest && n.closest(CONV2)) {
|
|
5824
|
+
assistantSeen = true;
|
|
5825
|
+
return;
|
|
5826
|
+
}
|
|
5827
|
+
}
|
|
5828
|
+
}
|
|
5829
|
+
});
|
|
5830
|
+
convObserver.observe(document.body, { childList: true, subtree: true, characterData: true });
|
|
5831
|
+
const startAt = Date.now();
|
|
5832
|
+
let lastCount = texts.length;
|
|
5833
|
+
let lastChange = Date.now();
|
|
5834
|
+
try {
|
|
5835
|
+
while (Date.now() - startAt < COLLECT_MAX_MS) {
|
|
5836
|
+
await sleep(500);
|
|
5837
|
+
if (currentKey() !== key) {
|
|
5838
|
+
lastChange = Date.now();
|
|
5839
|
+
continue;
|
|
5840
|
+
}
|
|
5841
|
+
texts = userTexts();
|
|
5842
|
+
if (texts.length !== lastCount) {
|
|
5843
|
+
lastCount = texts.length;
|
|
5844
|
+
lastChange = Date.now();
|
|
5845
|
+
}
|
|
5846
|
+
if (assistantSeen) break;
|
|
5847
|
+
if (Date.now() - lastChange >= QUIET_FALLBACK_MS) break;
|
|
5848
|
+
}
|
|
5849
|
+
} finally {
|
|
5850
|
+
convObserver.disconnect();
|
|
5851
|
+
}
|
|
5852
|
+
if (!texts.length) return;
|
|
5853
|
+
const res = await rpc("/title-gen/run", { method: "POST", body: { sessId, text: texts.join("\n") } }).catch(() => null);
|
|
5854
|
+
if (res && res.ok && res.written && res.title) {
|
|
5855
|
+
setRowTitle(key, res.title);
|
|
5856
|
+
void refreshPinnedTitles();
|
|
5857
|
+
}
|
|
5858
|
+
}
|
|
5859
|
+
function scanForNewRows() {
|
|
5860
|
+
for (const el of document.querySelectorAll("[data-task-item-key]")) {
|
|
5861
|
+
const key = el.getAttribute("data-task-item-key") || "";
|
|
5862
|
+
if (!key || knownKeys.has(key)) continue;
|
|
5863
|
+
knownKeys.add(key);
|
|
5864
|
+
void onNewTaskRow(key);
|
|
5865
|
+
}
|
|
5866
|
+
}
|
|
5867
|
+
var TASK_SEL2 = "[data-task-item-key]";
|
|
5868
|
+
var inTaskRow3 = (node) => !!(node instanceof Element && node.closest && node.closest(TASK_SEL2));
|
|
5869
|
+
function taskRowMutations3(muts) {
|
|
5870
|
+
for (const m of muts) {
|
|
5871
|
+
if (m.type === "attributes") {
|
|
5872
|
+
if (inTaskRow3(m.target)) return true;
|
|
5873
|
+
} else if (m.type === "characterData") {
|
|
5874
|
+
if (m.target.parentElement && inTaskRow3(m.target.parentElement)) return true;
|
|
5875
|
+
} else if (inTaskRow3(m.target)) {
|
|
5876
|
+
return true;
|
|
5877
|
+
} else {
|
|
5878
|
+
for (const n of m.addedNodes) {
|
|
5879
|
+
if (n instanceof Element && (n.matches(TASK_SEL2) || !!n.querySelector(TASK_SEL2))) return true;
|
|
5880
|
+
}
|
|
5881
|
+
}
|
|
5882
|
+
}
|
|
5883
|
+
return false;
|
|
5884
|
+
}
|
|
5885
|
+
var scanDebounce3 = 0;
|
|
5886
|
+
function scheduleScan3() {
|
|
5887
|
+
if (scanDebounce3) return;
|
|
5888
|
+
scanDebounce3 = setTimeout(() => {
|
|
5889
|
+
scanDebounce3 = 0;
|
|
5890
|
+
scanForNewRows();
|
|
5891
|
+
}, SCAN_DEBOUNCE_MS3);
|
|
5892
|
+
}
|
|
5893
|
+
function startTitleGen() {
|
|
5894
|
+
if (installed3 || typeof document === "undefined") return;
|
|
5895
|
+
installed3 = true;
|
|
5896
|
+
scanForNewRows();
|
|
5897
|
+
new MutationObserver((muts) => {
|
|
5898
|
+
if (taskRowMutations3(muts)) scheduleScan3();
|
|
5899
|
+
}).observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ["class"], characterData: true });
|
|
5900
|
+
setInterval(() => {
|
|
5901
|
+
if (!document.hidden) scanForNewRows();
|
|
5902
|
+
}, SCAN_FALLBACK_MS3);
|
|
5903
|
+
document.addEventListener("visibilitychange", () => {
|
|
5904
|
+
if (!document.hidden) scanForNewRows();
|
|
5905
|
+
});
|
|
5906
|
+
}
|
|
5907
|
+
|
|
5908
|
+
// src/inject/features/pinned-expand.js
|
|
5909
|
+
var installed4 = false;
|
|
5464
5910
|
var keepCollapsed = false;
|
|
5465
5911
|
var CONFIG_POLL_MIN_MS = 5e3;
|
|
5466
5912
|
var CONFIG_POLL_MAX_MS = 6e4;
|
|
@@ -5487,8 +5933,8 @@
|
|
|
5487
5933
|
}, pollMs);
|
|
5488
5934
|
}
|
|
5489
5935
|
function startPinnedExpandSuppression() {
|
|
5490
|
-
if (
|
|
5491
|
-
|
|
5936
|
+
if (installed4 || typeof document === "undefined") return;
|
|
5937
|
+
installed4 = true;
|
|
5492
5938
|
void refreshConfig();
|
|
5493
5939
|
pollConfig();
|
|
5494
5940
|
document.addEventListener("visibilitychange", () => {
|
|
@@ -5567,10 +6013,10 @@
|
|
|
5567
6013
|
}
|
|
5568
6014
|
|
|
5569
6015
|
// src/inject/features/ws-running.js
|
|
5570
|
-
var
|
|
6016
|
+
var installed5 = false;
|
|
5571
6017
|
var enabled3 = true;
|
|
5572
|
-
var
|
|
5573
|
-
var
|
|
6018
|
+
var SCAN_DEBOUNCE_MS4 = 150;
|
|
6019
|
+
var SCAN_FALLBACK_MS4 = 5e3;
|
|
5574
6020
|
var PEEK_FIRST_MS = 2e4;
|
|
5575
6021
|
var PEEK_REPEAT_MS = 6e4;
|
|
5576
6022
|
var PEEK_SETTLE_MS = 160;
|
|
@@ -5578,7 +6024,7 @@
|
|
|
5578
6024
|
var PEEK_UNMOUNT_WAIT_MS = 800;
|
|
5579
6025
|
var CONFIG_POLL_MIN_MS2 = 5e3;
|
|
5580
6026
|
var CONFIG_POLL_MAX_MS2 = 6e4;
|
|
5581
|
-
var
|
|
6027
|
+
var TASK_SEL3 = "[data-task-item-key]";
|
|
5582
6028
|
var WS_SEL = '[data-testid^="workspace-item-"]';
|
|
5583
6029
|
var runningByWs = /* @__PURE__ */ new Map();
|
|
5584
6030
|
var peekTimers = /* @__PURE__ */ new Map();
|
|
@@ -5601,10 +6047,10 @@
|
|
|
5601
6047
|
return [...holder.children].some((c) => c.tagName === "svg" && (c.getAttribute("class") || "").includes("lucide-loader"));
|
|
5602
6048
|
}
|
|
5603
6049
|
function domRowsOf(ws) {
|
|
5604
|
-
return [...document.querySelectorAll(
|
|
6050
|
+
return [...document.querySelectorAll(TASK_SEL3)].filter((e) => workspaceOf2(e.getAttribute("data-task-item-key") || "") === ws);
|
|
5605
6051
|
}
|
|
5606
6052
|
function currentTaskRow2() {
|
|
5607
|
-
for (const el of document.querySelectorAll(
|
|
6053
|
+
for (const el of document.querySelectorAll(TASK_SEL3)) {
|
|
5608
6054
|
if ((el.className + "").includes("bg-selected")) return el;
|
|
5609
6055
|
}
|
|
5610
6056
|
return null;
|
|
@@ -5620,12 +6066,12 @@
|
|
|
5620
6066
|
const backKey = cur ? cur.getAttribute("data-task-item-key") : "";
|
|
5621
6067
|
synthClick(head);
|
|
5622
6068
|
if (!backKey) return;
|
|
5623
|
-
const back = cur && cur.isConnected ? cur : document.querySelector(`${
|
|
6069
|
+
const back = cur && cur.isConnected ? cur : document.querySelector(`${TASK_SEL3}[data-task-item-key="${CSS.escape(backKey)}"]`);
|
|
5624
6070
|
if (back) synthClick(back);
|
|
5625
6071
|
}
|
|
5626
6072
|
function scan3() {
|
|
5627
6073
|
wsWithRows = /* @__PURE__ */ new Set();
|
|
5628
|
-
for (const el of document.querySelectorAll(
|
|
6074
|
+
for (const el of document.querySelectorAll(TASK_SEL3)) {
|
|
5629
6075
|
const key = el.getAttribute("data-task-item-key") || "";
|
|
5630
6076
|
const ws = workspaceOf2(key);
|
|
5631
6077
|
if (!ws) continue;
|
|
@@ -5651,8 +6097,8 @@
|
|
|
5651
6097
|
if (m.type !== "childList") continue;
|
|
5652
6098
|
for (const n of m.removedNodes) {
|
|
5653
6099
|
if (!(n instanceof Element)) continue;
|
|
5654
|
-
if (n.matches(
|
|
5655
|
-
else for (const r of n.querySelectorAll(
|
|
6100
|
+
if (n.matches(TASK_SEL3)) removed.push(n);
|
|
6101
|
+
else for (const r of n.querySelectorAll(TASK_SEL3)) removed.push(r);
|
|
5656
6102
|
}
|
|
5657
6103
|
}
|
|
5658
6104
|
if (!removed.length) return;
|
|
@@ -5835,7 +6281,7 @@
|
|
|
5835
6281
|
var PEEK_EXEMPT_CLASS = "zcodepro-peek-exempt";
|
|
5836
6282
|
var cssAttr = (v) => String(v).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
5837
6283
|
function installPeekHider(ws) {
|
|
5838
|
-
const rowSel3 = `${
|
|
6284
|
+
const rowSel3 = `${TASK_SEL3}[data-task-item-key^="${cssAttr(ws + ":")}"]`;
|
|
5839
6285
|
for (const r of document.querySelectorAll(rowSel3)) r.classList.add(PEEK_EXEMPT_CLASS);
|
|
5840
6286
|
const style = document.createElement("style");
|
|
5841
6287
|
style.textContent = `${rowSel3}:not(.${PEEK_EXEMPT_CLASS}){display:none!important}`;
|
|
@@ -5847,7 +6293,7 @@
|
|
|
5847
6293
|
for (const r of document.querySelectorAll("." + PEEK_EXEMPT_CLASS)) r.classList.remove(PEEK_EXEMPT_CLASS);
|
|
5848
6294
|
}
|
|
5849
6295
|
function waitForRowsGone(ws) {
|
|
5850
|
-
const sel = `${
|
|
6296
|
+
const sel = `${TASK_SEL3}[data-task-item-key^="${cssAttr(ws + ":")}"]:not(.${PEEK_EXEMPT_CLASS})`;
|
|
5851
6297
|
return new Promise((resolve) => {
|
|
5852
6298
|
const t0 = Date.now();
|
|
5853
6299
|
const timer = setInterval(() => {
|
|
@@ -5869,12 +6315,12 @@
|
|
|
5869
6315
|
}
|
|
5870
6316
|
function relevant(muts) {
|
|
5871
6317
|
for (const m of muts) {
|
|
5872
|
-
if (inSel(m.target,
|
|
6318
|
+
if (inSel(m.target, TASK_SEL3) || inSel(m.target, WS_SEL)) return true;
|
|
5873
6319
|
for (const n of m.addedNodes) {
|
|
5874
|
-
if (n instanceof Element && (n.matches(
|
|
6320
|
+
if (n instanceof Element && (n.matches(TASK_SEL3) || n.matches(WS_SEL) || n.querySelector(TASK_SEL3) || n.querySelector(WS_SEL))) return true;
|
|
5875
6321
|
}
|
|
5876
6322
|
for (const n of m.removedNodes) {
|
|
5877
|
-
if (n instanceof Element && (n.matches(
|
|
6323
|
+
if (n instanceof Element && (n.matches(TASK_SEL3) || n.matches(WS_SEL) || n.querySelector(TASK_SEL3))) return true;
|
|
5878
6324
|
}
|
|
5879
6325
|
}
|
|
5880
6326
|
return false;
|
|
@@ -5905,27 +6351,27 @@
|
|
|
5905
6351
|
pollConfig2();
|
|
5906
6352
|
}, pollMs2);
|
|
5907
6353
|
}
|
|
5908
|
-
var
|
|
6354
|
+
var scanDebounce4 = 0;
|
|
5909
6355
|
function startWsRunningSpin() {
|
|
5910
|
-
if (
|
|
5911
|
-
|
|
6356
|
+
if (installed5 || typeof document === "undefined") return;
|
|
6357
|
+
installed5 = true;
|
|
5912
6358
|
void refreshConfig2();
|
|
5913
6359
|
pollConfig2();
|
|
5914
6360
|
const observer2 = new MutationObserver((muts) => {
|
|
5915
6361
|
if (!relevant(muts)) return;
|
|
5916
6362
|
handleRemovals(muts);
|
|
5917
|
-
if (!
|
|
5918
|
-
|
|
5919
|
-
|
|
6363
|
+
if (!scanDebounce4) {
|
|
6364
|
+
scanDebounce4 = setTimeout(() => {
|
|
6365
|
+
scanDebounce4 = 0;
|
|
5920
6366
|
scan3();
|
|
5921
|
-
},
|
|
6367
|
+
}, SCAN_DEBOUNCE_MS4);
|
|
5922
6368
|
}
|
|
5923
6369
|
});
|
|
5924
6370
|
observer2.observe(document.body, { childList: true, subtree: true });
|
|
5925
6371
|
scan3();
|
|
5926
6372
|
setInterval(() => {
|
|
5927
6373
|
if (!document.hidden && enabled3) scan3();
|
|
5928
|
-
},
|
|
6374
|
+
}, SCAN_FALLBACK_MS4);
|
|
5929
6375
|
document.addEventListener("visibilitychange", () => {
|
|
5930
6376
|
if (!document.hidden) scan3();
|
|
5931
6377
|
});
|
|
@@ -6089,7 +6535,7 @@
|
|
|
6089
6535
|
// src/inject/features/toolbar-icons.js
|
|
6090
6536
|
var HIDE_CLASS = "zcodepro-tb-hidden";
|
|
6091
6537
|
var SYNC_DEBOUNCE_MS = 150;
|
|
6092
|
-
var
|
|
6538
|
+
var SCAN_FALLBACK_MS5 = 5e3;
|
|
6093
6539
|
var ROW_SEL = "[data-task-item-key]";
|
|
6094
6540
|
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
6541
|
var enabled4 = true;
|
|
@@ -6161,6 +6607,7 @@
|
|
|
6161
6607
|
menu.classList.add(HIDE_CLASS);
|
|
6162
6608
|
origs = next;
|
|
6163
6609
|
rowEl?.remove();
|
|
6610
|
+
navRow.classList.add("zcodepro-tb-hidden-native");
|
|
6164
6611
|
const L = t();
|
|
6165
6612
|
const mk = (kind, orig, nameSel, fallback) => h("button", {
|
|
6166
6613
|
type: "button",
|
|
@@ -6186,7 +6633,9 @@
|
|
|
6186
6633
|
const pIcon = iconOf(next.plugin);
|
|
6187
6634
|
if (pIcon) pluginBtn.append(pIcon);
|
|
6188
6635
|
rowEl = h("div", { class: "zcodepro-tb-row" }, newBtn, searchBtn, autoBtn, pluginBtn);
|
|
6189
|
-
navRow.
|
|
6636
|
+
const updBtn = [...navRow.querySelectorAll("button")].find((b) => /bg-(success|emerald)/.test(b.className || ""));
|
|
6637
|
+
if (updBtn) updBtn.before(rowEl);
|
|
6638
|
+
else navRow.append(rowEl);
|
|
6190
6639
|
return true;
|
|
6191
6640
|
}
|
|
6192
6641
|
function sidebarCollapsed() {
|
|
@@ -6216,10 +6665,18 @@
|
|
|
6216
6665
|
if (sidebarCollapsed() || sidebarTooNarrow()) {
|
|
6217
6666
|
if (rowEl) rowEl.style.display = "none";
|
|
6218
6667
|
menu.classList.remove(HIDE_CLASS);
|
|
6668
|
+
document.querySelectorAll(".zcodepro-tb-hidden-native").forEach((el) => el.classList.remove("zcodepro-tb-hidden-native"));
|
|
6219
6669
|
return;
|
|
6220
6670
|
}
|
|
6221
6671
|
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())
|
|
6672
|
+
if (!alive && !rebuild()) {
|
|
6673
|
+
if (rowEl) rowEl.style.display = "none";
|
|
6674
|
+
setTimeout(scheduleSync, 400);
|
|
6675
|
+
setTimeout(scheduleSync, 1200);
|
|
6676
|
+
return;
|
|
6677
|
+
}
|
|
6678
|
+
const navRow = document.querySelector('[data-testid="desktop-top-nav-back"]')?.parentElement;
|
|
6679
|
+
if (navRow) navRow.classList.add("zcodepro-tb-hidden-native");
|
|
6223
6680
|
menu.classList.add(HIDE_CLASS);
|
|
6224
6681
|
if (rowEl) rowEl.style.display = "";
|
|
6225
6682
|
syncActive();
|
|
@@ -6255,6 +6712,7 @@
|
|
|
6255
6712
|
rowEl = null;
|
|
6256
6713
|
if (origs) {
|
|
6257
6714
|
origs.menu.classList.remove(HIDE_CLASS);
|
|
6715
|
+
document.querySelectorAll(".zcodepro-tb-hidden-native").forEach((el) => el.classList.remove("zcodepro-tb-hidden-native"));
|
|
6258
6716
|
origs = null;
|
|
6259
6717
|
}
|
|
6260
6718
|
}
|
|
@@ -6275,7 +6733,7 @@
|
|
|
6275
6733
|
}).observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ["class", "aria-pressed"] });
|
|
6276
6734
|
setInterval(() => {
|
|
6277
6735
|
if (!document.hidden) sync();
|
|
6278
|
-
},
|
|
6736
|
+
}, SCAN_FALLBACK_MS5);
|
|
6279
6737
|
document.addEventListener("visibilitychange", () => {
|
|
6280
6738
|
if (!document.hidden) sync();
|
|
6281
6739
|
});
|
|
@@ -6286,7 +6744,7 @@
|
|
|
6286
6744
|
var HEAD_CLASS = "zcodepro-pin-head";
|
|
6287
6745
|
var STORE_KEY = "zcodepro:pinned-collapsed";
|
|
6288
6746
|
var SYNC_DEBOUNCE_MS2 = 300;
|
|
6289
|
-
var
|
|
6747
|
+
var SCAN_FALLBACK_MS6 = 5e3;
|
|
6290
6748
|
var enabled5 = true;
|
|
6291
6749
|
var syncTimer2 = 0;
|
|
6292
6750
|
function findPinnedHeader() {
|
|
@@ -6405,7 +6863,7 @@
|
|
|
6405
6863
|
}).observe(document.body, { childList: true, subtree: true });
|
|
6406
6864
|
setInterval(() => {
|
|
6407
6865
|
if (!document.hidden) sync2();
|
|
6408
|
-
},
|
|
6866
|
+
}, SCAN_FALLBACK_MS6);
|
|
6409
6867
|
document.addEventListener("visibilitychange", () => {
|
|
6410
6868
|
if (!document.hidden) sync2();
|
|
6411
6869
|
});
|
|
@@ -6486,6 +6944,10 @@
|
|
|
6486
6944
|
startTitleLock();
|
|
6487
6945
|
} catch {
|
|
6488
6946
|
}
|
|
6947
|
+
try {
|
|
6948
|
+
startTitleGen();
|
|
6949
|
+
} catch {
|
|
6950
|
+
}
|
|
6489
6951
|
try {
|
|
6490
6952
|
startImageMenu();
|
|
6491
6953
|
} catch {
|