dsh-plugin-t-expert 0.3.28 → 0.3.40
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/lib/client.js +297 -24
- package/lib/index.js +12 -1
- package/lib/remote-schemas.js +3 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -19874,11 +19874,14 @@ var enabledStateSchema = external_exports.object({
|
|
|
19874
19874
|
});
|
|
19875
19875
|
var uiPrefsSchema = external_exports.object({
|
|
19876
19876
|
showTaskBadge: external_exports.boolean(),
|
|
19877
|
-
showScheduleButton: external_exports.boolean()
|
|
19877
|
+
showScheduleButton: external_exports.boolean(),
|
|
19878
|
+
// 窗口右上角「活跃指示」是否显示。宿主**总是**返回布尔(缺省按 true 算),所以这里必填。
|
|
19879
|
+
showActivePulse: external_exports.boolean()
|
|
19878
19880
|
});
|
|
19879
19881
|
var uiPrefsPatchSchema = external_exports.object({
|
|
19880
19882
|
showTaskBadge: external_exports.boolean().optional(),
|
|
19881
|
-
showScheduleButton: external_exports.boolean().optional()
|
|
19883
|
+
showScheduleButton: external_exports.boolean().optional(),
|
|
19884
|
+
showActivePulse: external_exports.boolean().optional()
|
|
19882
19885
|
});
|
|
19883
19886
|
var promptSchema = external_exports.object({ prompt: external_exports.string() });
|
|
19884
19887
|
var squadMemberSchema = external_exports.object({
|
|
@@ -20015,8 +20018,9 @@ var scheduleWorkspaceSchema = external_exports.object({
|
|
|
20015
20018
|
|
|
20016
20019
|
// src/client.jsx
|
|
20017
20020
|
var NS = "t-team";
|
|
20018
|
-
var CLIENT_BUILD_VERSION = "0.3.
|
|
20019
|
-
var uiPrefs = { showTaskBadge: true, showScheduleButton: true };
|
|
20021
|
+
var CLIENT_BUILD_VERSION = "0.3.40";
|
|
20022
|
+
var uiPrefs = { showTaskBadge: true, showScheduleButton: true, showActivePulse: true };
|
|
20023
|
+
var UI_PREF_KEYS = Object.keys(uiPrefs);
|
|
20020
20024
|
var uiPrefsListeners = /* @__PURE__ */ new Set();
|
|
20021
20025
|
function setUiPrefs(next) {
|
|
20022
20026
|
let changed = false;
|
|
@@ -20052,6 +20056,9 @@ function useShowTaskBadge() {
|
|
|
20052
20056
|
function useShowScheduleButton() {
|
|
20053
20057
|
return useUiPref("showScheduleButton", true);
|
|
20054
20058
|
}
|
|
20059
|
+
function useShowActivePulse() {
|
|
20060
|
+
return useUiPref("showActivePulse", true);
|
|
20061
|
+
}
|
|
20055
20062
|
var PLUGIN_ID = "dsh-plugin-t-expert";
|
|
20056
20063
|
var DIVISION_FALLBACK = "specialized";
|
|
20057
20064
|
var NEW_DIVISION = "__new";
|
|
@@ -20060,6 +20067,15 @@ var zh = {
|
|
|
20060
20067
|
"settings.showTaskBadge": "\u663E\u793A\u4EFB\u52A1\u5FBD\u7AE0",
|
|
20061
20068
|
"settings.showTaskBadgeHint": "\u5173\u95ED\u540E\u4E0D\u518D\u81EA\u52A8\u51FA\u73B0\u53F3\u4E0A\u89D2\u7684\u4EFB\u52A1\u5FBD\u7AE0\uFF08\u8F93\u5165\u533A\u6D6E\u5C42\u91CC\u7684\u300C\u4EFB\u52A1\u300D\u9875\u4ECD\u7136\u53EF\u7528\uFF09",
|
|
20062
20069
|
"settings.showTaskBadgeUnreadable": "\u8BFB\u53D6\u8BE5\u8BBE\u7F6E\u5931\u8D25",
|
|
20070
|
+
"settings.uiPrefsWriteFailed": "\u4FDD\u5B58\u8BE5\u8BBE\u7F6E\u5931\u8D25",
|
|
20071
|
+
"settings.showActivePulse": "\u663E\u793A\u6D3B\u8DC3\u6307\u793A",
|
|
20072
|
+
"settings.showActivePulseHint": "\u4F1A\u8BDD\u6807\u9898\u680F\u91CC\u90A3\u679A\u5FC3\u7535\u56FE\u56FE\u6807\uFF1A\u6709\u4F1A\u8BDD\u6B63\u5728\u8DD1\u3001\u6216\u6709\u4E8B\u7B49\u4F60\u67E5\u770B\u65F6\u663E\u793A\u5F69\u8272\uFF0C\u5168\u90E8\u7A7A\u95F2\u4E14\u65E0\u5F85\u770B\u65F6\u663E\u793A\u7070\u8272\u3002\u70B9\u5B83\u53EF\u4EE5\u5217\u51FA\u9700\u8981\u6CE8\u610F\u7684\u4F1A\u8BDD\uFF0C\u70B9\u5176\u4E2D\u4E00\u6761\u5C31\u76F4\u63A5\u63A5\u4E0A\u90A3\u4E2A\u4F1A\u8BDD",
|
|
20073
|
+
"pulse.on": "\u6709\u4F1A\u8BDD\u6B63\u5728\u6D3B\u52A8\uFF0C\u6216\u6709\u4E8B\u7B49\u4F60\u67E5\u770B",
|
|
20074
|
+
"pulse.off": "\u5168\u90E8\u7A7A\u95F2\uFF0C\u4E14\u6CA1\u6709\u5F85\u4F60\u67E5\u770B\u7684",
|
|
20075
|
+
"pulse.title": "\u9700\u8981\u6CE8\u610F\u7684\u4F1A\u8BDD",
|
|
20076
|
+
"pulse.empty": "\u73B0\u5728\u6CA1\u6709\u9700\u8981\u6CE8\u610F\u7684\u4F1A\u8BDD",
|
|
20077
|
+
"pulse.running": "\u8FD0\u884C\u4E2D",
|
|
20078
|
+
"pulse.pending": "\u5F85\u67E5\u770B",
|
|
20063
20079
|
"settings.loading": "\u6B63\u5728\u8BFB\u53D6\u540D\u518C\u2026",
|
|
20064
20080
|
"settings.retry": "\u91CD\u8BD5",
|
|
20065
20081
|
"settings.search": "\u641C\u7D22\u4E13\u5BB6\u540D\u6216\u7B80\u4ECB",
|
|
@@ -20330,7 +20346,16 @@ var en = {
|
|
|
20330
20346
|
"settings.title": "T Expert",
|
|
20331
20347
|
"settings.showTaskBadge": "Show task badge",
|
|
20332
20348
|
"settings.showTaskBadgeHint": "When off, the top-right task badge no longer appears (the Tasks tab in the input floater still works)",
|
|
20349
|
+
"settings.showActivePulse": "Show activity indicator",
|
|
20350
|
+
"settings.showActivePulseHint": "The ECG icon in the session header: coloured when a session is running or something awaits your review, grey when everything is idle. Click it to list the sessions that need attention and jump straight into one",
|
|
20351
|
+
"pulse.on": "A session is running, or something awaits your review",
|
|
20352
|
+
"pulse.off": "Everything is idle and nothing awaits you",
|
|
20353
|
+
"pulse.title": "Sessions needing attention",
|
|
20354
|
+
"pulse.empty": "Nothing needs your attention right now",
|
|
20355
|
+
"pulse.running": "Running",
|
|
20356
|
+
"pulse.pending": "Unread",
|
|
20333
20357
|
"settings.showTaskBadgeUnreadable": "Failed to read this setting",
|
|
20358
|
+
"settings.uiPrefsWriteFailed": "Failed to save this setting",
|
|
20334
20359
|
"settings.loading": "Loading roster\u2026",
|
|
20335
20360
|
"settings.retry": "Retry",
|
|
20336
20361
|
"settings.search": "Search expert name or description",
|
|
@@ -20664,6 +20689,28 @@ var CSS = `
|
|
|
20664
20689
|
.t-team-badge{font-size:11px;border-radius:999px;padding:1px 8px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary)}
|
|
20665
20690
|
.t-team-badge[data-tone="warn"]{color:var(--dsw-alias-state-warn-primary)}
|
|
20666
20691
|
.t-team-badge[data-tone="error"]{color:var(--dsw-alias-state-error-primary)}
|
|
20692
|
+
/* \u6D3B\u8DC3\u6307\u793A\uFF1A\u4F1A\u8BDD\u6807\u9898\u680F\u91CC\u7684\u4E00\u679A\u5FC3\u7535\u56FE\u56FE\u6807 \u2014\u2014 \u7D27\u8D34 agent preset \u80F6\u56CA\u5DE6\u4FA7\uFF08order \u6BD4\u5B83\u5C0F\uFF09\u3002
|
|
20693
|
+
\u5F69\u8272 = \u6709\u6D3B\u52A8\u6216\u6709\u5F85\u770B\uFF0C\u7070 = \u5168\u7A7A\u95F2\u3002pointer-events:none\uFF1A\u5B83\u53EA\u662F\u6307\u793A\uFF0C\u4E0D\u8BE5\u6321\u4F4F\u70B9\u51FB\u3002 */
|
|
20694
|
+
.t-team-pulse{display:inline-flex;align-items:center;justify-content:center;flex:none;width:24px;height:24px;margin-right:2px;padding:0;border:0;font:inherit;border-radius:7px;cursor:pointer;color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 14%,transparent)}
|
|
20695
|
+
.t-team-pulse[data-on="false"]{color:var(--dsw-alias-label-caption);background:color-mix(in srgb,var(--dsw-alias-label-caption) 12%,transparent)}
|
|
20696
|
+
.t-team-pulse:hover{background:color-mix(in srgb,var(--dsw-alias-label-primary) 12%,transparent)}
|
|
20697
|
+
/* \u70B9\u5FBD\u7AE0\u5F39\u51FA\u7684\u300C\u9700\u8981\u6CE8\u610F\u7684\u4F1A\u8BDD\u300D\u6E05\u5355\uFF1A\u8D34\u5FBD\u7AE0\u53F3\u7F18\u3001\u56FE\u6807\u4E0B\u65B9\u3002 */
|
|
20698
|
+
.t-team-pulse-pop{position:fixed;z-index:70;width:300px;max-height:min(420px,60vh);overflow:auto;box-sizing:border-box;display:flex;flex-direction:column;gap:2px;padding:8px;border-radius:12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-specific-menu,var(--dsw-alias-bg-layer-3));box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary)}
|
|
20699
|
+
.t-team-pulse-pop-head{font-size:12px;font-weight:600;color:var(--dsw-alias-label-secondary);padding:4px 6px 6px}
|
|
20700
|
+
.t-team-pulse-pop-empty{font-size:12px;color:var(--dsw-alias-label-caption);padding:8px 6px}
|
|
20701
|
+
.t-team-pulse-pop-row{display:flex;align-items:center;gap:8px;width:100%;box-sizing:border-box;border:0;background:transparent;color:inherit;font:inherit;font-size:13px;text-align:left;padding:7px 8px;border-radius:8px;cursor:pointer}
|
|
20702
|
+
.t-team-pulse-pop-row:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
20703
|
+
.t-team-pulse-pop-dot{flex:none;width:6px;height:6px;border-radius:50%;background:var(--dsw-alias-state-success-primary)}
|
|
20704
|
+
.t-team-pulse-pop-dot[data-state="pending"]{background:var(--dsw-alias-state-warn-primary)}
|
|
20705
|
+
.t-team-pulse-pop-title{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
20706
|
+
.t-team-pulse-pop-tag{flex:none;font-size:11px;color:var(--dsw-alias-label-caption)}
|
|
20707
|
+
/* \u6D3B\u52A8\u6001\u52A8\u6548\uFF1A\u4E00\u6BB5\u9AD8\u4EAE\u6CBF\u5FC3\u7535\u56FE\u8DEF\u5F84\u6EDA\u52A8\uFF08\u8D70\u7EB8\uFF0F\u76D1\u62A4\u4EEA\u626B\u8FC7\u90A3\u4E00\u4E0B\uFF09\uFF0C\u53EA\u5BF9\u6709\u6D3B\u52A8\u6216\u6709\u5F85\u770B\u65F6\u751F\u6548\uFF1B
|
|
20708
|
+
pathLength=100 \u8BA9\u8FD9\u91CC\u7684 100 \u5C31\u662F"\u6574\u6761\u8DEF\u5F84"\uFF0C\u4E0D\u5FC5\u77E5\u9053\u771F\u5B9E\u957F\u5EA6\u3002\u7A7A\u95F2\uFF08\u7070\uFF09\u65F6\u662F\u9759\u6B62\u5B9E\u7EBF\u3002
|
|
20709
|
+
\u53C2\u6570\uFF08\u7528\u6237 2026-09-15 \u8C03\u8FC7\u4E24\u8F6E\uFF09\uFF1A\u9AD8\u4EAE\u7EA6\u5360\u4E00\u534A\u8DEF\u5F84\u30011.2s \u8DD1\u5B8C\u4E00\u5708 \u2014\u2014 \u60F3\u518D\u8C03\u5C31\u6539\u8FD9\u4E24\u4E2A\u6570\u3002
|
|
20710
|
+
\u6CE8\u610F\u522B\u628A\u9AD8\u4EAE\u8C03\u5230\u63A5\u8FD1 100\uFF1A\u6697\u6BB5\u592A\u77ED\u5C31\u770B\u4E0D\u51FA"\u5728\u6EDA\u52A8"\u4E86\u3002 */
|
|
20711
|
+
@keyframes t-team-pulse-scan{from{stroke-dashoffset:100}to{stroke-dashoffset:0}}
|
|
20712
|
+
.t-team-pulse[data-on="true"] path{stroke-dasharray:48 52;animation:t-team-pulse-scan 1.2s linear infinite}
|
|
20713
|
+
@media (prefers-reduced-motion:reduce){.t-team-pulse[data-on="true"] path{animation:none;stroke-dasharray:none}}
|
|
20667
20714
|
.t-team-team-meta{font-size:12px;color:var(--dsw-alias-label-caption);display:flex;gap:10px;flex-wrap:wrap}
|
|
20668
20715
|
.t-team-note{font-size:12px;color:var(--dsw-alias-label-caption)}
|
|
20669
20716
|
.t-team-ok{font-size:12px;color:var(--dsw-alias-state-success-primary)}
|
|
@@ -21872,6 +21919,171 @@ function ScheduleGlyph({ size = 16 }) {
|
|
|
21872
21919
|
/* @__PURE__ */ import_react.default.createElement("path", { d: "M6.1 9.7l1.3 1.3 2.5-2.7" })
|
|
21873
21920
|
);
|
|
21874
21921
|
}
|
|
21922
|
+
var attentionCache = { key: "", list: [] };
|
|
21923
|
+
function useAttentionSessions(ctx) {
|
|
21924
|
+
const subscribe = import_react.default.useCallback((onChange) => {
|
|
21925
|
+
const list = ctx?.sessions?.list;
|
|
21926
|
+
if (typeof list?.subscribe !== "function") return () => {
|
|
21927
|
+
};
|
|
21928
|
+
return list.subscribe(onChange);
|
|
21929
|
+
}, [ctx]);
|
|
21930
|
+
const read = import_react.default.useCallback(() => {
|
|
21931
|
+
const byId = ctx?.sessions?.list?.getSnapshot?.()?.byId ?? {};
|
|
21932
|
+
const runningSubagents = /* @__PURE__ */ new Map();
|
|
21933
|
+
for (const id of Object.keys(byId)) {
|
|
21934
|
+
const child = byId[id];
|
|
21935
|
+
if (child?.origin !== "subagent" || child.running !== true) continue;
|
|
21936
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21937
|
+
let parent = child.parentId;
|
|
21938
|
+
while (typeof parent === "string" && parent !== "" && !seen.has(parent)) {
|
|
21939
|
+
seen.add(parent);
|
|
21940
|
+
runningSubagents.set(parent, (runningSubagents.get(parent) ?? 0) + 1);
|
|
21941
|
+
parent = byId[parent]?.parentId;
|
|
21942
|
+
}
|
|
21943
|
+
}
|
|
21944
|
+
const rows = [];
|
|
21945
|
+
for (const id of Object.keys(byId)) {
|
|
21946
|
+
const session = byId[id];
|
|
21947
|
+
if (session === void 0 || session === null) continue;
|
|
21948
|
+
if (session.origin === "subagent" || session.blank === true) continue;
|
|
21949
|
+
const running = session.running === true || (runningSubagents.get(id) ?? 0) > 0;
|
|
21950
|
+
const pending = session.completed === true;
|
|
21951
|
+
if (!running && !pending) continue;
|
|
21952
|
+
rows.push({
|
|
21953
|
+
id,
|
|
21954
|
+
title: session.displayTitle || session.title || id,
|
|
21955
|
+
running,
|
|
21956
|
+
pending,
|
|
21957
|
+
at: typeof session.updatedAt === "number" ? session.updatedAt : 0
|
|
21958
|
+
});
|
|
21959
|
+
}
|
|
21960
|
+
rows.sort((a, b) => a.running === b.running ? b.at - a.at : a.running ? -1 : 1);
|
|
21961
|
+
const key = rows.map((row) => `${row.id}:${row.running ? 1 : 0}${row.pending ? 1 : 0}:${row.title}`).join("|");
|
|
21962
|
+
if (key !== attentionCache.key) {
|
|
21963
|
+
attentionCache.key = key;
|
|
21964
|
+
attentionCache.list = rows;
|
|
21965
|
+
}
|
|
21966
|
+
return attentionCache.list;
|
|
21967
|
+
}, [ctx]);
|
|
21968
|
+
return import_react.default.useSyncExternalStore(subscribe, read, () => attentionCache.list);
|
|
21969
|
+
}
|
|
21970
|
+
var expandGroupFailureReported = false;
|
|
21971
|
+
function reportExpandFailure(cause) {
|
|
21972
|
+
if (expandGroupFailureReported) return;
|
|
21973
|
+
expandGroupFailureReported = true;
|
|
21974
|
+
console.warn("[t-team] \u5C55\u5F00\u5DE5\u4F5C\u533A\u5206\u7EC4\u5931\u8D25\uFF08\u53EA\u63D0\u793A\u4E00\u6B21\uFF0C\u4E0D\u5F71\u54CD\u8DF3\u8F6C\uFF09\uFF1A", cause);
|
|
21975
|
+
}
|
|
21976
|
+
function owningWorkspaceKey(items, sessionId) {
|
|
21977
|
+
return items.find((item) => Array.isArray(item?.sessionIds) && item.sessionIds.includes(sessionId))?.workspaceId ?? "";
|
|
21978
|
+
}
|
|
21979
|
+
function expandOwningWorkspaceGroup(ctx, sessionId) {
|
|
21980
|
+
try {
|
|
21981
|
+
if (typeof sessionId !== "string" || sessionId === "") return;
|
|
21982
|
+
const items = ctx?.get?.("workspaces")?.list?.getSnapshot?.()?.items;
|
|
21983
|
+
if (!Array.isArray(items) || items.length === 0) return;
|
|
21984
|
+
const entries = ctx?.slots?.entries?.("sidebar.workspaces");
|
|
21985
|
+
if (!Array.isArray(entries) || entries.length === 0) return;
|
|
21986
|
+
const entry = entries.find((row) => row?.store?.spec?.actions?.setGroupExpanded !== void 0);
|
|
21987
|
+
if (entry === void 0) {
|
|
21988
|
+
reportExpandFailure("\u4FA7\u680F\u69FD\u91CC\u627E\u4E0D\u5230\u5E26 setGroupExpanded \u7684 store \u58F0\u660E\uFF08\u4E0A\u6E38\u63A5\u53E3\u53EF\u80FD\u6539\u4E86\uFF09");
|
|
21989
|
+
return;
|
|
21990
|
+
}
|
|
21991
|
+
const store = ctx?.slots?.hostFace?.()?.storeOf?.(entry);
|
|
21992
|
+
if (store?.actions?.setGroupExpanded === void 0) {
|
|
21993
|
+
reportExpandFailure("\u62FF\u5230\u7684\u4FA7\u680F store \u5B9E\u4F8B\u6CA1\u6709 setGroupExpanded\uFF08\u4E0A\u6E38\u63A5\u53E3\u53EF\u80FD\u6539\u4E86\uFF09");
|
|
21994
|
+
return;
|
|
21995
|
+
}
|
|
21996
|
+
const key = owningWorkspaceKey(items, sessionId);
|
|
21997
|
+
if (store.getSnapshot?.()?.groupExpansion?.[key] === true) return;
|
|
21998
|
+
store.actions.setGroupExpanded(key, true);
|
|
21999
|
+
} catch (error62) {
|
|
22000
|
+
reportExpandFailure(error62);
|
|
22001
|
+
}
|
|
22002
|
+
}
|
|
22003
|
+
function AttentionPanel({ t, sessions, anchor: anchor2, onClose, onOpen }) {
|
|
22004
|
+
import_react.default.useEffect(() => {
|
|
22005
|
+
const onKey = (event) => {
|
|
22006
|
+
if (event.key === "Escape") onClose();
|
|
22007
|
+
};
|
|
22008
|
+
const onDown = (event) => {
|
|
22009
|
+
const target = event.target;
|
|
22010
|
+
if (target instanceof Element && target.closest(".t-team-pulse-pop, .t-team-pulse") !== null) return;
|
|
22011
|
+
onClose();
|
|
22012
|
+
};
|
|
22013
|
+
window.addEventListener("keydown", onKey);
|
|
22014
|
+
window.addEventListener("mousedown", onDown, true);
|
|
22015
|
+
return () => {
|
|
22016
|
+
window.removeEventListener("keydown", onKey);
|
|
22017
|
+
window.removeEventListener("mousedown", onDown, true);
|
|
22018
|
+
};
|
|
22019
|
+
}, [onClose]);
|
|
22020
|
+
return /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-pulse-pop", style: { right: anchor2.right, top: anchor2.top }, role: "dialog", "aria-label": t("pulse.title") }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-pulse-pop-head" }, t("pulse.title")), sessions.length === 0 && /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-pulse-pop-empty" }, t("pulse.empty")), sessions.map((row) => /* @__PURE__ */ import_react.default.createElement("button", { key: row.id, type: "button", className: "t-team-pulse-pop-row", onClick: () => onOpen(row.id), title: row.title }, /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-pulse-pop-dot", "data-state": row.running ? "running" : "pending", "aria-hidden": "true" }), /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-pulse-pop-title" }, row.title), /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-pulse-pop-tag" }, t(row.running ? "pulse.running" : "pulse.pending")))));
|
|
22021
|
+
}
|
|
22022
|
+
function ActivePulse({ ctx, t }) {
|
|
22023
|
+
const show = useShowActivePulse();
|
|
22024
|
+
const sessions = useAttentionSessions(ctx);
|
|
22025
|
+
const [anchor2, setAnchor] = import_react.default.useState(null);
|
|
22026
|
+
import_react.default.useEffect(() => subscribePopoverClaims((owner) => {
|
|
22027
|
+
if (owner !== "pulse") setAnchor(null);
|
|
22028
|
+
}), []);
|
|
22029
|
+
const close = () => {
|
|
22030
|
+
setAnchor(null);
|
|
22031
|
+
releasePopover("pulse");
|
|
22032
|
+
};
|
|
22033
|
+
const attention = sessions.length > 0;
|
|
22034
|
+
if (!show) return null;
|
|
22035
|
+
const label = t(attention ? "pulse.on" : "pulse.off");
|
|
22036
|
+
const toggle = (event) => {
|
|
22037
|
+
if (anchor2 !== null) {
|
|
22038
|
+
close();
|
|
22039
|
+
return;
|
|
22040
|
+
}
|
|
22041
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
22042
|
+
claimPopover("pulse");
|
|
22043
|
+
setAnchor({ right: Math.max(8, window.innerWidth - rect.right - 24), top: Math.round(rect.bottom) + 6 });
|
|
22044
|
+
};
|
|
22045
|
+
return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(
|
|
22046
|
+
"button",
|
|
22047
|
+
{
|
|
22048
|
+
type: "button",
|
|
22049
|
+
className: "t-team-pulse",
|
|
22050
|
+
"data-on": attention,
|
|
22051
|
+
onClick: toggle,
|
|
22052
|
+
"aria-label": label,
|
|
22053
|
+
"aria-expanded": anchor2 !== null,
|
|
22054
|
+
title: label
|
|
22055
|
+
},
|
|
22056
|
+
/* @__PURE__ */ import_react.default.createElement(
|
|
22057
|
+
"svg",
|
|
22058
|
+
{
|
|
22059
|
+
width: "16",
|
|
22060
|
+
height: "16",
|
|
22061
|
+
viewBox: "0 0 16 16",
|
|
22062
|
+
fill: "none",
|
|
22063
|
+
stroke: "currentColor",
|
|
22064
|
+
strokeWidth: "1.5",
|
|
22065
|
+
strokeLinecap: "round",
|
|
22066
|
+
strokeLinejoin: "round",
|
|
22067
|
+
"aria-hidden": "true",
|
|
22068
|
+
focusable: "false"
|
|
22069
|
+
},
|
|
22070
|
+
/* @__PURE__ */ import_react.default.createElement("path", { pathLength: "100", d: "M1 8h3.2l1.4-4.2 2.6 8.4 1.5-5.2 1 1H15" })
|
|
22071
|
+
)
|
|
22072
|
+
), anchor2 !== null && /* @__PURE__ */ import_react.default.createElement(
|
|
22073
|
+
AttentionPanel,
|
|
22074
|
+
{
|
|
22075
|
+
t,
|
|
22076
|
+
sessions,
|
|
22077
|
+
anchor: anchor2,
|
|
22078
|
+
onClose: close,
|
|
22079
|
+
onOpen: (id) => {
|
|
22080
|
+
expandOwningWorkspaceGroup(ctx, id);
|
|
22081
|
+
ctx?.sessions?.open?.(id);
|
|
22082
|
+
close();
|
|
22083
|
+
}
|
|
22084
|
+
}
|
|
22085
|
+
));
|
|
22086
|
+
}
|
|
21875
22087
|
function SettingsPanel({ t, ctx, remote, getActive, refreshCatalog, initialTab, squadsPreview, teamsPreview, draftPreview }) {
|
|
21876
22088
|
const [snapshot, setSnapshot] = import_react.default.useState(() => snapshotOf(remote) ?? null);
|
|
21877
22089
|
const [query, setQuery] = import_react.default.useState("");
|
|
@@ -22080,26 +22292,27 @@ function SettingsPanel({ t, ctx, remote, getActive, refreshCatalog, initialTab,
|
|
|
22080
22292
|
setBusy(false);
|
|
22081
22293
|
}
|
|
22082
22294
|
}
|
|
22083
|
-
if (snapshot === null) {
|
|
22084
|
-
return /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-settings" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-title" }, t("settings.title")), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-meta" }, t("settings.loading")), error62 !== "" && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-error" }, t("settings.loadFailed", { detail: error62 })), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-row" }, /* @__PURE__ */ import_react.default.createElement("button", { className: "t-team-chip", type: "button", onClick: () => void reload(true) }, t("settings.retry")))));
|
|
22085
|
-
}
|
|
22086
22295
|
const [showTaskBadge, setShowTaskBadgeState] = import_react.default.useState(true);
|
|
22087
22296
|
const [showScheduleButton, setShowScheduleButtonState] = import_react.default.useState(true);
|
|
22297
|
+
const [showActivePulse, setShowActivePulseState] = import_react.default.useState(true);
|
|
22088
22298
|
const [uiPrefsError, setUiPrefsError] = import_react.default.useState("");
|
|
22299
|
+
const [uiPrefsWriteError, setUiPrefsWriteError] = import_react.default.useState("");
|
|
22300
|
+
const uiPrefQueue = import_react.default.useRef(Promise.resolve());
|
|
22089
22301
|
import_react.default.useEffect(() => {
|
|
22090
22302
|
let alive = true;
|
|
22091
22303
|
void (async () => {
|
|
22092
22304
|
try {
|
|
22093
22305
|
const data = unwrap(await remote.getUiPrefs(), "getUiPrefs");
|
|
22094
22306
|
if (!alive) return;
|
|
22095
|
-
if (typeof data?.showTaskBadge !== "boolean" || typeof data?.showScheduleButton !== "boolean") {
|
|
22307
|
+
if (typeof data?.showTaskBadge !== "boolean" || typeof data?.showScheduleButton !== "boolean" || typeof data?.showActivePulse !== "boolean") {
|
|
22096
22308
|
setUiPrefsError(t("settings.showTaskBadgeUnreadable"));
|
|
22097
22309
|
return;
|
|
22098
22310
|
}
|
|
22099
22311
|
setUiPrefsError("");
|
|
22100
22312
|
setShowTaskBadgeState(data.showTaskBadge);
|
|
22101
22313
|
setShowScheduleButtonState(data.showScheduleButton);
|
|
22102
|
-
|
|
22314
|
+
setShowActivePulseState(data.showActivePulse);
|
|
22315
|
+
setUiPrefs({ showTaskBadge: data.showTaskBadge, showScheduleButton: data.showScheduleButton, showActivePulse: data.showActivePulse });
|
|
22103
22316
|
} catch (cause) {
|
|
22104
22317
|
console.error("[t-team] \u754C\u9762\u504F\u597D\u8BFB\u53D6\u5931\u8D25\uFF0C\u6682\u6309\u9ED8\u8BA4\uFF08\u663E\u793A\u5FBD\u7AE0\uFF09\u5904\u7406\uFF1A", cause);
|
|
22105
22318
|
if (alive) setUiPrefsError(cause instanceof Error ? cause.message : String(cause));
|
|
@@ -22109,19 +22322,30 @@ function SettingsPanel({ t, ctx, remote, getActive, refreshCatalog, initialTab,
|
|
|
22109
22322
|
alive = false;
|
|
22110
22323
|
};
|
|
22111
22324
|
}, [remote]);
|
|
22325
|
+
if (snapshot === null) {
|
|
22326
|
+
return /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-settings" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-title" }, t("settings.title")), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-meta" }, t("settings.loading")), error62 !== "" && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-error" }, t("settings.loadFailed", { detail: error62 })), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-row" }, /* @__PURE__ */ import_react.default.createElement("button", { className: "t-team-chip", type: "button", onClick: () => void reload(true) }, t("settings.retry")))));
|
|
22327
|
+
}
|
|
22112
22328
|
async function writeUiPref(patch, rollback) {
|
|
22113
22329
|
setUiPrefs(patch);
|
|
22114
|
-
|
|
22115
|
-
|
|
22116
|
-
|
|
22117
|
-
|
|
22118
|
-
|
|
22119
|
-
|
|
22120
|
-
|
|
22121
|
-
|
|
22122
|
-
|
|
22123
|
-
|
|
22124
|
-
|
|
22330
|
+
const run = uiPrefQueue.current.then(async () => {
|
|
22331
|
+
try {
|
|
22332
|
+
const next = unwrap(await remote.setUiPrefs(patch), "setUiPrefs");
|
|
22333
|
+
setUiPrefs(next);
|
|
22334
|
+
setShowTaskBadgeState(next.showTaskBadge);
|
|
22335
|
+
setShowScheduleButtonState(next.showScheduleButton);
|
|
22336
|
+
setShowActivePulseState(next.showActivePulse);
|
|
22337
|
+
setUiPrefsWriteError("");
|
|
22338
|
+
} catch (cause) {
|
|
22339
|
+
setUiPrefs(rollback);
|
|
22340
|
+
setShowTaskBadgeState(rollback.showTaskBadge ?? showTaskBadge);
|
|
22341
|
+
setShowScheduleButtonState(rollback.showScheduleButton ?? showScheduleButton);
|
|
22342
|
+
setShowActivePulseState(rollback.showActivePulse ?? showActivePulse);
|
|
22343
|
+
setUiPrefsWriteError(cause instanceof Error ? cause.message : String(cause));
|
|
22344
|
+
}
|
|
22345
|
+
});
|
|
22346
|
+
uiPrefQueue.current = run.catch(() => {
|
|
22347
|
+
});
|
|
22348
|
+
await run;
|
|
22125
22349
|
}
|
|
22126
22350
|
async function setShowTaskBadge(next) {
|
|
22127
22351
|
setShowTaskBadgeState(next);
|
|
@@ -22131,6 +22355,10 @@ function SettingsPanel({ t, ctx, remote, getActive, refreshCatalog, initialTab,
|
|
|
22131
22355
|
setShowScheduleButtonState(next);
|
|
22132
22356
|
await writeUiPref({ showScheduleButton: next }, { showScheduleButton: !next });
|
|
22133
22357
|
}
|
|
22358
|
+
async function setShowActivePulse(next) {
|
|
22359
|
+
setShowActivePulseState(next);
|
|
22360
|
+
await writeUiPref({ showActivePulse: next }, { showActivePulse: !next });
|
|
22361
|
+
}
|
|
22134
22362
|
const enabledCount = snapshot.enabled.length;
|
|
22135
22363
|
return /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-settings" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-head" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-title" }, t("settings.title")), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-meta" }, t("settings.enabledCount", { enabled: enabledCount, total: experts.length }), " \xB7 v", CLIENT_BUILD_VERSION)), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-row" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-head" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-setting-name" }, t("settings.showTaskBadge")), /* @__PURE__ */ import_react.default.createElement(
|
|
22136
22364
|
"button",
|
|
@@ -22143,7 +22371,7 @@ function SettingsPanel({ t, ctx, remote, getActive, refreshCatalog, initialTab,
|
|
|
22143
22371
|
onClick: () => void setShowTaskBadge(!showTaskBadge)
|
|
22144
22372
|
},
|
|
22145
22373
|
/* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-switch-knob" })
|
|
22146
|
-
)), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-hint" }, t("settings.showTaskBadgeHint")), uiPrefsError !== "" && /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-error" }, t("settings.showTaskBadgeUnreadable"), "\uFF1A", uiPrefsError)), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-row" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-head" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-setting-name" }, t("settings.showScheduleButton")), /* @__PURE__ */ import_react.default.createElement(
|
|
22374
|
+
)), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-hint" }, t("settings.showTaskBadgeHint")), uiPrefsError !== "" && /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-error" }, t("settings.showTaskBadgeUnreadable"), "\uFF1A", uiPrefsError), uiPrefsWriteError !== "" && /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-error" }, t("settings.uiPrefsWriteFailed"), "\uFF1A", uiPrefsWriteError)), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-row" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-head" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-setting-name" }, t("settings.showScheduleButton")), /* @__PURE__ */ import_react.default.createElement(
|
|
22147
22375
|
"button",
|
|
22148
22376
|
{
|
|
22149
22377
|
className: "t-team-switch",
|
|
@@ -22154,7 +22382,18 @@ function SettingsPanel({ t, ctx, remote, getActive, refreshCatalog, initialTab,
|
|
|
22154
22382
|
onClick: () => void setShowScheduleButton(!showScheduleButton)
|
|
22155
22383
|
},
|
|
22156
22384
|
/* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-switch-knob" })
|
|
22157
|
-
)), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-hint" }, t("settings.showScheduleButtonHint"))), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-
|
|
22385
|
+
)), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-hint" }, t("settings.showScheduleButtonHint"))), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-row" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-head" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-setting-name" }, t("settings.showActivePulse")), /* @__PURE__ */ import_react.default.createElement(
|
|
22386
|
+
"button",
|
|
22387
|
+
{
|
|
22388
|
+
className: "t-team-switch",
|
|
22389
|
+
type: "button",
|
|
22390
|
+
role: "switch",
|
|
22391
|
+
"aria-checked": showActivePulse,
|
|
22392
|
+
"data-on": showActivePulse,
|
|
22393
|
+
onClick: () => void setShowActivePulse(!showActivePulse)
|
|
22394
|
+
},
|
|
22395
|
+
/* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-switch-knob" })
|
|
22396
|
+
)), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-setting-hint" }, t("settings.showActivePulseHint"))), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-tabs", role: "tablist" }, [["experts", "tab.experts"], ["categories", "tab.categories"], ["roster", "tab.roster"], ["teams", "tab.teams"]].map(([key, label]) => /* @__PURE__ */ import_react.default.createElement(
|
|
22158
22397
|
"button",
|
|
22159
22398
|
{
|
|
22160
22399
|
className: "t-team-tab",
|
|
@@ -22617,6 +22856,21 @@ function useDockUi() {
|
|
|
22617
22856
|
() => dockUi
|
|
22618
22857
|
);
|
|
22619
22858
|
}
|
|
22859
|
+
var popoverClaim = { owner: "", listeners: /* @__PURE__ */ new Set() };
|
|
22860
|
+
function claimPopover(id) {
|
|
22861
|
+
if (popoverClaim.owner === id) return;
|
|
22862
|
+
popoverClaim.owner = id;
|
|
22863
|
+
for (const listener of [...popoverClaim.listeners]) listener(popoverClaim.owner);
|
|
22864
|
+
}
|
|
22865
|
+
function releasePopover(id) {
|
|
22866
|
+
if (popoverClaim.owner !== id) return;
|
|
22867
|
+
popoverClaim.owner = "";
|
|
22868
|
+
for (const listener of [...popoverClaim.listeners]) listener(popoverClaim.owner);
|
|
22869
|
+
}
|
|
22870
|
+
function subscribePopoverClaims(listener) {
|
|
22871
|
+
popoverClaim.listeners.add(listener);
|
|
22872
|
+
return () => popoverClaim.listeners.delete(listener);
|
|
22873
|
+
}
|
|
22620
22874
|
function jobDockPerfReset() {
|
|
22621
22875
|
try {
|
|
22622
22876
|
performance.clearMarks("t-team-jobs-open");
|
|
@@ -22640,6 +22894,9 @@ function JobsBadge({ t, ctx }) {
|
|
|
22640
22894
|
import_react.default.useEffect(() => {
|
|
22641
22895
|
if (!showBadge) setDockOpen(false);
|
|
22642
22896
|
}, [showBadge]);
|
|
22897
|
+
import_react.default.useEffect(() => subscribePopoverClaims((owner) => {
|
|
22898
|
+
if (owner !== "dock") setDockOpen(false);
|
|
22899
|
+
}), []);
|
|
22643
22900
|
if (!showBadge) return null;
|
|
22644
22901
|
if (rows.length === 0 && subagents.length === 0) return null;
|
|
22645
22902
|
const anyLive = liveCount > 0 || subagentsRunning > 0;
|
|
@@ -22659,7 +22916,10 @@ function JobsBadge({ t, ctx }) {
|
|
|
22659
22916
|
onClick: () => {
|
|
22660
22917
|
const next = !ui.open;
|
|
22661
22918
|
setDockOpen(next);
|
|
22662
|
-
if (next)
|
|
22919
|
+
if (next) {
|
|
22920
|
+
claimPopover("dock");
|
|
22921
|
+
jobDockPerfReset();
|
|
22922
|
+
}
|
|
22663
22923
|
try {
|
|
22664
22924
|
if (next) window.localStorage.removeItem(JOB_DOCK_CLOSED_KEY);
|
|
22665
22925
|
else window.localStorage.setItem(JOB_DOCK_CLOSED_KEY, "1");
|
|
@@ -23403,7 +23663,9 @@ async function apply(ctx) {
|
|
|
23403
23663
|
void (async () => {
|
|
23404
23664
|
try {
|
|
23405
23665
|
const data = unwrap(await remote.getUiPrefs(), "getUiPrefs");
|
|
23406
|
-
|
|
23666
|
+
const patch = {};
|
|
23667
|
+
for (const key of UI_PREF_KEYS) if (typeof data?.[key] === "boolean") patch[key] = data[key];
|
|
23668
|
+
setUiPrefs(patch);
|
|
23407
23669
|
} catch (cause) {
|
|
23408
23670
|
console.warn("[t-team] \u754C\u9762\u504F\u597D\u8BFB\u53D6\u5931\u8D25\uFF0C\u6682\u6309\u9ED8\u8BA4\uFF08\u663E\u793A\u5FBD\u7AE0\uFF09\u5904\u7406\uFF1A", cause);
|
|
23409
23671
|
}
|
|
@@ -23472,6 +23734,17 @@ async function apply(ctx) {
|
|
|
23472
23734
|
t: ctx.locale.bind(NS),
|
|
23473
23735
|
ctx: props?.ctx ?? ctx
|
|
23474
23736
|
})));
|
|
23737
|
+
ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({
|
|
23738
|
+
name: "conversation.session.header.utilities",
|
|
23739
|
+
id: `${NS}-pulse`,
|
|
23740
|
+
order: 1,
|
|
23741
|
+
label: () => ctx.locale.bind(NS)("pulse.on"),
|
|
23742
|
+
locale: NS
|
|
23743
|
+
}, (props) => import_react.default.createElement(ActivePulse, {
|
|
23744
|
+
...props,
|
|
23745
|
+
t: ctx.locale.bind(NS),
|
|
23746
|
+
ctx: props?.ctx ?? ctx
|
|
23747
|
+
})));
|
|
23475
23748
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
23476
23749
|
name: "shell.overlay",
|
|
23477
23750
|
id: `${NS}-jobs`,
|
package/lib/index.js
CHANGED
|
@@ -167,6 +167,14 @@ const settingsSchema = schema.object({
|
|
|
167
167
|
* (见 apply 里的 applyScheduleArmed)。任务与执行记录完整保留,重新打开即恢复调度。
|
|
168
168
|
*/
|
|
169
169
|
showScheduleButton: schema.boolean().default(true),
|
|
170
|
+
/**
|
|
171
|
+
* 是否显示窗口右上角的「活跃指示」(心电图图标,界面偏好)。
|
|
172
|
+
*
|
|
173
|
+
* 彩色 = 有会话正在活动(自己在跑、或子代理在跑)**或**有待查看的完成提醒;
|
|
174
|
+
* 灰色 = 全部空闲且没有待看。与任务徽章的差别:它是**全局**的(挂 shell.overlay),
|
|
175
|
+
* 不受"当前打开哪个会话"影响。
|
|
176
|
+
*/
|
|
177
|
+
showActivePulse: schema.boolean().default(true),
|
|
170
178
|
});
|
|
171
179
|
|
|
172
180
|
/**
|
|
@@ -394,7 +402,7 @@ export function apply(ctx, config) {
|
|
|
394
402
|
return;
|
|
395
403
|
}
|
|
396
404
|
scope = settingsService.register(SETTINGS_NAMESPACE, settingsSchema, {
|
|
397
|
-
base: { enabled: [], showTaskBadge: true, showScheduleButton: true },
|
|
405
|
+
base: { enabled: [], showTaskBadge: true, showScheduleButton: true, showActivePulse: true },
|
|
398
406
|
applies: "live",
|
|
399
407
|
validate: (value) => {
|
|
400
408
|
const list = value?.enabled;
|
|
@@ -902,6 +910,7 @@ export function apply(ctx, config) {
|
|
|
902
910
|
return {
|
|
903
911
|
showTaskBadge: current?.showTaskBadge !== false,
|
|
904
912
|
showScheduleButton: current?.showScheduleButton !== false,
|
|
913
|
+
showActivePulse: current?.showActivePulse !== false,
|
|
905
914
|
};
|
|
906
915
|
}
|
|
907
916
|
|
|
@@ -911,6 +920,7 @@ export function apply(ctx, config) {
|
|
|
911
920
|
return {
|
|
912
921
|
...(typeof source.showTaskBadge === "boolean" ? { showTaskBadge: source.showTaskBadge } : {}),
|
|
913
922
|
...(typeof source.showScheduleButton === "boolean" ? { showScheduleButton: source.showScheduleButton } : {}),
|
|
923
|
+
...(typeof source.showActivePulse === "boolean" ? { showActivePulse: source.showActivePulse } : {}),
|
|
914
924
|
};
|
|
915
925
|
}
|
|
916
926
|
|
|
@@ -927,6 +937,7 @@ export function apply(ctx, config) {
|
|
|
927
937
|
[
|
|
928
938
|
{ op: "set", path: ["showTaskBadge"], value: next.showTaskBadge },
|
|
929
939
|
{ op: "set", path: ["showScheduleButton"], value: next.showScheduleButton },
|
|
940
|
+
{ op: "set", path: ["showActivePulse"], value: next.showActivePulse },
|
|
930
941
|
],
|
|
931
942
|
revision(),
|
|
932
943
|
);
|
package/lib/remote-schemas.js
CHANGED
|
@@ -82,12 +82,15 @@ export const enabledStateSchema = z.object({
|
|
|
82
82
|
export const uiPrefsSchema = z.object({
|
|
83
83
|
showTaskBadge: z.boolean(),
|
|
84
84
|
showScheduleButton: z.boolean(),
|
|
85
|
+
// 窗口右上角「活跃指示」是否显示。宿主**总是**返回布尔(缺省按 true 算),所以这里必填。
|
|
86
|
+
showActivePulse: z.boolean(),
|
|
85
87
|
});
|
|
86
88
|
|
|
87
89
|
/** `setUiPrefs` 的入参:想改哪个传哪个(未传的键保持原值)。 */
|
|
88
90
|
export const uiPrefsPatchSchema = z.object({
|
|
89
91
|
showTaskBadge: z.boolean().optional(),
|
|
90
92
|
showScheduleButton: z.boolean().optional(),
|
|
93
|
+
showActivePulse: z.boolean().optional(),
|
|
91
94
|
});
|
|
92
95
|
|
|
93
96
|
export const promptSchema = z.object({ prompt: z.string() });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-t-expert",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.40",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "T Expert — a 323-expert, 22-division roster with full Chinese translations, as a standalone DeepSeek Harness plugin, with a built-in multi-agent team engine (T Team).",
|
|
6
6
|
"license": "MIT",
|