@michengai/dsh-codex-ui 0.2.53 → 0.2.55
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/dist/client.js +73 -49
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +20 -4
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -4246,19 +4246,19 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4246
4246
|
//#region src/client/TurnNavigator.tsx
|
|
4247
4247
|
const stylesheet = `
|
|
4248
4248
|
.dcu-turn-navigator{position:fixed;z-index:20;top:50%;left:var(--dcu-turn-left,288px);transform:translateY(-50%);width:16px;max-height:calc(100vh - 120px);overflow:visible;pointer-events:none}
|
|
4249
|
-
.dcu-turn-
|
|
4250
|
-
.dcu-turn-
|
|
4249
|
+
.dcu-turn-scroll{width:16px;max-height:inherit;overflow-x:hidden;overflow-y:auto;scrollbar-width:none;pointer-events:none}
|
|
4250
|
+
.dcu-turn-scroll::-webkit-scrollbar{display:none}
|
|
4251
|
+
.dcu-turn-list{display:grid;gap:2px;margin:0;padding:4px 0;list-style:none;width:16px;pointer-events:none}
|
|
4251
4252
|
.dcu-turn-link{pointer-events:auto;position:relative;display:flex;align-items:center;width:16px;height:8px;overflow:visible;padding:0;border:0;border-radius:4px;background:transparent;color:var(--dsw-alias-label-tertiary);font:13px/18px var(--dsw-font-family);text-align:left;cursor:pointer;transition:color 320ms cubic-bezier(.16,1,.3,1)}
|
|
4252
4253
|
.dcu-turn-link::before{width:var(--dcu-tick-w,5px);height:var(--dcu-tick-h,1px);flex:0 0 var(--dcu-tick-w,5px);border-radius:1px;background:currentcolor;content:'';transition:width 360ms cubic-bezier(.16,1,.3,1),height 360ms cubic-bezier(.16,1,.3,1),flex-basis 360ms cubic-bezier(.16,1,.3,1),background-color 320ms cubic-bezier(.16,1,.3,1)}
|
|
4253
|
-
.dcu-turn-summary{position:absolute;left:16px;top:50
|
|
4254
|
+
.dcu-turn-summary{position:absolute;left:16px;top:var(--dcu-summary-top,50%);transform:translateY(-50%);box-sizing:border-box;width:max-content;max-width:240px;height:32px;padding:0 12px;border-radius:16px;background:#3a3d3c;color:#e8ebe9;box-shadow:0 8px 24px rgba(0,0,0,.28);pointer-events:none;z-index:2;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;line-height:32px}
|
|
4254
4255
|
.dcu-turn-link[data-active=true]{color:var(--dsw-alias-label-primary)}
|
|
4255
|
-
.dcu-turn-link[data-active=true] .dcu-turn-summary{opacity:1}
|
|
4256
4256
|
.dcu-turn-link[aria-current=true]{color:var(--dsw-alias-label-primary)}
|
|
4257
4257
|
.dcu-turn-link[aria-current=true]::before{width:var(--dcu-tick-w,5px);flex-basis:var(--dcu-tick-w,5px);height:var(--dcu-tick-h,1px)}
|
|
4258
4258
|
.dcu-turn-navigator[data-hovering=true] .dcu-turn-link[aria-current=true]{color:var(--dsw-alias-label-tertiary)}
|
|
4259
4259
|
.dcu-turn-navigator[data-hovering=true] .dcu-turn-link[data-active=true]{color:var(--dsw-alias-label-primary)}
|
|
4260
4260
|
.dcu-turn-link:focus-visible{outline:0;box-shadow:0 0 0 2px var(--dsw-alias-button-info-fill)}
|
|
4261
|
-
@media (prefers-reduced-motion:reduce){.dcu-turn-link,.dcu-turn-link::before
|
|
4261
|
+
@media (prefers-reduced-motion:reduce){.dcu-turn-link,.dcu-turn-link::before{transition:none}}
|
|
4262
4262
|
@media (max-width:760px){.dcu-turn-summary{max-width:200px}}
|
|
4263
4263
|
`;
|
|
4264
4264
|
function tickMarkSize(index, hoverAt, _isCurrent) {
|
|
@@ -4320,8 +4320,12 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4320
4320
|
const [current, setCurrent] = (0, react.useState)(turns[0]?.key ?? null);
|
|
4321
4321
|
const [hoverAt, setHoverAt] = (0, react.useState)(null);
|
|
4322
4322
|
const [railLeft, setRailLeft] = (0, react.useState)(288);
|
|
4323
|
+
const [summaryTop, setSummaryTop] = (0, react.useState)(0);
|
|
4324
|
+
const navRef = (0, react.useRef)(null);
|
|
4325
|
+
const listRef = (0, react.useRef)(null);
|
|
4323
4326
|
const turnKeys = (0, react.useMemo)(() => turns.map((turn) => turn.key).join("|"), [turns]);
|
|
4324
4327
|
const activeIndex = hoverAt === null ? -1 : Math.max(0, Math.min(turns.length - 1, Math.round(hoverAt)));
|
|
4328
|
+
const activeTurn = activeIndex >= 0 ? turns[activeIndex] : void 0;
|
|
4325
4329
|
(0, react.useEffect)(() => {
|
|
4326
4330
|
const sidebar = document.querySelector(".dcu-root");
|
|
4327
4331
|
const update = () => {
|
|
@@ -4363,63 +4367,83 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4363
4367
|
if (frame !== null) window.cancelAnimationFrame(frame);
|
|
4364
4368
|
};
|
|
4365
4369
|
}, [turnKeys, turns]);
|
|
4370
|
+
(0, react.useEffect)(() => {
|
|
4371
|
+
const nav = navRef.current;
|
|
4372
|
+
const list = listRef.current;
|
|
4373
|
+
if (nav === null || list === null || activeIndex < 0) return;
|
|
4374
|
+
const button = list.querySelectorAll(".dcu-turn-link")[activeIndex];
|
|
4375
|
+
if (button === void 0) return;
|
|
4376
|
+
const next = Math.round(button.getBoundingClientRect().top + button.getBoundingClientRect().height / 2 - nav.getBoundingClientRect().top);
|
|
4377
|
+
setSummaryTop((previous) => previous === next ? previous : next);
|
|
4378
|
+
}, [activeIndex, turns.length]);
|
|
4366
4379
|
if (turns.length === 0) return null;
|
|
4367
4380
|
const moveHover = (event) => {
|
|
4368
4381
|
setHoverAt(hoverIndexFromPoint(event.currentTarget, event.clientY, turns.length));
|
|
4369
4382
|
};
|
|
4370
|
-
const style = {
|
|
4383
|
+
const style = {
|
|
4384
|
+
"--dcu-turn-left": `${railLeft}px`,
|
|
4385
|
+
"--dcu-summary-top": `${summaryTop}px`
|
|
4386
|
+
};
|
|
4371
4387
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
|
|
4388
|
+
ref: navRef,
|
|
4372
4389
|
className: "dcu-turn-navigator",
|
|
4373
4390
|
"data-hovering": hoverAt !== null || void 0,
|
|
4374
4391
|
"aria-label": t("turns.label"),
|
|
4375
4392
|
style,
|
|
4376
|
-
children: [
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
const tickStyle = hoverAt === null ? void 0 : {
|
|
4386
|
-
"--dcu-tick-w": `${mark.width}px`,
|
|
4387
|
-
"--dcu-tick-h": `${mark.height}px`
|
|
4388
|
-
};
|
|
4389
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4390
|
-
type: "button",
|
|
4391
|
-
className: "dcu-turn-link",
|
|
4392
|
-
"data-active": active || void 0,
|
|
4393
|
-
"aria-current": current === turn.key || void 0,
|
|
4394
|
-
"aria-label": t("turns.jump", {
|
|
4395
|
-
index: index + 1,
|
|
4396
|
-
summary: turn.summary
|
|
4397
|
-
}),
|
|
4398
|
-
title: turn.summary,
|
|
4399
|
-
style: tickStyle,
|
|
4400
|
-
onFocus: () => {
|
|
4401
|
-
setHoverAt(index);
|
|
4402
|
-
},
|
|
4403
|
-
onBlur: () => {
|
|
4393
|
+
children: [
|
|
4394
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: stylesheet }),
|
|
4395
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4396
|
+
className: "dcu-turn-scroll",
|
|
4397
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ol", {
|
|
4398
|
+
ref: listRef,
|
|
4399
|
+
className: "dcu-turn-list",
|
|
4400
|
+
onMouseMove: moveHover,
|
|
4401
|
+
onMouseLeave: () => {
|
|
4404
4402
|
setHoverAt(null);
|
|
4405
4403
|
},
|
|
4406
|
-
|
|
4407
|
-
const
|
|
4408
|
-
const
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4404
|
+
children: turns.map((turn, index) => {
|
|
4405
|
+
const mark = tickMarkSize(index, hoverAt, current === turn.key);
|
|
4406
|
+
const active = hoverAt !== null && index === activeIndex;
|
|
4407
|
+
const tickStyle = hoverAt === null ? void 0 : {
|
|
4408
|
+
"--dcu-tick-w": `${mark.width}px`,
|
|
4409
|
+
"--dcu-tick-h": `${mark.height}px`
|
|
4410
|
+
};
|
|
4411
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4412
|
+
type: "button",
|
|
4413
|
+
className: "dcu-turn-link",
|
|
4414
|
+
"data-active": active || void 0,
|
|
4415
|
+
"aria-current": current === turn.key || void 0,
|
|
4416
|
+
"aria-label": t("turns.jump", {
|
|
4417
|
+
index: index + 1,
|
|
4418
|
+
summary: turn.summary
|
|
4419
|
+
}),
|
|
4420
|
+
title: turn.summary,
|
|
4421
|
+
style: tickStyle,
|
|
4422
|
+
onFocus: () => {
|
|
4423
|
+
setHoverAt(index);
|
|
4424
|
+
},
|
|
4425
|
+
onBlur: () => {
|
|
4426
|
+
setHoverAt(null);
|
|
4427
|
+
},
|
|
4428
|
+
onClick: () => {
|
|
4429
|
+
const host = conversationScrollRoot();
|
|
4430
|
+
const anchor = host === null ? null : conversationAnchor(host, turn.key);
|
|
4431
|
+
if (host === null || anchor === null) return;
|
|
4432
|
+
const reduceMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
|
|
4433
|
+
host.scrollTo({
|
|
4434
|
+
top: host.scrollTop + anchor.getBoundingClientRect().top - host.getBoundingClientRect().top - 12,
|
|
4435
|
+
behavior: reduceMotion ? "auto" : "smooth"
|
|
4436
|
+
});
|
|
4437
|
+
}
|
|
4438
|
+
}) }, turn.key);
|
|
4419
4439
|
})
|
|
4420
|
-
})
|
|
4440
|
+
})
|
|
4441
|
+
}),
|
|
4442
|
+
activeTurn !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4443
|
+
className: "dcu-turn-summary",
|
|
4444
|
+
children: activeTurn.summary
|
|
4421
4445
|
})
|
|
4422
|
-
|
|
4446
|
+
]
|
|
4423
4447
|
});
|
|
4424
4448
|
}
|
|
4425
4449
|
//#endregion
|
package/dist/index.d.mts
CHANGED
|
@@ -12,8 +12,10 @@ type HostRequest = {
|
|
|
12
12
|
* 非浏览器客户端(curl、CLI)仍然放行。
|
|
13
13
|
*/
|
|
14
14
|
declare function crossSiteRequest(request: HostRequest): boolean;
|
|
15
|
+
/** 把安装错误收成可给浏览器看的文案:我们自己的中文说明保留,带本地路径的底层错误脱敏。 */
|
|
16
|
+
declare function publicDependencyError(error: unknown): string;
|
|
15
17
|
declare const inject: string[];
|
|
16
18
|
/** 提供不泄露地址、命令和凭证的连接器目录。 */
|
|
17
19
|
declare function apply(ctx: Context): void;
|
|
18
20
|
//#endregion
|
|
19
|
-
export { apply, crossSiteRequest, inject };
|
|
21
|
+
export { apply, crossSiteRequest, inject, publicDependencyError };
|
package/dist/index.mjs
CHANGED
|
@@ -169,6 +169,7 @@ function pluginCommandError(stderr) {
|
|
|
169
169
|
const detail = stderr.replace(/\s+/g, " ").trim();
|
|
170
170
|
if (detail.includes("minimumReleaseAge") || detail.includes("Release age")) return /* @__PURE__ */ new Error("更新被 pnpm 发布时间保护拦截。请确认已写入当前版本白名单后重试。");
|
|
171
171
|
if (detail.includes("EPERM") || detail.includes("EBUSY") || detail.includes("EACCES")) return /* @__PURE__ */ new Error("无法覆盖正在运行的插件文件。请先停止 DSH Web,再点击更新。");
|
|
172
|
+
if (detail.includes("NO_MATCHING_VERSION") || detail.includes("No matching version")) return /* @__PURE__ */ new Error("当前 npm 镜像还没有这个版本。请稍后重试,或改用官方源安装。");
|
|
172
173
|
return /* @__PURE__ */ new Error("从 npm 安装或更新依赖失败。请检查网络、npm registry 或发布时间保护后重试。");
|
|
173
174
|
}
|
|
174
175
|
/**
|
|
@@ -228,7 +229,11 @@ async function installDependencyLocked(id) {
|
|
|
228
229
|
const latestVersion = await npmLatestVersion(dependency.packageName);
|
|
229
230
|
if (latestVersion === void 0) throw new Error("无法获取 npm 最新版本,请检查网络或 npm registry 后重试。");
|
|
230
231
|
await ensureLatestReleaseAllowed(dependency.packageName, latestVersion);
|
|
231
|
-
await runDshPlugin([
|
|
232
|
+
await runDshPlugin([
|
|
233
|
+
"add",
|
|
234
|
+
`${dependency.packageName}@${latestVersion}`,
|
|
235
|
+
"--registry=https://registry.npmjs.org/"
|
|
236
|
+
]);
|
|
232
237
|
const installed = await installedPackageVersion(dependency.packageName);
|
|
233
238
|
if (installed !== latestVersion) throw new Error(`已请求 ${dependency.packageName}@${latestVersion},但当前仍是 ${installed ?? "未安装"}。请先停止 DSH Web 后再更新。`);
|
|
234
239
|
return dependencyStatuses();
|
|
@@ -272,7 +277,18 @@ function crossSiteRequest(request) {
|
|
|
272
277
|
const origin = headerValue(headers, "origin");
|
|
273
278
|
if (origin === void 0) return false;
|
|
274
279
|
const host = headerValue(headers, "host");
|
|
275
|
-
|
|
280
|
+
if (host === void 0) return true;
|
|
281
|
+
try {
|
|
282
|
+
return new URL(origin).host !== host;
|
|
283
|
+
} catch {
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/** 把安装错误收成可给浏览器看的文案:我们自己的中文说明保留,带本地路径的底层错误脱敏。 */
|
|
288
|
+
function publicDependencyError(error) {
|
|
289
|
+
const message = error instanceof Error ? error.message : "依赖管理暂不可用。";
|
|
290
|
+
if (/[A-Za-z]:[\\/]|\/(?:home|Users|var|tmp)\//.test(message)) return "依赖管理暂不可用,请查看服务端日志。";
|
|
291
|
+
return message;
|
|
276
292
|
}
|
|
277
293
|
const inject = [
|
|
278
294
|
"webServer",
|
|
@@ -368,7 +384,7 @@ function apply(ctx) {
|
|
|
368
384
|
"content-type": "application/json; charset=utf-8",
|
|
369
385
|
"cache-control": "no-store"
|
|
370
386
|
});
|
|
371
|
-
response.end(JSON.stringify({ error:
|
|
387
|
+
response.end(JSON.stringify({ error: publicDependencyError(error) }));
|
|
372
388
|
}
|
|
373
389
|
}
|
|
374
390
|
});
|
|
@@ -379,4 +395,4 @@ function apply(ctx) {
|
|
|
379
395
|
}, "michengai-codex-ui: catalogs");
|
|
380
396
|
}
|
|
381
397
|
//#endregion
|
|
382
|
-
export { apply, crossSiteRequest, inject };
|
|
398
|
+
export { apply, crossSiteRequest, inject, publicDependencyError };
|