@michengai/dsh-codex-ui 1.1.25 → 1.1.27
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 +20 -751
- package/CHANGELOG.zh-CN.md +20 -751
- package/lib/client.js +705 -640
- package/package.json +2 -2
package/lib/client.js
CHANGED
|
@@ -2291,7 +2291,7 @@ window.__ModuleLoader__.load({
|
|
|
2291
2291
|
const HEADER_PROJECT_TIP_EVENT = "dcu-header-project-tip";
|
|
2292
2292
|
const HEADER_SESSION_MENU_EVENT = "dcu-header-session-menu";
|
|
2293
2293
|
const CONVERSATION_HEADER_STYLE = `
|
|
2294
|
-
header:has([data-dcu-inline-tabs]){box-sizing:border-box;display:flex;flex-wrap:nowrap;align-items:center;gap:10px;min-height:34px;padding-top:
|
|
2294
|
+
header:has([data-dcu-inline-tabs]){box-sizing:border-box;display:flex;flex-wrap:nowrap;align-items:center;gap:10px;min-height:var(--dcu-header-height,34px);padding-top:calc((var(--dcu-header-height,34px) - 28px)/2);padding-bottom:calc((var(--dcu-header-height,34px) - 28px)/2);border-bottom:0}
|
|
2295
2295
|
header:has([data-dcu-inline-tabs]):after{display:none;content:none}
|
|
2296
2296
|
header:has([data-dcu-inline-tabs]) [class*="titleRow"],header:has([data-dcu-inline-tabs]) [class*="titleCluster"]{display:contents}
|
|
2297
2297
|
header:has([data-dcu-inline-tabs]) [class*="crumbs"]{order:1;flex:0 1 auto;min-width:0}
|
|
@@ -6458,6 +6458,14 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
6458
6458
|
if (marked !== null) return marked;
|
|
6459
6459
|
for (const node of root.querySelectorAll("div")) if (parseSidebarGrid(node.style.gridTemplateColumns) !== void 0) return node;
|
|
6460
6460
|
}
|
|
6461
|
+
/** Settings is portaled to body, so explicitly carry over the expanded width. */
|
|
6462
|
+
function settingsSidebarWidth(root) {
|
|
6463
|
+
const frame = findSidebarFrame(root);
|
|
6464
|
+
const expanded = Number.parseFloat(frame?.style.getPropertyValue("--dcu-sidebar-expanded-width") ?? "");
|
|
6465
|
+
if (Number.isFinite(expanded) && expanded >= 240) return expanded;
|
|
6466
|
+
const width = frame === void 0 ? void 0 : parseSidebarGrid(frame.style.gridTemplateColumns)?.sidebar;
|
|
6467
|
+
return width !== void 0 && width >= 240 ? width : 240;
|
|
6468
|
+
}
|
|
6461
6469
|
/** 同步侧栏网格和拖拽柄,保证两者始终使用同一个可见宽度。 */
|
|
6462
6470
|
function applySidebarWidth(frame, width) {
|
|
6463
6471
|
const tracks = parseSidebarGrid(frame.style.gridTemplateColumns);
|
|
@@ -6981,21 +6989,21 @@ body[data-ds-dark-theme] [data-conversation-scroll] [data-trigger-menu]{backgrou
|
|
|
6981
6989
|
body[data-we-sidebar-glass] .dcu-root{position:relative;background:transparent}body[data-we-sidebar-glass] .dcu-root::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;background-color:color-mix(in srgb,var(--we-sidebar-color,#fff) calc(var(--we-sidebar-alpha,.15)*.66*100%),transparent);background-image:linear-gradient(180deg,rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.14)),rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.04)) 38%,rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.01)));-webkit-backdrop-filter:blur(var(--we-sidebar-blur,16px)) saturate(var(--we-sidebar-saturate,1.8)) brightness(var(--we-glass-brightness,1.04)) contrast(1.01);backdrop-filter:blur(var(--we-sidebar-blur,16px)) saturate(var(--we-sidebar-saturate,1.8)) brightness(var(--we-glass-brightness,1.04)) contrast(1.01);box-shadow:inset 0 1px 0 rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.32)),inset 0 -1px 0 rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.08)),inset 0 0 0 .5px rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.06))}body[data-ds-dark-theme][data-we-sidebar-glass] .dcu-root::before{background-color:color-mix(in srgb,var(--we-sidebar-color,#fff) calc(var(--we-sidebar-alpha,.15)*.33*100%),transparent)}body[data-we-appwindow][data-we-sidebar-glass] .dcu-root::before{-webkit-backdrop-filter:none;backdrop-filter:none}@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){body[data-we-sidebar-glass] .dcu-root{background:#eef7f5}body[data-ds-dark-theme][data-we-sidebar-glass] .dcu-root{background:#1d2120}body[data-we-sidebar-glass] .dcu-root::before{display:none}}
|
|
6982
6990
|
body[data-we-sidebar-glass] .dcu-expanded-shell,body[data-we-sidebar-glass] .dcu-compact-shell,body[data-we-sidebar-glass] .dcu-foot{position:relative}
|
|
6983
6991
|
.dcu-expanded-shell{display:flex;width:100%;min-height:0;flex:1 1 0;overflow:hidden;flex-direction:column;transform-origin:left center;transition:opacity 500ms cubic-bezier(.16,1,.3,1),transform 500ms cubic-bezier(.16,1,.3,1);animation:dcu-sidebar-expanded-in 500ms cubic-bezier(.16,1,.3,1)}.dcu-compact-shell{display:none;width:56px}.dcu-root.dcu-collapsing .dcu-expanded-shell{opacity:0;transform:translateX(-6px);pointer-events:none}.dcu-root.dcu-compact .dcu-expanded-shell{display:none}.dcu-root.dcu-compact .dcu-compact-shell{display:flex;min-height:0;flex:1;flex-direction:column;align-items:center;animation:dcu-sidebar-compact-in 140ms ease-out}@keyframes dcu-sidebar-expanded-in{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}@keyframes dcu-sidebar-compact-in{from{opacity:0;transform:translateX(-4px)}to{opacity:1;transform:none}}
|
|
6984
|
-
.dcu-root *{box-sizing:border-box}.dcu-head{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:8px;height:
|
|
6992
|
+
.dcu-root *{box-sizing:border-box}.dcu-head{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:8px;flex:none;height:var(--dcu-header-height,34px);padding:calc((var(--dcu-header-height,34px) - 28px)/2) 8px calc((var(--dcu-header-height,34px) - 28px)/2) 12px}.dcu-brand{border:0;background:transparent;color:inherit;padding:0;display:flex;align-items:center;min-width:0;overflow:hidden}.dcu-brand svg{display:block;width:auto;max-width:100%;height:24px;min-width:0}.dcu-head-actions{display:grid;grid-auto-flow:column;grid-auto-columns:28px;align-items:center;column-gap:8px;height:28px}
|
|
6985
6993
|
.dcu-icon,.dcu-menu button,.dcu-footer-link{appearance:none;border:0;background:transparent;color:inherit;font:inherit;cursor:pointer}.dcu-icon{display:grid;place-items:center;width:36px;height:36px;border-radius:8px;color:var(--dcu-sidebar-icon)}.dcu-head .dcu-icon{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;margin:0;padding:0;border-radius:50%;line-height:0}.dcu-head .dcu-icon svg{display:block;width:16px;height:16px}
|
|
6986
6994
|
.dcu-icon:hover,.dcu-menu button:hover:not(:disabled),.dcu-footer-link:hover{background:var(--dcu-sidebar-hover);color:var(--dcu-sidebar-primary)}
|
|
6987
6995
|
.dcu-menu{padding:0 6px 8px;display:grid;gap:2px}.dcu-menu button,.dcu-footer-link{display:grid;grid-template-columns:20px minmax(0,1fr);column-gap:8px;align-items:center;width:100%;min-height:36px;padding:0 4px;border-radius:8px;color:var(--dcu-sidebar-navigation);font-size:14px;line-height:20px;text-align:left;font-weight:400}
|
|
6988
6996
|
.dcu-menu-icon{display:grid;place-items:center start;width:20px;height:20px}.dcu-menu-icon svg,.dcu-footer-link svg{display:block;width:16px;height:16px;color:var(--dcu-sidebar-icon)}.dcu-menu button:disabled{color:var(--dcu-sidebar-secondary);cursor:default;opacity:1}.dcu-menu button:disabled svg{color:var(--dcu-sidebar-secondary)}
|
|
6989
6997
|
.dcu-extensions-group{display:grid}.dcu-extension-leading{position:relative;display:block;width:16px;height:16px}.dcu-extension-leading svg{position:absolute;inset:0;transition:opacity 140ms ease-out,transform 220ms cubic-bezier(.16,1,.3,1)}.dcu-extension-default-icon{opacity:1}.dcu-extension-state-arrow{opacity:0;transform:rotate(0)}.dcu-extensions-group:hover .dcu-extension-default-icon,.dcu-extensions-toggle:focus-visible .dcu-extension-default-icon{opacity:0}.dcu-extensions-group:hover .dcu-extension-state-arrow,.dcu-extensions-toggle:focus-visible .dcu-extension-state-arrow{opacity:1}.dcu-extensions-toggle[aria-expanded=true] .dcu-extension-state-arrow{transform:rotate(90deg)}.dcu-extension-panel{display:grid;grid-template-rows:1fr;opacity:1;transition:grid-template-rows 220ms cubic-bezier(.16,1,.3,1),opacity 160ms ease-out}.dcu-extension-panel[data-open=false]{grid-template-rows:0fr;opacity:0;pointer-events:none}.dcu-extension-panel-inner{position:relative;min-height:0;overflow:hidden}.dcu-extension-items{position:relative;display:grid;gap:1px;margin:1px 0 4px 28px}.dcu-extension-items::before{content:"";position:absolute;left:-16px;top:0;bottom:4px;width:1px;background:var(--dcu-sidebar-border)}.dcu-extension-items button{grid-template-columns:minmax(0,1fr);min-height:32px;color:var(--dcu-sidebar-secondary);font-size:13px;font-weight:400}.dcu-extension-items .dcu-menu-icon{display:none}
|
|
6990
|
-
.dcu-workspaces{display:flex;min-height:0;flex:1;flex-direction:column;margin-top:2px;padding-top:8px;border-top:1px solid var(--dcu-sidebar-border)}.dcu-workspaces.dcu-workspaces-tabs{padding-top:0;border-top:0}.dcu-im-tabs{display:flex;gap:16px;margin:0 8px 12px;padding:0;border-bottom:1px solid var(--dcu-sidebar-border)}.dcu-im-tab{appearance:none;border:0;background:transparent;color:var(--dcu-sidebar-secondary);padding:8px 0 7px;font:14px/22px var(--dsw-font-family);font-weight:500;cursor:pointer}.dcu-im-tab[data-on=true]{color:var(--dcu-sidebar-primary);font-weight:600;box-shadow:inset 0 -2px 0 currentColor}.dcu-native-workspaces{display:flex;min-height:0;flex:1}.dcu-native-workspaces>*{min-width:0;flex:1}.dcu-native-workspaces .ima-tabs,.dcu-native-workspaces [role=tablist]{display:none!important}.dcu-schedule-browser{display:flex;min-height:0;flex:1;flex-direction:column}.dcu-native-workspaces .dcu-schedule-views{display:flex!important;flex:none;min-height:30px;margin:0 8px 8px;padding:2px;border:1px solid var(--dcu-sidebar-border);border-radius:8px;background:rgba(255,255,255,.025)}.dcu-schedule-views button{appearance:none;flex:1;min-width:0;height:24px;border:0;border-radius:6px;background:transparent;color:var(--dcu-sidebar-secondary);font:600 12px/18px var(--dsw-font-family);cursor:pointer}.dcu-schedule-views button[aria-selected=true]{background:var(--dcu-sidebar-hover);color:var(--dcu-sidebar-primary);box-shadow:inset 0 0 0 1px var(--dcu-sidebar-border)}.dcu-schedule-pane{display:flex;min-height:0;flex:1}.dcu-schedule-pane>*{min-width:0;flex:1}.dcu-schedule-pane>[data-slot="sidebar.schedule"]{display:flex!important;width:100%;min-width:0;flex:1}.dcu-schedule-pane>[data-slot="sidebar.schedule"]>.dsh-st-rail{width:100%;min-width:0;padding-right:8px;scrollbar-gutter:auto}.dcu-schedule-pane .dsh-st-overview{padding-right:8px}.dcu-foot{display:grid;width:100%;gap:4px;padding:8px 6px 12px;border-top:1px solid var(--dcu-sidebar-border);transition:opacity 500ms cubic-bezier(.16,1,.3,1),transform 500ms cubic-bezier(.16,1,.3,1)}.dcu-root.dcu-collapsing>.dcu-foot{opacity:0;transform:translateX(-4px);pointer-events:none}.dcu-footer-actions:empty,.dcu-settings-seat:empty{display:none}.dcu-settings-seat>button{width:100%;min-height:36px;padding-left:4px!important;color:var(--dcu-sidebar-navigation);font:14px/20px var(--dsw-font-family);font-weight:400}.dcu-compact{width:100%;align-items:flex-start;overflow:hidden;padding:
|
|
6998
|
+
.dcu-workspaces{display:flex;min-height:0;flex:1;flex-direction:column;margin-top:2px;padding-top:8px;border-top:1px solid var(--dcu-sidebar-border)}.dcu-workspaces.dcu-workspaces-tabs{padding-top:0;border-top:0}.dcu-im-tabs{display:flex;gap:16px;margin:0 8px 12px;padding:0;border-bottom:1px solid var(--dcu-sidebar-border)}.dcu-im-tab{appearance:none;border:0;background:transparent;color:var(--dcu-sidebar-secondary);padding:8px 0 7px;font:14px/22px var(--dsw-font-family);font-weight:500;cursor:pointer}.dcu-im-tab[data-on=true]{color:var(--dcu-sidebar-primary);font-weight:600;box-shadow:inset 0 -2px 0 currentColor}.dcu-native-workspaces{display:flex;min-height:0;flex:1}.dcu-native-workspaces>*{min-width:0;flex:1}.dcu-native-workspaces .ima-tabs,.dcu-native-workspaces [role=tablist]{display:none!important}.dcu-schedule-browser{display:flex;min-height:0;flex:1;flex-direction:column}.dcu-native-workspaces .dcu-schedule-views{display:flex!important;flex:none;min-height:30px;margin:0 8px 8px;padding:2px;border:1px solid var(--dcu-sidebar-border);border-radius:8px;background:rgba(255,255,255,.025)}.dcu-schedule-views button{appearance:none;flex:1;min-width:0;height:24px;border:0;border-radius:6px;background:transparent;color:var(--dcu-sidebar-secondary);font:600 12px/18px var(--dsw-font-family);cursor:pointer}.dcu-schedule-views button[aria-selected=true]{background:var(--dcu-sidebar-hover);color:var(--dcu-sidebar-primary);box-shadow:inset 0 0 0 1px var(--dcu-sidebar-border)}.dcu-schedule-pane{display:flex;min-height:0;flex:1}.dcu-schedule-pane>*{min-width:0;flex:1}.dcu-schedule-pane>[data-slot="sidebar.schedule"]{display:flex!important;width:100%;min-width:0;flex:1}.dcu-schedule-pane>[data-slot="sidebar.schedule"]>.dsh-st-rail{width:100%;min-width:0;padding-right:8px;scrollbar-gutter:auto}.dcu-schedule-pane .dsh-st-overview{padding-right:8px}.dcu-foot{display:grid;width:100%;gap:4px;padding:8px 6px 12px;border-top:1px solid var(--dcu-sidebar-border);transition:opacity 500ms cubic-bezier(.16,1,.3,1),transform 500ms cubic-bezier(.16,1,.3,1)}.dcu-root.dcu-collapsing>.dcu-foot{opacity:0;transform:translateX(-4px);pointer-events:none}.dcu-footer-actions:empty,.dcu-settings-seat:empty{display:none}.dcu-settings-seat>button{width:100%;min-height:36px;padding-left:4px!important;color:var(--dcu-sidebar-navigation);font:14px/20px var(--dsw-font-family);font-weight:400}.dcu-compact{width:100%;align-items:flex-start;overflow:hidden;padding:calc((var(--dcu-header-height,34px) - 28px)/2) 0 8px}.dcu-compact-nav{display:flex;flex:1;min-height:0;flex-direction:column;align-items:center;gap:2px;overflow:auto;padding:6px 0}.dcu-compact .dcu-icon{width:36px;height:36px;flex:none}.dcu-compact .dcu-foot{width:36px;margin-top:auto;margin-left:10px;padding:8px 0;border-top:0}.dcu-compact .dcu-settings-seat{width:36px;overflow:hidden}.dcu-compact .dcu-settings-seat>button{display:grid;place-items:center;width:36px;min-height:36px;padding:0!important;font-size:0!important;line-height:0}.dcu-compact .dcu-settings-seat>button svg{width:16px;height:16px}.dcu-compact .dcu-footer-link{display:flex;justify-content:center;width:36px;padding:0;font-size:0}.dcu-compact .dcu-footer-link svg{width:16px;height:16px}
|
|
6991
6999
|
.dcu-settings-seat [data-slot="settings.trigger"]{color:var(--dcu-sidebar-navigation)}
|
|
6992
7000
|
.dcu-settings-seat [data-slot="settings.trigger"]>svg{color:var(--dcu-sidebar-icon)}
|
|
6993
7001
|
/* 宿主列负责缩放,宽态内容保持展开宽度,避免中文竖排与工作区逐帧重排。 */
|
|
6994
7002
|
.dcu-expanded-shell,.dcu-root:not(.dcu-compact)>.dcu-foot{width:var(--dcu-sidebar-expanded-width,240px);flex-shrink:0}
|
|
6995
7003
|
/* 对齐 Codex 的半秒布局节奏;显式声明避免依赖宿主主题的动画 token。 */
|
|
6996
7004
|
.dcu-root{position:relative}
|
|
6997
|
-
.dcu-root.dcu-collapsing .dcu-compact-shell{position:absolute;left:0;top:
|
|
6998
|
-
.dcu-root.dcu-collapsing .dcu-compact-shell .dcu-icon{width:36px;height:36px;flex:none}
|
|
7005
|
+
.dcu-root.dcu-collapsing .dcu-compact-shell{position:absolute;left:0;top:calc((var(--dcu-header-height,34px) - 28px)/2);bottom:8px;display:flex;flex-direction:column;align-items:center;animation:dcu-sidebar-compact-in 500ms cubic-bezier(.16,1,.3,1)}
|
|
7006
|
+
.dcu-root.dcu-collapsing .dcu-compact-shell .dcu-icon{width:36px;height:36px;flex:none}.dcu-root .dcu-compact-shell>.dcu-icon,.dcu-root.dcu-collapsing .dcu-compact-shell>.dcu-icon{width:28px;height:28px;flex:none;margin:0;padding:0;border-radius:50%}
|
|
6999
7007
|
/* 收尾仅移除宽态层,窄轨不重复淡入,否则会在半秒处闪烁。 */
|
|
7000
7008
|
.dcu-root.dcu-compact .dcu-compact-shell{animation:none}
|
|
7001
7009
|
[data-dcu-codex-sidebar-initialized]{transition:grid-template-columns 500ms cubic-bezier(.16,1,.3,1)}
|
|
@@ -7021,8 +7029,11 @@ body[data-ds-dark-theme] [data-conversation-scroll]{--dcu-composer-bg:var(--dsw-
|
|
|
7021
7029
|
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div>div{gap:4px}
|
|
7022
7030
|
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div>div>div{gap:4px}
|
|
7023
7031
|
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div :is(button,select):not([role]){min-height:28px;height:28px}
|
|
7024
|
-
|
|
7025
|
-
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div button[class$=_primary]:
|
|
7032
|
+
/* 保留 Codex 黑白发送键;使用独立主题颜色,避免壁纸的透明表面令牌影响 currentColor 箭头。 */
|
|
7033
|
+
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div button[class$=_primary]{width:28px;transform:none;background:#0f1115;color:#fff}
|
|
7034
|
+
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div button[class$=_primary]:hover:not(:disabled){background:#40434a}
|
|
7035
|
+
body[data-ds-dark-theme] [data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div button[class$=_primary]{background:#fff;color:#0f1115}
|
|
7036
|
+
body[data-ds-dark-theme] [data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div button[class$=_primary]:hover:not(:disabled){background:#d5d7dc}
|
|
7026
7037
|
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div :is(button,select):focus-visible{outline:2px solid var(--dsw-alias-label-secondary);outline-offset:2px}
|
|
7027
7038
|
@supports(corner-shape:superellipse(1.5)){[data-conversation-scroll] [data-composer-card]{border-radius:25px;corner-shape:superellipse(1.5)}}
|
|
7028
7039
|
@media(max-width:639px){[data-conversation-scroll]{--dcu-composer-shadow:0 0 0 1px #0000000a,0 2px 8px #0000000a,0 4px 40px 8px #00000006}}
|
|
@@ -7876,638 +7887,6 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
7876
7887
|
}
|
|
7877
7888
|
CodexSidebar.displayName = "michengai-codex-ui";
|
|
7878
7889
|
//#endregion
|
|
7879
|
-
//#region src/dependencies.ts
|
|
7880
|
-
const MANAGED_DEPENDENCIES = [
|
|
7881
|
-
{
|
|
7882
|
-
id: "ui",
|
|
7883
|
-
packageName: "@michengai/dsh-codex-ui"
|
|
7884
|
-
},
|
|
7885
|
-
{
|
|
7886
|
-
id: "experts",
|
|
7887
|
-
packageName: "@michengai/dsh-agency-agents"
|
|
7888
|
-
},
|
|
7889
|
-
{
|
|
7890
|
-
id: "skills",
|
|
7891
|
-
packageName: "@michengai/dsh-skills-manager"
|
|
7892
|
-
},
|
|
7893
|
-
{
|
|
7894
|
-
id: "archive",
|
|
7895
|
-
packageName: "@michengai/dsh-archive-manager"
|
|
7896
|
-
},
|
|
7897
|
-
{
|
|
7898
|
-
id: "im",
|
|
7899
|
-
packageName: "@michengai/dsh-im-connect"
|
|
7900
|
-
},
|
|
7901
|
-
{
|
|
7902
|
-
id: "schedule",
|
|
7903
|
-
packageName: "@michengai/dsh-automation"
|
|
7904
|
-
},
|
|
7905
|
-
{
|
|
7906
|
-
id: "btw",
|
|
7907
|
-
packageName: "@michengai/dsh-btw"
|
|
7908
|
-
},
|
|
7909
|
-
{
|
|
7910
|
-
id: "simplify",
|
|
7911
|
-
packageName: "@michengai/dsh-simplify"
|
|
7912
|
-
},
|
|
7913
|
-
{
|
|
7914
|
-
id: "pua",
|
|
7915
|
-
packageName: "@michengai/dsh-pua"
|
|
7916
|
-
},
|
|
7917
|
-
{
|
|
7918
|
-
id: "review",
|
|
7919
|
-
packageName: "@michengai/dsh-code-review"
|
|
7920
|
-
},
|
|
7921
|
-
{
|
|
7922
|
-
id: "pet",
|
|
7923
|
-
packageName: "@michengai/dsh-codex-pet"
|
|
7924
|
-
},
|
|
7925
|
-
{
|
|
7926
|
-
id: "market",
|
|
7927
|
-
packageName: "dshmarket"
|
|
7928
|
-
}
|
|
7929
|
-
];
|
|
7930
|
-
//#endregion
|
|
7931
|
-
//#region src/client/AboutSection.tsx
|
|
7932
|
-
const PROJECT_HOMEPAGES = Object.fromEntries(MANAGED_DEPENDENCIES.map(({ id, packageName }) => [id, id === "market" ? "https://dshmarket.com" : `https://github.com/MichengAI/${packageName.split("/")[1]}`]));
|
|
7933
|
-
const PROGRESS_PHASES = /* @__PURE__ */ new Set([
|
|
7934
|
-
"resolving",
|
|
7935
|
-
"downloading",
|
|
7936
|
-
"linking",
|
|
7937
|
-
"building"
|
|
7938
|
-
]);
|
|
7939
|
-
const endpoint = CODEX_UI_API_ENDPOINTS.dependencies;
|
|
7940
|
-
const stylesheet$2 = `
|
|
7941
|
-
.dcu-about{color:var(--dsw-alias-label-primary)}.dcu-about h2{margin:0;font-size:20px;line-height:28px}.dcu-about-intro{margin:6px 0 22px;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px}.dcu-about h3{margin:24px 0 8px;font-size:14px;line-height:20px}.dcu-about-features{margin:0;padding-left:20px;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:24px}.dcu-about-dependencies-heading{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:24px}.dcu-about-dependencies-heading h3{margin:0}.dcu-about-dependencies-heading+.dcu-about-intro{margin-bottom:14px}.dcu-about-dependencies{overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:10px}.dcu-about-dependency{display:flex;align-items:center;gap:12px;min-height:64px;padding:12px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dcu-about-dependency:last-child{border-bottom:0}.dcu-about-copy{min-width:0;flex:1}.dcu-about-name{font-size:13px;line-height:20px;font-weight:600}.dcu-about-package{overflow:hidden;margin-top:2px;color:var(--dsw-alias-label-tertiary);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.dcu-about-status{display:flex;align-items:center;gap:5px;font-size:12px}.dcu-about-status[data-installed=true]{color:var(--dsw-alias-state-success-primary)}.dcu-about-status[data-installed=false]{color:var(--dsw-alias-state-error-primary)}.dcu-about-status[data-update=true]{color:var(--dsw-alias-state-warning-primary)}.dcu-about-install{display:inline-flex;align-items:center;justify-content:center;gap:5px;min-height:32px;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;padding:6px 9px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;cursor:pointer}.dcu-about-install:hover:not(:disabled){background:var(--dsw-specific-menu-item-hover)}.dcu-about-install:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.dcu-about-install:disabled{cursor:wait;opacity:.65}.dcu-about-update-all{min-width:92px}.dcu-about-message{margin:10px 0 0;border-radius:8px;padding:9px 10px;background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent);color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}.dcu-about-message[data-error=true]{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent);color:var(--dsw-alias-state-error-primary)}.dcu-about-progress{display:grid;grid-template-columns:auto 1fr auto;gap:8px 10px;align-items:center;margin-top:10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:9px 10px}.dcu-about-progress code{min-width:0;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dcu-about-progress-pct{color:var(--dsw-alias-label-tertiary);font-size:12px;font-variant-numeric:tabular-nums}.dcu-about-progress-bar{grid-column:1/-1;height:4px;overflow:hidden;border-radius:99px;background:var(--dsw-alias-border-l2)}.dcu-about-progress-fill{height:100%;background:var(--dsw-alias-state-business-primary);transition:width .2s ease}.dcu-about-progress-fill[data-wave=true]{width:28%;animation:dcu-about-progress-wave 1.2s ease-in-out infinite}@keyframes dcu-about-progress-wave{0%{transform:translateX(-60%)}100%{transform:translateX(280%)}}
|
|
7942
|
-
.dcu-about-title-row{display:flex;align-items:center;gap:8px;min-width:0}.dcu-about-links{display:flex;align-items:center;gap:4px}.dcu-about-external-link{display:inline-flex;align-items:center;gap:5px;min-height:28px;padding:0 8px;color:var(--dsw-alias-label-secondary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;font-size:12px;font-weight:500;line-height:18px;text-decoration:none;white-space:nowrap}.dcu-about-external-link:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dcu-about-external-link:focus-visible{outline:2px solid var(--dsw-alias-state-success-primary);outline-offset:2px}.dcu-about-external-link svg{flex:none}@media(max-width:720px){.dcu-about-title-row{flex-wrap:wrap}}
|
|
7943
|
-
.dcu-about-version{margin-left:8px;color:var(--dsw-alias-label-tertiary);font-family:inherit;font-size:12px;font-weight:500;line-height:18px;letter-spacing:0;white-space:nowrap;vertical-align:baseline}
|
|
7944
|
-
.dcu-about-project-link{color:inherit;text-decoration:none}.dcu-about-project-link:hover{text-decoration:underline;text-underline-offset:3px}.dcu-about-project-link:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px;border-radius:2px}
|
|
7945
|
-
.dcu-about-name-row{display:flex;align-items:center;gap:10px;min-width:0}.dcu-about-name-row .dcu-about-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dcu-about-downloads{display:inline-flex;align-items:center;gap:4px;flex:none;color:var(--dsw-alias-label-secondary);font-size:11px;line-height:20px;font-weight:400;font-variant-numeric:tabular-nums;text-decoration:none;white-space:nowrap}.dcu-about-downloads svg{flex:none;opacity:.75}.dcu-about-downloads:hover{color:var(--dsw-alias-label-primary)}.dcu-about-downloads:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:3px;border-radius:2px}@media(max-width:480px){.dcu-about-dependency{flex-wrap:wrap;gap:8px}.dcu-about-copy{flex-basis:100%}}
|
|
7946
|
-
`;
|
|
7947
|
-
/** 宿主图标库不提供 GitHub 品牌标识,内联后可离线使用并继承当前文字颜色。 */
|
|
7948
|
-
function GithubMark16() {
|
|
7949
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
7950
|
-
viewBox: "0 0 16 16",
|
|
7951
|
-
width: 16,
|
|
7952
|
-
height: 16,
|
|
7953
|
-
"aria-hidden": "true",
|
|
7954
|
-
focusable: "false",
|
|
7955
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
7956
|
-
fill: "currentColor",
|
|
7957
|
-
d: "M8 0a8 8 0 0 0-2.53 15.59c.4.074.547-.173.547-.385 0-.19-.007-.693-.01-1.36-2.226.484-2.695-1.073-2.695-1.073-.364-.924-.89-1.17-.89-1.17-.726-.496.055-.486.055-.486.803.056 1.225.824 1.225.824.714 1.223 1.872.87 2.328.665.072-.517.28-.87.508-1.07-1.777-.202-3.645-.888-3.645-3.956 0-.874.31-1.588.823-2.148-.083-.202-.357-1.017.078-2.12 0 0 .672-.215 2.2.82A7.65 7.65 0 0 1 8 4.8c.68.003 1.365.092 2.004.27 1.527-1.035 2.197-.82 2.197-.82.437 1.103.162 1.918.08 2.12.513.56.822 1.274.822 2.148 0 3.076-1.872 3.752-3.654 3.95.288.248.544.735.544 1.482 0 1.07-.01 1.932-.01 2.195 0 .214.144.463.55.384A8.001 8.001 0 0 0 8 0Z"
|
|
7958
|
-
})
|
|
7959
|
-
});
|
|
7960
|
-
}
|
|
7961
|
-
function isDependencyStatus(value) {
|
|
7962
|
-
if (value === null || typeof value !== "object") return false;
|
|
7963
|
-
const status = value;
|
|
7964
|
-
return MANAGED_DEPENDENCIES.some((dependency) => dependency.id === status.id) && typeof status.packageName === "string" && typeof status.installed === "boolean" && typeof status.updateAvailable === "boolean";
|
|
7965
|
-
}
|
|
7966
|
-
function isInstallProgress(value) {
|
|
7967
|
-
if (value === null || typeof value !== "object") return false;
|
|
7968
|
-
const progress = value;
|
|
7969
|
-
const phase = progress.phase;
|
|
7970
|
-
const total = progress.total;
|
|
7971
|
-
const percent = progress.percent;
|
|
7972
|
-
const currentPackage = progress.currentPackage;
|
|
7973
|
-
return typeof progress.active === "boolean" && typeof progress.target === "string" && typeof progress.seconds === "number" && Number.isInteger(progress.seconds) && progress.seconds >= 0 && typeof progress.lastLine === "string" && (phase === null || typeof phase === "string" && PROGRESS_PHASES.has(phase)) && typeof progress.done === "number" && Number.isInteger(progress.done) && progress.done >= 0 && (total === null || typeof total === "number" && Number.isInteger(total) && total >= 0) && (percent === null || typeof percent === "number" && Number.isFinite(percent) && percent >= 0 && percent <= 100) && (currentPackage === null || typeof currentPackage === "string");
|
|
7974
|
-
}
|
|
7975
|
-
function progressLabel(progress, t) {
|
|
7976
|
-
if (progress.phase !== null) {
|
|
7977
|
-
const current = progress.currentPackage === null || progress.currentPackage === "" ? "" : ` · ${progress.currentPackage}`;
|
|
7978
|
-
const done = progress.done > 0 ? ` · ${t("about.packagesDone").replace("{0}", String(progress.done))}` : "";
|
|
7979
|
-
return `${t(`about.progress.${progress.phase}`)}${current}${done}`;
|
|
7980
|
-
}
|
|
7981
|
-
if (progress.lastLine !== "") return `${progress.lastLine} (${progress.seconds}s)`;
|
|
7982
|
-
return t("about.progressHint");
|
|
7983
|
-
}
|
|
7984
|
-
/** Codex UI 的功能说明、配套管理插件状态与受限安装入口。 */
|
|
7985
|
-
function AboutSection({ t }) {
|
|
7986
|
-
const [dependencies, setDependencies] = (0, react.useState)([]);
|
|
7987
|
-
const [state, setState] = (0, react.useState)("loading");
|
|
7988
|
-
const [installing, setInstalling] = (0, react.useState)();
|
|
7989
|
-
const [progress, setProgress] = (0, react.useState)();
|
|
7990
|
-
const [message, setMessage] = (0, react.useState)();
|
|
7991
|
-
const [refreshFailed, setRefreshFailed] = (0, react.useState)(false);
|
|
7992
|
-
const [loadFailure, setLoadFailure] = (0, react.useState)();
|
|
7993
|
-
const alive = (0, react.useRef)(true);
|
|
7994
|
-
const root = (0, react.useRef)(null);
|
|
7995
|
-
const stateRef = (0, react.useRef)("loading");
|
|
7996
|
-
const requestId = (0, react.useRef)(0);
|
|
7997
|
-
const installingRef = (0, react.useRef)();
|
|
7998
|
-
stateRef.current = state;
|
|
7999
|
-
(0, react.useEffect)(() => {
|
|
8000
|
-
alive.current = true;
|
|
8001
|
-
return () => {
|
|
8002
|
-
alive.current = false;
|
|
8003
|
-
};
|
|
8004
|
-
}, []);
|
|
8005
|
-
const load = (0, react.useCallback)(async (signal) => {
|
|
8006
|
-
const currentRequest = ++requestId.current;
|
|
8007
|
-
if (stateRef.current !== "ready") setState("loading");
|
|
8008
|
-
try {
|
|
8009
|
-
const response = await fetch(endpoint, {
|
|
8010
|
-
cache: "no-store",
|
|
8011
|
-
signal
|
|
8012
|
-
});
|
|
8013
|
-
if (!response.ok) throw new BusinessRequestError(response.status);
|
|
8014
|
-
const payload = await response.json();
|
|
8015
|
-
if (signal?.aborted || currentRequest !== requestId.current) return;
|
|
8016
|
-
if (!Array.isArray(payload.dependencies) || !payload.dependencies.every(isDependencyStatus)) throw new Error();
|
|
8017
|
-
setDependencies(payload.dependencies);
|
|
8018
|
-
setState("ready");
|
|
8019
|
-
setRefreshFailed(false);
|
|
8020
|
-
setLoadFailure(void 0);
|
|
8021
|
-
} catch (error) {
|
|
8022
|
-
if (signal?.aborted || error instanceof DOMException && error.name === "AbortError" || currentRequest !== requestId.current) return;
|
|
8023
|
-
setLoadFailure(error);
|
|
8024
|
-
if (stateRef.current === "ready") setRefreshFailed(true);
|
|
8025
|
-
else setState("failed");
|
|
8026
|
-
}
|
|
8027
|
-
}, []);
|
|
8028
|
-
(0, react.useEffect)(() => {
|
|
8029
|
-
const node = root.current;
|
|
8030
|
-
const controller = new AbortController();
|
|
8031
|
-
const refresh = () => {
|
|
8032
|
-
load(controller.signal);
|
|
8033
|
-
};
|
|
8034
|
-
refresh();
|
|
8035
|
-
if (node === null || typeof IntersectionObserver === "undefined") return () => {
|
|
8036
|
-
controller.abort();
|
|
8037
|
-
};
|
|
8038
|
-
let initialized = false;
|
|
8039
|
-
let wasVisible = false;
|
|
8040
|
-
const observer = new IntersectionObserver((entries) => {
|
|
8041
|
-
const visible = entries.some((entry) => entry.isIntersecting);
|
|
8042
|
-
if (!initialized) {
|
|
8043
|
-
initialized = true;
|
|
8044
|
-
wasVisible = visible;
|
|
8045
|
-
return;
|
|
8046
|
-
}
|
|
8047
|
-
if (visible && !wasVisible) refresh();
|
|
8048
|
-
wasVisible = visible;
|
|
8049
|
-
}, { threshold: .2 });
|
|
8050
|
-
observer.observe(node);
|
|
8051
|
-
return () => {
|
|
8052
|
-
controller.abort();
|
|
8053
|
-
observer.disconnect();
|
|
8054
|
-
};
|
|
8055
|
-
}, [load]);
|
|
8056
|
-
(0, react.useEffect)(() => {
|
|
8057
|
-
if (installing === void 0) {
|
|
8058
|
-
setProgress(void 0);
|
|
8059
|
-
return;
|
|
8060
|
-
}
|
|
8061
|
-
let cancelled = false;
|
|
8062
|
-
const pull = async () => {
|
|
8063
|
-
try {
|
|
8064
|
-
const response = await fetch(`${endpoint}?action=progress`, { cache: "no-store" });
|
|
8065
|
-
const payload = await response.json();
|
|
8066
|
-
if (cancelled || !response.ok || !isInstallProgress(payload.progress)) return;
|
|
8067
|
-
setProgress(payload.progress);
|
|
8068
|
-
} catch {
|
|
8069
|
-
if (!cancelled) return;
|
|
8070
|
-
}
|
|
8071
|
-
};
|
|
8072
|
-
pull();
|
|
8073
|
-
const timer = window.setInterval(() => {
|
|
8074
|
-
pull();
|
|
8075
|
-
}, 800);
|
|
8076
|
-
return () => {
|
|
8077
|
-
cancelled = true;
|
|
8078
|
-
window.clearInterval(timer);
|
|
8079
|
-
};
|
|
8080
|
-
}, [installing]);
|
|
8081
|
-
const install = async (id) => {
|
|
8082
|
-
if (installingRef.current !== void 0) return;
|
|
8083
|
-
installingRef.current = id;
|
|
8084
|
-
setInstalling(id);
|
|
8085
|
-
setMessage(void 0);
|
|
8086
|
-
try {
|
|
8087
|
-
const response = await fetch(`${endpoint}?dependency=${encodeURIComponent(id)}`, { method: "POST" });
|
|
8088
|
-
if ([
|
|
8089
|
-
401,
|
|
8090
|
-
403,
|
|
8091
|
-
503
|
|
8092
|
-
].includes(response.status)) throw new BusinessRequestError(response.status);
|
|
8093
|
-
const payload = await response.json();
|
|
8094
|
-
if (!response.ok || !Array.isArray(payload.dependencies) || !payload.dependencies.every(isDependencyStatus)) throw new Error(typeof payload.error === "string" ? payload.error : t("about.installFailed"));
|
|
8095
|
-
if (!alive.current) return;
|
|
8096
|
-
setDependencies(payload.dependencies);
|
|
8097
|
-
setState("ready");
|
|
8098
|
-
setRefreshFailed(false);
|
|
8099
|
-
setMessage({
|
|
8100
|
-
error: false,
|
|
8101
|
-
text: payload.autoReload === false ? t("about.restartManually") : t("about.restartRequired")
|
|
8102
|
-
});
|
|
8103
|
-
} catch (error) {
|
|
8104
|
-
if (!alive.current) return;
|
|
8105
|
-
setMessage({
|
|
8106
|
-
error: true,
|
|
8107
|
-
text: installErrorText(error, t)
|
|
8108
|
-
});
|
|
8109
|
-
} finally {
|
|
8110
|
-
installingRef.current = void 0;
|
|
8111
|
-
if (alive.current) setInstalling(void 0);
|
|
8112
|
-
}
|
|
8113
|
-
};
|
|
8114
|
-
const updateAll = async () => {
|
|
8115
|
-
if (installingRef.current !== void 0) return;
|
|
8116
|
-
installingRef.current = "all";
|
|
8117
|
-
setInstalling("all");
|
|
8118
|
-
setMessage(void 0);
|
|
8119
|
-
try {
|
|
8120
|
-
const response = await fetch(`${endpoint}?action=update-all`, { method: "POST" });
|
|
8121
|
-
if ([
|
|
8122
|
-
401,
|
|
8123
|
-
403,
|
|
8124
|
-
503
|
|
8125
|
-
].includes(response.status)) throw new BusinessRequestError(response.status);
|
|
8126
|
-
const payload = await response.json();
|
|
8127
|
-
if (!response.ok || !Array.isArray(payload.dependencies) || !payload.dependencies.every(isDependencyStatus)) throw new Error(typeof payload.error === "string" ? payload.error : t("about.installFailed"));
|
|
8128
|
-
if (!alive.current) return;
|
|
8129
|
-
setDependencies(payload.dependencies);
|
|
8130
|
-
setState("ready");
|
|
8131
|
-
setRefreshFailed(false);
|
|
8132
|
-
setMessage({
|
|
8133
|
-
error: false,
|
|
8134
|
-
text: payload.restartRequired === false ? t("about.upToDate") : payload.autoReload === false ? t("about.restartManually") : t("about.restartRequired")
|
|
8135
|
-
});
|
|
8136
|
-
} catch (error) {
|
|
8137
|
-
if (!alive.current) return;
|
|
8138
|
-
setMessage({
|
|
8139
|
-
error: true,
|
|
8140
|
-
text: installErrorText(error, t)
|
|
8141
|
-
});
|
|
8142
|
-
} finally {
|
|
8143
|
-
installingRef.current = void 0;
|
|
8144
|
-
if (alive.current) setInstalling(void 0);
|
|
8145
|
-
}
|
|
8146
|
-
};
|
|
8147
|
-
const actionableCount = dependencies.filter((dependency) => !dependency.installed || dependency.updateAvailable).length;
|
|
8148
|
-
const selfVersion = dependencies.find((dependency) => dependency.id === "ui")?.version;
|
|
8149
|
-
const title = (id) => t(`about.dependency.${id}`);
|
|
8150
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
8151
|
-
ref: root,
|
|
8152
|
-
className: "dcu-about",
|
|
8153
|
-
"aria-label": t("about.nav"),
|
|
8154
|
-
children: [
|
|
8155
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: stylesheet$2 }),
|
|
8156
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8157
|
-
className: "dcu-about-title-row",
|
|
8158
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h2", { children: [t("about.title"), selfVersion === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8159
|
-
className: "dcu-about-version",
|
|
8160
|
-
children: ["v", selfVersion]
|
|
8161
|
-
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8162
|
-
className: "dcu-about-links",
|
|
8163
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
8164
|
-
className: "dcu-about-external-link",
|
|
8165
|
-
href: "https://github.com/MichengAI/dsh-codex-ui",
|
|
8166
|
-
target: "_blank",
|
|
8167
|
-
rel: "noreferrer",
|
|
8168
|
-
"aria-label": t("about.viewProject"),
|
|
8169
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(GithubMark16, {}), t("about.viewProject")]
|
|
8170
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
8171
|
-
className: "dcu-about-external-link",
|
|
8172
|
-
href: "https://github.com/MichengAI/dsh-codex-ui/issues",
|
|
8173
|
-
target: "_blank",
|
|
8174
|
-
rel: "noreferrer",
|
|
8175
|
-
"aria-label": t("about.feedback"),
|
|
8176
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconListPenOutlineMedium, {}), t("about.feedback")]
|
|
8177
|
-
})]
|
|
8178
|
-
})]
|
|
8179
|
-
}),
|
|
8180
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
8181
|
-
className: "dcu-about-intro",
|
|
8182
|
-
children: t("about.description")
|
|
8183
|
-
}),
|
|
8184
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("about.features") }),
|
|
8185
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
|
|
8186
|
-
className: "dcu-about-features",
|
|
8187
|
-
children: [
|
|
8188
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.sidebar") }),
|
|
8189
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.search") }),
|
|
8190
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.workspace") }),
|
|
8191
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.sessions") }),
|
|
8192
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.conversation") }),
|
|
8193
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.navigator") })
|
|
8194
|
-
]
|
|
8195
|
-
}),
|
|
8196
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8197
|
-
className: "dcu-about-dependencies-heading",
|
|
8198
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("about.dependencies") }), state === "ready" && actionableCount > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
8199
|
-
className: "dcu-about-install dcu-about-update-all",
|
|
8200
|
-
type: "button",
|
|
8201
|
-
"aria-busy": installing === "all",
|
|
8202
|
-
disabled: installing !== void 0,
|
|
8203
|
-
onClick: () => {
|
|
8204
|
-
updateAll();
|
|
8205
|
-
},
|
|
8206
|
-
children: [installing === "all" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconLoadingOutlineMedium, { size: 14 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconDownloadOutlineMedium, { size: 14 }), installing === "all" ? t("about.updatingAll") : t("about.updateAll")]
|
|
8207
|
-
})]
|
|
8208
|
-
}),
|
|
8209
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
8210
|
-
className: "dcu-about-intro",
|
|
8211
|
-
children: t("about.dependenciesDescription")
|
|
8212
|
-
}),
|
|
8213
|
-
state === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8214
|
-
className: "dcu-about-message",
|
|
8215
|
-
role: "status",
|
|
8216
|
-
children: t("about.loading")
|
|
8217
|
-
}) : state === "failed" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8218
|
-
className: "dcu-about-message",
|
|
8219
|
-
"data-error": "true",
|
|
8220
|
-
role: "alert",
|
|
8221
|
-
children: t(businessRequestErrorKey(loadFailure) ?? "about.statusFailed")
|
|
8222
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8223
|
-
className: "dcu-about-dependencies",
|
|
8224
|
-
"aria-busy": installing !== void 0,
|
|
8225
|
-
children: dependencies.map((dependency) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
8226
|
-
className: "dcu-about-dependency",
|
|
8227
|
-
children: [
|
|
8228
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8229
|
-
className: "dcu-about-copy",
|
|
8230
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8231
|
-
className: "dcu-about-name-row",
|
|
8232
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
8233
|
-
className: "dcu-about-name dcu-about-project-link",
|
|
8234
|
-
href: PROJECT_HOMEPAGES[dependency.id],
|
|
8235
|
-
target: "_blank",
|
|
8236
|
-
rel: "noreferrer",
|
|
8237
|
-
children: title(dependency.id)
|
|
8238
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
8239
|
-
className: "dcu-about-downloads",
|
|
8240
|
-
href: `https://www.npmjs.com/package/${dependency.packageName}`,
|
|
8241
|
-
target: "_blank",
|
|
8242
|
-
rel: "noreferrer",
|
|
8243
|
-
title: t("about.downloadsSource"),
|
|
8244
|
-
"aria-label": `${dependency.packageName} · ${t("about.totalDownloads")} · ${typeof dependency.totalDownloads === "number" && Number.isSafeInteger(dependency.totalDownloads) && dependency.totalDownloads >= 0 ? dependency.totalDownloads.toLocaleString() : t("about.downloadsUnavailable")}`,
|
|
8245
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconDownloadOutlineMedium, {
|
|
8246
|
-
size: 12,
|
|
8247
|
-
"aria-hidden": "true"
|
|
8248
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8249
|
-
className: "dcu-about-downloads-count",
|
|
8250
|
-
children: typeof dependency.totalDownloads === "number" && Number.isSafeInteger(dependency.totalDownloads) && dependency.totalDownloads >= 0 ? dependency.totalDownloads.toLocaleString() : "—"
|
|
8251
|
-
})]
|
|
8252
|
-
})]
|
|
8253
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8254
|
-
className: "dcu-about-package",
|
|
8255
|
-
title: dependency.packageName,
|
|
8256
|
-
children: [
|
|
8257
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
8258
|
-
className: "dcu-about-project-link",
|
|
8259
|
-
href: PROJECT_HOMEPAGES[dependency.id],
|
|
8260
|
-
target: "_blank",
|
|
8261
|
-
rel: "noreferrer",
|
|
8262
|
-
children: dependency.packageName
|
|
8263
|
-
}),
|
|
8264
|
-
dependency.version === void 0 ? "" : ` · ${dependency.version}`,
|
|
8265
|
-
dependency.updateAvailable && dependency.latestVersion !== void 0 ? ` → ${dependency.latestVersion}` : ""
|
|
8266
|
-
]
|
|
8267
|
-
})]
|
|
8268
|
-
}),
|
|
8269
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8270
|
-
className: "dcu-about-status",
|
|
8271
|
-
"data-installed": dependency.installed,
|
|
8272
|
-
"data-update": dependency.updateAvailable,
|
|
8273
|
-
children: [dependency.installed && !dependency.updateAvailable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCheckOutlineMedium, { size: 14 }), dependency.updateAvailable ? t("about.updateAvailable") : dependency.installed ? t("about.installed") : t("about.missing")]
|
|
8274
|
-
}),
|
|
8275
|
-
(!dependency.installed || dependency.updateAvailable) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
8276
|
-
className: "dcu-about-install",
|
|
8277
|
-
type: "button",
|
|
8278
|
-
disabled: installing !== void 0,
|
|
8279
|
-
onClick: () => {
|
|
8280
|
-
install(dependency.id);
|
|
8281
|
-
},
|
|
8282
|
-
children: [installing === dependency.id ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconLoadingOutlineMedium, { size: 14 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconDownloadOutlineMedium, { size: 14 }), installing === dependency.id ? t("about.installing") : dependency.updateAvailable ? t("about.update") : t("about.install")]
|
|
8283
|
-
})
|
|
8284
|
-
]
|
|
8285
|
-
}, dependency.id))
|
|
8286
|
-
}),
|
|
8287
|
-
installing !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8288
|
-
className: "dcu-about-progress",
|
|
8289
|
-
role: "status",
|
|
8290
|
-
children: [
|
|
8291
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconLoadingOutlineMedium, { size: 14 }) }),
|
|
8292
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: progress === void 0 ? t("about.progressHint") : progressLabel(progress, t) }),
|
|
8293
|
-
progress?.percent !== null && progress?.percent !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8294
|
-
className: "dcu-about-progress-pct",
|
|
8295
|
-
children: [progress.percent, "%"]
|
|
8296
|
-
}),
|
|
8297
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8298
|
-
className: "dcu-about-progress-bar",
|
|
8299
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8300
|
-
className: "dcu-about-progress-fill",
|
|
8301
|
-
"data-wave": progress?.percent === null || progress?.percent === void 0,
|
|
8302
|
-
style: progress?.percent === null || progress?.percent === void 0 ? void 0 : { width: `${progress.percent}%` }
|
|
8303
|
-
})
|
|
8304
|
-
})
|
|
8305
|
-
]
|
|
8306
|
-
}),
|
|
8307
|
-
refreshFailed && state === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8308
|
-
className: "dcu-about-message",
|
|
8309
|
-
"data-error": "true",
|
|
8310
|
-
role: "status",
|
|
8311
|
-
children: t(businessRequestErrorKey(loadFailure) ?? "about.refreshFailed")
|
|
8312
|
-
}),
|
|
8313
|
-
message !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8314
|
-
className: "dcu-about-message",
|
|
8315
|
-
"data-error": message.error,
|
|
8316
|
-
role: message.error ? "alert" : "status",
|
|
8317
|
-
children: message.text
|
|
8318
|
-
})
|
|
8319
|
-
]
|
|
8320
|
-
});
|
|
8321
|
-
}
|
|
8322
|
-
//#endregion
|
|
8323
|
-
//#region src/client/ConnectorsSection.tsx
|
|
8324
|
-
const MCP_CONNECTOR_UI = "/mcp-connector/ui/";
|
|
8325
|
-
const PROMPT_REQUEST_TYPE = "mcp-connector:start-session";
|
|
8326
|
-
const PROMPT_RESULT_TYPE = "mcp-connector:start-session-result";
|
|
8327
|
-
const stylesheet$1 = `
|
|
8328
|
-
.dcu-connectors{color:var(--dsw-alias-label-primary)}.dcu-connectors h2{margin:0;font-size:18px}.dcu-connectors p{margin:6px 0 18px;color:var(--dsw-alias-label-secondary);font-size:12px}.dcu-connector-frame{display:block;width:100%;height:clamp(420px,calc(100vh - 160px),700px);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-base);color-scheme:light dark}.dcu-connector-list{overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:9px}.dcu-connector{padding:12px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dcu-connector:last-child{border-bottom:0}.dcu-connector-head{display:flex;align-items:center;gap:8px;font-weight:650}.dcu-connector-meta{margin:3px 0 8px;color:var(--dsw-alias-label-tertiary);font-size:11px}.dcu-connector-tool{padding:5px 0 0 24px;color:var(--dsw-alias-label-secondary);font-size:12px}.dcu-connector-tool span{display:block;margin-top:1px;color:var(--dsw-alias-label-tertiary);font-size:11px}.dcu-connector-empty{padding:20px 8px;color:var(--dsw-alias-label-secondary);text-align:center}
|
|
8329
|
-
`;
|
|
8330
|
-
const frameLightTheme = `:root{color-scheme:light;--bg:#fff;--card:#fafafa;--line:#e5e5e5;--text:#303030;--text-2:#737373;--muted:#767676;--accent:#303030;--accent-hover:#171717;--accent-light:#e9e9e9;--dcu-action:#303030;--dcu-action-hover:#171717;--dcu-on-action:#fff;--ok:#059669;--ok-bg:#ecfdf5;--warn:#d97706;--warn-bg:#fffbeb;--bad:#dc2626;--bad-bg:#fef2f2;--shadow:0 1px 3px rgba(0,0,0,.08),0 1px 2px rgba(0,0,0,.06);--shadow-lg:0 10px 25px rgba(0,0,0,.1)}`;
|
|
8331
|
-
const frameDarkTheme = `:root{color-scheme:dark;--bg:#181818;--card:#232323;--line:#333;--text:#dedede;--text-2:#a1a1a1;--muted:#929292;--accent:#dedede;--accent-hover:#fff;--accent-light:#303332;--dcu-action:#383838;--dcu-action-hover:#454545;--dcu-on-action:#eee;--ok:#34d399;--ok-bg:#0d3027;--warn:#fbbf24;--warn-bg:#35280b;--bad:#f87171;--bad-bg:#3b171b;--shadow:0 1px 3px rgba(0,0,0,.35);--shadow-lg:0 16px 35px rgba(0,0,0,.45)}`;
|
|
8332
|
-
const frameSurfaceTheme = `
|
|
8333
|
-
.card.featured{border-color:var(--line)}
|
|
8334
|
-
.card:hover,.card.featured:hover{border-color:var(--muted)}
|
|
8335
|
-
.btn:not(.ghost):not(.danger):not(.status-warning):not(.status-bad),.icon-btn.primary,.btn-primary,.prompt-item .send-btn{background:var(--dcu-action);border-color:var(--dcu-action);color:var(--dcu-on-action)}
|
|
8336
|
-
.btn:not(.ghost):not(.danger):not(.status-warning):not(.status-bad):hover,.icon-btn.primary:hover,.btn-primary:hover,.prompt-item .send-btn:hover{background:var(--dcu-action-hover);border-color:var(--dcu-action-hover)}
|
|
8337
|
-
`;
|
|
8338
|
-
function isConnector(value) {
|
|
8339
|
-
if (value === null || typeof value !== "object") return false;
|
|
8340
|
-
const item = value;
|
|
8341
|
-
return typeof item.name === "string" && Array.isArray(item.tools) && item.tools.every((tool) => tool !== null && typeof tool === "object" && typeof tool.name === "string" && typeof tool.description === "string");
|
|
8342
|
-
}
|
|
8343
|
-
function isPromptRequest(value) {
|
|
8344
|
-
if (value === null || typeof value !== "object") return false;
|
|
8345
|
-
const item = value;
|
|
8346
|
-
return item.type === PROMPT_REQUEST_TYPE && typeof item.requestId === "string" && item.requestId !== "" && typeof item.prompt === "string" && item.prompt.trim() !== "";
|
|
8347
|
-
}
|
|
8348
|
-
function syncFrameTheme(frame) {
|
|
8349
|
-
const doc = frame?.contentDocument;
|
|
8350
|
-
if (doc === null || doc === void 0) return;
|
|
8351
|
-
let style = doc.head.querySelector("style[data-michengai-host-theme]");
|
|
8352
|
-
if (style === null) {
|
|
8353
|
-
style = doc.createElement("style");
|
|
8354
|
-
style.dataset.michengaiHostTheme = "true";
|
|
8355
|
-
doc.head.append(style);
|
|
8356
|
-
}
|
|
8357
|
-
style.textContent = (document.body.hasAttribute("data-ds-dark-theme") ? frameDarkTheme : frameLightTheme) + frameSurfaceTheme;
|
|
8358
|
-
}
|
|
8359
|
-
function ConnectorMarket({ startPromptSession, t }) {
|
|
8360
|
-
const frameRef = (0, react.useRef)(null);
|
|
8361
|
-
(0, react.useEffect)(() => {
|
|
8362
|
-
const onMessage = (event) => {
|
|
8363
|
-
const frameWindow = frameRef.current?.contentWindow;
|
|
8364
|
-
if (event.origin !== window.location.origin || frameWindow === null || frameWindow === void 0 || event.source !== frameWindow) return;
|
|
8365
|
-
if (!isPromptRequest(event.data)) return;
|
|
8366
|
-
const { requestId, prompt } = event.data;
|
|
8367
|
-
const reply = (ok, message) => {
|
|
8368
|
-
frameWindow.postMessage({
|
|
8369
|
-
type: PROMPT_RESULT_TYPE,
|
|
8370
|
-
requestId,
|
|
8371
|
-
ok,
|
|
8372
|
-
message
|
|
8373
|
-
}, window.location.origin);
|
|
8374
|
-
};
|
|
8375
|
-
startPromptSession(prompt).then(() => {
|
|
8376
|
-
reply(true, t("connectors.promptReady"));
|
|
8377
|
-
}, (error) => {
|
|
8378
|
-
reply(false, userErrorText(error, t));
|
|
8379
|
-
});
|
|
8380
|
-
};
|
|
8381
|
-
const syncTheme = () => {
|
|
8382
|
-
syncFrameTheme(frameRef.current);
|
|
8383
|
-
};
|
|
8384
|
-
const observer = new MutationObserver(syncTheme);
|
|
8385
|
-
observer.observe(document.body, {
|
|
8386
|
-
attributes: true,
|
|
8387
|
-
attributeFilter: ["data-ds-dark-theme"]
|
|
8388
|
-
});
|
|
8389
|
-
window.addEventListener("message", onMessage);
|
|
8390
|
-
return () => {
|
|
8391
|
-
observer.disconnect();
|
|
8392
|
-
window.removeEventListener("message", onMessage);
|
|
8393
|
-
};
|
|
8394
|
-
}, [startPromptSession, t]);
|
|
8395
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
|
|
8396
|
-
ref: frameRef,
|
|
8397
|
-
className: "dcu-connector-frame",
|
|
8398
|
-
src: MCP_CONNECTOR_UI,
|
|
8399
|
-
title: t("connectors.title"),
|
|
8400
|
-
onLoad: () => {
|
|
8401
|
-
syncFrameTheme(frameRef.current);
|
|
8402
|
-
}
|
|
8403
|
-
});
|
|
8404
|
-
}
|
|
8405
|
-
function NativeConnectorList({ sessionStore, t }) {
|
|
8406
|
-
const sessionId = (0, react.useSyncExternalStore)(sessionStore.subscribe, () => currentSessionId(sessionStore.getSnapshot()));
|
|
8407
|
-
const [connectors, setConnectors] = (0, react.useState)([]);
|
|
8408
|
-
const [state, setState] = (0, react.useState)("loading");
|
|
8409
|
-
const [failure, setFailure] = (0, react.useState)();
|
|
8410
|
-
(0, react.useEffect)(() => {
|
|
8411
|
-
if (sessionId === void 0) {
|
|
8412
|
-
setConnectors([]);
|
|
8413
|
-
setState("ready");
|
|
8414
|
-
return;
|
|
8415
|
-
}
|
|
8416
|
-
const controller = new AbortController();
|
|
8417
|
-
setState("loading");
|
|
8418
|
-
fetch(`${CODEX_UI_API_ENDPOINTS.connectors}?sessionId=${encodeURIComponent(sessionId)}`, { signal: controller.signal }).then(async (response) => {
|
|
8419
|
-
if (!response.ok) throw new BusinessRequestError(response.status);
|
|
8420
|
-
const payload = await response.json();
|
|
8421
|
-
if (!Array.isArray(payload.connectors) || !payload.connectors.every(isConnector)) throw new Error("连接器目录返回格式无效。");
|
|
8422
|
-
if (!controller.signal.aborted) setConnectors(payload.connectors);
|
|
8423
|
-
}).then(() => {
|
|
8424
|
-
if (!controller.signal.aborted) setState("ready");
|
|
8425
|
-
}).catch((error) => {
|
|
8426
|
-
if (!controller.signal.aborted) {
|
|
8427
|
-
setFailure(error);
|
|
8428
|
-
setState("failed");
|
|
8429
|
-
}
|
|
8430
|
-
});
|
|
8431
|
-
return () => {
|
|
8432
|
-
controller.abort();
|
|
8433
|
-
};
|
|
8434
|
-
}, [sessionId]);
|
|
8435
|
-
if (sessionId === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8436
|
-
className: "dcu-connector-empty",
|
|
8437
|
-
children: t("connectors.openSession")
|
|
8438
|
-
});
|
|
8439
|
-
if (state === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8440
|
-
className: "dcu-connector-empty",
|
|
8441
|
-
children: t("connectors.loading")
|
|
8442
|
-
});
|
|
8443
|
-
if (state === "failed") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8444
|
-
className: "dcu-connector-empty",
|
|
8445
|
-
role: "alert",
|
|
8446
|
-
children: t(businessRequestErrorKey(failure) ?? "connectors.failed")
|
|
8447
|
-
});
|
|
8448
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8449
|
-
className: "dcu-connector-list",
|
|
8450
|
-
children: [connectors.map((connector) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
8451
|
-
className: "dcu-connector",
|
|
8452
|
-
children: [
|
|
8453
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8454
|
-
className: "dcu-connector-head",
|
|
8455
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconLinkOutlineMedium, { size: 16 }), connector.name]
|
|
8456
|
-
}),
|
|
8457
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8458
|
-
className: "dcu-connector-meta",
|
|
8459
|
-
children: t("connectors.toolCount", { count: connector.tools.length })
|
|
8460
|
-
}),
|
|
8461
|
-
connector.tools.map((tool) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8462
|
-
className: "dcu-connector-tool",
|
|
8463
|
-
children: [tool.name, tool.description !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tool.description })]
|
|
8464
|
-
}, tool.name))
|
|
8465
|
-
]
|
|
8466
|
-
}, connector.name)), connectors.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8467
|
-
className: "dcu-connector-empty",
|
|
8468
|
-
children: t("connectors.empty")
|
|
8469
|
-
})]
|
|
8470
|
-
});
|
|
8471
|
-
}
|
|
8472
|
-
/** 安装 dsh-mcp-connector 时显示完整市场,否则回退到当前会话的 MCP 工具目录。 */
|
|
8473
|
-
function ConnectorsSection({ sessionStore, startPromptSession, t }) {
|
|
8474
|
-
const [marketAvailable, setMarketAvailable] = (0, react.useState)();
|
|
8475
|
-
(0, react.useEffect)(() => {
|
|
8476
|
-
const controller = new AbortController();
|
|
8477
|
-
fetch(MCP_CONNECTOR_UI, {
|
|
8478
|
-
method: "GET",
|
|
8479
|
-
cache: "no-store",
|
|
8480
|
-
signal: controller.signal
|
|
8481
|
-
}).then((response) => {
|
|
8482
|
-
response.body?.cancel().catch(() => {});
|
|
8483
|
-
if (!controller.signal.aborted) setMarketAvailable(response.ok);
|
|
8484
|
-
}).catch(() => {
|
|
8485
|
-
if (!controller.signal.aborted) setMarketAvailable(false);
|
|
8486
|
-
});
|
|
8487
|
-
return () => {
|
|
8488
|
-
controller.abort();
|
|
8489
|
-
};
|
|
8490
|
-
}, []);
|
|
8491
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
8492
|
-
className: "dcu-connectors",
|
|
8493
|
-
"aria-label": t("connectors.title"),
|
|
8494
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: stylesheet$1 }), marketAvailable === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8495
|
-
className: "dcu-connector-empty",
|
|
8496
|
-
children: t("connectors.loading")
|
|
8497
|
-
}) : marketAvailable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConnectorMarket, {
|
|
8498
|
-
startPromptSession,
|
|
8499
|
-
t
|
|
8500
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
8501
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: t("connectors.title") }),
|
|
8502
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("connectors.description") }),
|
|
8503
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NativeConnectorList, {
|
|
8504
|
-
sessionStore,
|
|
8505
|
-
t
|
|
8506
|
-
})
|
|
8507
|
-
] })]
|
|
8508
|
-
});
|
|
8509
|
-
}
|
|
8510
|
-
//#endregion
|
|
8511
7890
|
//#region src/client/locales.ts
|
|
8512
7891
|
/** 本插件独占的界面文案命名空间。 */
|
|
8513
7892
|
const NS = "michengai.codexUi";
|
|
@@ -9079,6 +8458,688 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
9079
8458
|
"sessionTitle.type.research": "Research",
|
|
9080
8459
|
"meta.locale": "en-US"
|
|
9081
8460
|
};
|
|
8461
|
+
//#endregion
|
|
8462
|
+
//#region src/client/SidebarExpandControl.tsx
|
|
8463
|
+
const SIDEBAR_EXPAND_STYLE = `
|
|
8464
|
+
.dcu-shell-expand{appearance:none;border:0;background:transparent;color:var(--dsw-alias-label-secondary);display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border-radius:50%;cursor:pointer;-webkit-app-region:no-drag}
|
|
8465
|
+
.dcu-shell-expand svg{display:block;width:16px;height:16px}
|
|
8466
|
+
.dcu-shell-expand:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
8467
|
+
.dcu-shell-expand:focus-visible{outline:2px solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:-2px}
|
|
8468
|
+
.dcu-shell-expand-windows{display:none;position:fixed;left:12px;top:calc((var(--dsh-windows-titlebar-height,40px) - 28px) / 2);z-index:30}
|
|
8469
|
+
html[data-windows-titlebar] [data-sidebar-collapsed] [data-shell-overlay] .dcu-shell-expand-windows{display:inline-flex}
|
|
8470
|
+
html[data-windows-titlebar]:has([data-sidebar-collapsed] .dcu-shell-expand-windows){--dsh-windows-menu-start:48px}
|
|
8471
|
+
html[data-windows-titlebar][data-fullscreen] .dcu-shell-expand-windows{top:3px}
|
|
8472
|
+
html[data-windows-titlebar][data-fullscreen] [data-sidebar-collapsed]{--dsh-frame-leading-clearance:60px}
|
|
8473
|
+
html[data-windows-titlebar][data-fullscreen] [data-sidebar-collapsed] header:has([data-dcu-inline-tabs]){padding-inline-start:60px}
|
|
8474
|
+
`;
|
|
8475
|
+
/** The host mounts shell.leading only for a collapsed macOS sidebar. Windows
|
|
8476
|
+
* uses shell.overlay so the caption button survives the zero-width column. */
|
|
8477
|
+
function SidebarExpandControl({ toggleSidebar, t, windows = false }) {
|
|
8478
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: SIDEBAR_EXPAND_STYLE }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8479
|
+
type: "button",
|
|
8480
|
+
className: `dcu-shell-expand${windows ? " dcu-shell-expand-windows" : ""}`,
|
|
8481
|
+
"aria-label": t("sidebar.expand"),
|
|
8482
|
+
onClick: toggleSidebar,
|
|
8483
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconPanelLeftOutlineMedium, { size: 16 })
|
|
8484
|
+
})] });
|
|
8485
|
+
}
|
|
8486
|
+
function registerSidebarExpandControls(ctx) {
|
|
8487
|
+
ctx.slots.inject("shell.leading", () => ctx.slots.register({
|
|
8488
|
+
name: "shell.leading",
|
|
8489
|
+
registrant: "michengai-codex-ui",
|
|
8490
|
+
locale: NS,
|
|
8491
|
+
inject: () => ({
|
|
8492
|
+
toggleSidebar: () => {
|
|
8493
|
+
ctx.layout.toggleSidebar();
|
|
8494
|
+
},
|
|
8495
|
+
windows: false
|
|
8496
|
+
})
|
|
8497
|
+
}, SidebarExpandControl));
|
|
8498
|
+
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
8499
|
+
name: "shell.overlay",
|
|
8500
|
+
id: "michengai-codex-ui-sidebar-expand",
|
|
8501
|
+
registrant: "michengai-codex-ui",
|
|
8502
|
+
locale: NS,
|
|
8503
|
+
inject: () => ({
|
|
8504
|
+
toggleSidebar: () => {
|
|
8505
|
+
ctx.layout.toggleSidebar();
|
|
8506
|
+
},
|
|
8507
|
+
windows: true
|
|
8508
|
+
})
|
|
8509
|
+
}, SidebarExpandControl));
|
|
8510
|
+
}
|
|
8511
|
+
//#endregion
|
|
8512
|
+
//#region src/dependencies.ts
|
|
8513
|
+
const MANAGED_DEPENDENCIES = [
|
|
8514
|
+
{
|
|
8515
|
+
id: "ui",
|
|
8516
|
+
packageName: "@michengai/dsh-codex-ui"
|
|
8517
|
+
},
|
|
8518
|
+
{
|
|
8519
|
+
id: "experts",
|
|
8520
|
+
packageName: "@michengai/dsh-agency-agents"
|
|
8521
|
+
},
|
|
8522
|
+
{
|
|
8523
|
+
id: "skills",
|
|
8524
|
+
packageName: "@michengai/dsh-skills-manager"
|
|
8525
|
+
},
|
|
8526
|
+
{
|
|
8527
|
+
id: "archive",
|
|
8528
|
+
packageName: "@michengai/dsh-archive-manager"
|
|
8529
|
+
},
|
|
8530
|
+
{
|
|
8531
|
+
id: "im",
|
|
8532
|
+
packageName: "@michengai/dsh-im-connect"
|
|
8533
|
+
},
|
|
8534
|
+
{
|
|
8535
|
+
id: "schedule",
|
|
8536
|
+
packageName: "@michengai/dsh-automation"
|
|
8537
|
+
},
|
|
8538
|
+
{
|
|
8539
|
+
id: "btw",
|
|
8540
|
+
packageName: "@michengai/dsh-btw"
|
|
8541
|
+
},
|
|
8542
|
+
{
|
|
8543
|
+
id: "simplify",
|
|
8544
|
+
packageName: "@michengai/dsh-simplify"
|
|
8545
|
+
},
|
|
8546
|
+
{
|
|
8547
|
+
id: "pua",
|
|
8548
|
+
packageName: "@michengai/dsh-pua"
|
|
8549
|
+
},
|
|
8550
|
+
{
|
|
8551
|
+
id: "review",
|
|
8552
|
+
packageName: "@michengai/dsh-code-review"
|
|
8553
|
+
},
|
|
8554
|
+
{
|
|
8555
|
+
id: "pet",
|
|
8556
|
+
packageName: "@michengai/dsh-codex-pet"
|
|
8557
|
+
},
|
|
8558
|
+
{
|
|
8559
|
+
id: "market",
|
|
8560
|
+
packageName: "dshmarket"
|
|
8561
|
+
}
|
|
8562
|
+
];
|
|
8563
|
+
//#endregion
|
|
8564
|
+
//#region src/client/AboutSection.tsx
|
|
8565
|
+
const PROJECT_HOMEPAGES = Object.fromEntries(MANAGED_DEPENDENCIES.map(({ id, packageName }) => [id, id === "market" ? "https://dshmarket.com" : `https://github.com/MichengAI/${packageName.split("/")[1]}`]));
|
|
8566
|
+
const PROGRESS_PHASES = /* @__PURE__ */ new Set([
|
|
8567
|
+
"resolving",
|
|
8568
|
+
"downloading",
|
|
8569
|
+
"linking",
|
|
8570
|
+
"building"
|
|
8571
|
+
]);
|
|
8572
|
+
const endpoint = CODEX_UI_API_ENDPOINTS.dependencies;
|
|
8573
|
+
const stylesheet$2 = `
|
|
8574
|
+
.dcu-about{color:var(--dsw-alias-label-primary)}.dcu-about h2{margin:0;font-size:20px;line-height:28px}.dcu-about-intro{margin:6px 0 22px;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px}.dcu-about h3{margin:24px 0 8px;font-size:14px;line-height:20px}.dcu-about-features{margin:0;padding-left:20px;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:24px}.dcu-about-dependencies-heading{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:24px}.dcu-about-dependencies-heading h3{margin:0}.dcu-about-dependencies-heading+.dcu-about-intro{margin-bottom:14px}.dcu-about-dependencies{overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:10px}.dcu-about-dependency{display:flex;align-items:center;gap:12px;min-height:64px;padding:12px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dcu-about-dependency:last-child{border-bottom:0}.dcu-about-copy{min-width:0;flex:1}.dcu-about-name{font-size:13px;line-height:20px;font-weight:600}.dcu-about-package{overflow:hidden;margin-top:2px;color:var(--dsw-alias-label-tertiary);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.dcu-about-status{display:flex;align-items:center;gap:5px;font-size:12px}.dcu-about-status[data-installed=true]{color:var(--dsw-alias-state-success-primary)}.dcu-about-status[data-installed=false]{color:var(--dsw-alias-state-error-primary)}.dcu-about-status[data-update=true]{color:var(--dsw-alias-state-warning-primary)}.dcu-about-install{display:inline-flex;align-items:center;justify-content:center;gap:5px;min-height:32px;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;padding:6px 9px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;cursor:pointer}.dcu-about-install:hover:not(:disabled){background:var(--dsw-specific-menu-item-hover)}.dcu-about-install:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.dcu-about-install:disabled{cursor:wait;opacity:.65}.dcu-about-update-all{min-width:92px}.dcu-about-message{margin:10px 0 0;border-radius:8px;padding:9px 10px;background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent);color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}.dcu-about-message[data-error=true]{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent);color:var(--dsw-alias-state-error-primary)}.dcu-about-progress{display:grid;grid-template-columns:auto 1fr auto;gap:8px 10px;align-items:center;margin-top:10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:9px 10px}.dcu-about-progress code{min-width:0;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dcu-about-progress-pct{color:var(--dsw-alias-label-tertiary);font-size:12px;font-variant-numeric:tabular-nums}.dcu-about-progress-bar{grid-column:1/-1;height:4px;overflow:hidden;border-radius:99px;background:var(--dsw-alias-border-l2)}.dcu-about-progress-fill{height:100%;background:var(--dsw-alias-state-business-primary);transition:width .2s ease}.dcu-about-progress-fill[data-wave=true]{width:28%;animation:dcu-about-progress-wave 1.2s ease-in-out infinite}@keyframes dcu-about-progress-wave{0%{transform:translateX(-60%)}100%{transform:translateX(280%)}}
|
|
8575
|
+
.dcu-about-title-row{display:flex;align-items:center;gap:8px;min-width:0}.dcu-about-links{display:flex;align-items:center;gap:4px}.dcu-about-external-link{display:inline-flex;align-items:center;gap:5px;min-height:28px;padding:0 8px;color:var(--dsw-alias-label-secondary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;font-size:12px;font-weight:500;line-height:18px;text-decoration:none;white-space:nowrap}.dcu-about-external-link:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dcu-about-external-link:focus-visible{outline:2px solid var(--dsw-alias-state-success-primary);outline-offset:2px}.dcu-about-external-link svg{flex:none}@media(max-width:720px){.dcu-about-title-row{flex-wrap:wrap}}
|
|
8576
|
+
.dcu-about-version{margin-left:8px;color:var(--dsw-alias-label-tertiary);font-family:inherit;font-size:12px;font-weight:500;line-height:18px;letter-spacing:0;white-space:nowrap;vertical-align:baseline}
|
|
8577
|
+
.dcu-about-project-link{color:inherit;text-decoration:none}.dcu-about-project-link:hover{text-decoration:underline;text-underline-offset:3px}.dcu-about-project-link:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px;border-radius:2px}
|
|
8578
|
+
.dcu-about-name-row{display:flex;align-items:center;gap:10px;min-width:0}.dcu-about-name-row .dcu-about-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dcu-about-downloads{display:inline-flex;align-items:center;gap:4px;flex:none;color:var(--dsw-alias-label-secondary);font-size:11px;line-height:20px;font-weight:400;font-variant-numeric:tabular-nums;text-decoration:none;white-space:nowrap}.dcu-about-downloads svg{flex:none;opacity:.75}.dcu-about-downloads:hover{color:var(--dsw-alias-label-primary)}.dcu-about-downloads:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:3px;border-radius:2px}@media(max-width:480px){.dcu-about-dependency{flex-wrap:wrap;gap:8px}.dcu-about-copy{flex-basis:100%}}
|
|
8579
|
+
`;
|
|
8580
|
+
/** 宿主图标库不提供 GitHub 品牌标识,内联后可离线使用并继承当前文字颜色。 */
|
|
8581
|
+
function GithubMark16() {
|
|
8582
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
8583
|
+
viewBox: "0 0 16 16",
|
|
8584
|
+
width: 16,
|
|
8585
|
+
height: 16,
|
|
8586
|
+
"aria-hidden": "true",
|
|
8587
|
+
focusable: "false",
|
|
8588
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
8589
|
+
fill: "currentColor",
|
|
8590
|
+
d: "M8 0a8 8 0 0 0-2.53 15.59c.4.074.547-.173.547-.385 0-.19-.007-.693-.01-1.36-2.226.484-2.695-1.073-2.695-1.073-.364-.924-.89-1.17-.89-1.17-.726-.496.055-.486.055-.486.803.056 1.225.824 1.225.824.714 1.223 1.872.87 2.328.665.072-.517.28-.87.508-1.07-1.777-.202-3.645-.888-3.645-3.956 0-.874.31-1.588.823-2.148-.083-.202-.357-1.017.078-2.12 0 0 .672-.215 2.2.82A7.65 7.65 0 0 1 8 4.8c.68.003 1.365.092 2.004.27 1.527-1.035 2.197-.82 2.197-.82.437 1.103.162 1.918.08 2.12.513.56.822 1.274.822 2.148 0 3.076-1.872 3.752-3.654 3.95.288.248.544.735.544 1.482 0 1.07-.01 1.932-.01 2.195 0 .214.144.463.55.384A8.001 8.001 0 0 0 8 0Z"
|
|
8591
|
+
})
|
|
8592
|
+
});
|
|
8593
|
+
}
|
|
8594
|
+
function isDependencyStatus(value) {
|
|
8595
|
+
if (value === null || typeof value !== "object") return false;
|
|
8596
|
+
const status = value;
|
|
8597
|
+
return MANAGED_DEPENDENCIES.some((dependency) => dependency.id === status.id) && typeof status.packageName === "string" && typeof status.installed === "boolean" && typeof status.updateAvailable === "boolean";
|
|
8598
|
+
}
|
|
8599
|
+
function isInstallProgress(value) {
|
|
8600
|
+
if (value === null || typeof value !== "object") return false;
|
|
8601
|
+
const progress = value;
|
|
8602
|
+
const phase = progress.phase;
|
|
8603
|
+
const total = progress.total;
|
|
8604
|
+
const percent = progress.percent;
|
|
8605
|
+
const currentPackage = progress.currentPackage;
|
|
8606
|
+
return typeof progress.active === "boolean" && typeof progress.target === "string" && typeof progress.seconds === "number" && Number.isInteger(progress.seconds) && progress.seconds >= 0 && typeof progress.lastLine === "string" && (phase === null || typeof phase === "string" && PROGRESS_PHASES.has(phase)) && typeof progress.done === "number" && Number.isInteger(progress.done) && progress.done >= 0 && (total === null || typeof total === "number" && Number.isInteger(total) && total >= 0) && (percent === null || typeof percent === "number" && Number.isFinite(percent) && percent >= 0 && percent <= 100) && (currentPackage === null || typeof currentPackage === "string");
|
|
8607
|
+
}
|
|
8608
|
+
function progressLabel(progress, t) {
|
|
8609
|
+
if (progress.phase !== null) {
|
|
8610
|
+
const current = progress.currentPackage === null || progress.currentPackage === "" ? "" : ` · ${progress.currentPackage}`;
|
|
8611
|
+
const done = progress.done > 0 ? ` · ${t("about.packagesDone").replace("{0}", String(progress.done))}` : "";
|
|
8612
|
+
return `${t(`about.progress.${progress.phase}`)}${current}${done}`;
|
|
8613
|
+
}
|
|
8614
|
+
if (progress.lastLine !== "") return `${progress.lastLine} (${progress.seconds}s)`;
|
|
8615
|
+
return t("about.progressHint");
|
|
8616
|
+
}
|
|
8617
|
+
/** Codex UI 的功能说明、配套管理插件状态与受限安装入口。 */
|
|
8618
|
+
function AboutSection({ t }) {
|
|
8619
|
+
const [dependencies, setDependencies] = (0, react.useState)([]);
|
|
8620
|
+
const [state, setState] = (0, react.useState)("loading");
|
|
8621
|
+
const [installing, setInstalling] = (0, react.useState)();
|
|
8622
|
+
const [progress, setProgress] = (0, react.useState)();
|
|
8623
|
+
const [message, setMessage] = (0, react.useState)();
|
|
8624
|
+
const [refreshFailed, setRefreshFailed] = (0, react.useState)(false);
|
|
8625
|
+
const [loadFailure, setLoadFailure] = (0, react.useState)();
|
|
8626
|
+
const alive = (0, react.useRef)(true);
|
|
8627
|
+
const root = (0, react.useRef)(null);
|
|
8628
|
+
const stateRef = (0, react.useRef)("loading");
|
|
8629
|
+
const requestId = (0, react.useRef)(0);
|
|
8630
|
+
const installingRef = (0, react.useRef)();
|
|
8631
|
+
stateRef.current = state;
|
|
8632
|
+
(0, react.useEffect)(() => {
|
|
8633
|
+
alive.current = true;
|
|
8634
|
+
return () => {
|
|
8635
|
+
alive.current = false;
|
|
8636
|
+
};
|
|
8637
|
+
}, []);
|
|
8638
|
+
const load = (0, react.useCallback)(async (signal) => {
|
|
8639
|
+
const currentRequest = ++requestId.current;
|
|
8640
|
+
if (stateRef.current !== "ready") setState("loading");
|
|
8641
|
+
try {
|
|
8642
|
+
const response = await fetch(endpoint, {
|
|
8643
|
+
cache: "no-store",
|
|
8644
|
+
signal
|
|
8645
|
+
});
|
|
8646
|
+
if (!response.ok) throw new BusinessRequestError(response.status);
|
|
8647
|
+
const payload = await response.json();
|
|
8648
|
+
if (signal?.aborted || currentRequest !== requestId.current) return;
|
|
8649
|
+
if (!Array.isArray(payload.dependencies) || !payload.dependencies.every(isDependencyStatus)) throw new Error();
|
|
8650
|
+
setDependencies(payload.dependencies);
|
|
8651
|
+
setState("ready");
|
|
8652
|
+
setRefreshFailed(false);
|
|
8653
|
+
setLoadFailure(void 0);
|
|
8654
|
+
} catch (error) {
|
|
8655
|
+
if (signal?.aborted || error instanceof DOMException && error.name === "AbortError" || currentRequest !== requestId.current) return;
|
|
8656
|
+
setLoadFailure(error);
|
|
8657
|
+
if (stateRef.current === "ready") setRefreshFailed(true);
|
|
8658
|
+
else setState("failed");
|
|
8659
|
+
}
|
|
8660
|
+
}, []);
|
|
8661
|
+
(0, react.useEffect)(() => {
|
|
8662
|
+
const node = root.current;
|
|
8663
|
+
const controller = new AbortController();
|
|
8664
|
+
const refresh = () => {
|
|
8665
|
+
load(controller.signal);
|
|
8666
|
+
};
|
|
8667
|
+
refresh();
|
|
8668
|
+
if (node === null || typeof IntersectionObserver === "undefined") return () => {
|
|
8669
|
+
controller.abort();
|
|
8670
|
+
};
|
|
8671
|
+
let initialized = false;
|
|
8672
|
+
let wasVisible = false;
|
|
8673
|
+
const observer = new IntersectionObserver((entries) => {
|
|
8674
|
+
const visible = entries.some((entry) => entry.isIntersecting);
|
|
8675
|
+
if (!initialized) {
|
|
8676
|
+
initialized = true;
|
|
8677
|
+
wasVisible = visible;
|
|
8678
|
+
return;
|
|
8679
|
+
}
|
|
8680
|
+
if (visible && !wasVisible) refresh();
|
|
8681
|
+
wasVisible = visible;
|
|
8682
|
+
}, { threshold: .2 });
|
|
8683
|
+
observer.observe(node);
|
|
8684
|
+
return () => {
|
|
8685
|
+
controller.abort();
|
|
8686
|
+
observer.disconnect();
|
|
8687
|
+
};
|
|
8688
|
+
}, [load]);
|
|
8689
|
+
(0, react.useEffect)(() => {
|
|
8690
|
+
if (installing === void 0) {
|
|
8691
|
+
setProgress(void 0);
|
|
8692
|
+
return;
|
|
8693
|
+
}
|
|
8694
|
+
let cancelled = false;
|
|
8695
|
+
const pull = async () => {
|
|
8696
|
+
try {
|
|
8697
|
+
const response = await fetch(`${endpoint}?action=progress`, { cache: "no-store" });
|
|
8698
|
+
const payload = await response.json();
|
|
8699
|
+
if (cancelled || !response.ok || !isInstallProgress(payload.progress)) return;
|
|
8700
|
+
setProgress(payload.progress);
|
|
8701
|
+
} catch {
|
|
8702
|
+
if (!cancelled) return;
|
|
8703
|
+
}
|
|
8704
|
+
};
|
|
8705
|
+
pull();
|
|
8706
|
+
const timer = window.setInterval(() => {
|
|
8707
|
+
pull();
|
|
8708
|
+
}, 800);
|
|
8709
|
+
return () => {
|
|
8710
|
+
cancelled = true;
|
|
8711
|
+
window.clearInterval(timer);
|
|
8712
|
+
};
|
|
8713
|
+
}, [installing]);
|
|
8714
|
+
const install = async (id) => {
|
|
8715
|
+
if (installingRef.current !== void 0) return;
|
|
8716
|
+
installingRef.current = id;
|
|
8717
|
+
setInstalling(id);
|
|
8718
|
+
setMessage(void 0);
|
|
8719
|
+
try {
|
|
8720
|
+
const response = await fetch(`${endpoint}?dependency=${encodeURIComponent(id)}`, { method: "POST" });
|
|
8721
|
+
if ([
|
|
8722
|
+
401,
|
|
8723
|
+
403,
|
|
8724
|
+
503
|
|
8725
|
+
].includes(response.status)) throw new BusinessRequestError(response.status);
|
|
8726
|
+
const payload = await response.json();
|
|
8727
|
+
if (!response.ok || !Array.isArray(payload.dependencies) || !payload.dependencies.every(isDependencyStatus)) throw new Error(typeof payload.error === "string" ? payload.error : t("about.installFailed"));
|
|
8728
|
+
if (!alive.current) return;
|
|
8729
|
+
setDependencies(payload.dependencies);
|
|
8730
|
+
setState("ready");
|
|
8731
|
+
setRefreshFailed(false);
|
|
8732
|
+
setMessage({
|
|
8733
|
+
error: false,
|
|
8734
|
+
text: payload.autoReload === false ? t("about.restartManually") : t("about.restartRequired")
|
|
8735
|
+
});
|
|
8736
|
+
} catch (error) {
|
|
8737
|
+
if (!alive.current) return;
|
|
8738
|
+
setMessage({
|
|
8739
|
+
error: true,
|
|
8740
|
+
text: installErrorText(error, t)
|
|
8741
|
+
});
|
|
8742
|
+
} finally {
|
|
8743
|
+
installingRef.current = void 0;
|
|
8744
|
+
if (alive.current) setInstalling(void 0);
|
|
8745
|
+
}
|
|
8746
|
+
};
|
|
8747
|
+
const updateAll = async () => {
|
|
8748
|
+
if (installingRef.current !== void 0) return;
|
|
8749
|
+
installingRef.current = "all";
|
|
8750
|
+
setInstalling("all");
|
|
8751
|
+
setMessage(void 0);
|
|
8752
|
+
try {
|
|
8753
|
+
const response = await fetch(`${endpoint}?action=update-all`, { method: "POST" });
|
|
8754
|
+
if ([
|
|
8755
|
+
401,
|
|
8756
|
+
403,
|
|
8757
|
+
503
|
|
8758
|
+
].includes(response.status)) throw new BusinessRequestError(response.status);
|
|
8759
|
+
const payload = await response.json();
|
|
8760
|
+
if (!response.ok || !Array.isArray(payload.dependencies) || !payload.dependencies.every(isDependencyStatus)) throw new Error(typeof payload.error === "string" ? payload.error : t("about.installFailed"));
|
|
8761
|
+
if (!alive.current) return;
|
|
8762
|
+
setDependencies(payload.dependencies);
|
|
8763
|
+
setState("ready");
|
|
8764
|
+
setRefreshFailed(false);
|
|
8765
|
+
setMessage({
|
|
8766
|
+
error: false,
|
|
8767
|
+
text: payload.restartRequired === false ? t("about.upToDate") : payload.autoReload === false ? t("about.restartManually") : t("about.restartRequired")
|
|
8768
|
+
});
|
|
8769
|
+
} catch (error) {
|
|
8770
|
+
if (!alive.current) return;
|
|
8771
|
+
setMessage({
|
|
8772
|
+
error: true,
|
|
8773
|
+
text: installErrorText(error, t)
|
|
8774
|
+
});
|
|
8775
|
+
} finally {
|
|
8776
|
+
installingRef.current = void 0;
|
|
8777
|
+
if (alive.current) setInstalling(void 0);
|
|
8778
|
+
}
|
|
8779
|
+
};
|
|
8780
|
+
const actionableCount = dependencies.filter((dependency) => !dependency.installed || dependency.updateAvailable).length;
|
|
8781
|
+
const selfVersion = dependencies.find((dependency) => dependency.id === "ui")?.version;
|
|
8782
|
+
const title = (id) => t(`about.dependency.${id}`);
|
|
8783
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
8784
|
+
ref: root,
|
|
8785
|
+
className: "dcu-about",
|
|
8786
|
+
"aria-label": t("about.nav"),
|
|
8787
|
+
children: [
|
|
8788
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: stylesheet$2 }),
|
|
8789
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8790
|
+
className: "dcu-about-title-row",
|
|
8791
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h2", { children: [t("about.title"), selfVersion === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8792
|
+
className: "dcu-about-version",
|
|
8793
|
+
children: ["v", selfVersion]
|
|
8794
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8795
|
+
className: "dcu-about-links",
|
|
8796
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
8797
|
+
className: "dcu-about-external-link",
|
|
8798
|
+
href: "https://github.com/MichengAI/dsh-codex-ui",
|
|
8799
|
+
target: "_blank",
|
|
8800
|
+
rel: "noreferrer",
|
|
8801
|
+
"aria-label": t("about.viewProject"),
|
|
8802
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(GithubMark16, {}), t("about.viewProject")]
|
|
8803
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
8804
|
+
className: "dcu-about-external-link",
|
|
8805
|
+
href: "https://github.com/MichengAI/dsh-codex-ui/issues",
|
|
8806
|
+
target: "_blank",
|
|
8807
|
+
rel: "noreferrer",
|
|
8808
|
+
"aria-label": t("about.feedback"),
|
|
8809
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconListPenOutlineMedium, {}), t("about.feedback")]
|
|
8810
|
+
})]
|
|
8811
|
+
})]
|
|
8812
|
+
}),
|
|
8813
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
8814
|
+
className: "dcu-about-intro",
|
|
8815
|
+
children: t("about.description")
|
|
8816
|
+
}),
|
|
8817
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("about.features") }),
|
|
8818
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
|
|
8819
|
+
className: "dcu-about-features",
|
|
8820
|
+
children: [
|
|
8821
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.sidebar") }),
|
|
8822
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.search") }),
|
|
8823
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.workspace") }),
|
|
8824
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.sessions") }),
|
|
8825
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.conversation") }),
|
|
8826
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t("about.feature.navigator") })
|
|
8827
|
+
]
|
|
8828
|
+
}),
|
|
8829
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8830
|
+
className: "dcu-about-dependencies-heading",
|
|
8831
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("about.dependencies") }), state === "ready" && actionableCount > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
8832
|
+
className: "dcu-about-install dcu-about-update-all",
|
|
8833
|
+
type: "button",
|
|
8834
|
+
"aria-busy": installing === "all",
|
|
8835
|
+
disabled: installing !== void 0,
|
|
8836
|
+
onClick: () => {
|
|
8837
|
+
updateAll();
|
|
8838
|
+
},
|
|
8839
|
+
children: [installing === "all" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconLoadingOutlineMedium, { size: 14 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconDownloadOutlineMedium, { size: 14 }), installing === "all" ? t("about.updatingAll") : t("about.updateAll")]
|
|
8840
|
+
})]
|
|
8841
|
+
}),
|
|
8842
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
8843
|
+
className: "dcu-about-intro",
|
|
8844
|
+
children: t("about.dependenciesDescription")
|
|
8845
|
+
}),
|
|
8846
|
+
state === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8847
|
+
className: "dcu-about-message",
|
|
8848
|
+
role: "status",
|
|
8849
|
+
children: t("about.loading")
|
|
8850
|
+
}) : state === "failed" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8851
|
+
className: "dcu-about-message",
|
|
8852
|
+
"data-error": "true",
|
|
8853
|
+
role: "alert",
|
|
8854
|
+
children: t(businessRequestErrorKey(loadFailure) ?? "about.statusFailed")
|
|
8855
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8856
|
+
className: "dcu-about-dependencies",
|
|
8857
|
+
"aria-busy": installing !== void 0,
|
|
8858
|
+
children: dependencies.map((dependency) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
8859
|
+
className: "dcu-about-dependency",
|
|
8860
|
+
children: [
|
|
8861
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8862
|
+
className: "dcu-about-copy",
|
|
8863
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8864
|
+
className: "dcu-about-name-row",
|
|
8865
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
8866
|
+
className: "dcu-about-name dcu-about-project-link",
|
|
8867
|
+
href: PROJECT_HOMEPAGES[dependency.id],
|
|
8868
|
+
target: "_blank",
|
|
8869
|
+
rel: "noreferrer",
|
|
8870
|
+
children: title(dependency.id)
|
|
8871
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
8872
|
+
className: "dcu-about-downloads",
|
|
8873
|
+
href: `https://www.npmjs.com/package/${dependency.packageName}`,
|
|
8874
|
+
target: "_blank",
|
|
8875
|
+
rel: "noreferrer",
|
|
8876
|
+
title: t("about.downloadsSource"),
|
|
8877
|
+
"aria-label": `${dependency.packageName} · ${t("about.totalDownloads")} · ${typeof dependency.totalDownloads === "number" && Number.isSafeInteger(dependency.totalDownloads) && dependency.totalDownloads >= 0 ? dependency.totalDownloads.toLocaleString() : t("about.downloadsUnavailable")}`,
|
|
8878
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconDownloadOutlineMedium, {
|
|
8879
|
+
size: 12,
|
|
8880
|
+
"aria-hidden": "true"
|
|
8881
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8882
|
+
className: "dcu-about-downloads-count",
|
|
8883
|
+
children: typeof dependency.totalDownloads === "number" && Number.isSafeInteger(dependency.totalDownloads) && dependency.totalDownloads >= 0 ? dependency.totalDownloads.toLocaleString() : "—"
|
|
8884
|
+
})]
|
|
8885
|
+
})]
|
|
8886
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8887
|
+
className: "dcu-about-package",
|
|
8888
|
+
title: dependency.packageName,
|
|
8889
|
+
children: [
|
|
8890
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
8891
|
+
className: "dcu-about-project-link",
|
|
8892
|
+
href: PROJECT_HOMEPAGES[dependency.id],
|
|
8893
|
+
target: "_blank",
|
|
8894
|
+
rel: "noreferrer",
|
|
8895
|
+
children: dependency.packageName
|
|
8896
|
+
}),
|
|
8897
|
+
dependency.version === void 0 ? "" : ` · ${dependency.version}`,
|
|
8898
|
+
dependency.updateAvailable && dependency.latestVersion !== void 0 ? ` → ${dependency.latestVersion}` : ""
|
|
8899
|
+
]
|
|
8900
|
+
})]
|
|
8901
|
+
}),
|
|
8902
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8903
|
+
className: "dcu-about-status",
|
|
8904
|
+
"data-installed": dependency.installed,
|
|
8905
|
+
"data-update": dependency.updateAvailable,
|
|
8906
|
+
children: [dependency.installed && !dependency.updateAvailable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCheckOutlineMedium, { size: 14 }), dependency.updateAvailable ? t("about.updateAvailable") : dependency.installed ? t("about.installed") : t("about.missing")]
|
|
8907
|
+
}),
|
|
8908
|
+
(!dependency.installed || dependency.updateAvailable) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
8909
|
+
className: "dcu-about-install",
|
|
8910
|
+
type: "button",
|
|
8911
|
+
disabled: installing !== void 0,
|
|
8912
|
+
onClick: () => {
|
|
8913
|
+
install(dependency.id);
|
|
8914
|
+
},
|
|
8915
|
+
children: [installing === dependency.id ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconLoadingOutlineMedium, { size: 14 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconDownloadOutlineMedium, { size: 14 }), installing === dependency.id ? t("about.installing") : dependency.updateAvailable ? t("about.update") : t("about.install")]
|
|
8916
|
+
})
|
|
8917
|
+
]
|
|
8918
|
+
}, dependency.id))
|
|
8919
|
+
}),
|
|
8920
|
+
installing !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8921
|
+
className: "dcu-about-progress",
|
|
8922
|
+
role: "status",
|
|
8923
|
+
children: [
|
|
8924
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconLoadingOutlineMedium, { size: 14 }) }),
|
|
8925
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: progress === void 0 ? t("about.progressHint") : progressLabel(progress, t) }),
|
|
8926
|
+
progress?.percent !== null && progress?.percent !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8927
|
+
className: "dcu-about-progress-pct",
|
|
8928
|
+
children: [progress.percent, "%"]
|
|
8929
|
+
}),
|
|
8930
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8931
|
+
className: "dcu-about-progress-bar",
|
|
8932
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8933
|
+
className: "dcu-about-progress-fill",
|
|
8934
|
+
"data-wave": progress?.percent === null || progress?.percent === void 0,
|
|
8935
|
+
style: progress?.percent === null || progress?.percent === void 0 ? void 0 : { width: `${progress.percent}%` }
|
|
8936
|
+
})
|
|
8937
|
+
})
|
|
8938
|
+
]
|
|
8939
|
+
}),
|
|
8940
|
+
refreshFailed && state === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8941
|
+
className: "dcu-about-message",
|
|
8942
|
+
"data-error": "true",
|
|
8943
|
+
role: "status",
|
|
8944
|
+
children: t(businessRequestErrorKey(loadFailure) ?? "about.refreshFailed")
|
|
8945
|
+
}),
|
|
8946
|
+
message !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8947
|
+
className: "dcu-about-message",
|
|
8948
|
+
"data-error": message.error,
|
|
8949
|
+
role: message.error ? "alert" : "status",
|
|
8950
|
+
children: message.text
|
|
8951
|
+
})
|
|
8952
|
+
]
|
|
8953
|
+
});
|
|
8954
|
+
}
|
|
8955
|
+
//#endregion
|
|
8956
|
+
//#region src/client/ConnectorsSection.tsx
|
|
8957
|
+
const MCP_CONNECTOR_UI = "/mcp-connector/ui/";
|
|
8958
|
+
const PROMPT_REQUEST_TYPE = "mcp-connector:start-session";
|
|
8959
|
+
const PROMPT_RESULT_TYPE = "mcp-connector:start-session-result";
|
|
8960
|
+
const stylesheet$1 = `
|
|
8961
|
+
.dcu-connectors{color:var(--dsw-alias-label-primary)}.dcu-connectors h2{margin:0;font-size:18px}.dcu-connectors p{margin:6px 0 18px;color:var(--dsw-alias-label-secondary);font-size:12px}.dcu-connector-frame{display:block;width:100%;height:clamp(420px,calc(100vh - 160px),700px);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-base);color-scheme:light dark}.dcu-connector-list{overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:9px}.dcu-connector{padding:12px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dcu-connector:last-child{border-bottom:0}.dcu-connector-head{display:flex;align-items:center;gap:8px;font-weight:650}.dcu-connector-meta{margin:3px 0 8px;color:var(--dsw-alias-label-tertiary);font-size:11px}.dcu-connector-tool{padding:5px 0 0 24px;color:var(--dsw-alias-label-secondary);font-size:12px}.dcu-connector-tool span{display:block;margin-top:1px;color:var(--dsw-alias-label-tertiary);font-size:11px}.dcu-connector-empty{padding:20px 8px;color:var(--dsw-alias-label-secondary);text-align:center}
|
|
8962
|
+
`;
|
|
8963
|
+
const frameLightTheme = `:root{color-scheme:light;--bg:#fff;--card:#fafafa;--line:#e5e5e5;--text:#303030;--text-2:#737373;--muted:#767676;--accent:#303030;--accent-hover:#171717;--accent-light:#e9e9e9;--dcu-action:#303030;--dcu-action-hover:#171717;--dcu-on-action:#fff;--ok:#059669;--ok-bg:#ecfdf5;--warn:#d97706;--warn-bg:#fffbeb;--bad:#dc2626;--bad-bg:#fef2f2;--shadow:0 1px 3px rgba(0,0,0,.08),0 1px 2px rgba(0,0,0,.06);--shadow-lg:0 10px 25px rgba(0,0,0,.1)}`;
|
|
8964
|
+
const frameDarkTheme = `:root{color-scheme:dark;--bg:#181818;--card:#232323;--line:#333;--text:#dedede;--text-2:#a1a1a1;--muted:#929292;--accent:#dedede;--accent-hover:#fff;--accent-light:#303332;--dcu-action:#383838;--dcu-action-hover:#454545;--dcu-on-action:#eee;--ok:#34d399;--ok-bg:#0d3027;--warn:#fbbf24;--warn-bg:#35280b;--bad:#f87171;--bad-bg:#3b171b;--shadow:0 1px 3px rgba(0,0,0,.35);--shadow-lg:0 16px 35px rgba(0,0,0,.45)}`;
|
|
8965
|
+
const frameSurfaceTheme = `
|
|
8966
|
+
.card.featured{border-color:var(--line)}
|
|
8967
|
+
.card:hover,.card.featured:hover{border-color:var(--muted)}
|
|
8968
|
+
.btn:not(.ghost):not(.danger):not(.status-warning):not(.status-bad),.icon-btn.primary,.btn-primary,.prompt-item .send-btn{background:var(--dcu-action);border-color:var(--dcu-action);color:var(--dcu-on-action)}
|
|
8969
|
+
.btn:not(.ghost):not(.danger):not(.status-warning):not(.status-bad):hover,.icon-btn.primary:hover,.btn-primary:hover,.prompt-item .send-btn:hover{background:var(--dcu-action-hover);border-color:var(--dcu-action-hover)}
|
|
8970
|
+
`;
|
|
8971
|
+
function isConnector(value) {
|
|
8972
|
+
if (value === null || typeof value !== "object") return false;
|
|
8973
|
+
const item = value;
|
|
8974
|
+
return typeof item.name === "string" && Array.isArray(item.tools) && item.tools.every((tool) => tool !== null && typeof tool === "object" && typeof tool.name === "string" && typeof tool.description === "string");
|
|
8975
|
+
}
|
|
8976
|
+
function isPromptRequest(value) {
|
|
8977
|
+
if (value === null || typeof value !== "object") return false;
|
|
8978
|
+
const item = value;
|
|
8979
|
+
return item.type === PROMPT_REQUEST_TYPE && typeof item.requestId === "string" && item.requestId !== "" && typeof item.prompt === "string" && item.prompt.trim() !== "";
|
|
8980
|
+
}
|
|
8981
|
+
function syncFrameTheme(frame) {
|
|
8982
|
+
const doc = frame?.contentDocument;
|
|
8983
|
+
if (doc === null || doc === void 0) return;
|
|
8984
|
+
let style = doc.head.querySelector("style[data-michengai-host-theme]");
|
|
8985
|
+
if (style === null) {
|
|
8986
|
+
style = doc.createElement("style");
|
|
8987
|
+
style.dataset.michengaiHostTheme = "true";
|
|
8988
|
+
doc.head.append(style);
|
|
8989
|
+
}
|
|
8990
|
+
style.textContent = (document.body.hasAttribute("data-ds-dark-theme") ? frameDarkTheme : frameLightTheme) + frameSurfaceTheme;
|
|
8991
|
+
}
|
|
8992
|
+
function ConnectorMarket({ startPromptSession, t }) {
|
|
8993
|
+
const frameRef = (0, react.useRef)(null);
|
|
8994
|
+
(0, react.useEffect)(() => {
|
|
8995
|
+
const onMessage = (event) => {
|
|
8996
|
+
const frameWindow = frameRef.current?.contentWindow;
|
|
8997
|
+
if (event.origin !== window.location.origin || frameWindow === null || frameWindow === void 0 || event.source !== frameWindow) return;
|
|
8998
|
+
if (!isPromptRequest(event.data)) return;
|
|
8999
|
+
const { requestId, prompt } = event.data;
|
|
9000
|
+
const reply = (ok, message) => {
|
|
9001
|
+
frameWindow.postMessage({
|
|
9002
|
+
type: PROMPT_RESULT_TYPE,
|
|
9003
|
+
requestId,
|
|
9004
|
+
ok,
|
|
9005
|
+
message
|
|
9006
|
+
}, window.location.origin);
|
|
9007
|
+
};
|
|
9008
|
+
startPromptSession(prompt).then(() => {
|
|
9009
|
+
reply(true, t("connectors.promptReady"));
|
|
9010
|
+
}, (error) => {
|
|
9011
|
+
reply(false, userErrorText(error, t));
|
|
9012
|
+
});
|
|
9013
|
+
};
|
|
9014
|
+
const syncTheme = () => {
|
|
9015
|
+
syncFrameTheme(frameRef.current);
|
|
9016
|
+
};
|
|
9017
|
+
const observer = new MutationObserver(syncTheme);
|
|
9018
|
+
observer.observe(document.body, {
|
|
9019
|
+
attributes: true,
|
|
9020
|
+
attributeFilter: ["data-ds-dark-theme"]
|
|
9021
|
+
});
|
|
9022
|
+
window.addEventListener("message", onMessage);
|
|
9023
|
+
return () => {
|
|
9024
|
+
observer.disconnect();
|
|
9025
|
+
window.removeEventListener("message", onMessage);
|
|
9026
|
+
};
|
|
9027
|
+
}, [startPromptSession, t]);
|
|
9028
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
|
|
9029
|
+
ref: frameRef,
|
|
9030
|
+
className: "dcu-connector-frame",
|
|
9031
|
+
src: MCP_CONNECTOR_UI,
|
|
9032
|
+
title: t("connectors.title"),
|
|
9033
|
+
onLoad: () => {
|
|
9034
|
+
syncFrameTheme(frameRef.current);
|
|
9035
|
+
}
|
|
9036
|
+
});
|
|
9037
|
+
}
|
|
9038
|
+
function NativeConnectorList({ sessionStore, t }) {
|
|
9039
|
+
const sessionId = (0, react.useSyncExternalStore)(sessionStore.subscribe, () => currentSessionId(sessionStore.getSnapshot()));
|
|
9040
|
+
const [connectors, setConnectors] = (0, react.useState)([]);
|
|
9041
|
+
const [state, setState] = (0, react.useState)("loading");
|
|
9042
|
+
const [failure, setFailure] = (0, react.useState)();
|
|
9043
|
+
(0, react.useEffect)(() => {
|
|
9044
|
+
if (sessionId === void 0) {
|
|
9045
|
+
setConnectors([]);
|
|
9046
|
+
setState("ready");
|
|
9047
|
+
return;
|
|
9048
|
+
}
|
|
9049
|
+
const controller = new AbortController();
|
|
9050
|
+
setState("loading");
|
|
9051
|
+
fetch(`${CODEX_UI_API_ENDPOINTS.connectors}?sessionId=${encodeURIComponent(sessionId)}`, { signal: controller.signal }).then(async (response) => {
|
|
9052
|
+
if (!response.ok) throw new BusinessRequestError(response.status);
|
|
9053
|
+
const payload = await response.json();
|
|
9054
|
+
if (!Array.isArray(payload.connectors) || !payload.connectors.every(isConnector)) throw new Error("连接器目录返回格式无效。");
|
|
9055
|
+
if (!controller.signal.aborted) setConnectors(payload.connectors);
|
|
9056
|
+
}).then(() => {
|
|
9057
|
+
if (!controller.signal.aborted) setState("ready");
|
|
9058
|
+
}).catch((error) => {
|
|
9059
|
+
if (!controller.signal.aborted) {
|
|
9060
|
+
setFailure(error);
|
|
9061
|
+
setState("failed");
|
|
9062
|
+
}
|
|
9063
|
+
});
|
|
9064
|
+
return () => {
|
|
9065
|
+
controller.abort();
|
|
9066
|
+
};
|
|
9067
|
+
}, [sessionId]);
|
|
9068
|
+
if (sessionId === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9069
|
+
className: "dcu-connector-empty",
|
|
9070
|
+
children: t("connectors.openSession")
|
|
9071
|
+
});
|
|
9072
|
+
if (state === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9073
|
+
className: "dcu-connector-empty",
|
|
9074
|
+
children: t("connectors.loading")
|
|
9075
|
+
});
|
|
9076
|
+
if (state === "failed") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9077
|
+
className: "dcu-connector-empty",
|
|
9078
|
+
role: "alert",
|
|
9079
|
+
children: t(businessRequestErrorKey(failure) ?? "connectors.failed")
|
|
9080
|
+
});
|
|
9081
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9082
|
+
className: "dcu-connector-list",
|
|
9083
|
+
children: [connectors.map((connector) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
9084
|
+
className: "dcu-connector",
|
|
9085
|
+
children: [
|
|
9086
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9087
|
+
className: "dcu-connector-head",
|
|
9088
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconLinkOutlineMedium, { size: 16 }), connector.name]
|
|
9089
|
+
}),
|
|
9090
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9091
|
+
className: "dcu-connector-meta",
|
|
9092
|
+
children: t("connectors.toolCount", { count: connector.tools.length })
|
|
9093
|
+
}),
|
|
9094
|
+
connector.tools.map((tool) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9095
|
+
className: "dcu-connector-tool",
|
|
9096
|
+
children: [tool.name, tool.description !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tool.description })]
|
|
9097
|
+
}, tool.name))
|
|
9098
|
+
]
|
|
9099
|
+
}, connector.name)), connectors.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9100
|
+
className: "dcu-connector-empty",
|
|
9101
|
+
children: t("connectors.empty")
|
|
9102
|
+
})]
|
|
9103
|
+
});
|
|
9104
|
+
}
|
|
9105
|
+
/** 安装 dsh-mcp-connector 时显示完整市场,否则回退到当前会话的 MCP 工具目录。 */
|
|
9106
|
+
function ConnectorsSection({ sessionStore, startPromptSession, t }) {
|
|
9107
|
+
const [marketAvailable, setMarketAvailable] = (0, react.useState)();
|
|
9108
|
+
(0, react.useEffect)(() => {
|
|
9109
|
+
const controller = new AbortController();
|
|
9110
|
+
fetch(MCP_CONNECTOR_UI, {
|
|
9111
|
+
method: "GET",
|
|
9112
|
+
cache: "no-store",
|
|
9113
|
+
signal: controller.signal
|
|
9114
|
+
}).then((response) => {
|
|
9115
|
+
response.body?.cancel().catch(() => {});
|
|
9116
|
+
if (!controller.signal.aborted) setMarketAvailable(response.ok);
|
|
9117
|
+
}).catch(() => {
|
|
9118
|
+
if (!controller.signal.aborted) setMarketAvailable(false);
|
|
9119
|
+
});
|
|
9120
|
+
return () => {
|
|
9121
|
+
controller.abort();
|
|
9122
|
+
};
|
|
9123
|
+
}, []);
|
|
9124
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
9125
|
+
className: "dcu-connectors",
|
|
9126
|
+
"aria-label": t("connectors.title"),
|
|
9127
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: stylesheet$1 }), marketAvailable === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9128
|
+
className: "dcu-connector-empty",
|
|
9129
|
+
children: t("connectors.loading")
|
|
9130
|
+
}) : marketAvailable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConnectorMarket, {
|
|
9131
|
+
startPromptSession,
|
|
9132
|
+
t
|
|
9133
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
9134
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: t("connectors.title") }),
|
|
9135
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("connectors.description") }),
|
|
9136
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NativeConnectorList, {
|
|
9137
|
+
sessionStore,
|
|
9138
|
+
t
|
|
9139
|
+
})
|
|
9140
|
+
] })]
|
|
9141
|
+
});
|
|
9142
|
+
}
|
|
9082
9143
|
const HIDDEN_FOOTER_ACTION_IDS = /* @__PURE__ */ new Set(["context-overview"]);
|
|
9083
9144
|
function visibleFooterActions(slots) {
|
|
9084
9145
|
return slots.entriesOfSlot("sidebar.footer.action").flatMap(({ options }) => {
|
|
@@ -9429,7 +9490,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
9429
9490
|
//#region src/client/settings-page-styles.ts
|
|
9430
9491
|
/** Codex 设置页的局部 tokens 与布局,不覆盖宿主其他弹窗。 */
|
|
9431
9492
|
const settingsPageStyles = `
|
|
9432
|
-
.dcu-settings-page{--sp-bg:#fff;--sp-nav:var(--dcu-sidebar-background,#eef7f5);--sp-card:#fafafa;--sp-border:#e5e5e5;--sp-text:#303030;--sp-muted:#737373;--sp-hover:#e9e9e9;--sp-active:#e4e4e4;position:fixed;inset:0;z-index:1000;display:grid;grid-template-columns:clamp(240px,var(--dcu-sidebar-expanded-width,
|
|
9493
|
+
.dcu-settings-page{--sp-bg:#fff;--sp-nav:var(--dcu-sidebar-background,#eef7f5);--sp-card:#fafafa;--sp-border:#e5e5e5;--sp-text:#303030;--sp-muted:#737373;--sp-hover:#e9e9e9;--sp-active:#e4e4e4;position:fixed;inset:0;z-index:1000;display:grid;grid-template-columns:clamp(240px,var(--dcu-sidebar-expanded-width,240px),min(520px,calc(100vw - 320px))) minmax(0,1fr);background:var(--sp-bg);color:var(--sp-text);font:14px/1.5 var(--dsw-font-family);text-align:left;isolation:isolate}
|
|
9433
9494
|
body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:var(--dcu-sidebar-background,#1d2120);--sp-card:#232323;--sp-border:#333;--sp-text:#dedede;--sp-muted:#a1a1a1;--sp-hover:#292c2b;--sp-active:#303332;color-scheme:dark}
|
|
9434
9495
|
.dcu-settings-page *{box-sizing:border-box}
|
|
9435
9496
|
.dcu-settings-page button,.dcu-settings-page input{font:inherit}
|
|
@@ -9629,6 +9690,9 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
|
|
|
9629
9690
|
(0, react.useEffect)(() => () => {
|
|
9630
9691
|
exitAnimation.current?.cancel();
|
|
9631
9692
|
}, []);
|
|
9693
|
+
(0, react.useLayoutEffect)(() => {
|
|
9694
|
+
if (open && page.current !== null) page.current.style.setProperty("--dcu-sidebar-expanded-width", `${settingsSidebarWidth(document)}px`);
|
|
9695
|
+
}, [open]);
|
|
9632
9696
|
(0, react.useEffect)(() => {
|
|
9633
9697
|
if (!onboardingActive) setCompleted(/* @__PURE__ */ new Set());
|
|
9634
9698
|
}, [onboardingActive]);
|
|
@@ -10824,6 +10888,7 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
|
|
|
10824
10888
|
const companionSlots = createCompanionTabSource(ctx.slots);
|
|
10825
10889
|
const globalPanels = createGlobalPanelSource(ctx.slots, ctx.locale);
|
|
10826
10890
|
const footerActions = createFooterActionSource(ctx.slots);
|
|
10891
|
+
registerSidebarExpandControls(ctx);
|
|
10827
10892
|
ctx.slots.inject("sidebar", () => ctx.slots.register({
|
|
10828
10893
|
name: "sidebar",
|
|
10829
10894
|
registrant: "michengai-codex-ui",
|