@michengai/dsh-agency-agents 0.1.33 → 0.1.34
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/CHANGELOG.md +5 -0
- package/CHANGELOG.zh-CN.md +5 -0
- package/lib/client.js +69 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,11 @@ The five most recent published versions are listed below.
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 0.1.34 - 2026-09-08
|
|
10
|
+
|
|
11
|
+
- Fixed the composer Expert picker so its scrollable menu opens within the available viewport space instead of being clipped when many experts are enabled.
|
|
12
|
+
- Kept the initial enabled-first ordering in Expert Settings stable while toggling individual experts, preventing cards from jumping during bulk setup.
|
|
13
|
+
|
|
9
14
|
## 0.1.33 - 2026-09-07
|
|
10
15
|
|
|
11
16
|
- Added independent in-product update checks with automatic updates when a verified DSH update service is available and a profile-specific manual fallback otherwise.
|
package/CHANGELOG.zh-CN.md
CHANGED
package/lib/client.js
CHANGED
|
@@ -7690,6 +7690,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7690
7690
|
else inactive.push(expert);
|
|
7691
7691
|
return [...active, ...inactive];
|
|
7692
7692
|
}
|
|
7693
|
+
/** 按首次进入设置页时保存的顺序排列;不在单项启停后重新排序。 */
|
|
7694
|
+
function sortExpertsByOrder(list, order) {
|
|
7695
|
+
const positions = new Map(order.map((slug, index) => [slug, index]));
|
|
7696
|
+
return list.slice().sort((left, right) => {
|
|
7697
|
+
return (positions.get(left.slug) ?? Number.MAX_SAFE_INTEGER) - (positions.get(right.slug) ?? Number.MAX_SAFE_INTEGER);
|
|
7698
|
+
});
|
|
7699
|
+
}
|
|
7693
7700
|
const DIVISION_COUNTS = Object.fromEntries(DIVISION_ORDER.map((division) => [division, EXPERTS.filter((expert) => expert.division === division).length]));
|
|
7694
7701
|
/** 根据 slug 稳定分配复用头像;空头像池安全回退为第 0 项。 */
|
|
7695
7702
|
function expertAvatarIndex(slug, avatarCount) {
|
|
@@ -7828,7 +7835,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7828
7835
|
const MENU_NAME_OVERRIDE = DIVISION_ORDER.map((division) => inputTriggerSourceId(division)).map((name) => `[role="listbox"] div[data-source=${JSON.stringify(name)}] ~ button`).map((selector) => `${selector} span:last-child`).join(",");
|
|
7829
7836
|
/** Windows 优先使用彩色 emoji 字体,名称中的普通文字由后续字体安全回退。 */
|
|
7830
7837
|
const EXPERT_MENU_NAME_STYLE = "flex:1 1 auto;max-width:none;min-width:0;font-family:\"Segoe UI Emoji\",\"Apple Color Emoji\",\"Noto Color Emoji\",sans-serif!important;font-variant-emoji:emoji!important";
|
|
7831
|
-
const COMPOSER_CSS = ".aag-btn-wrap{position:relative;order:1;margin-right:-8px}.aag-btn{display:inline-flex;align-items:center;gap:4px;height:28px;padding:0 4px 0 8px;border:none;border-radius:24px;background:transparent;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px;font-weight:500;cursor:pointer}.aag-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.aag-menu{position:absolute;bottom:calc(100% + 4px);left:0;box-sizing:border-box;padding:4px;display:flex;flex-direction:column;gap:0;width:300px;max-width:360px;max-height:calc(
|
|
7838
|
+
const COMPOSER_CSS = ".aag-btn-wrap{position:relative;order:1;margin-right:-8px}.aag-btn{display:inline-flex;align-items:center;gap:4px;height:28px;padding:0 4px 0 8px;border:none;border-radius:24px;background:transparent;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px;font-weight:500;cursor:pointer}.aag-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.aag-menu{position:absolute;bottom:calc(100% + 4px);left:0;box-sizing:border-box;padding:4px;display:flex;flex-direction:column;gap:0;width:300px;max-width:360px;max-height:calc(100dvh - 24px);overflow-y:auto;border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv3);z-index:10000}.aag-menu[data-placement=\"below\"]{top:calc(100% + 4px);bottom:auto}.aag-menu-title{padding:8px 10px;font-size:12px;line-height:16px;color:var(--dsw-alias-label-tertiary)}.aag-menu-item{display:flex;align-items:center;gap:8px;width:100%;min-height:40px;padding:8px 10px;border:none;border-radius:10px;background:transparent;cursor:pointer;text-align:left;font-size:14px;line-height:22px;color:var(--dsw-alias-label-primary);box-sizing:border-box}.aag-menu-item:hover{background:var(--dsw-alias-interactive-bg-hover)}.aag-emoji{flex:0 0 auto;font-size:16px}.aag-menu-empty{padding:8px 10px;color:var(--dsw-alias-label-secondary);font-size:13px}[data-composer-card] :has(> button[aria-haspopup=\"listbox\"]) > :nth-child(2){order:2}";
|
|
7832
7839
|
const SETTINGS_CSS = `
|
|
7833
7840
|
.aag-section{box-sizing:border-box;display:flex;min-width:0;max-width:760px;width:100%;margin:0 auto;flex-direction:column;gap:16px;padding:0 0 32px;color:var(--dsw-alias-label-primary)}
|
|
7834
7841
|
.aag-toolbar{display:flex;align-items:flex-start;gap:16px;padding-bottom:12px}
|
|
@@ -8047,6 +8054,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8047
8054
|
function resolveExpertToolbarClick(enabledCount) {
|
|
8048
8055
|
return enabledCount === 0 ? "settings" : "menu";
|
|
8049
8056
|
}
|
|
8057
|
+
/**
|
|
8058
|
+
* 让浮层始终留在可视区域内。输入框通常贴近底部,因此默认向上展开;
|
|
8059
|
+
* 当上方空间更小时,改为向下展开并将列表限制在实际可滚动的高度内。
|
|
8060
|
+
*/
|
|
8061
|
+
function resolveExpertMenuPosition(trigger, viewportHeight) {
|
|
8062
|
+
const gap = 4;
|
|
8063
|
+
const viewportInset = 12;
|
|
8064
|
+
const above = Math.max(0, Math.floor(trigger.top - gap - viewportInset));
|
|
8065
|
+
const below = Math.max(0, Math.floor(viewportHeight - trigger.bottom - gap - viewportInset));
|
|
8066
|
+
return above >= below ? {
|
|
8067
|
+
placement: "above",
|
|
8068
|
+
maxHeight: above
|
|
8069
|
+
} : {
|
|
8070
|
+
placement: "below",
|
|
8071
|
+
maxHeight: below
|
|
8072
|
+
};
|
|
8073
|
+
}
|
|
8050
8074
|
const SETTINGS_TRIGGER_LABELS = /* @__PURE__ */ new Set(["设置", "Settings"]);
|
|
8051
8075
|
const COMPOSER_TRIGGER_SCOPE = "[data-composer-card], .aag-btn-wrap";
|
|
8052
8076
|
function isSettingsTriggerLabel(label) {
|
|
@@ -8146,6 +8170,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8146
8170
|
const [open, setOpen] = react.default.useState(false);
|
|
8147
8171
|
const [enabled, setEnabled] = react.default.useState(/* @__PURE__ */ new Set());
|
|
8148
8172
|
const [insertError, setInsertError] = react.default.useState(null);
|
|
8173
|
+
const [menuPosition, setMenuPosition] = react.default.useState();
|
|
8174
|
+
const rootRef = react.default.useRef(null);
|
|
8175
|
+
react.default.useLayoutEffect(() => {
|
|
8176
|
+
if (!open) return;
|
|
8177
|
+
const updatePosition = () => {
|
|
8178
|
+
const root = rootRef.current;
|
|
8179
|
+
if (root === null) return;
|
|
8180
|
+
const viewportHeight = window.visualViewport?.height ?? window.innerHeight;
|
|
8181
|
+
const next = resolveExpertMenuPosition(root.getBoundingClientRect(), viewportHeight);
|
|
8182
|
+
setMenuPosition((current) => current?.placement === next.placement && current.maxHeight === next.maxHeight ? current : next);
|
|
8183
|
+
};
|
|
8184
|
+
updatePosition();
|
|
8185
|
+
window.addEventListener("resize", updatePosition);
|
|
8186
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
8187
|
+
const visualViewport = window.visualViewport;
|
|
8188
|
+
visualViewport?.addEventListener("resize", updatePosition);
|
|
8189
|
+
visualViewport?.addEventListener("scroll", updatePosition);
|
|
8190
|
+
const observer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(updatePosition);
|
|
8191
|
+
if (rootRef.current !== null) observer?.observe(rootRef.current);
|
|
8192
|
+
return () => {
|
|
8193
|
+
window.removeEventListener("resize", updatePosition);
|
|
8194
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
8195
|
+
visualViewport?.removeEventListener("resize", updatePosition);
|
|
8196
|
+
visualViewport?.removeEventListener("scroll", updatePosition);
|
|
8197
|
+
observer?.disconnect();
|
|
8198
|
+
};
|
|
8199
|
+
}, [open]);
|
|
8149
8200
|
react.default.useEffect(() => {
|
|
8150
8201
|
if (!open) return;
|
|
8151
8202
|
const onPointerDown = (ev) => {
|
|
@@ -8181,14 +8232,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8181
8232
|
setOpen(false);
|
|
8182
8233
|
};
|
|
8183
8234
|
const groups = groupByDivision(EXPERTS.filter((e) => enabled.has(e.slug)), props.getActive());
|
|
8184
|
-
const menu = open ? react.default.createElement("div", {
|
|
8235
|
+
const menu = open ? react.default.createElement("div", {
|
|
8236
|
+
className: "aag-menu",
|
|
8237
|
+
"data-placement": menuPosition?.placement,
|
|
8238
|
+
style: menuPosition === void 0 ? void 0 : { maxHeight: `${menuPosition.maxHeight}px` }
|
|
8239
|
+
}, insertError === null ? null : react.default.createElement("div", {
|
|
8185
8240
|
className: "aag-error",
|
|
8186
8241
|
role: "alert"
|
|
8187
8242
|
}, insertError), groups.length === 0 ? react.default.createElement("div", { className: "aag-menu-empty" }, props.t("menu.empty")) : groups.map((g) => menuGroup(g, pick, props.t, props.getActive))) : null;
|
|
8188
|
-
return react.default.createElement("div", {
|
|
8243
|
+
return react.default.createElement("div", {
|
|
8244
|
+
className: "aag-btn-wrap",
|
|
8245
|
+
ref: rootRef
|
|
8246
|
+
}, react.default.createElement("button", {
|
|
8189
8247
|
type: "button",
|
|
8190
8248
|
className: "aag-btn",
|
|
8191
8249
|
title: props.t("button.title"),
|
|
8250
|
+
"aria-expanded": open,
|
|
8192
8251
|
onMouseDown: keepComposerFocus,
|
|
8193
8252
|
onClick
|
|
8194
8253
|
}, expertIcon(), react.default.createElement("span", null, props.t("settings.nav"))), menu);
|
|
@@ -8349,6 +8408,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8349
8408
|
}
|
|
8350
8409
|
function ExpertCardsSettings(props) {
|
|
8351
8410
|
const [state, setState] = react.default.useState(null);
|
|
8411
|
+
const [initialOrder, setInitialOrder] = react.default.useState(null);
|
|
8352
8412
|
const [error, setError] = react.default.useState(null);
|
|
8353
8413
|
const [query, setQuery] = react.default.useState("");
|
|
8354
8414
|
const [division, setDivision] = react.default.useState("");
|
|
@@ -8361,6 +8421,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8361
8421
|
const load = react.default.useCallback(() => {
|
|
8362
8422
|
readEnabled(props.remote).then((current) => {
|
|
8363
8423
|
setState(current);
|
|
8424
|
+
setInitialOrder((order) => order ?? sortExpertsByEnabled(EXPERTS, current.enabled).map((expert) => expert.slug));
|
|
8364
8425
|
setError(null);
|
|
8365
8426
|
props.onEnabledChange?.(current.enabled);
|
|
8366
8427
|
}).catch((err) => {
|
|
@@ -8372,6 +8433,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8372
8433
|
readEnabled(props.remote).then((current) => {
|
|
8373
8434
|
if (!alive) return;
|
|
8374
8435
|
setState(current);
|
|
8436
|
+
setInitialOrder((order) => order ?? sortExpertsByEnabled(EXPERTS, current.enabled).map((expert) => expert.slug));
|
|
8375
8437
|
props.onEnabledChange?.(current.enabled);
|
|
8376
8438
|
}).catch((err) => {
|
|
8377
8439
|
if (alive) setError(err instanceof Error ? err.message : String(err));
|
|
@@ -8459,10 +8521,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8459
8521
|
className: "aag-note"
|
|
8460
8522
|
}, props.t("settings.loading")));
|
|
8461
8523
|
else {
|
|
8462
|
-
const filtered = sortExpertsByEnabled(
|
|
8524
|
+
const filtered = filterExperts(initialOrder === null ? sortExpertsByEnabled(EXPERTS, state.enabled) : sortExpertsByOrder(EXPERTS, initialOrder), {
|
|
8463
8525
|
query,
|
|
8464
8526
|
division
|
|
8465
|
-
})
|
|
8527
|
+
});
|
|
8466
8528
|
const enabledCount = [...state.enabled].filter((slug) => EXPERTS.some((expert) => expert.slug === slug)).length;
|
|
8467
8529
|
const total = EXPERTS.length;
|
|
8468
8530
|
const hasFilter = normalizeExpertQuery(query) !== "" || division !== "";
|
|
@@ -8784,9 +8846,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8784
8846
|
exports.normalizeExpertQuery = normalizeExpertQuery;
|
|
8785
8847
|
exports.openAgentSettings = openAgentSettings;
|
|
8786
8848
|
exports.pickHostSettingsTrigger = pickHostSettingsTrigger;
|
|
8849
|
+
exports.resolveExpertMenuPosition = resolveExpertMenuPosition;
|
|
8787
8850
|
exports.resolveExpertToolbarClick = resolveExpertToolbarClick;
|
|
8788
8851
|
exports.resolveReferenceInsertionTarget = resolveReferenceInsertionTarget;
|
|
8789
8852
|
exports.sortExpertsByEnabled = sortExpertsByEnabled;
|
|
8853
|
+
exports.sortExpertsByOrder = sortExpertsByOrder;
|
|
8790
8854
|
exports.writeErrorKey = writeErrorKey;
|
|
8791
8855
|
exports.writeErrorMessage = writeErrorMessage;
|
|
8792
8856
|
return module.exports;
|
package/package.json
CHANGED