zcode-pro 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +3 -0
- package/README.md +3 -0
- package/dist/inject.js +986 -84
- package/package.json +1 -1
- package/src/host/helper.mjs +174 -4
- package/src/host/taskIndex.mjs +18 -0
- package/src/inject/core.js +88 -0
- package/src/inject/features/plugin-card-retry.js +48 -0
- package/src/inject/features/sandbox-reclaim.js +49 -20
- package/src/inject/features/settings-dialog.js +146 -3
- package/src/inject/features/status-bar.js +274 -0
- package/src/inject/features/turn-usage.js +195 -0
- package/src/inject/index.js +8 -0
- package/src/inject/ui.js +50 -0
package/dist/inject.js
CHANGED
|
@@ -42,6 +42,28 @@
|
|
|
42
42
|
switchAttention: "r"
|
|
43
43
|
// 打开运行中 / 未查看
|
|
44
44
|
};
|
|
45
|
+
var STATUS_SESSION_IDS = /* @__PURE__ */ new Set(["ctx", "sessionCost", "questions"]);
|
|
46
|
+
var STATUS_GLOBAL_IDS = /* @__PURE__ */ new Set(["todayTokens", "todayCost", "totalTokens", "totalCost", "tasks"]);
|
|
47
|
+
var DEFAULT_TURN_ITEMS = [
|
|
48
|
+
{ id: "turnIn", on: true },
|
|
49
|
+
// 输入
|
|
50
|
+
{ id: "turnOut", on: true },
|
|
51
|
+
// 输出
|
|
52
|
+
{ id: "turnCache", on: true }
|
|
53
|
+
// 缓存命中率
|
|
54
|
+
];
|
|
55
|
+
var DEFAULT_STATUS_ITEMS = [
|
|
56
|
+
{ id: "ctx", on: true },
|
|
57
|
+
// 上下文占用
|
|
58
|
+
{ id: "questions", on: true },
|
|
59
|
+
// 提问次数
|
|
60
|
+
{ id: "todayTokens", on: true },
|
|
61
|
+
// 今日 token(今天的会话记录完整,数据准确)
|
|
62
|
+
{ id: "totalTokens", on: true },
|
|
63
|
+
// 累计 token(官方使用统计,全历史)
|
|
64
|
+
{ id: "tasks", on: true }
|
|
65
|
+
// 任务总数
|
|
66
|
+
];
|
|
45
67
|
function zcodeAppVersion() {
|
|
46
68
|
const v = liveBoot().zcodeVersion;
|
|
47
69
|
return typeof v === "string" && v ? v : "";
|
|
@@ -235,6 +257,11 @@
|
|
|
235
257
|
tbPluginStore: "\u63D2\u4EF6\u5E02\u573A",
|
|
236
258
|
featurePinnedCollapse: "\u5DF2\u7F6E\u9876\u5206\u533A\u53EF\u6298\u53E0",
|
|
237
259
|
featurePinnedCollapseDesc: "\u4FA7\u8FB9\u680F\u201C\u5DF2\u7F6E\u9876\u201D\u6807\u9898\u53EF\u70B9\u51FB\u6298\u53E0/\u5C55\u5F00\u5176\u4EFB\u52A1\u5217\u8868\uFF08\u4E0E\u201C\u9879\u76EE\u201D\u201C\u5206\u7EC4\u201D\u5206\u533A\u4E00\u81F4\uFF09\uFF0C\u72B6\u6001\u8BB0\u4F4F\u3002",
|
|
260
|
+
featureSandboxReclaim: "\u63D2\u4EF6\u754C\u9762\u6C99\u7BB1\u56DE\u6536",
|
|
261
|
+
featureSandboxReclaimDesc: "\u63D2\u4EF6\u5361\u7247\u6C99\u7BB1\u6570\u91CF\u8FBE\u5230\u4E0A\u9650\u65F6\u81EA\u52A8\u91CA\u653E\u6700\u65E9\u521B\u5EFA\u7684\uFF08\u6B63\u5728\u67E5\u770B\u7684\u6392\u6700\u540E\uFF09\uFF0C\u907F\u514D 64 \u4E2A\u540D\u989D\u8017\u5C3D\u540E\u65B0\u5361\u7247\u6253\u4E0D\u5F00\uFF1B\u88AB\u91CA\u653E\u7684\u65E7\u5361\u7247\u91CD\u65B0\u6253\u5F00\u6240\u5728\u4F1A\u8BDD\u5373\u6062\u590D\uFF08\u9884\u7B97\u53EF\u5728\u914D\u7F6E\u6587\u4EF6 sandboxReclaimBudget \u8C03\u6574\uFF09\u3002",
|
|
262
|
+
featurePluginCardRetry: "\u63D2\u4EF6\u5361\u7247\u81EA\u52A8\u91CD\u8BD5",
|
|
263
|
+
featurePluginCardRetryDesc: "\u56E0\u540D\u989D\u4E0A\u9650\u52A0\u8F7D\u5931\u8D25\u7684\u63D2\u4EF6\u5361\u7247\u81EA\u52A8\u70B9\u51FB\u201C\u91CD\u65B0\u52A0\u8F7D\u201D\uFF0C\u540D\u989D\u7A7A\u51FA\u540E\u81EA\u52A8\u6062\u590D\uFF0C\u65E0\u9700\u624B\u52A8\u8E72\u5B88\u3002",
|
|
264
|
+
visionCardUi: "\u601D\u8003\u8FC7\u7A0B\u663E\u793A\u8BC6\u56FE\u5361\u7247",
|
|
238
265
|
pinnedToggleAria: "\u6298\u53E0/\u5C55\u5F00\u5DF2\u7F6E\u9876",
|
|
239
266
|
sidebarProjectSpacingName: "\u9879\u76EE\u95F4\u8DDD",
|
|
240
267
|
sidebarProjectSpacingDesc: "\u4FA7\u8FB9\u680F\u4E2D\u76F8\u90BB\u9879\u76EE\u884C\u4E4B\u95F4\u7684\u89C6\u89C9\u95F4\u8DDD\uFF08\u542B\u884C\u5185\u7559\u767D\uFF09\uFF1B\u8BBE\u7F6E\u540E\u5404\u5206\u533A\uFF08\u5DF2\u7F6E\u9876/\u9879\u76EE/\u4EFB\u52A1\uFF09\u4E4B\u95F4\u7684\u95F4\u8DDD\u4E5F\u7EDF\u4E00\u4E3A\u8BE5\u503C\u3002",
|
|
@@ -259,6 +286,34 @@
|
|
|
259
286
|
featureNewtabPanelsDesc: "\u5B98\u65B9\u201C\u65B0\u6807\u7B7E\u9875\u201D\u53EA\u5217\u5B98\u65B9\u9762\u677F\u4E0E\u63A8\u8350\u7684\u5B98\u65B9\u63D2\u4EF6\uFF0C\u6B64\u529F\u80FD\u628A\u7B2C\u4E09\u65B9\u5E02\u573A\u63D2\u4EF6\uFF08headroom\u3001rtk \u7B49\uFF09\u7684\u9762\u677F\u5361\u7247\u52A0\u8FDB\u53BB\uFF0C\u70B9\u51FB\u5728\u4FA7\u8FB9\u9762\u677F\u6253\u5F00\u3002",
|
|
260
287
|
ntpDescSuffix: "\u63D2\u4EF6\u9762\u677F",
|
|
261
288
|
ntpNeedSession: "\u5148\u6253\u5F00\u4E00\u4E2A\u4EFB\u52A1\u4F1A\u8BDD\uFF0C\u518D\u4ECE\u65B0\u6807\u7B7E\u9875\u6253\u5F00\u63D2\u4EF6\u9762\u677F",
|
|
289
|
+
featureStatusBar: "\u72B6\u6001\u680F\u7EDF\u8BA1",
|
|
290
|
+
featureStatusBarDesc: "\u4E3B\u754C\u9762\u5E95\u90E8\u53F3\u4E0B\u89D2\u663E\u793A\u7EDF\u8BA1\u9879\uFF1A\u4E0A\u4E0B\u6587\u5360\u7528\u3001\u4F1A\u8BDD/\u4ECA\u65E5/\u7D2F\u8BA1 token\u3001\u4EFB\u52A1\u6570\u7B49\uFF1B\u5404\u9879\u7684\u987A\u5E8F\u4E0E\u663E\u9690\u5728\u201C\u6837\u5F0F \u2192 \u72B6\u6001\u680F\u201D\u91CC\u8C03\u6574\u3002",
|
|
291
|
+
tabStylesPane: "\u6837\u5F0F\u8C03\u6574",
|
|
292
|
+
tabStatusPane: "\u72B6\u6001\u680F",
|
|
293
|
+
sbItemCtx: "\u4E0A\u4E0B\u6587\u5360\u7528",
|
|
294
|
+
sbItemQuestions: "\u63D0\u95EE\u6B21\u6570",
|
|
295
|
+
sbGroupSession: "\u4F1A\u8BDD\u7EDF\u8BA1\uFF08\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD\uFF09",
|
|
296
|
+
sbGroupGlobal: "\u603B\u7EDF\u8BA1",
|
|
297
|
+
sbGroupTurn: "\u6BCF\u8F6E\u7EDF\u8BA1\uFF08\u56DE\u7B54\u672B\u5C3E\uFF09",
|
|
298
|
+
sbLabelIn: "\u8F93\u5165",
|
|
299
|
+
sbLabelOut: "\u8F93\u51FA",
|
|
300
|
+
sbLabelCache: "\u7F13\u5B58",
|
|
301
|
+
featureTurnUsage: "\u6BCF\u8F6E\u56DE\u7B54 token \u7528\u91CF",
|
|
302
|
+
featureTurnUsageDesc: "\u5728\u6BCF\u6761\u56DE\u7B54\u672B\u5C3E\u64CD\u4F5C\u6309\u94AE\u7684\u65F6\u95F4\u540E\u9762\u663E\u793A\u8BE5\u8F6E\u7684\u8F93\u5165/\u8F93\u51FA token\uFF08\u672C\u5730\u8BB0\u5F55\u53EA\u4FDD\u7559\u6700\u8FD1\u82E5\u5E72\u8F6E\uFF0C\u5BF9\u4E0D\u4E0A\u65F6\u95F4\u7684\u65E7\u56DE\u7B54\u4E0D\u663E\u793A\uFF09\u3002",
|
|
303
|
+
turnUsageTitle: "\u672C\u8F6E token",
|
|
304
|
+
sbLabelQuestions: "\u63D0\u95EE",
|
|
305
|
+
sbItemTodayTokens: "\u4ECA\u65E5 token",
|
|
306
|
+
sbItemTasks: "\u4EFB\u52A1\u603B\u6570",
|
|
307
|
+
sbLabelCtx: "\u4E0A\u4E0B\u6587",
|
|
308
|
+
sbLabelTurns: "\u8C03\u7528",
|
|
309
|
+
sbLabelToday: "\u4ECA\u65E5",
|
|
310
|
+
sbLabelTasks: "\u4EFB\u52A1",
|
|
311
|
+
sbItemTotalTokens: "\u7D2F\u8BA1 token",
|
|
312
|
+
sbLabelTotal: "\u7D2F\u8BA1",
|
|
313
|
+
sbMoveUp: "\u4E0A\u79FB",
|
|
314
|
+
sbMoveDown: "\u4E0B\u79FB",
|
|
315
|
+
sbVisible: "\u663E\u793A",
|
|
316
|
+
sbHidden: "\u9690\u85CF",
|
|
262
317
|
tabShortcuts: "\u5FEB\u6377\u952E",
|
|
263
318
|
hkTitle: "\u4F1A\u8BDD\u5FEB\u6377\u5207\u6362",
|
|
264
319
|
hkAltZ: "\u5728\u5F53\u524D\u4E0E\u4E0A\u6B21\u4F7F\u7528\u7684\u4F1A\u8BDD\u95F4\u6765\u56DE\u5207\u6362",
|
|
@@ -659,6 +714,11 @@
|
|
|
659
714
|
tbPluginStore: "Plugin store",
|
|
660
715
|
featurePinnedCollapse: "Collapsible Pinned section",
|
|
661
716
|
featurePinnedCollapseDesc: 'The sidebar "Pinned" header collapses/expands its task list (like Projects and Groups); the state is remembered.',
|
|
717
|
+
featureSandboxReclaim: "Plugin card sandbox reclaim",
|
|
718
|
+
featureSandboxReclaimDesc: "Releases the oldest plugin-card sandboxes once the cap is hit (the one being viewed goes last), so new cards keep opening after the 64-slot pool fills up; released cards come back when their session is reopened (budget adjustable via sandboxReclaimBudget in the config file).",
|
|
719
|
+
featurePluginCardRetry: "Plugin card auto-retry",
|
|
720
|
+
featurePluginCardRetryDesc: 'Auto-clicks "Reload" on cards that failed the slot cap; they recover as soon as a slot frees up.',
|
|
721
|
+
visionCardUi: "Vision cards",
|
|
662
722
|
pinnedToggleAria: "Collapse/expand Pinned",
|
|
663
723
|
sidebarProjectSpacingName: "Project spacing",
|
|
664
724
|
sidebarProjectSpacingDesc: "Visual spacing between adjacent project rows in the sidebar (row padding included); when set, section gaps (Pinned/Projects/Tasks) follow the same value.",
|
|
@@ -683,6 +743,34 @@
|
|
|
683
743
|
featureNewtabPanelsDesc: 'The built-in "new tab page" only lists built-in panels and recommended official plugins; this adds cards for third-party marketplace plugin panels (headroom, rtk, \u2026) that open in the side pane.',
|
|
684
744
|
ntpDescSuffix: "plugin panel",
|
|
685
745
|
ntpNeedSession: "Open a task session first, then open plugin panels from the new tab page",
|
|
746
|
+
featureStatusBar: "Status bar statistics",
|
|
747
|
+
featureStatusBarDesc: 'Shows statistics at the bottom-right of the main view: context usage, session/today/total tokens, task count, etc.; reorder or hide each item under "Styles \u2192 Status bar".',
|
|
748
|
+
tabStylesPane: "Styles",
|
|
749
|
+
tabStatusPane: "Status bar",
|
|
750
|
+
sbItemCtx: "Context usage",
|
|
751
|
+
sbItemQuestions: "Questions asked",
|
|
752
|
+
sbGroupSession: "Session statistics (follows current session)",
|
|
753
|
+
sbGroupGlobal: "Global statistics",
|
|
754
|
+
sbGroupTurn: "Per-turn statistics (answer rows)",
|
|
755
|
+
sbLabelIn: "in",
|
|
756
|
+
sbLabelOut: "out",
|
|
757
|
+
sbLabelCache: "cache",
|
|
758
|
+
featureTurnUsage: "Per-turn token usage",
|
|
759
|
+
featureTurnUsageDesc: "Shows that turn's in/out tokens after the time in each answer's action row (local records keep only the most recent turns; older answers without a match stay unlabelled).",
|
|
760
|
+
turnUsageTitle: "Turn tokens",
|
|
761
|
+
sbLabelQuestions: "asks",
|
|
762
|
+
sbItemTodayTokens: "Today tokens",
|
|
763
|
+
sbItemTasks: "Tasks",
|
|
764
|
+
sbLabelCtx: "ctx",
|
|
765
|
+
sbLabelTurns: "calls",
|
|
766
|
+
sbLabelToday: "today",
|
|
767
|
+
sbLabelTasks: "tasks",
|
|
768
|
+
sbItemTotalTokens: "Total tokens",
|
|
769
|
+
sbLabelTotal: "total",
|
|
770
|
+
sbMoveUp: "Up",
|
|
771
|
+
sbMoveDown: "Down",
|
|
772
|
+
sbVisible: "shown",
|
|
773
|
+
sbHidden: "hidden",
|
|
686
774
|
tabShortcuts: "Shortcuts",
|
|
687
775
|
hkTitle: "Session quick switch",
|
|
688
776
|
hkAltZ: "Toggle between the current and the last-used session",
|
|
@@ -1022,20 +1110,20 @@
|
|
|
1022
1110
|
}
|
|
1023
1111
|
}
|
|
1024
1112
|
function observeRadixPopups(onPopup) {
|
|
1025
|
-
const
|
|
1113
|
+
const seen2 = /* @__PURE__ */ new WeakSet();
|
|
1026
1114
|
const check = (node) => {
|
|
1027
1115
|
if (!(node instanceof HTMLElement)) return;
|
|
1028
1116
|
if (node.hasAttribute("data-radix-popper-content-wrapper")) {
|
|
1029
1117
|
requestAnimationFrame(() => {
|
|
1030
1118
|
const content = node.firstElementChild;
|
|
1031
|
-
if (content && !
|
|
1032
|
-
|
|
1119
|
+
if (content && !seen2.has(content)) {
|
|
1120
|
+
seen2.add(content);
|
|
1033
1121
|
onPopup(content);
|
|
1034
1122
|
}
|
|
1035
1123
|
});
|
|
1036
1124
|
}
|
|
1037
|
-
if (node.getAttribute && node.getAttribute("role") === "menu" && !
|
|
1038
|
-
|
|
1125
|
+
if (node.getAttribute && node.getAttribute("role") === "menu" && !seen2.has(node)) {
|
|
1126
|
+
seen2.add(node);
|
|
1039
1127
|
requestAnimationFrame(() => {
|
|
1040
1128
|
if (node.isConnected) onPopup(node);
|
|
1041
1129
|
});
|
|
@@ -1695,6 +1783,56 @@
|
|
|
1695
1783
|
text-align: center;
|
|
1696
1784
|
color: var(--color-muted-foreground, #888);
|
|
1697
1785
|
}
|
|
1786
|
+
/* \u72B6\u6001\u680F\u7EDF\u8BA1\uFF08status-bar.js\uFF09\uFF1A\u8F93\u5165\u6846\u4E0B\u65B9\u53F3\u5BF9\u9F50\u7684\u4E00\u884C\u5C0F\u5B57\uFF0C\u6BCF\u9879\u5E26 lucide \u5C0F\u56FE\u6807\u3002
|
|
1787
|
+
\u4E0A\u4E0B\u95F4\u8DDD\u7531\u811A\u672C\u6309\u89C6\u56FE\u63A7\u5236\uFF08status-bar.js\uFF1A\u4E0B\u65B9\u6709\u5185\u5BB9\u65F6\u5BF9\u79F0 7px\uFF0C
|
|
1788
|
+
\u4E0B\u65B9\u662F\u7A97\u5E95\u7559\u767D\u65F6\u8D1F margin \u538B\u5165\u8D34\u5E95\uFF09 */
|
|
1789
|
+
.zcodepro-statusbar {
|
|
1790
|
+
display: flex;
|
|
1791
|
+
justify-content: flex-end;
|
|
1792
|
+
align-items: center;
|
|
1793
|
+
gap: 8px;
|
|
1794
|
+
padding: 7px 14px 0;
|
|
1795
|
+
font-size: 11px;
|
|
1796
|
+
line-height: 1.4;
|
|
1797
|
+
color: var(--color-muted-foreground, #888);
|
|
1798
|
+
user-select: none;
|
|
1799
|
+
pointer-events: none;
|
|
1800
|
+
}
|
|
1801
|
+
.zcodepro-statusbar span[data-tone='warn'] { color: var(--color-amber-500, #f59e0b); }
|
|
1802
|
+
.zcodepro-statusbar span[data-tone='danger'] { color: var(--color-red-500, #ef4444); }
|
|
1803
|
+
.zcodepro-statusbar-sep { opacity: 0.45; }
|
|
1804
|
+
/* \u4F1A\u8BDD\u7EC4\u4E0E\u5168\u5C40\u7EC4\u4E4B\u95F4\u7684\u5206\u754C\u7AD6\u7EBF */
|
|
1805
|
+
.zcodepro-statusbar-groupsep {
|
|
1806
|
+
width: 1px;
|
|
1807
|
+
height: 10px;
|
|
1808
|
+
background: currentColor;
|
|
1809
|
+
opacity: 0.3;
|
|
1810
|
+
margin: 0 2px;
|
|
1811
|
+
}
|
|
1812
|
+
/* \u6BCF\u9879\u5185\u90E8\u7528 flex \u5BF9\u9F50\uFF1A\u56FE\u6807\u3001\u6807\u7B7E\u3001\u6570\u503C\u5782\u76F4\u5C45\u4E2D\uFF0C\u95F4\u8DDD\u7EDF\u4E00 */
|
|
1813
|
+
.zcodepro-statusbar span[title] {
|
|
1814
|
+
display: inline-flex;
|
|
1815
|
+
align-items: center;
|
|
1816
|
+
gap: 3px;
|
|
1817
|
+
white-space: nowrap;
|
|
1818
|
+
}
|
|
1819
|
+
.zcodepro-sb-icon {
|
|
1820
|
+
width: 12px;
|
|
1821
|
+
height: 12px;
|
|
1822
|
+
flex-shrink: 0;
|
|
1823
|
+
opacity: 0.6;
|
|
1824
|
+
}
|
|
1825
|
+
.zcodepro-statusbar b { font-weight: 600; color: var(--color-foreground-subtle, #666); }
|
|
1826
|
+
.zcodepro-statusbar i {
|
|
1827
|
+
font-style: normal;
|
|
1828
|
+
opacity: 0.7;
|
|
1829
|
+
font-size: 10px;
|
|
1830
|
+
}
|
|
1831
|
+
/* \u9879\u5185\u77ED\u6807\u7B7E\uFF08\u5982\u201C\u4E0A\u4E0B\u6587\u201D\u201C\u7D2F\u8BA1\u201D\uFF09\uFF0C\u5F31\u5316\u4E0D\u62A2\u6570\u503C */
|
|
1832
|
+
.zcodepro-statusbar em {
|
|
1833
|
+
font-style: normal;
|
|
1834
|
+
opacity: 0.75;
|
|
1835
|
+
}
|
|
1698
1836
|
.zcodepro-switcher-ws {
|
|
1699
1837
|
font-size: 11px;
|
|
1700
1838
|
color: var(--color-muted-foreground, #888);
|
|
@@ -2504,10 +2642,10 @@
|
|
|
2504
2642
|
}
|
|
2505
2643
|
function handleProjectMenu(content) {
|
|
2506
2644
|
if (content.querySelector("[data-zcodepro-item]")) return;
|
|
2507
|
-
const
|
|
2645
|
+
const items2 = itemsOf(content);
|
|
2508
2646
|
const newUi = isNewProjectSidebar();
|
|
2509
2647
|
const menuRow = newUi ? openMenuProjectRow() : null;
|
|
2510
|
-
const anchor = newUi ?
|
|
2648
|
+
const anchor = newUi ? items2.find((el) => el.getAttribute("data-testid") === "virtual-project-edit") : items2.find(
|
|
2511
2649
|
(el) => el.hasAttribute("data-testid") && REMOVE_TEXTS.some((x) => itemText(el).startsWith(x))
|
|
2512
2650
|
);
|
|
2513
2651
|
if (!anchor) return;
|
|
@@ -2600,7 +2738,7 @@
|
|
|
2600
2738
|
if (looksLikePath(p2)) return p2;
|
|
2601
2739
|
return pathFromReactFiber(content);
|
|
2602
2740
|
}
|
|
2603
|
-
function appendMenuItem(content, template, anchor, { marker, label, icon, onPick }) {
|
|
2741
|
+
function appendMenuItem(content, template, anchor, { marker, label, icon: icon2, onPick }) {
|
|
2604
2742
|
const item = template.cloneNode(true);
|
|
2605
2743
|
item.removeAttribute("data-testid");
|
|
2606
2744
|
item.removeAttribute("data-highlighted");
|
|
@@ -2609,7 +2747,7 @@
|
|
|
2609
2747
|
item.setAttribute("data-zcodepro-item", marker);
|
|
2610
2748
|
for (const child of [...item.childNodes]) child.remove();
|
|
2611
2749
|
const origIcon = template.querySelector("svg");
|
|
2612
|
-
item.append(buildIcon(origIcon?.getAttribute("class") || "size-4",
|
|
2750
|
+
item.append(buildIcon(origIcon?.getAttribute("class") || "size-4", icon2), document.createTextNode(label));
|
|
2613
2751
|
item.addEventListener("mouseenter", () => {
|
|
2614
2752
|
for (const el of content.querySelectorAll('[role="menuitem"]')) el.removeAttribute("data-highlighted");
|
|
2615
2753
|
item.setAttribute("data-highlighted", "");
|
|
@@ -2624,8 +2762,8 @@
|
|
|
2624
2762
|
}
|
|
2625
2763
|
function handleFileMenu(content) {
|
|
2626
2764
|
if (content.dataset.zcodeproFileMenu) return;
|
|
2627
|
-
const
|
|
2628
|
-
const copyAbs =
|
|
2765
|
+
const items2 = itemsOf(content);
|
|
2766
|
+
const copyAbs = items2.find((el) => COPY_ABS_TEXTS.some((x) => itemText(el).startsWith(x)));
|
|
2629
2767
|
if (!copyAbs) return;
|
|
2630
2768
|
content.dataset.zcodeproFileMenu = "1";
|
|
2631
2769
|
void (async () => {
|
|
@@ -2640,7 +2778,7 @@
|
|
|
2640
2778
|
}).catch(() => {
|
|
2641
2779
|
});
|
|
2642
2780
|
};
|
|
2643
|
-
const noApps =
|
|
2781
|
+
const noApps = items2.find((el) => NO_APPS_TEXTS.some((x) => itemText(el) === x)) || content.querySelector('[data-disabled][role="menuitem"]');
|
|
2644
2782
|
const openAnchor = noApps && content.contains(noApps) ? noApps : copyAbs;
|
|
2645
2783
|
appendMenuItem(content, copyAbs, openAnchor, {
|
|
2646
2784
|
marker: "file-open-default",
|
|
@@ -2850,10 +2988,10 @@
|
|
|
2850
2988
|
function startImageMenu() {
|
|
2851
2989
|
if (typeof window === "undefined") return;
|
|
2852
2990
|
if (typeof navigator.clipboard?.write !== "function" || typeof window.ClipboardItem === "undefined") return;
|
|
2853
|
-
let
|
|
2991
|
+
let enabled9 = true;
|
|
2854
2992
|
const refresh = () => {
|
|
2855
2993
|
void getConfig().then((c) => {
|
|
2856
|
-
|
|
2994
|
+
enabled9 = !(c.features && c.features.imageCopy === false);
|
|
2857
2995
|
});
|
|
2858
2996
|
};
|
|
2859
2997
|
refresh();
|
|
@@ -2862,7 +3000,7 @@
|
|
|
2862
3000
|
const img = copyTargetOf(e.target, e.clientX, e.clientY);
|
|
2863
3001
|
if (!img) return;
|
|
2864
3002
|
e.preventDefault();
|
|
2865
|
-
if (
|
|
3003
|
+
if (enabled9) showMenu(e.clientX, e.clientY, img);
|
|
2866
3004
|
refresh();
|
|
2867
3005
|
}, true);
|
|
2868
3006
|
}
|
|
@@ -2966,7 +3104,7 @@
|
|
|
2966
3104
|
function waitFor(getter, timeoutMs, step) {
|
|
2967
3105
|
const start = Date.now();
|
|
2968
3106
|
return new Promise((resolve, reject) => {
|
|
2969
|
-
const
|
|
3107
|
+
const tick6 = () => {
|
|
2970
3108
|
let v = null;
|
|
2971
3109
|
try {
|
|
2972
3110
|
v = getter();
|
|
@@ -2980,9 +3118,9 @@
|
|
|
2980
3118
|
reject(new Error(step));
|
|
2981
3119
|
return;
|
|
2982
3120
|
}
|
|
2983
|
-
setTimeout(
|
|
3121
|
+
setTimeout(tick6, 120);
|
|
2984
3122
|
};
|
|
2985
|
-
|
|
3123
|
+
tick6();
|
|
2986
3124
|
});
|
|
2987
3125
|
}
|
|
2988
3126
|
function setReactInputValue(input, value) {
|
|
@@ -3754,7 +3892,7 @@
|
|
|
3754
3892
|
setState(L.upgradeFound.replaceAll("{v}", res.latest || ""));
|
|
3755
3893
|
btn.textContent = L.upgradeNow;
|
|
3756
3894
|
};
|
|
3757
|
-
const
|
|
3895
|
+
const tick6 = async () => {
|
|
3758
3896
|
const res = await rpc(endpoint + "/upgrade");
|
|
3759
3897
|
if (!res.ok) {
|
|
3760
3898
|
stopPoll();
|
|
@@ -3794,9 +3932,9 @@
|
|
|
3794
3932
|
btn.textContent = L.upgradeStop;
|
|
3795
3933
|
setState(L.upgradeRunning);
|
|
3796
3934
|
timer = setInterval(() => {
|
|
3797
|
-
void
|
|
3935
|
+
void tick6();
|
|
3798
3936
|
}, 1500);
|
|
3799
|
-
void
|
|
3937
|
+
void tick6();
|
|
3800
3938
|
};
|
|
3801
3939
|
void (async () => {
|
|
3802
3940
|
const res = await rpc(endpoint + "/upgrade");
|
|
@@ -4005,6 +4143,16 @@
|
|
|
4005
4143
|
if (await setFeature("imageCopy", next)) f.imageCopy = next;
|
|
4006
4144
|
refreshRows();
|
|
4007
4145
|
}),
|
|
4146
|
+
settingRow(L.featureSandboxReclaim, L.featureSandboxReclaimDesc, f.sandboxReclaim !== false, async () => {
|
|
4147
|
+
const next = !(f.sandboxReclaim !== false);
|
|
4148
|
+
if (await setFeature("sandboxReclaim", next)) f.sandboxReclaim = next;
|
|
4149
|
+
refreshRows();
|
|
4150
|
+
}),
|
|
4151
|
+
settingRow(L.featurePluginCardRetry, L.featurePluginCardRetryDesc, f.pluginCardRetry !== false, async () => {
|
|
4152
|
+
const next = !(f.pluginCardRetry !== false);
|
|
4153
|
+
if (await setFeature("pluginCardRetry", next)) f.pluginCardRetry = next;
|
|
4154
|
+
refreshRows();
|
|
4155
|
+
}),
|
|
4008
4156
|
settingRow(L.featureWsRunning, L.featureWsRunningDesc, f.wsRunningSpin !== false, async () => {
|
|
4009
4157
|
const next = !(f.wsRunningSpin !== false);
|
|
4010
4158
|
if (await setFeature("wsRunningSpin", next)) f.wsRunningSpin = next;
|
|
@@ -4015,6 +4163,16 @@
|
|
|
4015
4163
|
if (await setFeature("newtabPanels", next)) f.newtabPanels = next;
|
|
4016
4164
|
refreshRows();
|
|
4017
4165
|
}),
|
|
4166
|
+
settingRow(L.featureStatusBar, L.featureStatusBarDesc, f.statusBar !== false, async () => {
|
|
4167
|
+
const next = !(f.statusBar !== false);
|
|
4168
|
+
if (await setFeature("statusBar", next)) f.statusBar = next;
|
|
4169
|
+
refreshRows();
|
|
4170
|
+
}),
|
|
4171
|
+
settingRow(L.featureTurnUsage, L.featureTurnUsageDesc, f.turnUsage !== false, async () => {
|
|
4172
|
+
const next = !(f.turnUsage !== false);
|
|
4173
|
+
if (await setFeature("turnUsage", next)) f.turnUsage = next;
|
|
4174
|
+
refreshRows();
|
|
4175
|
+
}),
|
|
4018
4176
|
(() => {
|
|
4019
4177
|
const repoLink = h("span", {
|
|
4020
4178
|
class: "cursor-pointer underline-offset-4 hover:underline",
|
|
@@ -4047,7 +4205,7 @@
|
|
|
4047
4205
|
const WECHAT_ID = "ai4only";
|
|
4048
4206
|
const ns = "http://www.w3.org/2000/svg";
|
|
4049
4207
|
const extIcon = () => {
|
|
4050
|
-
const
|
|
4208
|
+
const icon2 = h("svg", {
|
|
4051
4209
|
viewBox: "0 0 24 24",
|
|
4052
4210
|
fill: "none",
|
|
4053
4211
|
stroke: "currentColor",
|
|
@@ -4059,11 +4217,11 @@
|
|
|
4059
4217
|
for (const d of ["M15 3h6v6", "M10 14 21 3", "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"]) {
|
|
4060
4218
|
const p2 = document.createElementNS(ns, "path");
|
|
4061
4219
|
p2.setAttribute("d", d);
|
|
4062
|
-
|
|
4220
|
+
icon2.append(p2);
|
|
4063
4221
|
}
|
|
4064
|
-
return
|
|
4222
|
+
return icon2;
|
|
4065
4223
|
};
|
|
4066
|
-
const communityCard = (title, desc,
|
|
4224
|
+
const communityCard = (title, desc, icon2, onClick) => h(
|
|
4067
4225
|
"div",
|
|
4068
4226
|
{
|
|
4069
4227
|
class: "flex cursor-pointer items-center justify-between gap-2 rounded-xl border border-border p-2 transition-colors hover:bg-surface-hover",
|
|
@@ -4075,7 +4233,7 @@
|
|
|
4075
4233
|
h("div", { class: "truncate text-ui-sm font-medium text-foreground" }, title),
|
|
4076
4234
|
h("div", { class: "mt-0.5 truncate text-ui-xs/relaxed text-foreground-subtle" }, desc)
|
|
4077
4235
|
),
|
|
4078
|
-
|
|
4236
|
+
icon2()
|
|
4079
4237
|
);
|
|
4080
4238
|
const communityCards = h(
|
|
4081
4239
|
"div",
|
|
@@ -4218,7 +4376,7 @@
|
|
|
4218
4376
|
),
|
|
4219
4377
|
hkCard
|
|
4220
4378
|
);
|
|
4221
|
-
const paneStyles = h("div", { role: "tabpanel", class: "mt-
|
|
4379
|
+
const paneStyles = h("div", { role: "tabpanel", class: "mt-2", style: "display:none" });
|
|
4222
4380
|
const panePerf = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
4223
4381
|
const paneAgents = h("div", { role: "tabpanel", class: "mt-2", style: "display:none" });
|
|
4224
4382
|
const paneProxy = h("div", { role: "tabpanel", class: "mt-4", style: "display:none" });
|
|
@@ -4433,7 +4591,162 @@
|
|
|
4433
4591
|
for (const c of fontCells) c.setOptions(list);
|
|
4434
4592
|
})();
|
|
4435
4593
|
renderToolbarSwitch();
|
|
4436
|
-
|
|
4594
|
+
const paneStylesSub1 = h("div", { class: "mt-4" });
|
|
4595
|
+
const paneStylesSub2 = h("div", { class: "mt-4", style: "display:none" });
|
|
4596
|
+
const ITEM_NAMES = {
|
|
4597
|
+
ctx: "sbItemCtx",
|
|
4598
|
+
questions: "sbItemQuestions",
|
|
4599
|
+
todayTokens: "sbItemTodayTokens",
|
|
4600
|
+
totalTokens: "sbItemTotalTokens",
|
|
4601
|
+
tasks: "sbItemTasks"
|
|
4602
|
+
};
|
|
4603
|
+
const sbItems = () => {
|
|
4604
|
+
const saved = config.statusBar && Array.isArray(config.statusBar.items) ? config.statusBar.items : null;
|
|
4605
|
+
if (!saved) return DEFAULT_STATUS_ITEMS.map((x) => ({ ...x }));
|
|
4606
|
+
const byId = new Map(saved.map((x) => [x.id, x]));
|
|
4607
|
+
const list = saved.filter((x) => ITEM_NAMES[x.id]).map((x) => ({ on: x.on !== false, id: x.id }));
|
|
4608
|
+
for (const d of DEFAULT_STATUS_ITEMS) if (!byId.has(d.id)) list.push({ ...d });
|
|
4609
|
+
return [
|
|
4610
|
+
...list.filter((x) => STATUS_SESSION_IDS.has(x.id)),
|
|
4611
|
+
...list.filter((x) => STATUS_GLOBAL_IDS.has(x.id))
|
|
4612
|
+
];
|
|
4613
|
+
};
|
|
4614
|
+
let sbSaving = false;
|
|
4615
|
+
const saveSbItems = async (next) => {
|
|
4616
|
+
if (sbSaving) return;
|
|
4617
|
+
sbSaving = true;
|
|
4618
|
+
try {
|
|
4619
|
+
const res = await rpc("/config", { method: "POST", body: { statusBar: { items: next } } });
|
|
4620
|
+
clearConfigCache();
|
|
4621
|
+
window.dispatchEvent(new CustomEvent("zcodepro:config-changed"));
|
|
4622
|
+
if (!res.ok) {
|
|
4623
|
+
showToast(L.failed + ": " + errText(res), "error");
|
|
4624
|
+
renderSbItems();
|
|
4625
|
+
return;
|
|
4626
|
+
}
|
|
4627
|
+
if (res.config && res.config.statusBar) config.statusBar = res.config.statusBar;
|
|
4628
|
+
} finally {
|
|
4629
|
+
sbSaving = false;
|
|
4630
|
+
}
|
|
4631
|
+
renderSbItems();
|
|
4632
|
+
};
|
|
4633
|
+
const sbList = h("div", { class: "divide-y divide-border rounded-xl border border-border" });
|
|
4634
|
+
const sbGlobalList = h("div", { class: "divide-y divide-border rounded-xl border border-border" });
|
|
4635
|
+
const TURN_NAMES = { turnIn: "sbLabelIn", turnOut: "sbLabelOut", turnCache: "sbLabelCache" };
|
|
4636
|
+
const turnItems = () => {
|
|
4637
|
+
const saved = config.statusBar && Array.isArray(config.statusBar.turnItems) ? config.statusBar.turnItems : null;
|
|
4638
|
+
if (!saved) return DEFAULT_TURN_ITEMS.map((x) => ({ ...x }));
|
|
4639
|
+
const byId = new Map(saved.map((x) => [x.id, x]));
|
|
4640
|
+
const list = saved.filter((x) => TURN_NAMES[x.id]).map((x) => ({ on: x.on !== false, id: x.id }));
|
|
4641
|
+
for (const d of DEFAULT_TURN_ITEMS) if (!byId.has(d.id)) list.push({ ...d });
|
|
4642
|
+
return list;
|
|
4643
|
+
};
|
|
4644
|
+
const saveTurnItems = async (next) => {
|
|
4645
|
+
if (sbSaving) return;
|
|
4646
|
+
sbSaving = true;
|
|
4647
|
+
try {
|
|
4648
|
+
const res = await rpc("/config", { method: "POST", body: { statusBar: { turnItems: next } } });
|
|
4649
|
+
clearConfigCache();
|
|
4650
|
+
window.dispatchEvent(new CustomEvent("zcodepro:config-changed"));
|
|
4651
|
+
if (!res.ok) {
|
|
4652
|
+
showToast(L.failed + ": " + errText(res), "error");
|
|
4653
|
+
renderSbItems();
|
|
4654
|
+
return;
|
|
4655
|
+
}
|
|
4656
|
+
if (res.config && res.config.statusBar) config.statusBar = res.config.statusBar;
|
|
4657
|
+
} finally {
|
|
4658
|
+
sbSaving = false;
|
|
4659
|
+
}
|
|
4660
|
+
renderSbItems();
|
|
4661
|
+
};
|
|
4662
|
+
const turnList = h("div", { class: "divide-y divide-border rounded-xl border border-border" });
|
|
4663
|
+
const renderSbItems = () => {
|
|
4664
|
+
turnList.replaceChildren(...turnItems().map((it, i) => h(
|
|
4665
|
+
"div",
|
|
4666
|
+
{ class: "flex items-center gap-2 px-3 py-2" },
|
|
4667
|
+
h("span", { class: "min-w-0 flex-1 truncate text-ui-sm text-foreground-subtle" }, L[TURN_NAMES[it.id]] || it.id),
|
|
4668
|
+
btnSmall(it.on ? L.sbVisible : L.sbHidden, () => {
|
|
4669
|
+
void saveTurnItems(turnItems().map((x) => x.id === it.id ? { ...x, on: !x.on } : x));
|
|
4670
|
+
}),
|
|
4671
|
+
btnSmall("\u2191", () => {
|
|
4672
|
+
const a = turnItems();
|
|
4673
|
+
if (i > 0) {
|
|
4674
|
+
[a[i - 1], a[i]] = [a[i], a[i - 1]];
|
|
4675
|
+
void saveTurnItems(a);
|
|
4676
|
+
}
|
|
4677
|
+
}),
|
|
4678
|
+
btnSmall("\u2193", () => {
|
|
4679
|
+
const a = turnItems();
|
|
4680
|
+
if (i < a.length - 1) {
|
|
4681
|
+
[a[i], a[i + 1]] = [a[i + 1], a[i]];
|
|
4682
|
+
void saveTurnItems(a);
|
|
4683
|
+
}
|
|
4684
|
+
})
|
|
4685
|
+
)));
|
|
4686
|
+
const list = sbItems();
|
|
4687
|
+
const renderGroup = (el, groupIds) => {
|
|
4688
|
+
const idxs = list.map((x, i) => i).filter((i) => groupIds.has(list[i].id));
|
|
4689
|
+
el.replaceChildren(...idxs.map((i) => {
|
|
4690
|
+
const it = list[i];
|
|
4691
|
+
const swap = (dir) => {
|
|
4692
|
+
const a = sbItems();
|
|
4693
|
+
const same = a.map((x, j) => j).filter((j) => groupIds.has(a[j].id));
|
|
4694
|
+
const pos = same.indexOf(i);
|
|
4695
|
+
const other = same[pos + dir];
|
|
4696
|
+
if (other == null) return;
|
|
4697
|
+
[a[i], a[other]] = [a[other], a[i]];
|
|
4698
|
+
void saveSbItems(a);
|
|
4699
|
+
};
|
|
4700
|
+
return h(
|
|
4701
|
+
"div",
|
|
4702
|
+
{ class: "flex items-center gap-2 px-3 py-2" },
|
|
4703
|
+
h(
|
|
4704
|
+
"span",
|
|
4705
|
+
{ class: "min-w-0 flex-1 truncate text-ui-sm text-foreground-subtle" },
|
|
4706
|
+
L[ITEM_NAMES[it.id]] || it.id
|
|
4707
|
+
),
|
|
4708
|
+
btnSmall(it.on ? L.sbVisible : L.sbHidden, () => {
|
|
4709
|
+
void saveSbItems(sbItems().map((x, j) => j === i ? { ...x, on: !x.on } : x));
|
|
4710
|
+
}),
|
|
4711
|
+
btnSmall("\u2191", () => swap(-1)),
|
|
4712
|
+
btnSmall("\u2193", () => swap(1))
|
|
4713
|
+
);
|
|
4714
|
+
}));
|
|
4715
|
+
};
|
|
4716
|
+
renderGroup(sbList, STATUS_SESSION_IDS);
|
|
4717
|
+
renderGroup(sbGlobalList, STATUS_GLOBAL_IDS);
|
|
4718
|
+
};
|
|
4719
|
+
renderSbItems();
|
|
4720
|
+
paneStylesSub2.append(
|
|
4721
|
+
h("p", { class: "text-ui-sm/relaxed text-foreground-subtle" }, L.featureStatusBarDesc),
|
|
4722
|
+
h("div", { class: "mt-3 mb-1 text-ui-sm font-medium" }, L.sbGroupSession),
|
|
4723
|
+
sbList,
|
|
4724
|
+
h("div", { class: "mt-3 mb-1 text-ui-sm font-medium" }, L.sbGroupGlobal),
|
|
4725
|
+
sbGlobalList,
|
|
4726
|
+
h("div", { class: "mt-3 mb-1 text-ui-sm font-medium" }, L.sbGroupTurn),
|
|
4727
|
+
turnList
|
|
4728
|
+
);
|
|
4729
|
+
let stylesSubTab = "styles";
|
|
4730
|
+
const stylesSubTablist = h("div", { role: "tablist", "aria-orientation": "horizontal", class: "zcodepro-tablist" });
|
|
4731
|
+
const renderStylesSubTabs = () => stylesSubTablist.replaceChildren(...[
|
|
4732
|
+
["styles", L.tabStylesPane],
|
|
4733
|
+
["status", L.tabStatusPane]
|
|
4734
|
+
].map(([id, label]) => h("button", {
|
|
4735
|
+
type: "button",
|
|
4736
|
+
role: "tab",
|
|
4737
|
+
class: "zcodepro-tab",
|
|
4738
|
+
"aria-selected": String(stylesSubTab === id),
|
|
4739
|
+
"data-state": stylesSubTab === id ? "active" : "inactive",
|
|
4740
|
+
onClick: () => {
|
|
4741
|
+
stylesSubTab = id;
|
|
4742
|
+
paneStylesSub1.style.display = id === "styles" ? "" : "none";
|
|
4743
|
+
paneStylesSub2.style.display = id === "status" ? "" : "none";
|
|
4744
|
+
renderStylesSubTabs();
|
|
4745
|
+
}
|
|
4746
|
+
}, label)));
|
|
4747
|
+
renderStylesSubTabs();
|
|
4748
|
+
paneStyles.append(stylesSubTablist, paneStylesSub1, paneStylesSub2);
|
|
4749
|
+
paneStylesSub1.append(
|
|
4437
4750
|
toolbarSwitchWrap,
|
|
4438
4751
|
h(
|
|
4439
4752
|
"div",
|
|
@@ -5431,6 +5744,11 @@
|
|
|
5431
5744
|
h(
|
|
5432
5745
|
"div",
|
|
5433
5746
|
{ class: "ml-auto flex items-center gap-4" },
|
|
5747
|
+
settingRow(L.visionCardUi, "", visionCfg.cardUi !== false, async () => {
|
|
5748
|
+
visionCfg.cardUi = !(visionCfg.cardUi !== false);
|
|
5749
|
+
await persistVision();
|
|
5750
|
+
renderVision();
|
|
5751
|
+
}),
|
|
5434
5752
|
settingRow(L.visionForceIntercept, "", visionCfg.forceIntercept !== false, async () => {
|
|
5435
5753
|
visionCfg.forceIntercept = !(visionCfg.forceIntercept !== false);
|
|
5436
5754
|
await persistVision();
|
|
@@ -6506,11 +6824,11 @@
|
|
|
6506
6824
|
const rootEl = document.getElementById("root");
|
|
6507
6825
|
const containerKey = rootEl && Object.keys(rootEl).find((k) => k.startsWith("__reactContainer$"));
|
|
6508
6826
|
if (!containerKey) return null;
|
|
6509
|
-
const
|
|
6827
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
6510
6828
|
let found = null;
|
|
6511
6829
|
const scanObj = (o) => {
|
|
6512
|
-
if (!o || typeof o !== "object" ||
|
|
6513
|
-
|
|
6830
|
+
if (!o || typeof o !== "object" || seen2.has(o) || found) return;
|
|
6831
|
+
seen2.add(o);
|
|
6514
6832
|
const ts = o.zcodeTaskService;
|
|
6515
6833
|
if (ts && typeof ts === "object" && typeof ts.releaseWorkspacePreparation === "function") found = o;
|
|
6516
6834
|
};
|
|
@@ -6649,22 +6967,22 @@
|
|
|
6649
6967
|
}, 0);
|
|
6650
6968
|
}
|
|
6651
6969
|
function apply() {
|
|
6652
|
-
const
|
|
6970
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
6653
6971
|
for (const row of document.querySelectorAll(WS_SEL())) {
|
|
6654
6972
|
const path = rowPath(row);
|
|
6655
6973
|
if (!path) continue;
|
|
6656
|
-
|
|
6974
|
+
seen2.add(path);
|
|
6657
6975
|
const head = wsHead(row);
|
|
6658
6976
|
const collapsed = !head || head.getAttribute("aria-expanded") === "false";
|
|
6659
6977
|
const domRunning = !!(runningByWs.get(path) && runningByWs.get(path).size);
|
|
6660
6978
|
const normP = (v) => String(v || "").replace(/[\\/]+$/, "");
|
|
6661
6979
|
const running = enabled2 && collapsed && (activeProjectPaths.size ? [...activeProjectPaths].some((p2) => normP(p2) === normP(path)) : domRunning);
|
|
6662
|
-
const
|
|
6663
|
-
|
|
6664
|
-
setRunningIcon(
|
|
6980
|
+
const icon2 = iconHolderOf(row);
|
|
6981
|
+
icon2?.classList.toggle("zcodepro-ws-running", running);
|
|
6982
|
+
setRunningIcon(icon2, running);
|
|
6665
6983
|
}
|
|
6666
6984
|
applySectionSpin();
|
|
6667
|
-
for (const ws of [...runningByWs.keys()]) if (!
|
|
6985
|
+
for (const ws of [...runningByWs.keys()]) if (!seen2.has(ws)) runningByWs.delete(ws);
|
|
6668
6986
|
}
|
|
6669
6987
|
var headInfoCache = /* @__PURE__ */ new WeakMap();
|
|
6670
6988
|
var PROJECT_HEAD_TEXTS = /* @__PURE__ */ new Set(["\u9879\u76EE", "projects"]);
|
|
@@ -7466,20 +7784,20 @@
|
|
|
7466
7784
|
}
|
|
7467
7785
|
function findBridge() {
|
|
7468
7786
|
let holder = null;
|
|
7469
|
-
const
|
|
7470
|
-
const
|
|
7471
|
-
if (!o || typeof o !== "object" ||
|
|
7472
|
-
|
|
7787
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
7788
|
+
const scan5 = (o) => {
|
|
7789
|
+
if (!o || typeof o !== "object" || seen2.has(o) || holder) return;
|
|
7790
|
+
seen2.add(o);
|
|
7473
7791
|
if (typeof o.pluginUiBridgeService === "object" && o.pluginUiBridgeService) {
|
|
7474
7792
|
holder = o.pluginUiBridgeService;
|
|
7475
7793
|
return;
|
|
7476
7794
|
}
|
|
7477
|
-
for (const v of Object.values(o)) if (v && typeof v === "object")
|
|
7795
|
+
for (const v of Object.values(o)) if (v && typeof v === "object") scan5(v);
|
|
7478
7796
|
};
|
|
7479
7797
|
eachFiber((f) => {
|
|
7480
7798
|
for (const h2 of [f.memoizedProps, f.memoizedState]) {
|
|
7481
7799
|
if (!h2 || typeof h2 !== "object") continue;
|
|
7482
|
-
|
|
7800
|
+
scan5(h2);
|
|
7483
7801
|
if (holder) return true;
|
|
7484
7802
|
}
|
|
7485
7803
|
return false;
|
|
@@ -7615,6 +7933,423 @@
|
|
|
7615
7933
|
setInterval(tryInject, 5e3);
|
|
7616
7934
|
}
|
|
7617
7935
|
|
|
7936
|
+
// src/inject/features/status-bar.js
|
|
7937
|
+
var enabled4 = true;
|
|
7938
|
+
var items = DEFAULT_STATUS_ITEMS.map((x) => ({ ...x }));
|
|
7939
|
+
var barEl = null;
|
|
7940
|
+
var lastStats = null;
|
|
7941
|
+
function readCtx() {
|
|
7942
|
+
for (const el of document.querySelectorAll("[title], [aria-label]")) {
|
|
7943
|
+
if (el.closest(".zcodepro-statusbar")) continue;
|
|
7944
|
+
const text = el.getAttribute("title") || el.getAttribute("aria-label") || "";
|
|
7945
|
+
if (!/上下文|context/i.test(text)) continue;
|
|
7946
|
+
const m = text.match(/([\d][\d,]*)\s*\/[^0-9]*([\d][\d,]*)/);
|
|
7947
|
+
if (!m) continue;
|
|
7948
|
+
const used = Number(m[1].replace(/,/g, ""));
|
|
7949
|
+
const size = Number(m[2].replace(/,/g, ""));
|
|
7950
|
+
if (used > 0 && size > used) return { used, size };
|
|
7951
|
+
}
|
|
7952
|
+
return null;
|
|
7953
|
+
}
|
|
7954
|
+
var usageSvc = null;
|
|
7955
|
+
var official = null;
|
|
7956
|
+
var officialAt = 0;
|
|
7957
|
+
function eachFiber2(visit) {
|
|
7958
|
+
const rootEl = document.getElementById("root");
|
|
7959
|
+
const key = rootEl && Object.keys(rootEl).find((k) => k.startsWith("__reactContainer$"));
|
|
7960
|
+
if (!key) return;
|
|
7961
|
+
let visited = 0;
|
|
7962
|
+
const walk = (f) => {
|
|
7963
|
+
if (!f || visited > 2e5) return false;
|
|
7964
|
+
visited++;
|
|
7965
|
+
if (visit(f)) return true;
|
|
7966
|
+
return walk(f.child) || walk(f.sibling);
|
|
7967
|
+
};
|
|
7968
|
+
walk(rootEl[key]);
|
|
7969
|
+
}
|
|
7970
|
+
function findUsageService() {
|
|
7971
|
+
let found = null;
|
|
7972
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
7973
|
+
const scan5 = (o) => {
|
|
7974
|
+
if (!o || typeof o !== "object" || seen2.has(o) || found) return;
|
|
7975
|
+
seen2.add(o);
|
|
7976
|
+
if (typeof o.usageStatsService === "object" && o.usageStatsService) {
|
|
7977
|
+
found = o.usageStatsService;
|
|
7978
|
+
return;
|
|
7979
|
+
}
|
|
7980
|
+
for (const v of Object.values(o)) if (v && typeof v === "object") scan5(v);
|
|
7981
|
+
};
|
|
7982
|
+
eachFiber2((f) => {
|
|
7983
|
+
for (const h2 of [f.memoizedProps, f.memoizedState]) {
|
|
7984
|
+
if (!h2 || typeof h2 !== "object") continue;
|
|
7985
|
+
scan5(h2);
|
|
7986
|
+
if (found) return true;
|
|
7987
|
+
}
|
|
7988
|
+
return false;
|
|
7989
|
+
});
|
|
7990
|
+
return found;
|
|
7991
|
+
}
|
|
7992
|
+
function refreshOfficial() {
|
|
7993
|
+
const period = official ? 5 * 6e4 : 3e4;
|
|
7994
|
+
if (Date.now() - officialAt < period) return;
|
|
7995
|
+
officialAt = Date.now();
|
|
7996
|
+
void (async () => {
|
|
7997
|
+
try {
|
|
7998
|
+
if (!usageSvc) usageSvc = findUsageService();
|
|
7999
|
+
if (!usageSvc || typeof usageSvc.getAppUsageSnapshot !== "function") return;
|
|
8000
|
+
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
8001
|
+
const [all, d7] = await Promise.all([
|
|
8002
|
+
usageSvc.getAppUsageSnapshot({ range: "all", timeZone }),
|
|
8003
|
+
usageSvc.getAppUsageSnapshot({ range: "7d", timeZone })
|
|
8004
|
+
]);
|
|
8005
|
+
const now = /* @__PURE__ */ new Date();
|
|
8006
|
+
const key = now.getFullYear() + "-" + String(now.getMonth() + 1).padStart(2, "0") + "-" + String(now.getDate()).padStart(2, "0");
|
|
8007
|
+
let todayTokens = 0;
|
|
8008
|
+
const day = (d7 && Array.isArray(d7.dailyModelUsage) ? d7.dailyModelUsage : []).find((d) => d.date === key);
|
|
8009
|
+
if (day) for (const m of day.models || []) todayTokens += Number(m.totalTokens) || 0;
|
|
8010
|
+
official = {
|
|
8011
|
+
todayTokens,
|
|
8012
|
+
totalTokens: Number(all && all.summary && all.summary.totalTokens) || 0,
|
|
8013
|
+
totalSessions: Number(all && all.summary && all.summary.totalSessions) || 0
|
|
8014
|
+
};
|
|
8015
|
+
renderBar();
|
|
8016
|
+
} catch {
|
|
8017
|
+
usageSvc = null;
|
|
8018
|
+
}
|
|
8019
|
+
})();
|
|
8020
|
+
}
|
|
8021
|
+
var GLOBAL_GROUP = /* @__PURE__ */ new Set(["todayTokens", "totalTokens", "tasks"]);
|
|
8022
|
+
var SB_ICONS = {
|
|
8023
|
+
ctx: '<path d="M21.21 15.89A10 10 0 1 1 8 2.83"/><path d="M22 12A10 10 0 0 0 12 2v10z"/>',
|
|
8024
|
+
asks: '<path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/>',
|
|
8025
|
+
today: '<circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/>',
|
|
8026
|
+
total: '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/>',
|
|
8027
|
+
tasks: '<rect x="3" y="5" width="6" height="6" rx="1"/><path d="m3 17 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/>',
|
|
8028
|
+
coins: '<circle cx="8" cy="8" r="6"/><path d="M18.09 10.37A6 6 0 1 1 10.34 18"/><path d="M7 6h1v4"/><path d="m16.71 13.88.7.71-2.82 2.82"/>'
|
|
8029
|
+
};
|
|
8030
|
+
var sbIcon = (name) => `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="zcodepro-sb-icon">${SB_ICONS[name]}</svg>`;
|
|
8031
|
+
function fmtTokens(n) {
|
|
8032
|
+
if (n >= 1e9) return (n / 1e9).toFixed(1) + "B";
|
|
8033
|
+
if (n >= 1e6) return (n / 1e6).toFixed(1) + "M";
|
|
8034
|
+
if (n >= 1e3) return (n / 1e3).toFixed(1) + "k";
|
|
8035
|
+
return String(n);
|
|
8036
|
+
}
|
|
8037
|
+
function fmtNum(n) {
|
|
8038
|
+
if (!isZhLocale()) return fmtTokens(n);
|
|
8039
|
+
if (n < 1e4) return String(n);
|
|
8040
|
+
if (n >= 1e8) {
|
|
8041
|
+
const yi = Math.round(n / 1e8 * 10) / 10;
|
|
8042
|
+
return (yi % 1 === 0 ? String(yi) : yi.toFixed(1)) + "\u4EBF";
|
|
8043
|
+
}
|
|
8044
|
+
const wan = Math.round(n / 1e4 * 10) / 10;
|
|
8045
|
+
return (wan % 1 === 0 ? String(wan) : wan.toFixed(1)) + "\u4E07";
|
|
8046
|
+
}
|
|
8047
|
+
function itemContent(id, L) {
|
|
8048
|
+
const g = lastStats && lastStats.global;
|
|
8049
|
+
const label = (text) => `<em>${text}</em>`;
|
|
8050
|
+
switch (id) {
|
|
8051
|
+
case "ctx": {
|
|
8052
|
+
const dom = readCtx();
|
|
8053
|
+
if (dom) {
|
|
8054
|
+
const pct = Math.round(dom.used / dom.size * 1e3) / 10;
|
|
8055
|
+
const tone = pct >= 95 ? "danger" : pct >= 80 ? "warn" : "";
|
|
8056
|
+
return {
|
|
8057
|
+
html: sbIcon("ctx") + label(L.sbLabelCtx) + `<b>${fmtNum(dom.used)}/${fmtNum(dom.size)}${isZhLocale() ? "\uFF08" : "("}${pct}%${isZhLocale() ? "\uFF09" : ")"}</b>`,
|
|
8058
|
+
title: `${L.sbItemCtx}\uFF1A${dom.used.toLocaleString()} / ${dom.size.toLocaleString()}`,
|
|
8059
|
+
tone
|
|
8060
|
+
};
|
|
8061
|
+
}
|
|
8062
|
+
return null;
|
|
8063
|
+
}
|
|
8064
|
+
case "questions": {
|
|
8065
|
+
const nav = document.querySelector('[data-testid="v4-turn-navigator"]');
|
|
8066
|
+
const n = nav ? Number(nav.getAttribute("data-item-count")) : 0;
|
|
8067
|
+
return n > 0 ? { html: sbIcon("asks") + label(L.sbLabelQuestions) + String(n), title: L.sbItemQuestions } : null;
|
|
8068
|
+
}
|
|
8069
|
+
case "todayTokens": {
|
|
8070
|
+
const n = official ? official.todayTokens : g ? g.todayTokens : 0;
|
|
8071
|
+
return n > 0 ? { html: sbIcon("today") + label(L.sbLabelToday) + fmtNum(n), title: L.sbItemTodayTokens } : null;
|
|
8072
|
+
}
|
|
8073
|
+
case "totalTokens": {
|
|
8074
|
+
const n = official ? official.totalTokens : g ? g.totalTokens : 0;
|
|
8075
|
+
return n > 0 ? { html: sbIcon("total") + label(L.sbLabelTotal) + fmtNum(n), title: L.sbItemTotalTokens } : null;
|
|
8076
|
+
}
|
|
8077
|
+
case "tasks": {
|
|
8078
|
+
const n = official ? official.totalSessions : g ? g.tasks : 0;
|
|
8079
|
+
return n > 0 ? { html: sbIcon("tasks") + label(L.sbLabelTasks) + String(n), title: L.sbItemTasks } : null;
|
|
8080
|
+
}
|
|
8081
|
+
default:
|
|
8082
|
+
return null;
|
|
8083
|
+
}
|
|
8084
|
+
}
|
|
8085
|
+
function renderBar() {
|
|
8086
|
+
const ta = document.querySelector("textarea, [contenteditable=true]");
|
|
8087
|
+
const host = ta && (ta.closest("form") || ta.parentElement);
|
|
8088
|
+
if (!enabled4 || !host || !host.parentElement) {
|
|
8089
|
+
if (barEl) barEl.remove();
|
|
8090
|
+
barEl = null;
|
|
8091
|
+
return;
|
|
8092
|
+
}
|
|
8093
|
+
if (!barEl || !barEl.isConnected) {
|
|
8094
|
+
if (!barEl) {
|
|
8095
|
+
barEl = document.createElement("div");
|
|
8096
|
+
barEl.className = "zcodepro-statusbar";
|
|
8097
|
+
}
|
|
8098
|
+
host.parentElement.insertBefore(barEl, host.nextSibling);
|
|
8099
|
+
}
|
|
8100
|
+
const hasSession = !![...document.querySelectorAll("[data-task-item-key]")].find((e) => (e.className + "").includes("bg-selected"));
|
|
8101
|
+
barEl.style.marginBottom = hasSession ? "-14px" : "0";
|
|
8102
|
+
barEl.style.paddingBottom = hasSession ? "0" : "7px";
|
|
8103
|
+
const L = t();
|
|
8104
|
+
const parts = [];
|
|
8105
|
+
let lastGroup = "";
|
|
8106
|
+
for (const it of items) {
|
|
8107
|
+
if (!it.on) continue;
|
|
8108
|
+
const c = itemContent(it.id, L);
|
|
8109
|
+
if (!c) continue;
|
|
8110
|
+
const group = GLOBAL_GROUP.has(it.id) ? "g" : "s";
|
|
8111
|
+
if (lastGroup && group !== lastGroup) parts.push('<span class="zcodepro-statusbar-groupsep"></span>');
|
|
8112
|
+
lastGroup = group;
|
|
8113
|
+
parts.push(`<span title="${c.title.replace(/"/g, """)}"${c.tone ? ` data-tone="${c.tone}"` : ""}>${c.html}</span>`);
|
|
8114
|
+
}
|
|
8115
|
+
const SEP = '<span class="zcodepro-statusbar-sep">\xB7</span>';
|
|
8116
|
+
const GROUPSEP = '<span class="zcodepro-statusbar-groupsep"></span>';
|
|
8117
|
+
barEl.innerHTML = parts.reduce((acc, p, i) => {
|
|
8118
|
+
if (i === 0) return p;
|
|
8119
|
+
if (p === GROUPSEP || parts[i - 1] === GROUPSEP) return acc + p;
|
|
8120
|
+
return acc + SEP + p;
|
|
8121
|
+
}, "");
|
|
8122
|
+
barEl.style.display = parts.length ? "" : "none";
|
|
8123
|
+
}
|
|
8124
|
+
async function tick() {
|
|
8125
|
+
if (!enabled4 || document.hidden) return;
|
|
8126
|
+
refreshOfficial();
|
|
8127
|
+
const res = await rpc("/stats/usage").catch(() => null);
|
|
8128
|
+
if (res && res.ok) lastStats = res;
|
|
8129
|
+
renderBar();
|
|
8130
|
+
}
|
|
8131
|
+
function startStatusBar() {
|
|
8132
|
+
ensureStyle();
|
|
8133
|
+
const refreshCfg = () => {
|
|
8134
|
+
void getConfig().then((cfg) => {
|
|
8135
|
+
enabled4 = cfg.features ? cfg.features.statusBar !== false : true;
|
|
8136
|
+
const saved = cfg.statusBar && Array.isArray(cfg.statusBar.items) ? cfg.statusBar.items : null;
|
|
8137
|
+
if (saved) {
|
|
8138
|
+
const byId = new Map(saved.map((x) => [x.id, x]));
|
|
8139
|
+
const list = saved.filter((x) => DEFAULT_STATUS_ITEMS.some((d) => d.id === x.id)).map((x) => ({ ...x }));
|
|
8140
|
+
const known = new Set(list.map((x) => x.id));
|
|
8141
|
+
for (const d of DEFAULT_STATUS_ITEMS) {
|
|
8142
|
+
if (!known.has(d.id)) list.push({ ...d });
|
|
8143
|
+
}
|
|
8144
|
+
items = [
|
|
8145
|
+
...list.filter((x) => !GLOBAL_GROUP.has(x.id)),
|
|
8146
|
+
...list.filter((x) => GLOBAL_GROUP.has(x.id))
|
|
8147
|
+
];
|
|
8148
|
+
} else {
|
|
8149
|
+
items = DEFAULT_STATUS_ITEMS.map((x) => ({ ...x }));
|
|
8150
|
+
}
|
|
8151
|
+
renderBar();
|
|
8152
|
+
}).catch(() => {
|
|
8153
|
+
});
|
|
8154
|
+
};
|
|
8155
|
+
refreshCfg();
|
|
8156
|
+
window.addEventListener("zcodepro:config-changed", refreshCfg);
|
|
8157
|
+
document.addEventListener("visibilitychange", () => {
|
|
8158
|
+
if (!document.hidden) void tick();
|
|
8159
|
+
});
|
|
8160
|
+
setInterval(() => {
|
|
8161
|
+
void tick();
|
|
8162
|
+
}, 2e3);
|
|
8163
|
+
let rerenderTimer = 0;
|
|
8164
|
+
new MutationObserver(() => {
|
|
8165
|
+
if (rerenderTimer) return;
|
|
8166
|
+
rerenderTimer = setTimeout(() => {
|
|
8167
|
+
rerenderTimer = 0;
|
|
8168
|
+
renderBar();
|
|
8169
|
+
}, 300);
|
|
8170
|
+
}).observe(document.body, { childList: true, subtree: true });
|
|
8171
|
+
}
|
|
8172
|
+
|
|
8173
|
+
// src/inject/features/turn-usage.js
|
|
8174
|
+
var enabled5 = true;
|
|
8175
|
+
var recentTurns = [];
|
|
8176
|
+
var scanTimer = 0;
|
|
8177
|
+
var turnCfg = [
|
|
8178
|
+
{ id: "turnIn", on: true },
|
|
8179
|
+
{ id: "turnOut", on: true },
|
|
8180
|
+
{ id: "turnCache", on: true }
|
|
8181
|
+
];
|
|
8182
|
+
var refreshTurnItems = () => {
|
|
8183
|
+
void getConfig().then((cfg) => {
|
|
8184
|
+
const saved = cfg.statusBar && Array.isArray(cfg.statusBar.turnItems) ? cfg.statusBar.turnItems : null;
|
|
8185
|
+
if (!saved) return;
|
|
8186
|
+
const known = new Set(turnCfg.map((x) => x.id));
|
|
8187
|
+
const list = saved.filter((x) => x && known.has(x.id)).map((x) => ({ id: x.id, on: x.on !== false }));
|
|
8188
|
+
for (const d of turnCfg) if (!list.some((x) => x.id === d.id)) list.push({ ...d });
|
|
8189
|
+
turnCfg = list;
|
|
8190
|
+
}).catch(() => {
|
|
8191
|
+
});
|
|
8192
|
+
};
|
|
8193
|
+
var ICONS = {
|
|
8194
|
+
up: '<path d="m5 12 7-7 7 7"/><path d="M12 19V5"/>',
|
|
8195
|
+
down: '<path d="M12 5v14"/><path d="m19 12-7 7-7-7"/>',
|
|
8196
|
+
cache: '<path d="m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z"/><path d="m22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65"/><path d="m22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65"/>'
|
|
8197
|
+
};
|
|
8198
|
+
var icon = (name) => `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:11px;height:11px;vertical-align:-1.5px;opacity:.6">${ICONS[name]}</svg>`;
|
|
8199
|
+
function fmt(n) {
|
|
8200
|
+
if (!isZhLocale()) {
|
|
8201
|
+
if (n >= 1e9) return (n / 1e9).toFixed(1) + "B";
|
|
8202
|
+
if (n >= 1e6) return (n / 1e6).toFixed(1) + "M";
|
|
8203
|
+
if (n >= 1e3) return (n / 1e3).toFixed(1) + "k";
|
|
8204
|
+
return String(n);
|
|
8205
|
+
}
|
|
8206
|
+
if (n >= 1e8) return (n / 1e8).toFixed(1) + "\u4EBF";
|
|
8207
|
+
if (n >= 1e4) {
|
|
8208
|
+
const wan = Math.round(n / 1e4 * 10) / 10;
|
|
8209
|
+
return (wan % 1 === 0 ? String(wan) : wan.toFixed(1)) + "\u4E07";
|
|
8210
|
+
}
|
|
8211
|
+
return String(n);
|
|
8212
|
+
}
|
|
8213
|
+
function findRows() {
|
|
8214
|
+
const rows = [];
|
|
8215
|
+
for (const btn of document.querySelectorAll('[data-testid^="v4-copy-"]')) {
|
|
8216
|
+
const row = btn.parentElement;
|
|
8217
|
+
if (!row || row.dataset.zcodeproTurn) continue;
|
|
8218
|
+
if (!row.querySelector('[data-testid^="v4-feedback-"]')) continue;
|
|
8219
|
+
const timeEl = [...row.querySelectorAll("span")].find((s) => /\d{1,2}:\d{2}$/.test((s.textContent || "").trim()));
|
|
8220
|
+
if (timeEl) {
|
|
8221
|
+
const ts = rowTimeTs((timeEl.textContent || "").trim());
|
|
8222
|
+
if (ts != null) rows.push({ row, ts });
|
|
8223
|
+
}
|
|
8224
|
+
}
|
|
8225
|
+
return rows;
|
|
8226
|
+
}
|
|
8227
|
+
function currentSessionId() {
|
|
8228
|
+
const rows = [...document.querySelectorAll("[data-task-item-key]")];
|
|
8229
|
+
const cur = rows.find((e) => (e.className + "").includes("bg-selected")) || rows[rows.length - 1];
|
|
8230
|
+
const key = cur ? cur.getAttribute("data-task-item-key") : "";
|
|
8231
|
+
const i = key.lastIndexOf(":sess");
|
|
8232
|
+
return i > 0 ? key.slice(i + 1) : "";
|
|
8233
|
+
}
|
|
8234
|
+
function injectRow(row, bucket) {
|
|
8235
|
+
row.dataset.zcodeproTurn = "1";
|
|
8236
|
+
if (!bucket || bucket.in + bucket.out <= 0) return;
|
|
8237
|
+
const L = t();
|
|
8238
|
+
const el = document.createElement("span");
|
|
8239
|
+
el.dataset.zcodeproTurnSpan = "1";
|
|
8240
|
+
el.className = "select-none text-ui-sm text-foreground-subtlest";
|
|
8241
|
+
el.style.whiteSpace = "nowrap";
|
|
8242
|
+
el.style.display = "inline-flex";
|
|
8243
|
+
el.style.alignItems = "center";
|
|
8244
|
+
el.style.gap = "4px";
|
|
8245
|
+
el.style.marginLeft = "10px";
|
|
8246
|
+
const cachePct = bucket.in > 0 && bucket.cacheRead > 0 ? (bucket.cacheRead / bucket.in * 100).toFixed(2) : "";
|
|
8247
|
+
const group = (html) => `<span style="display:inline-flex;align-items:center;gap:2px">${html}</span>`;
|
|
8248
|
+
const em = (text) => `<em style="font-style:normal;opacity:.75">${text}</em>`;
|
|
8249
|
+
const DOT = '<span style="opacity:.45">\xB7</span>';
|
|
8250
|
+
const sections = [];
|
|
8251
|
+
for (const s of turnCfg) {
|
|
8252
|
+
if (!s.on) continue;
|
|
8253
|
+
if (s.id === "turnIn") sections.push(group(icon("up") + em(L.sbLabelIn) + fmt(bucket.in)));
|
|
8254
|
+
else if (s.id === "turnOut") sections.push(group(icon("down") + em(L.sbLabelOut) + fmt(bucket.out)));
|
|
8255
|
+
else if (s.id === "turnCache" && cachePct) sections.push(group(icon("cache") + em(L.sbLabelCache) + cachePct + "%"));
|
|
8256
|
+
}
|
|
8257
|
+
if (!sections.length) {
|
|
8258
|
+
delete row.dataset.zcodeproTurn;
|
|
8259
|
+
el.remove();
|
|
8260
|
+
return;
|
|
8261
|
+
}
|
|
8262
|
+
const VBAR = '<span style="display:inline-block;width:1px;height:10px;background:currentColor;opacity:.3;margin:0 5px"></span>';
|
|
8263
|
+
el.innerHTML = VBAR + sections.join(DOT);
|
|
8264
|
+
el.title = `${L.turnUsageTitle}\uFF1A${L.sbLabelIn} ${bucket.in.toLocaleString()} / ${L.sbLabelOut} ${bucket.out.toLocaleString()}` + (bucket.cacheRead > 0 ? ` / ${L.sbLabelCache} ${bucket.cacheRead.toLocaleString()}` : "");
|
|
8265
|
+
row.append(el);
|
|
8266
|
+
}
|
|
8267
|
+
function rowTimeTs(text) {
|
|
8268
|
+
const now = /* @__PURE__ */ new Date();
|
|
8269
|
+
let m = text.match(/^(\d{1,2}):(\d{2})$/);
|
|
8270
|
+
if (m) return new Date(now.getFullYear(), now.getMonth(), now.getDate(), +m[1], +m[2]).getTime();
|
|
8271
|
+
m = text.match(/^昨天\s*(\d{1,2}):(\d{2})$/);
|
|
8272
|
+
if (m) {
|
|
8273
|
+
const y = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
|
|
8274
|
+
return new Date(y.getFullYear(), y.getMonth(), y.getDate(), +m[1], +m[2]).getTime();
|
|
8275
|
+
}
|
|
8276
|
+
m = text.match(/^(\d{1,2})\/(\d{1,2})\s*(\d{1,2}):(\d{2})$/);
|
|
8277
|
+
if (m) return new Date(now.getFullYear(), +m[1] - 1, +m[2], +m[3], +m[4]).getTime();
|
|
8278
|
+
return null;
|
|
8279
|
+
}
|
|
8280
|
+
var lastSid = "";
|
|
8281
|
+
function scan3() {
|
|
8282
|
+
if (!enabled5) return;
|
|
8283
|
+
const sid = currentSessionId();
|
|
8284
|
+
if (sid !== lastSid) {
|
|
8285
|
+
lastSid = sid;
|
|
8286
|
+
recentTurns = [];
|
|
8287
|
+
void tick2();
|
|
8288
|
+
}
|
|
8289
|
+
for (const el of document.querySelectorAll('[data-zcodepro-turn-span], span[title^="\u672C\u8F6E"], span[title^="Turn"]')) el.remove();
|
|
8290
|
+
for (const row of document.querySelectorAll("[data-zcodepro-turn]")) delete row.dataset.zcodeproTurn;
|
|
8291
|
+
if (document.hidden || !recentTurns.length) return;
|
|
8292
|
+
const rows = findRows().sort((a, b) => a.ts - b.ts);
|
|
8293
|
+
if (!rows.length) return;
|
|
8294
|
+
const agg = rows.map(() => ({ in: 0, out: 0, cacheRead: 0 }));
|
|
8295
|
+
const dayOf = (t2) => {
|
|
8296
|
+
const d = new Date(t2);
|
|
8297
|
+
return d.getFullYear() * 1e4 + (d.getMonth() + 1) * 100 + d.getDate();
|
|
8298
|
+
};
|
|
8299
|
+
for (const b of recentTurns) {
|
|
8300
|
+
let owner = -1;
|
|
8301
|
+
for (let i = 0; i < rows.length; i++) {
|
|
8302
|
+
if (rows[i].ts <= b.ts) owner = i;
|
|
8303
|
+
else break;
|
|
8304
|
+
}
|
|
8305
|
+
if (owner < 0) continue;
|
|
8306
|
+
if (dayOf(rows[owner].ts) !== dayOf(b.ts)) continue;
|
|
8307
|
+
agg[owner].in += b.in;
|
|
8308
|
+
agg[owner].out += b.out;
|
|
8309
|
+
agg[owner].cacheRead += b.cacheRead;
|
|
8310
|
+
}
|
|
8311
|
+
for (let i = 0; i < rows.length; i++) {
|
|
8312
|
+
if (agg[i].in + agg[i].out > 0) injectRow(rows[i].row, agg[i]);
|
|
8313
|
+
}
|
|
8314
|
+
}
|
|
8315
|
+
async function tick2() {
|
|
8316
|
+
if (!enabled5 || document.hidden) return;
|
|
8317
|
+
const sid = currentSessionId();
|
|
8318
|
+
const res = await rpc("/stats/usage" + (sid ? "?session=" + encodeURIComponent(sid) : "")).catch(() => null);
|
|
8319
|
+
if (res && res.ok && Array.isArray(res.recentTurns)) {
|
|
8320
|
+
recentTurns = res.recentTurns;
|
|
8321
|
+
scan3();
|
|
8322
|
+
}
|
|
8323
|
+
}
|
|
8324
|
+
function startTurnUsage() {
|
|
8325
|
+
void getConfig().then((cfg) => {
|
|
8326
|
+
enabled5 = cfg.features ? cfg.features.turnUsage !== false : true;
|
|
8327
|
+
}).catch(() => {
|
|
8328
|
+
});
|
|
8329
|
+
refreshTurnItems();
|
|
8330
|
+
window.addEventListener("zcodepro:config-changed", () => {
|
|
8331
|
+
void getConfig().then((cfg) => {
|
|
8332
|
+
enabled5 = cfg.features ? cfg.features.turnUsage !== false : true;
|
|
8333
|
+
}).catch(() => {
|
|
8334
|
+
});
|
|
8335
|
+
refreshTurnItems();
|
|
8336
|
+
});
|
|
8337
|
+
const observer2 = new MutationObserver(() => {
|
|
8338
|
+
if (scanTimer) return;
|
|
8339
|
+
scanTimer = setTimeout(() => {
|
|
8340
|
+
scanTimer = 0;
|
|
8341
|
+
scan3();
|
|
8342
|
+
}, 1200);
|
|
8343
|
+
});
|
|
8344
|
+
observer2.observe(document.body, { childList: true, subtree: true });
|
|
8345
|
+
setInterval(() => {
|
|
8346
|
+
void tick2();
|
|
8347
|
+
}, 5e3);
|
|
8348
|
+
document.addEventListener("visibilitychange", () => {
|
|
8349
|
+
if (!document.hidden) void tick2();
|
|
8350
|
+
});
|
|
8351
|
+
}
|
|
8352
|
+
|
|
7618
8353
|
// src/inject/features/title-lock.js
|
|
7619
8354
|
var TASK_SEL2 = "[data-task-item-key]";
|
|
7620
8355
|
var SCAN_DEBOUNCE_MS3 = 150;
|
|
@@ -7625,7 +8360,7 @@
|
|
|
7625
8360
|
var MAP_REFRESH_MS = 6e4;
|
|
7626
8361
|
var installed3 = false;
|
|
7627
8362
|
var seenRows = /* @__PURE__ */ new WeakSet();
|
|
7628
|
-
var
|
|
8363
|
+
var enabled6 = true;
|
|
7629
8364
|
var pinned = null;
|
|
7630
8365
|
var resolved = false;
|
|
7631
8366
|
var fetching = null;
|
|
@@ -7640,7 +8375,7 @@
|
|
|
7640
8375
|
const t2 = item.querySelector('[class*="truncate"]');
|
|
7641
8376
|
return t2 ? [t2] : [];
|
|
7642
8377
|
}
|
|
7643
|
-
function
|
|
8378
|
+
function findRows2(key) {
|
|
7644
8379
|
return [...document.querySelectorAll(`${TASK_SEL2}[data-task-item-key="${CSS.escape(key)}"]`)];
|
|
7645
8380
|
}
|
|
7646
8381
|
async function fetchPinned() {
|
|
@@ -7649,8 +8384,8 @@
|
|
|
7649
8384
|
const res = await rpc("/pinned-titles");
|
|
7650
8385
|
if (!res || !res.ok) return null;
|
|
7651
8386
|
resolved = true;
|
|
7652
|
-
|
|
7653
|
-
if (!
|
|
8387
|
+
enabled6 = res.enabled !== false;
|
|
8388
|
+
if (!enabled6) {
|
|
7654
8389
|
pinned = null;
|
|
7655
8390
|
return null;
|
|
7656
8391
|
}
|
|
@@ -7665,7 +8400,7 @@
|
|
|
7665
8400
|
}
|
|
7666
8401
|
}
|
|
7667
8402
|
function isMismatch(item) {
|
|
7668
|
-
if (!
|
|
8403
|
+
if (!enabled6 || !pinned) return null;
|
|
7669
8404
|
const key = item.getAttribute("data-task-item-key") || "";
|
|
7670
8405
|
const want = pinned.get(sessIdOf(key));
|
|
7671
8406
|
if (want === void 0) return null;
|
|
@@ -7683,10 +8418,10 @@
|
|
|
7683
8418
|
}
|
|
7684
8419
|
function scheduleEnforce(key, { immediate = false } = {}) {
|
|
7685
8420
|
if (immediate) {
|
|
7686
|
-
if (
|
|
8421
|
+
if (enabled6 && pinned) {
|
|
7687
8422
|
const want = pinned.get(sessIdOf(key));
|
|
7688
8423
|
if (want !== void 0) {
|
|
7689
|
-
for (const item of
|
|
8424
|
+
for (const item of findRows2(key)) {
|
|
7690
8425
|
for (const el of titleElsOf(item)) writeTitle(el, want);
|
|
7691
8426
|
}
|
|
7692
8427
|
}
|
|
@@ -7702,7 +8437,7 @@
|
|
|
7702
8437
|
const want = map.get(sessIdOf(key));
|
|
7703
8438
|
if (want === void 0) return;
|
|
7704
8439
|
let wrote = false;
|
|
7705
|
-
for (const item of
|
|
8440
|
+
for (const item of findRows2(key)) {
|
|
7706
8441
|
if (isMismatch(item) !== key) continue;
|
|
7707
8442
|
for (const el of titleElsOf(item)) writeTitle(el, want);
|
|
7708
8443
|
wrote = true;
|
|
@@ -7718,13 +8453,13 @@
|
|
|
7718
8453
|
if (!map) return;
|
|
7719
8454
|
const want = map.get(sessIdOf(key));
|
|
7720
8455
|
if (want === void 0) return;
|
|
7721
|
-
for (const item of
|
|
8456
|
+
for (const item of findRows2(key)) {
|
|
7722
8457
|
if (isMismatch(item) !== key) continue;
|
|
7723
8458
|
for (const el of titleElsOf(item)) writeTitle(el, want);
|
|
7724
8459
|
}
|
|
7725
8460
|
}
|
|
7726
|
-
function
|
|
7727
|
-
if (!
|
|
8461
|
+
function scan4() {
|
|
8462
|
+
if (!enabled6 || !pinned || pinned.size === 0) return;
|
|
7728
8463
|
for (const item of document.querySelectorAll(TASK_SEL2)) {
|
|
7729
8464
|
const key = isMismatch(item);
|
|
7730
8465
|
if (!key) {
|
|
@@ -7758,23 +8493,23 @@
|
|
|
7758
8493
|
if (scanDebounce3) return;
|
|
7759
8494
|
scanDebounce3 = setTimeout(() => {
|
|
7760
8495
|
scanDebounce3 = 0;
|
|
7761
|
-
|
|
8496
|
+
scan4();
|
|
7762
8497
|
}, SCAN_DEBOUNCE_MS3);
|
|
7763
8498
|
}
|
|
7764
8499
|
var mapRefreshTimer = 0;
|
|
7765
8500
|
function refreshMapSoon() {
|
|
7766
8501
|
if (mapRefreshTimer) return;
|
|
7767
|
-
const
|
|
8502
|
+
const tick6 = () => {
|
|
7768
8503
|
if (document.hidden) {
|
|
7769
|
-
mapRefreshTimer = setTimeout(
|
|
8504
|
+
mapRefreshTimer = setTimeout(tick6, 1e4);
|
|
7770
8505
|
return;
|
|
7771
8506
|
}
|
|
7772
8507
|
mapRefreshTimer = 0;
|
|
7773
|
-
if (
|
|
7774
|
-
if (m)
|
|
8508
|
+
if (enabled6 && resolved) void fetchPinned().then((m) => {
|
|
8509
|
+
if (m) scan4();
|
|
7775
8510
|
});
|
|
7776
8511
|
};
|
|
7777
|
-
mapRefreshTimer = setTimeout(
|
|
8512
|
+
mapRefreshTimer = setTimeout(tick6, MAP_REFRESH_MS);
|
|
7778
8513
|
}
|
|
7779
8514
|
var editingKey = null;
|
|
7780
8515
|
var bootDelay = 0;
|
|
@@ -7788,16 +8523,16 @@
|
|
|
7788
8523
|
}
|
|
7789
8524
|
async function bootstrap() {
|
|
7790
8525
|
const map = await fetchPinned();
|
|
7791
|
-
if (map)
|
|
8526
|
+
if (map) scan4();
|
|
7792
8527
|
}
|
|
7793
8528
|
function setRowTitle(key, text) {
|
|
7794
|
-
for (const item of
|
|
8529
|
+
for (const item of findRows2(key)) {
|
|
7795
8530
|
for (const el of titleElsOf(item)) writeTitle(el, text);
|
|
7796
8531
|
}
|
|
7797
8532
|
}
|
|
7798
8533
|
function refreshPinnedTitles() {
|
|
7799
8534
|
return fetchPinned().then((m) => {
|
|
7800
|
-
if (m)
|
|
8535
|
+
if (m) scan4();
|
|
7801
8536
|
});
|
|
7802
8537
|
}
|
|
7803
8538
|
var RENAME_CTX_VALID_MS = 15e3;
|
|
@@ -7816,7 +8551,7 @@
|
|
|
7816
8551
|
renameCtx = null;
|
|
7817
8552
|
return;
|
|
7818
8553
|
}
|
|
7819
|
-
if (!
|
|
8554
|
+
if (!enabled6 || !pinned) return;
|
|
7820
8555
|
const want = pinned.get(sessIdOf(renameCtx.key));
|
|
7821
8556
|
if (want === void 0) return;
|
|
7822
8557
|
for (const el of document.querySelectorAll('[role="dialog"] input, [role="dialog"] textarea, [role="dialog"] [contenteditable="true"]')) {
|
|
@@ -7854,10 +8589,10 @@
|
|
|
7854
8589
|
}, true);
|
|
7855
8590
|
scheduleBootRetry();
|
|
7856
8591
|
setInterval(() => {
|
|
7857
|
-
if (!document.hidden)
|
|
8592
|
+
if (!document.hidden) scan4();
|
|
7858
8593
|
}, SCAN_FALLBACK_MS3);
|
|
7859
8594
|
document.addEventListener("visibilitychange", () => {
|
|
7860
|
-
if (!document.hidden)
|
|
8595
|
+
if (!document.hidden) scan4();
|
|
7861
8596
|
});
|
|
7862
8597
|
window.addEventListener("zcodepro:config-changed", () => {
|
|
7863
8598
|
void bootstrap();
|
|
@@ -7873,7 +8608,7 @@
|
|
|
7873
8608
|
if (editingKey === null) return;
|
|
7874
8609
|
editingKey = null;
|
|
7875
8610
|
void fetchPinned().then((m) => {
|
|
7876
|
-
if (m)
|
|
8611
|
+
if (m) scan4();
|
|
7877
8612
|
});
|
|
7878
8613
|
});
|
|
7879
8614
|
}
|
|
@@ -8104,7 +8839,7 @@
|
|
|
8104
8839
|
await reclaim(ws);
|
|
8105
8840
|
blockUntil.set(ws, Date.now() + cooldownMs);
|
|
8106
8841
|
}
|
|
8107
|
-
async function
|
|
8842
|
+
async function tick3() {
|
|
8108
8843
|
const cfg = await getConfig();
|
|
8109
8844
|
if ((cfg.features || {}).idleReclaim === false) {
|
|
8110
8845
|
idleSince.clear();
|
|
@@ -8166,20 +8901,171 @@
|
|
|
8166
8901
|
}
|
|
8167
8902
|
function startIdleReclaim() {
|
|
8168
8903
|
const loop = () => {
|
|
8169
|
-
|
|
8904
|
+
tick3().catch(() => {
|
|
8170
8905
|
});
|
|
8171
8906
|
};
|
|
8172
8907
|
loop();
|
|
8173
8908
|
setInterval(loop, CHECK_MS);
|
|
8174
8909
|
}
|
|
8175
8910
|
|
|
8911
|
+
// src/inject/features/sandbox-reclaim.js
|
|
8912
|
+
var CHECK_MS2 = 3e4;
|
|
8913
|
+
var MIN_BUDGET = 8;
|
|
8914
|
+
var MAX_BUDGET = 64;
|
|
8915
|
+
var RETRY_COOLDOWN_MS = 10 * 6e4;
|
|
8916
|
+
var SEEN_KEY = "zcodepro:sbx-seen";
|
|
8917
|
+
var seen = /* @__PURE__ */ new Map();
|
|
8918
|
+
function loadSeen() {
|
|
8919
|
+
try {
|
|
8920
|
+
const raw = JSON.parse(localStorage.getItem(SEEN_KEY) || "{}");
|
|
8921
|
+
for (const [id, v] of Object.entries(raw)) {
|
|
8922
|
+
if (id && v && Number.isFinite(v.firstSeen)) seen.set(id, { initId: v.initId, firstSeen: v.firstSeen });
|
|
8923
|
+
}
|
|
8924
|
+
} catch {
|
|
8925
|
+
}
|
|
8926
|
+
}
|
|
8927
|
+
var saveSeenTimer = null;
|
|
8928
|
+
function saveSeenSoon() {
|
|
8929
|
+
if (saveSeenTimer) return;
|
|
8930
|
+
saveSeenTimer = setTimeout(() => {
|
|
8931
|
+
saveSeenTimer = null;
|
|
8932
|
+
try {
|
|
8933
|
+
const out = {};
|
|
8934
|
+
for (const [id, v] of seen) out[id] = v;
|
|
8935
|
+
localStorage.setItem(SEEN_KEY, JSON.stringify(out));
|
|
8936
|
+
} catch {
|
|
8937
|
+
}
|
|
8938
|
+
}, 2e3);
|
|
8939
|
+
}
|
|
8940
|
+
var cooldown = /* @__PURE__ */ new Map();
|
|
8941
|
+
var disabledLogged = false;
|
|
8942
|
+
function onPortsMessage(e) {
|
|
8943
|
+
const d = e.data;
|
|
8944
|
+
if (!d || d.type !== "zcode:plugin-sandbox-ports" || typeof d.sandboxId !== "string") return;
|
|
8945
|
+
seen.set(d.sandboxId, { initId: Number(d.initId) || 0, firstSeen: Date.now() });
|
|
8946
|
+
saveSeenSoon();
|
|
8947
|
+
}
|
|
8948
|
+
function extractSandboxId(wv) {
|
|
8949
|
+
const m = /instance\/(sb-[0-9a-f]+)\//.exec(wv.getAttribute("src") || "");
|
|
8950
|
+
return m ? m[1] : null;
|
|
8951
|
+
}
|
|
8952
|
+
function isVisible(wv) {
|
|
8953
|
+
const root = wv.closest("[data-sandbox-page-root]");
|
|
8954
|
+
if (!root) return wv.getClientRects().length > 0;
|
|
8955
|
+
if (!root.getClientRects().length) return false;
|
|
8956
|
+
return Number(getComputedStyle(root).opacity) > 0.5;
|
|
8957
|
+
}
|
|
8958
|
+
async function tick4() {
|
|
8959
|
+
const cfg = await getConfig();
|
|
8960
|
+
if ((cfg.features || {}).sandboxReclaim === false) {
|
|
8961
|
+
seen.clear();
|
|
8962
|
+
return;
|
|
8963
|
+
}
|
|
8964
|
+
const bridge = window.zcodePluginSandbox;
|
|
8965
|
+
if (!bridge || typeof bridge.disposeSandbox !== "function") {
|
|
8966
|
+
if (!disabledLogged) {
|
|
8967
|
+
disabledLogged = true;
|
|
8968
|
+
console.info("[zcodepro] sandbox-reclaim: \u5F53\u524D\u7A97\u53E3\u65E0 zcodePluginSandbox \u6865\uFF0C\u6C99\u7BB1\u56DE\u6536\u8DF3\u8FC7");
|
|
8969
|
+
}
|
|
8970
|
+
return;
|
|
8971
|
+
}
|
|
8972
|
+
let budget = Number(cfg.sandboxReclaimBudget);
|
|
8973
|
+
if (!Number.isFinite(budget)) budget = 60;
|
|
8974
|
+
budget = Math.min(MAX_BUDGET, Math.max(MIN_BUDGET, budget));
|
|
8975
|
+
const now = Date.now();
|
|
8976
|
+
const visible = /* @__PURE__ */ new Set();
|
|
8977
|
+
for (const wv of document.querySelectorAll("webview")) {
|
|
8978
|
+
const id = extractSandboxId(wv);
|
|
8979
|
+
if (id) {
|
|
8980
|
+
if (isVisible(wv)) visible.add(id);
|
|
8981
|
+
if (!seen.has(id)) {
|
|
8982
|
+
seen.set(id, { initId: void 0, firstSeen: now });
|
|
8983
|
+
saveSeenSoon();
|
|
8984
|
+
}
|
|
8985
|
+
}
|
|
8986
|
+
}
|
|
8987
|
+
while (seen.size > budget) {
|
|
8988
|
+
let pool = [...seen.keys()].filter((id2) => (cooldown.get(id2) || 0) <= now && !visible.has(id2));
|
|
8989
|
+
if (!pool.length) pool = [...seen.keys()].filter((id2) => (cooldown.get(id2) || 0) <= now);
|
|
8990
|
+
pool.sort((a, b) => ((seen.get(a) || {}).firstSeen || 0) - ((seen.get(b) || {}).firstSeen || 0));
|
|
8991
|
+
if (!pool.length) break;
|
|
8992
|
+
const id = pool[0];
|
|
8993
|
+
const entry = seen.get(id);
|
|
8994
|
+
try {
|
|
8995
|
+
await bridge.disposeSandbox(id, entry && entry.initId);
|
|
8996
|
+
console.info("[zcodepro] sandbox-reclaim: \u767B\u8BB0\u6570 " + seen.size + " \u8D85\u9884\u7B97 " + budget + "\uFF0C\u5DF2\u9A71\u9010\u6700\u65E9\u7684 " + id + (visible.has(id) ? "\uFF08\u53EF\u89C1\uFF0C\u5C5E\u515C\u5E95\uFF09" : ""));
|
|
8997
|
+
} catch (err) {
|
|
8998
|
+
console.warn("[zcodepro] sandbox-reclaim: \u91CA\u653E\u5931\u8D25 " + id, err);
|
|
8999
|
+
seen.delete(id);
|
|
9000
|
+
continue;
|
|
9001
|
+
}
|
|
9002
|
+
seen.delete(id);
|
|
9003
|
+
saveSeenSoon();
|
|
9004
|
+
cooldown.set(id, now + RETRY_COOLDOWN_MS);
|
|
9005
|
+
}
|
|
9006
|
+
if (cooldown.size > 256) {
|
|
9007
|
+
for (const [k, v] of cooldown) {
|
|
9008
|
+
if (v <= now) cooldown.delete(k);
|
|
9009
|
+
}
|
|
9010
|
+
}
|
|
9011
|
+
}
|
|
9012
|
+
function startSandboxReclaim() {
|
|
9013
|
+
loadSeen();
|
|
9014
|
+
window.addEventListener("message", onPortsMessage);
|
|
9015
|
+
const loop = () => {
|
|
9016
|
+
tick4().catch(() => {
|
|
9017
|
+
});
|
|
9018
|
+
};
|
|
9019
|
+
loop();
|
|
9020
|
+
setInterval(loop, CHECK_MS2);
|
|
9021
|
+
}
|
|
9022
|
+
|
|
9023
|
+
// src/inject/features/plugin-card-retry.js
|
|
9024
|
+
var SCAN_MS = 15e3;
|
|
9025
|
+
var CLICK_INTERVAL_MS = 3e4;
|
|
9026
|
+
var MARKERS = ["\u63D2\u4EF6\u754C\u9762"];
|
|
9027
|
+
var lastClickAt = 0;
|
|
9028
|
+
function failedRetryButtons() {
|
|
9029
|
+
const out = [];
|
|
9030
|
+
for (const btn of document.querySelectorAll("button")) {
|
|
9031
|
+
if ((btn.textContent || "").trim() !== "\u91CD\u65B0\u52A0\u8F7D") continue;
|
|
9032
|
+
let anc = btn;
|
|
9033
|
+
for (let i = 0; i < 4 && anc.parentElement; i++) {
|
|
9034
|
+
anc = anc.parentElement;
|
|
9035
|
+
const ctx = anc.textContent || "";
|
|
9036
|
+
if (MARKERS.some((m) => ctx.includes(m))) {
|
|
9037
|
+
out.push(btn);
|
|
9038
|
+
break;
|
|
9039
|
+
}
|
|
9040
|
+
}
|
|
9041
|
+
}
|
|
9042
|
+
return out;
|
|
9043
|
+
}
|
|
9044
|
+
async function tick5() {
|
|
9045
|
+
const cfg = await getConfig();
|
|
9046
|
+
if ((cfg.features || {}).pluginCardRetry === false) return;
|
|
9047
|
+
const now = Date.now();
|
|
9048
|
+
if (now - lastClickAt < CLICK_INTERVAL_MS) return;
|
|
9049
|
+
for (const btn of failedRetryButtons()) {
|
|
9050
|
+
lastClickAt = now;
|
|
9051
|
+
btn.click();
|
|
9052
|
+
break;
|
|
9053
|
+
}
|
|
9054
|
+
}
|
|
9055
|
+
function startPluginCardRetry() {
|
|
9056
|
+
setInterval(() => {
|
|
9057
|
+
tick5().catch(() => {
|
|
9058
|
+
});
|
|
9059
|
+
}, SCAN_MS);
|
|
9060
|
+
}
|
|
9061
|
+
|
|
8176
9062
|
// src/inject/features/toolbar-icons.js
|
|
8177
9063
|
var HIDE_CLASS = "zcodepro-tb-hidden";
|
|
8178
9064
|
var SYNC_DEBOUNCE_MS = 150;
|
|
8179
9065
|
var SCAN_FALLBACK_MS5 = 5e3;
|
|
8180
9066
|
var ROW_SEL = "[data-task-item-key]";
|
|
8181
9067
|
var MENU_SEL = '[data-testid="task-new-button"], [data-testid="automations-open"], [data-testid="plugin-store-sidebar-open"], [data-testid="sidebar-search-open"], [data-slot="command"], [data-testid="desktop-top-nav-back"]';
|
|
8182
|
-
var
|
|
9068
|
+
var enabled7 = true;
|
|
8183
9069
|
var rowEl = null;
|
|
8184
9070
|
var origs = null;
|
|
8185
9071
|
var syncTimer = 0;
|
|
@@ -8287,8 +9173,8 @@
|
|
|
8287
9173
|
}
|
|
8288
9174
|
});
|
|
8289
9175
|
const newBtn = mk("newTask", parts.newTask, "span.truncate", L.tbNewTask);
|
|
8290
|
-
const
|
|
8291
|
-
if (
|
|
9176
|
+
const icon2 = iconOf(parts.newTask);
|
|
9177
|
+
if (icon2) newBtn.append(icon2);
|
|
8292
9178
|
const searchBtn = mk("search", parts.search, "span.truncate", L.tbSearch);
|
|
8293
9179
|
const sIcon = iconOf(parts.search);
|
|
8294
9180
|
if (sIcon) searchBtn.append(sIcon);
|
|
@@ -8322,7 +9208,7 @@
|
|
|
8322
9208
|
return scroll.getBoundingClientRect().width < NARROW_SIDEBAR_PX;
|
|
8323
9209
|
}
|
|
8324
9210
|
function sync() {
|
|
8325
|
-
if (!
|
|
9211
|
+
if (!enabled7) return;
|
|
8326
9212
|
const parts = findParts();
|
|
8327
9213
|
if (!parts) {
|
|
8328
9214
|
if (rowEl) rowEl.style.display = "none";
|
|
@@ -8384,8 +9270,8 @@
|
|
|
8384
9270
|
}
|
|
8385
9271
|
async function refreshConfig2() {
|
|
8386
9272
|
const cfg = await getConfig(true).catch(() => null);
|
|
8387
|
-
|
|
8388
|
-
if (
|
|
9273
|
+
enabled7 = !cfg || !cfg.features || cfg.features.toolbarIcons !== false;
|
|
9274
|
+
if (enabled7) sync();
|
|
8389
9275
|
else teardown();
|
|
8390
9276
|
}
|
|
8391
9277
|
function startToolbarIcons() {
|
|
@@ -8411,7 +9297,7 @@
|
|
|
8411
9297
|
var STORE_KEY = "zcodepro:pinned-collapsed";
|
|
8412
9298
|
var SYNC_DEBOUNCE_MS2 = 300;
|
|
8413
9299
|
var SCAN_FALLBACK_MS6 = 5e3;
|
|
8414
|
-
var
|
|
9300
|
+
var enabled8 = true;
|
|
8415
9301
|
var syncTimer2 = 0;
|
|
8416
9302
|
function findPinnedHeader() {
|
|
8417
9303
|
for (const h3 of document.querySelectorAll("h3")) {
|
|
@@ -8468,7 +9354,7 @@
|
|
|
8468
9354
|
}
|
|
8469
9355
|
h3.classList.add(HEAD_CLASS);
|
|
8470
9356
|
h3.addEventListener("click", () => {
|
|
8471
|
-
if (
|
|
9357
|
+
if (enabled8) toggle();
|
|
8472
9358
|
});
|
|
8473
9359
|
const btn = h("button", {
|
|
8474
9360
|
type: "button",
|
|
@@ -8477,7 +9363,7 @@
|
|
|
8477
9363
|
"aria-expanded": collapsed ? "false" : "true",
|
|
8478
9364
|
onClick: (e) => {
|
|
8479
9365
|
e.stopPropagation();
|
|
8480
|
-
if (
|
|
9366
|
+
if (enabled8) toggle();
|
|
8481
9367
|
}
|
|
8482
9368
|
});
|
|
8483
9369
|
btn.append(chevronSvg());
|
|
@@ -8485,7 +9371,7 @@
|
|
|
8485
9371
|
return true;
|
|
8486
9372
|
}
|
|
8487
9373
|
function sync2() {
|
|
8488
|
-
if (
|
|
9374
|
+
if (enabled8) apply2();
|
|
8489
9375
|
}
|
|
8490
9376
|
function scheduleSync2() {
|
|
8491
9377
|
if (syncTimer2) return;
|
|
@@ -8514,8 +9400,8 @@
|
|
|
8514
9400
|
}
|
|
8515
9401
|
async function refreshConfig3() {
|
|
8516
9402
|
const cfg = await getConfig(true).catch(() => null);
|
|
8517
|
-
|
|
8518
|
-
if (
|
|
9403
|
+
enabled8 = !cfg || !cfg.features || cfg.features.pinnedCollapse !== false;
|
|
9404
|
+
if (enabled8) sync2();
|
|
8519
9405
|
else teardown2();
|
|
8520
9406
|
}
|
|
8521
9407
|
function startPinnedCollapse() {
|
|
@@ -8550,12 +9436,12 @@
|
|
|
8550
9436
|
return;
|
|
8551
9437
|
}
|
|
8552
9438
|
const sig = status.updates.map((u) => `${u.name}:${u.installed}>${u.latest}`).join(",");
|
|
8553
|
-
let
|
|
9439
|
+
let seen2 = "";
|
|
8554
9440
|
try {
|
|
8555
|
-
|
|
9441
|
+
seen2 = window.localStorage.getItem(NOTIFIED_KEY) || "";
|
|
8556
9442
|
} catch {
|
|
8557
9443
|
}
|
|
8558
|
-
if (
|
|
9444
|
+
if (seen2 === sig) return;
|
|
8559
9445
|
try {
|
|
8560
9446
|
window.localStorage.setItem(NOTIFIED_KEY, sig);
|
|
8561
9447
|
} catch {
|
|
@@ -8630,6 +9516,14 @@
|
|
|
8630
9516
|
startIdleReclaim();
|
|
8631
9517
|
} catch {
|
|
8632
9518
|
}
|
|
9519
|
+
try {
|
|
9520
|
+
startSandboxReclaim();
|
|
9521
|
+
} catch {
|
|
9522
|
+
}
|
|
9523
|
+
try {
|
|
9524
|
+
startPluginCardRetry();
|
|
9525
|
+
} catch {
|
|
9526
|
+
}
|
|
8633
9527
|
try {
|
|
8634
9528
|
startToolbarIcons();
|
|
8635
9529
|
} catch {
|
|
@@ -8638,6 +9532,14 @@
|
|
|
8638
9532
|
startNewtabPanels();
|
|
8639
9533
|
} catch {
|
|
8640
9534
|
}
|
|
9535
|
+
try {
|
|
9536
|
+
startStatusBar();
|
|
9537
|
+
} catch {
|
|
9538
|
+
}
|
|
9539
|
+
try {
|
|
9540
|
+
startTurnUsage();
|
|
9541
|
+
} catch {
|
|
9542
|
+
}
|
|
8641
9543
|
try {
|
|
8642
9544
|
startPinnedCollapse();
|
|
8643
9545
|
} catch {
|