dsh-github-flow 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +139 -54
- package/README.md +142 -54
- package/docs/architecture.md +19 -4
- package/docs/images/1.png +0 -0
- package/docs/images/3.png +0 -0
- package/docs/images/4.png +0 -0
- package/docs/npm-publish-guide.md +12 -0
- package/lib/api/route-helpers.d.ts +47 -0
- package/lib/api/route-helpers.js +134 -0
- package/lib/api/routes-actions.d.ts +9 -0
- package/lib/api/routes-actions.js +115 -0
- package/lib/api/routes-lifecycle.d.ts +9 -0
- package/lib/api/routes-lifecycle.js +75 -0
- package/lib/api/routes-overview.d.ts +11 -0
- package/lib/api/routes-overview.js +227 -0
- package/lib/api/routes-proxy.d.ts +18 -0
- package/lib/api/routes-proxy.js +63 -0
- package/lib/api/routes.d.ts +16 -6
- package/lib/api/routes.js +14 -504
- package/lib/client.js +383 -55
- package/lib/executor.d.ts +17 -0
- package/lib/executor.js +28 -0
- package/lib/main.d.ts +1 -0
- package/lib/main.js +40 -9
- package/lib/proxy.d.ts +87 -0
- package/lib/proxy.js +275 -0
- package/lib/renderers/markdown.d.ts +24 -0
- package/lib/renderers/markdown.js +493 -0
- package/lib/tools/api.d.ts +4 -0
- package/lib/tools/api.js +14 -4
- package/lib/tools/help.d.ts +31 -0
- package/lib/tools/help.js +212 -0
- package/lib/tools/issue.d.ts +32 -1
- package/lib/tools/issue.js +94 -17
- package/lib/tools/pr.d.ts +22 -1
- package/lib/tools/pr.js +67 -15
- package/lib/tools/release.d.ts +89 -0
- package/lib/tools/release.js +219 -0
- package/lib/tools/repo.d.ts +13 -1
- package/lib/tools/repo.js +46 -14
- package/lib/tools/run.d.ts +22 -1
- package/lib/tools/run.js +74 -14
- package/lib/tools/secret.d.ts +60 -0
- package/lib/tools/secret.js +175 -0
- package/lib/tools/skill.d.ts +63 -0
- package/lib/tools/skill.js +146 -0
- package/lib/types.d.ts +12 -0
- package/lib/updater.d.ts +8 -0
- package/lib/updater.js +9 -0
- package/lib/upgrade-manager.d.ts +4 -0
- package/lib/upgrade-manager.js +11 -1
- package/package.json +3 -2
- package/lib/client/icons.d.ts +0 -13
- package/lib/client/icons.js +0 -41
- package/lib/client/index.d.ts +0 -3
- package/lib/client/index.js +0 -36
- package/lib/client/panel.d.ts +0 -1
- package/lib/client/panel.js +0 -102
- package/lib/client/style.d.ts +0 -1
- package/lib/client/style.js +0 -555
package/lib/client.js
CHANGED
|
@@ -5,6 +5,10 @@ window.__ModuleLoader__.load({
|
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
var React = require("react");
|
|
8
|
+
// 面板样式(内联维护):DSH 客户端加载器以经典脚本语义执行本产物(build.mjs 剥除
|
|
9
|
+
// export 声明即为佐证),模块级 import 在该语境是 SyntaxError。曾尝试把 CSS 拆为
|
|
10
|
+
// 独立模块经 import 引入,导致 DSH 重启时客户端加载崩溃并触发插件批量卸载——
|
|
11
|
+
// 已回滚。样式与组件的分离改由「同文件内分区注释」维持,不再跨文件。
|
|
8
12
|
var GITHUB_PANEL_CSS = `
|
|
9
13
|
/* ==========================================================================
|
|
10
14
|
DSH GitHub Flow - 主题自适应样式系统 (Light / Dark 动态联动)
|
|
@@ -805,7 +809,7 @@ body[data-ds-dark-theme] .dsh-github-steps-list {
|
|
|
805
809
|
line-height: 1.4;
|
|
806
810
|
}
|
|
807
811
|
|
|
808
|
-
/* 16.
|
|
812
|
+
/* 16. 设置弹窗 (Settings Modal):左侧分区导航 + 右侧内容区 */
|
|
809
813
|
.dsh-github-modal-overlay {
|
|
810
814
|
position: fixed;
|
|
811
815
|
top: 0;
|
|
@@ -820,14 +824,18 @@ body[data-ds-dark-theme] .dsh-github-steps-list {
|
|
|
820
824
|
backdrop-filter: blur(2px);
|
|
821
825
|
}
|
|
822
826
|
.dsh-github-modal-dialog {
|
|
823
|
-
width:
|
|
824
|
-
max-width:
|
|
827
|
+
width: 92%;
|
|
828
|
+
max-width: 640px;
|
|
829
|
+
max-height: 86vh;
|
|
830
|
+
display: flex;
|
|
831
|
+
flex-direction: column;
|
|
825
832
|
background: var(--dsw-alias-bg-base, #ffffff);
|
|
826
833
|
border: 1px solid var(--dsw-alias-border-l2, #d0d7de);
|
|
827
834
|
border-radius: 12px;
|
|
828
835
|
box-shadow: 0 16px 32px rgba(0, 0, 0, 0.18);
|
|
829
|
-
padding:
|
|
836
|
+
padding: 0;
|
|
830
837
|
box-sizing: border-box;
|
|
838
|
+
overflow: hidden;
|
|
831
839
|
color: var(--dsw-alias-label-primary, #1f2328);
|
|
832
840
|
font-family: var(--dsw-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
|
|
833
841
|
}
|
|
@@ -836,6 +844,105 @@ body[data-ds-dark-theme] .dsh-github-modal-dialog {
|
|
|
836
844
|
border-color: var(--dsw-alias-border-l1, #30363d);
|
|
837
845
|
box-shadow: 0 16px 36px rgba(0, 0, 0, 0.45);
|
|
838
846
|
}
|
|
847
|
+
/* 弹窗头部(标题 + 关闭) */
|
|
848
|
+
.dsh-github-modal-header {
|
|
849
|
+
display: flex;
|
|
850
|
+
justify-content: space-between;
|
|
851
|
+
align-items: center;
|
|
852
|
+
padding: 18px 22px 14px;
|
|
853
|
+
border-bottom: 1px solid var(--dsw-alias-border-l2, #d0d7de);
|
|
854
|
+
flex-shrink: 0;
|
|
855
|
+
}
|
|
856
|
+
body[data-ds-dark-theme] .dsh-github-modal-header {
|
|
857
|
+
border-bottom-color: var(--dsw-alias-border-l1, #30363d);
|
|
858
|
+
}
|
|
859
|
+
/* 分区导航 + 内容 双栏骨架:窄屏(<560px)自动折叠为顶部横向页签 */
|
|
860
|
+
.dsh-github-modal-body {
|
|
861
|
+
display: flex;
|
|
862
|
+
min-height: 0;
|
|
863
|
+
flex: 1;
|
|
864
|
+
}
|
|
865
|
+
.dsh-github-settings-nav {
|
|
866
|
+
flex-shrink: 0;
|
|
867
|
+
width: 148px;
|
|
868
|
+
padding: 14px 10px;
|
|
869
|
+
border-right: 1px solid var(--dsw-alias-border-l2, #d0d7de);
|
|
870
|
+
display: flex;
|
|
871
|
+
flex-direction: column;
|
|
872
|
+
gap: 4px;
|
|
873
|
+
box-sizing: border-box;
|
|
874
|
+
}
|
|
875
|
+
body[data-ds-dark-theme] .dsh-github-settings-nav {
|
|
876
|
+
border-right-color: var(--dsw-alias-border-l1, #30363d);
|
|
877
|
+
}
|
|
878
|
+
.dsh-github-settings-nav-item {
|
|
879
|
+
display: flex;
|
|
880
|
+
align-items: center;
|
|
881
|
+
gap: 8px;
|
|
882
|
+
padding: 8px 10px;
|
|
883
|
+
border-radius: 6px;
|
|
884
|
+
border: none;
|
|
885
|
+
background: none;
|
|
886
|
+
cursor: pointer;
|
|
887
|
+
font-size: 13px;
|
|
888
|
+
text-align: left;
|
|
889
|
+
color: var(--dsw-alias-label-secondary, #656d76);
|
|
890
|
+
transition: background 0.12s ease, color 0.12s ease;
|
|
891
|
+
}
|
|
892
|
+
.dsh-github-settings-nav-item:hover {
|
|
893
|
+
background: var(--dsw-alias-bg-layer-1, #f6f8fa);
|
|
894
|
+
color: var(--dsw-alias-label-primary, #1f2328);
|
|
895
|
+
}
|
|
896
|
+
.dsh-github-settings-nav-item.active {
|
|
897
|
+
background: rgba(9, 105, 218, 0.1);
|
|
898
|
+
color: var(--dsw-alias-link, #0969da);
|
|
899
|
+
font-weight: 600;
|
|
900
|
+
}
|
|
901
|
+
body[data-ds-dark-theme] .dsh-github-settings-nav-item:hover {
|
|
902
|
+
background: rgba(240, 246, 252, 0.06);
|
|
903
|
+
color: var(--dsw-alias-label-primary, #f0f6fc);
|
|
904
|
+
}
|
|
905
|
+
body[data-ds-dark-theme] .dsh-github-settings-nav-item.active {
|
|
906
|
+
background: rgba(88, 166, 255, 0.15);
|
|
907
|
+
color: #58a6ff;
|
|
908
|
+
}
|
|
909
|
+
.dsh-github-settings-content {
|
|
910
|
+
flex: 1;
|
|
911
|
+
min-width: 0;
|
|
912
|
+
padding: 18px 22px 20px;
|
|
913
|
+
overflow-y: auto;
|
|
914
|
+
box-sizing: border-box;
|
|
915
|
+
}
|
|
916
|
+
@media (max-width: 560px) {
|
|
917
|
+
.dsh-github-modal-body {
|
|
918
|
+
flex-direction: column;
|
|
919
|
+
}
|
|
920
|
+
.dsh-github-settings-nav {
|
|
921
|
+
width: 100%;
|
|
922
|
+
flex-direction: row;
|
|
923
|
+
border-right: none;
|
|
924
|
+
border-bottom: 1px solid var(--dsw-alias-border-l2, #d0d7e0);
|
|
925
|
+
overflow-x: auto;
|
|
926
|
+
}
|
|
927
|
+
body[data-ds-dark-theme] .dsh-github-settings-nav {
|
|
928
|
+
border-bottom-color: var(--dsw-alias-border-l1, #30363d);
|
|
929
|
+
}
|
|
930
|
+
.dsh-github-settings-nav-item {
|
|
931
|
+
white-space: nowrap;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
/* 弹窗底部操作条 */
|
|
935
|
+
.dsh-github-modal-footer {
|
|
936
|
+
display: flex;
|
|
937
|
+
justify-content: flex-end;
|
|
938
|
+
gap: 8px;
|
|
939
|
+
padding: 14px 22px;
|
|
940
|
+
border-top: 1px solid var(--dsw-alias-border-l2, #d0d7de);
|
|
941
|
+
flex-shrink: 0;
|
|
942
|
+
}
|
|
943
|
+
body[data-ds-dark-theme] .dsh-github-modal-footer {
|
|
944
|
+
border-top-color: var(--dsw-alias-border-l1, #30363d);
|
|
945
|
+
}
|
|
839
946
|
.dsh-github-radio-card {
|
|
840
947
|
display: flex;
|
|
841
948
|
align-items: flex-start;
|
|
@@ -903,6 +1010,37 @@ body[data-ds-dark-theme] .dsh-github-select option {
|
|
|
903
1010
|
color: #f0f6fc;
|
|
904
1011
|
}
|
|
905
1012
|
|
|
1013
|
+
/* 代理设置弹窗的文本输入框(浅色/深色双模式,设计变量对齐 select 保持视觉一致) */
|
|
1014
|
+
.dsh-github-input {
|
|
1015
|
+
padding: 7px 12px;
|
|
1016
|
+
border-radius: 6px;
|
|
1017
|
+
border: 1px solid var(--dsw-alias-border-l2, #d0d7de);
|
|
1018
|
+
background: var(--dsw-alias-bg-base, #ffffff);
|
|
1019
|
+
color: var(--dsw-alias-label-primary, #1f2328);
|
|
1020
|
+
font-size: 13px;
|
|
1021
|
+
outline: none;
|
|
1022
|
+
box-sizing: border-box;
|
|
1023
|
+
color-scheme: light;
|
|
1024
|
+
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
|
1025
|
+
}
|
|
1026
|
+
.dsh-github-input:focus {
|
|
1027
|
+
border-color: var(--dsw-alias-link, #0969da);
|
|
1028
|
+
box-shadow: 0 0 0 3px rgba(9, 105, 218, 0.15);
|
|
1029
|
+
}
|
|
1030
|
+
.dsh-github-input::placeholder {
|
|
1031
|
+
color: var(--dsw-alias-label-tertiary, #8c959f);
|
|
1032
|
+
}
|
|
1033
|
+
body[data-ds-dark-theme] .dsh-github-input {
|
|
1034
|
+
border-color: var(--dsw-alias-border-l1, #30363d);
|
|
1035
|
+
background: var(--dsw-alias-bg-layer-2, #1e1e22);
|
|
1036
|
+
color: var(--dsw-alias-label-primary, #f0f6fc);
|
|
1037
|
+
color-scheme: dark;
|
|
1038
|
+
}
|
|
1039
|
+
body[data-ds-dark-theme] .dsh-github-input:focus {
|
|
1040
|
+
border-color: #58a6ff;
|
|
1041
|
+
box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.2);
|
|
1042
|
+
}
|
|
1043
|
+
|
|
906
1044
|
/* 缓存信息展示框 */
|
|
907
1045
|
.dsh-github-cache-info-box {
|
|
908
1046
|
padding: 10px 12px;
|
|
@@ -1463,9 +1601,12 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1463
1601
|
// 全局持久化缓存与偏好配置键名
|
|
1464
1602
|
var GLOBAL_OVERVIEW_CACHE_KEY = "dsh_github_global_overview_snapshot_v1";
|
|
1465
1603
|
var SYNC_SETTINGS_STORAGE_KEY = "dsh_github_sync_settings_v1";
|
|
1604
|
+
// 同步策略收敛为两态:'swr'(打开秒开旧数据+后台静默拉新)| 'manual'(仅手动刷新)。
|
|
1605
|
+
// 旧的第三态 'interval'(前端 setInterval 轮询)已删除:浏览器对后台标签页节流
|
|
1606
|
+
// 定时器、组件卸载即销毁,该模式在真实环境几乎从不按承诺工作(停留短于间隔则
|
|
1607
|
+
// 永不触发);其「打开即新鲜」的诉求由 SWR 挂载自愈覆盖,「持续同步」点刷新即可。
|
|
1466
1608
|
var DEFAULT_SYNC_SETTINGS = {
|
|
1467
|
-
strategy: "swr", // 'swr'
|
|
1468
|
-
intervalMs: 300000, // 默认 5 分钟 (300,000ms)
|
|
1609
|
+
strategy: "swr", // 'swr' | 'manual'
|
|
1469
1610
|
};
|
|
1470
1611
|
function getLocalSyncSettings() {
|
|
1471
1612
|
try {
|
|
@@ -1473,7 +1614,14 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1473
1614
|
if (!raw)
|
|
1474
1615
|
return DEFAULT_SYNC_SETTINGS;
|
|
1475
1616
|
var parsed = JSON.parse(raw);
|
|
1476
|
-
|
|
1617
|
+
var merged = Object.assign({}, DEFAULT_SYNC_SETTINGS, parsed);
|
|
1618
|
+
// 旧版本迁移:曾选过 'interval' 的用户自动回落 SWR(最接近原意图),
|
|
1619
|
+
// 并立即覆写存储防止每次读取都走迁移分支。
|
|
1620
|
+
if (merged.strategy === "interval") {
|
|
1621
|
+
merged.strategy = "swr";
|
|
1622
|
+
saveLocalSyncSettings(merged);
|
|
1623
|
+
}
|
|
1624
|
+
return merged;
|
|
1477
1625
|
}
|
|
1478
1626
|
catch (e) {
|
|
1479
1627
|
return DEFAULT_SYNC_SETTINGS;
|
|
@@ -1711,7 +1859,9 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1711
1859
|
setLoading(false);
|
|
1712
1860
|
}
|
|
1713
1861
|
}, [cwd, sessionId, data, syncSettings.strategy]);
|
|
1714
|
-
// 挂载与策略调度:与主页规则 100%
|
|
1862
|
+
// 挂载与策略调度:与主页规则 100% 保持一致。
|
|
1863
|
+
// SWR 分支不判 data:挂载 300ms 后台静默拉新,昨天的持久化快照当场自愈——
|
|
1864
|
+
// 「打开就能看到最新」是 SWR 的定义,不依赖用户停留时长。
|
|
1715
1865
|
React.useEffect(() => {
|
|
1716
1866
|
if (syncSettings.strategy === "swr") {
|
|
1717
1867
|
var timer = setTimeout(function () { loadData(false); }, 300);
|
|
@@ -1721,15 +1871,8 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1721
1871
|
loadData(false);
|
|
1722
1872
|
}
|
|
1723
1873
|
}, [cwd, sessionId, syncSettings.strategy]);
|
|
1724
|
-
//
|
|
1725
|
-
|
|
1726
|
-
if (syncSettings.strategy !== "interval" || !syncSettings.intervalMs || syncSettings.intervalMs <= 0)
|
|
1727
|
-
return;
|
|
1728
|
-
var timer = setInterval(function () {
|
|
1729
|
-
loadData(false);
|
|
1730
|
-
}, syncSettings.intervalMs);
|
|
1731
|
-
return function () { clearInterval(timer); };
|
|
1732
|
-
}, [syncSettings.strategy, syncSettings.intervalMs, loadData]);
|
|
1874
|
+
// (原定时轮询调度已随 'interval' 策略一并移除:前端 setInterval 受浏览器
|
|
1875
|
+
// 后台节流且随组件卸载销毁,无法兑现「定时自动更新」承诺)
|
|
1733
1876
|
// 窗口切回自动探测自愈:优先轻量快速探针,检测到已登录立即自愈
|
|
1734
1877
|
React.useEffect(() => {
|
|
1735
1878
|
var onFocus = () => {
|
|
@@ -1769,14 +1912,44 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1769
1912
|
className: "dsh-github-icon-inner" + (active ? " active" : "")
|
|
1770
1913
|
}, renderOctocat(18, "currentColor")));
|
|
1771
1914
|
}
|
|
1772
|
-
// 全景驾驶舱「⚙️
|
|
1915
|
+
// 全景驾驶舱「⚙️ 设置」模态弹窗组件:左侧分区导航(数据同步 / 网络代理)+ 右侧内容区。
|
|
1916
|
+
// 为什么改多分区:弹窗承载能力从单一「同步偏好」扩展为多项插件设置(后续可继续加),
|
|
1917
|
+
// 单页滚动堆叠会让用户找不到入口;分区导航让每项设置拥有独立心智空间与保存动作。
|
|
1773
1918
|
function GlobalSyncSettingsModal(props) {
|
|
1774
1919
|
if (!props.isOpen)
|
|
1775
1920
|
return null;
|
|
1921
|
+
// ---- 当前激活分区:sync(数据同步)/ proxy(网络代理)----
|
|
1922
|
+
var [activeSection, setActiveSection] = React.useState("sync");
|
|
1776
1923
|
var [strategy, setStrategy] = React.useState(props.currentSettings.strategy || "swr");
|
|
1777
|
-
var [intervalMs, setIntervalMs] = React.useState(props.currentSettings.intervalMs || 300000);
|
|
1778
1924
|
var [cacheMeta, setCacheMeta] = React.useState(getCacheStorageMeta());
|
|
1779
1925
|
var [clearTip, setClearTip] = React.useState("");
|
|
1926
|
+
// ---- 网络代理分区状态 ----
|
|
1927
|
+
// 打开弹窗时从后端拉取真实代理状态(权威源是 proxy.json 而非 localStorage),
|
|
1928
|
+
// 避免多窗口/外部手改文件导致的 UI 与实际生效配置漂移。
|
|
1929
|
+
var [proxyEnabled, setProxyEnabled] = React.useState(false);
|
|
1930
|
+
var [proxyUrl, setProxyUrl] = React.useState("");
|
|
1931
|
+
var [proxyNoProxy, setProxyNoProxy] = React.useState("localhost,127.0.0.1");
|
|
1932
|
+
var [proxyApplyNpm, setProxyApplyNpm] = React.useState(true);
|
|
1933
|
+
var [proxyBusy, setProxyBusy] = React.useState(false);
|
|
1934
|
+
var [proxyMsg, setProxyMsg] = React.useState(null);
|
|
1935
|
+
var [proxyProbe, setProxyProbe] = React.useState(null);
|
|
1936
|
+
React.useEffect(function () {
|
|
1937
|
+
if (!props.isOpen)
|
|
1938
|
+
return;
|
|
1939
|
+
fetch("/api/github/proxy")
|
|
1940
|
+
.then(function (r) { return r.json(); })
|
|
1941
|
+
.then(function (j) {
|
|
1942
|
+
if (j && j.ok && j.state) {
|
|
1943
|
+
setProxyEnabled(Boolean(j.state.config && j.state.config.url));
|
|
1944
|
+
setProxyUrl((j.state.config && j.state.config.url) || "");
|
|
1945
|
+
setProxyNoProxy((j.state.config && j.state.config.noProxy) || "localhost,127.0.0.1");
|
|
1946
|
+
setProxyApplyNpm(j.state.config ? j.state.config.applyToPackageManager !== false : true);
|
|
1947
|
+
if (j.state.lastProbe)
|
|
1948
|
+
setProxyProbe(j.state.lastProbe);
|
|
1949
|
+
}
|
|
1950
|
+
})
|
|
1951
|
+
.catch(function () { });
|
|
1952
|
+
}, [props.isOpen]);
|
|
1780
1953
|
// 键盘 Escape 快捷关闭支持
|
|
1781
1954
|
React.useEffect(function () {
|
|
1782
1955
|
var onKeyDown = function (e) {
|
|
@@ -1791,7 +1964,6 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1791
1964
|
var handleSave = function () {
|
|
1792
1965
|
var updated = {
|
|
1793
1966
|
strategy: strategy,
|
|
1794
|
-
intervalMs: Number(intervalMs),
|
|
1795
1967
|
};
|
|
1796
1968
|
saveLocalSyncSettings(updated);
|
|
1797
1969
|
props.onSave(updated);
|
|
@@ -1804,13 +1976,82 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1804
1976
|
setClearTip("本地缓存已彻底清空!");
|
|
1805
1977
|
setTimeout(function () { setClearTip(""); }, 2000);
|
|
1806
1978
|
};
|
|
1979
|
+
// 代理保存:POST 后端后立即全局生效(gh 子进程/升级链路 env + npm 探测 dispatcher)。
|
|
1980
|
+
// 保存成功即提示「无需重启」,与「设置完成之后全局生效」的语义对齐。
|
|
1981
|
+
var handleProxySave = function () {
|
|
1982
|
+
setProxyBusy(true);
|
|
1983
|
+
setProxyMsg(null);
|
|
1984
|
+
fetch("/api/github/proxy", {
|
|
1985
|
+
method: "POST",
|
|
1986
|
+
headers: { "Content-Type": "application/json" },
|
|
1987
|
+
body: JSON.stringify({
|
|
1988
|
+
url: proxyEnabled ? proxyUrl.trim() : "",
|
|
1989
|
+
noProxy: proxyNoProxy,
|
|
1990
|
+
applyToPackageManager: proxyApplyNpm,
|
|
1991
|
+
}),
|
|
1992
|
+
})
|
|
1993
|
+
.then(function (r) { return r.json(); })
|
|
1994
|
+
.then(function (j) {
|
|
1995
|
+
setProxyBusy(false);
|
|
1996
|
+
if (j && j.ok) {
|
|
1997
|
+
setProxyMsg({
|
|
1998
|
+
kind: "ok",
|
|
1999
|
+
text: j.state && j.state.config && j.state.config.url
|
|
2000
|
+
? "🌐 代理已保存并全局生效(驾驶舱 / 右侧栏 / Agent 工具 / 升级链路),无需重启"
|
|
2001
|
+
: "已切换为系统默认网络(直连或系统环境代理),无需重启",
|
|
2002
|
+
});
|
|
2003
|
+
if (j.state && j.state.lastProbe)
|
|
2004
|
+
setProxyProbe(j.state.lastProbe);
|
|
2005
|
+
}
|
|
2006
|
+
else {
|
|
2007
|
+
setProxyMsg({ kind: "err", text: (j && j.message) || "保存失败" });
|
|
2008
|
+
}
|
|
2009
|
+
})
|
|
2010
|
+
.catch(function (e) {
|
|
2011
|
+
setProxyBusy(false);
|
|
2012
|
+
setProxyMsg({ kind: "err", text: "网络请求失败: " + (e && e.message ? e.message : e) });
|
|
2013
|
+
});
|
|
2014
|
+
};
|
|
2015
|
+
// 连通性探测:验证经当前配置访问 GitHub API 的可达性(2.5s 超时由后端控制)
|
|
2016
|
+
var handleProxyProbe = function () {
|
|
2017
|
+
setProxyBusy(true);
|
|
2018
|
+
setProxyMsg(null);
|
|
2019
|
+
fetch("/api/github/proxy/probe", { method: "POST" })
|
|
2020
|
+
.then(function (r) { return r.json(); })
|
|
2021
|
+
.then(function (j) {
|
|
2022
|
+
setProxyBusy(false);
|
|
2023
|
+
if (j && j.ok && j.probe) {
|
|
2024
|
+
setProxyProbe(j.probe);
|
|
2025
|
+
setProxyMsg(j.probe.ok
|
|
2026
|
+
? { kind: "ok", text: "✅ GitHub API 可达 (" + j.probe.latencyMs + "ms)" }
|
|
2027
|
+
: { kind: "err", text: "❌ " + (j.probe.error || "探测失败") });
|
|
2028
|
+
}
|
|
2029
|
+
else {
|
|
2030
|
+
setProxyMsg({ kind: "err", text: (j && j.message) || "探测失败" });
|
|
2031
|
+
}
|
|
2032
|
+
})
|
|
2033
|
+
.catch(function (e) {
|
|
2034
|
+
setProxyBusy(false);
|
|
2035
|
+
setProxyMsg({ kind: "err", text: "探测请求失败: " + (e && e.message ? e.message : e) });
|
|
2036
|
+
});
|
|
2037
|
+
};
|
|
1807
2038
|
return h("div", { className: "dsh-github-modal-overlay", onClick: props.onClose }, h("div", {
|
|
1808
2039
|
className: "dsh-github-modal-dialog",
|
|
1809
2040
|
onClick: function (e) { e.stopPropagation(); },
|
|
1810
|
-
},
|
|
2041
|
+
},
|
|
2042
|
+
// 弹窗头部:标题 + 关闭按钮
|
|
2043
|
+
h("div", { className: "dsh-github-modal-header" }, h("h3", { style: { margin: 0, fontSize: "16px", fontWeight: 600 } }, "⚙️ 设置"), h("button", {
|
|
1811
2044
|
style: { background: "none", border: "none", cursor: "pointer", fontSize: "18px", color: "var(--dsw-alias-label-secondary, #656d76)" },
|
|
1812
2045
|
onClick: props.onClose,
|
|
1813
|
-
}, "✕")),
|
|
2046
|
+
}, "✕")),
|
|
2047
|
+
// 双栏骨架:左侧分区导航 + 右侧内容区(窄屏自动折叠为横向页签)
|
|
2048
|
+
h("div", { className: "dsh-github-modal-body" }, h("div", { className: "dsh-github-settings-nav" }, h("button", {
|
|
2049
|
+
className: "dsh-github-settings-nav-item" + (activeSection === "sync" ? " active" : ""),
|
|
2050
|
+
onClick: function () { setActiveSection("sync"); },
|
|
2051
|
+
}, "🔄 数据同步"), h("button", {
|
|
2052
|
+
className: "dsh-github-settings-nav-item" + (activeSection === "proxy" ? " active" : ""),
|
|
2053
|
+
onClick: function () { setActiveSection("proxy"); },
|
|
2054
|
+
}, "🌐 网络代理")), h("div", { className: "dsh-github-settings-content" }, activeSection === "sync" ? h("div", null, h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginBottom: "14px", lineHeight: "1.5" } }, "配置 GitHub 全景驾驶舱的数据拉取节奏。启用秒开模式可利用本地持久化缓存消除每次打开时的漫长等待。"),
|
|
1814
2055
|
// 刷新策略选择
|
|
1815
2056
|
h("div", { style: { marginBottom: "16px" } }, h("div", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "8px" } }, "数据刷新策略"),
|
|
1816
2057
|
// 策略 A: SWR 秒开
|
|
@@ -1822,18 +2063,10 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1822
2063
|
h("div", {
|
|
1823
2064
|
className: "dsh-github-radio-card" + (strategy === "manual" ? " active" : ""),
|
|
1824
2065
|
onClick: function () { setStrategy("manual"); },
|
|
1825
|
-
}, h("input", { type: "radio", className: "dsh-github-radio", checked: strategy === "manual", readOnly: true }), h("div", null, h("div", { style: { fontWeight: 600, fontSize: "13px" } }, "📋 仅在手动点击时拉取 (Manual Only)"), h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginTop: "2px" } }, "打开只浏览本地缓存,绝不自动触发后台 gh
|
|
1826
|
-
//
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
onClick: function () { setStrategy("interval"); },
|
|
1830
|
-
}, h("input", { type: "radio", className: "dsh-github-radio", checked: strategy === "interval", readOnly: true }), h("div", null, h("div", { style: { fontWeight: 600, fontSize: "13px" } }, "⏱️ 定时自动轮询 (Auto Poll)"), h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginTop: "2px" } }, "驾驶舱打开期间,按照下方设定的时间间隔在后台自动轮询。")))),
|
|
1831
|
-
// 自动拉取间隔下拉
|
|
1832
|
-
h("div", { style: { marginBottom: "18px" } }, h("div", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "6px" } }, "后台自动拉取间隔"), h("select", {
|
|
1833
|
-
className: "dsh-github-select",
|
|
1834
|
-
value: intervalMs,
|
|
1835
|
-
onChange: function (e) { setIntervalMs(Number(e.target.value)); },
|
|
1836
|
-
}, h("option", { value: 60000 }, "1 分钟 (高频刷新)"), h("option", { value: 300000 }, "5 分钟 (默认推荐)"), h("option", { value: 900000 }, "15 分钟"), h("option", { value: 1800000 }, "30 分钟 (推荐节能)"), h("option", { value: 3600000 }, "1 小时"), h("option", { value: 0 }, "从不自动刷新 (仅手动)"))),
|
|
2066
|
+
}, h("input", { type: "radio", className: "dsh-github-radio", checked: strategy === "manual", readOnly: true }), h("div", null, h("div", { style: { fontWeight: 600, fontSize: "13px" } }, "📋 仅在手动点击时拉取 (Manual Only)"), h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginTop: "2px" } }, "打开只浏览本地缓存,绝不自动触发后台 gh 进程,最省电、最省资源;想更新时点击「🔄 刷新」即可。")))
|
|
2067
|
+
// (第三种「定时自动轮询」策略已移除:前端定时器受浏览器后台节流且随
|
|
2068
|
+
// 组件卸载销毁,无法兑现定时更新承诺;SWR 挂载自愈已覆盖「打开即新鲜」)
|
|
2069
|
+
),
|
|
1837
2070
|
// 本地缓存信息与清理
|
|
1838
2071
|
h("div", {
|
|
1839
2072
|
className: "dsh-github-cache-info-box",
|
|
@@ -1843,13 +2076,70 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1843
2076
|
className: "dsh-github-btn-sm",
|
|
1844
2077
|
style: { padding: "3px 8px", fontSize: "11px", color: "var(--dsw-alias-state-error-primary, #cf222e)" },
|
|
1845
2078
|
onClick: handleClear,
|
|
1846
|
-
}, "🗑️ 清空缓存") : null), clearTip ? h("div", { style: { color: "var(--dsw-alias-state-success, #2ea043)", marginTop: "4px", fontWeight: 500 } }, clearTip) : null),
|
|
1847
|
-
//
|
|
1848
|
-
|
|
2079
|
+
}, "🗑️ 清空缓存") : null), clearTip ? h("div", { style: { color: "var(--dsw-alias-state-success, #2ea043)", marginTop: "4px", fontWeight: 500 } }, clearTip) : null)) : h("div", null,
|
|
2080
|
+
// 🌐 网络代理分区:设置保存即全局生效(驾驶舱/右侧栏/Agent 工具/升级链路),
|
|
2081
|
+
// 未启用时回落系统环境代理或直连(「默认走系统设置」语义)。
|
|
2082
|
+
h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginBottom: "14px", lineHeight: "1.5" } }, "设置后插件的 GitHub 数据链路(本页面、右侧栏、Agent 工具调用、版本升级)全部经代理访问;未启用时默认使用系统环境代理或直连。保存后立即生效,无需重启。"), h("label", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "10px", cursor: "pointer", fontSize: "13px" } }, h("input", {
|
|
2083
|
+
type: "checkbox",
|
|
2084
|
+
checked: proxyEnabled,
|
|
2085
|
+
onChange: function (e) { setProxyEnabled(Boolean(e.target.checked)); },
|
|
2086
|
+
}), "启用代理"), proxyEnabled ? h("div", null, h("div", { style: { fontSize: "12px", marginBottom: "4px" } }, "代理地址"), h("input", {
|
|
2087
|
+
className: "dsh-github-input",
|
|
2088
|
+
style: { width: "100%", boxSizing: "border-box", padding: "6px 10px", fontSize: "13px", marginBottom: "10px" },
|
|
2089
|
+
placeholder: "http://127.0.0.1:7890 或 socks5h://127.0.0.1:1080(DNS 由代理解析)",
|
|
2090
|
+
value: proxyUrl,
|
|
2091
|
+
onChange: function (e) { setProxyUrl(e.target.value); },
|
|
2092
|
+
}), h("div", { style: { fontSize: "12px", marginBottom: "4px" } }, "NO_PROXY 排除列表(逗号分隔,localhost 与 127.0.0.1 强制包含)"), h("input", {
|
|
2093
|
+
className: "dsh-github-input",
|
|
2094
|
+
style: { width: "100%", boxSizing: "border-box", padding: "6px 10px", fontSize: "12px", marginBottom: "10px" },
|
|
2095
|
+
value: proxyNoProxy,
|
|
2096
|
+
onChange: function (e) { setProxyNoProxy(e.target.value); },
|
|
2097
|
+
}), h("label", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "8px", cursor: "pointer", fontSize: "12px" } }, h("input", {
|
|
2098
|
+
type: "checkbox",
|
|
2099
|
+
checked: proxyApplyNpm,
|
|
2100
|
+
onChange: function (e) { setProxyApplyNpm(Boolean(e.target.checked)); },
|
|
2101
|
+
}), "同时应用于 npm 版本探测与一键升级")) : null,
|
|
2102
|
+
// 操作与反馈行:探测/保存按钮 + 结果胶囊
|
|
2103
|
+
h("div", { style: { display: "flex", alignItems: "center", gap: "8px", flexWrap: "wrap" } }, h("button", {
|
|
1849
2104
|
className: "dsh-github-btn-sm",
|
|
1850
|
-
style: { padding: "
|
|
1851
|
-
|
|
1852
|
-
|
|
2105
|
+
style: { padding: "5px 12px", fontSize: "12px" },
|
|
2106
|
+
disabled: proxyBusy || !proxyEnabled,
|
|
2107
|
+
onClick: handleProxyProbe,
|
|
2108
|
+
title: "经当前配置探测 GitHub API 连通性(约 2.5 秒)",
|
|
2109
|
+
}, "🧪 测试连通性"), h("button", {
|
|
2110
|
+
className: "dsh-github-btn-sm",
|
|
2111
|
+
style: {
|
|
2112
|
+
padding: "5px 14px",
|
|
2113
|
+
fontSize: "12px",
|
|
2114
|
+
background: "var(--dsw-alias-link, #0969da)",
|
|
2115
|
+
color: "#ffffff",
|
|
2116
|
+
borderColor: "var(--dsw-alias-link, #0969da)",
|
|
2117
|
+
fontWeight: 600,
|
|
2118
|
+
},
|
|
2119
|
+
disabled: proxyBusy,
|
|
2120
|
+
onClick: handleProxySave,
|
|
2121
|
+
}, proxyBusy ? "处理中..." : "💾 保存并全局应用"), proxyProbe ? h("span", {
|
|
2122
|
+
style: {
|
|
2123
|
+
fontSize: "12px",
|
|
2124
|
+
fontWeight: 500,
|
|
2125
|
+
color: proxyProbe.ok ? "var(--dsw-alias-state-success, #2ea043)" : "var(--dsw-alias-state-error-primary, #cf222e)",
|
|
2126
|
+
},
|
|
2127
|
+
title: proxyProbe.error || "",
|
|
2128
|
+
}, proxyProbe.ok ? "✅ " + proxyProbe.latencyMs + "ms" : "❌ 探测失败") : null), proxyMsg ? h("div", {
|
|
2129
|
+
style: {
|
|
2130
|
+
marginTop: "8px",
|
|
2131
|
+
fontSize: "12px",
|
|
2132
|
+
lineHeight: "1.5",
|
|
2133
|
+
color: proxyMsg.kind === "ok"
|
|
2134
|
+
? "var(--dsw-alias-state-success, #2ea043)"
|
|
2135
|
+
: proxyMsg.kind === "err"
|
|
2136
|
+
? "var(--dsw-alias-state-error-primary, #cf222e)"
|
|
2137
|
+
: "var(--dsw-alias-label-secondary, #656d76)",
|
|
2138
|
+
},
|
|
2139
|
+
}, proxyMsg.text) : null))),
|
|
2140
|
+
// 底部操作条:sync 分区提供主保存动作;proxy 分区有自己的「保存并全局应用」,
|
|
2141
|
+
// 底部统一为「完成」关闭弹窗,避免两个保存按钮的语义冲突。
|
|
2142
|
+
h("div", { className: "dsh-github-modal-footer" }, activeSection === "sync" ? h("button", {
|
|
1853
2143
|
className: "dsh-github-btn-sm",
|
|
1854
2144
|
style: {
|
|
1855
2145
|
padding: "6px 16px",
|
|
@@ -1859,7 +2149,11 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1859
2149
|
fontWeight: 600,
|
|
1860
2150
|
},
|
|
1861
2151
|
onClick: handleSave,
|
|
1862
|
-
}, "
|
|
2152
|
+
}, "保存同步设置") : null, h("button", {
|
|
2153
|
+
className: "dsh-github-btn-sm",
|
|
2154
|
+
style: { padding: "6px 14px" },
|
|
2155
|
+
onClick: props.onClose,
|
|
2156
|
+
}, activeSection === "sync" ? "取消" : "完成"))));
|
|
1863
2157
|
}
|
|
1864
2158
|
function GithubWorkspacePanel() {
|
|
1865
2159
|
// 1. 读取本地偏好配置与历史持久化快照 (0ms 纯内存读取)
|
|
@@ -1876,6 +2170,23 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1876
2170
|
var [activeTab, setActiveTab] = React.useState("workspaces"); // 'workspaces' | 'repos' | 'mywork'
|
|
1877
2171
|
var [searchQuery, setSearchQuery] = React.useState("");
|
|
1878
2172
|
var [issueFilter, setIssueFilter] = React.useState("all"); // 'all' | 'reported' | 'assigned' | 'created'
|
|
2173
|
+
// 代理生效状态(标题栏 🌐 徽章数据源):挂载时读一次 + 弹窗关闭时刷新
|
|
2174
|
+
//(保存发生在弹窗内,关闭时机足以让徽章与最新配置对齐,无需轮询)
|
|
2175
|
+
var [proxyActive, setProxyActive] = React.useState(null);
|
|
2176
|
+
var refreshProxyBadge = React.useCallback(function () {
|
|
2177
|
+
fetch("/api/github/proxy")
|
|
2178
|
+
.then(function (r) { return r.json(); })
|
|
2179
|
+
.then(function (j) {
|
|
2180
|
+
if (j && j.ok && j.state && j.state.config) {
|
|
2181
|
+
setProxyActive({ enabled: Boolean(j.state.config.url), url: j.state.config.url || "" });
|
|
2182
|
+
}
|
|
2183
|
+
else {
|
|
2184
|
+
setProxyActive({ enabled: false, url: "" });
|
|
2185
|
+
}
|
|
2186
|
+
})
|
|
2187
|
+
.catch(function () { });
|
|
2188
|
+
}, []);
|
|
2189
|
+
React.useEffect(function () { refreshProxyBadge(); }, [refreshProxyBadge]);
|
|
1879
2190
|
// gh 业务数据就绪后,闲时 1.5 秒异步静默检测升级,绝不影响首屏
|
|
1880
2191
|
React.useEffect(() => {
|
|
1881
2192
|
if (!data)
|
|
@@ -1960,7 +2271,9 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1960
2271
|
setLoading(false);
|
|
1961
2272
|
}
|
|
1962
2273
|
}, [data, syncSettings]);
|
|
1963
|
-
// 挂载加载调度:SWR 模式下初次延迟 300ms
|
|
2274
|
+
// 挂载加载调度:SWR 模式下初次延迟 300ms 后台平滑发起静默同步。
|
|
2275
|
+
// 无论本地是否有旧快照都拉:昨天的持久化快照在挂载后 300ms 内自愈,
|
|
2276
|
+
// 「打开驾驶舱即新鲜」由 SWR 定义本身保证,而非依赖用户停留或手动刷新。
|
|
1964
2277
|
React.useEffect(() => {
|
|
1965
2278
|
if (syncSettings.strategy === "swr") {
|
|
1966
2279
|
var timer = setTimeout(function () { loadData(false); }, 300);
|
|
@@ -1970,15 +2283,7 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1970
2283
|
loadData(false);
|
|
1971
2284
|
}
|
|
1972
2285
|
}, [syncSettings.strategy]);
|
|
1973
|
-
//
|
|
1974
|
-
React.useEffect(() => {
|
|
1975
|
-
if (syncSettings.strategy !== "interval" || !syncSettings.intervalMs || syncSettings.intervalMs <= 0)
|
|
1976
|
-
return;
|
|
1977
|
-
var timer = setInterval(function () {
|
|
1978
|
-
loadData(false);
|
|
1979
|
-
}, syncSettings.intervalMs);
|
|
1980
|
-
return function () { clearInterval(timer); };
|
|
1981
|
-
}, [syncSettings.strategy, syncSettings.intervalMs, loadData]);
|
|
2286
|
+
// (原定时轮询调度已随 'interval' 策略一并移除)
|
|
1982
2287
|
// 窗口切回自动探测自愈:优先轻量快速探针,检测到已登录立即自愈
|
|
1983
2288
|
React.useEffect(() => {
|
|
1984
2289
|
var onFocus = () => {
|
|
@@ -1998,16 +2303,35 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
1998
2303
|
return () => window.removeEventListener("focus", onFocus);
|
|
1999
2304
|
}, [data, loadData]);
|
|
2000
2305
|
var h = React.createElement;
|
|
2001
|
-
var headerEl = h("div", { className: "dsh-github-header" }, h("div", { className: "dsh-github-title" }, renderOctocatBadge(32), h("h2", null, "GitHub 全景驾驶舱"), h(SyncStatusBadge, { syncStatus, lastSyncedAt })
|
|
2306
|
+
var headerEl = h("div", { className: "dsh-github-header" }, h("div", { className: "dsh-github-title" }, renderOctocatBadge(32), h("h2", null, "GitHub 全景驾驶舱"), h(SyncStatusBadge, { syncStatus, lastSyncedAt }),
|
|
2307
|
+
// 代理生效徽章:启用时可见,hover 展示代理地址,让用户随时确认「当前确实在走代理」
|
|
2308
|
+
proxyActive && proxyActive.enabled
|
|
2309
|
+
? h("span", {
|
|
2310
|
+
style: {
|
|
2311
|
+
display: "inline-flex",
|
|
2312
|
+
alignItems: "center",
|
|
2313
|
+
gap: "4px",
|
|
2314
|
+
fontSize: "11px",
|
|
2315
|
+
fontWeight: 500,
|
|
2316
|
+
padding: "2px 8px",
|
|
2317
|
+
borderRadius: "999px",
|
|
2318
|
+
background: "rgba(9, 105, 218, 0.1)",
|
|
2319
|
+
border: "1px solid rgba(9, 105, 218, 0.35)",
|
|
2320
|
+
color: "var(--dsw-alias-link, #0969da)",
|
|
2321
|
+
cursor: "default",
|
|
2322
|
+
},
|
|
2323
|
+
title: "插件网络代理已启用: " + proxyActive.url + "(GitHub 数据链路与工具调用经此代理;点击 ⚙️ 可修改)",
|
|
2324
|
+
}, "🌐 代理")
|
|
2325
|
+
: null), h("div", { style: { display: "flex", alignItems: "center", gap: "8px" } }, h("button", {
|
|
2002
2326
|
className: "dsh-github-refresh-btn",
|
|
2003
2327
|
onClick: () => loadData(true),
|
|
2004
2328
|
disabled: loading,
|
|
2005
2329
|
}, loading ? "同步中..." : "🔄 刷新全局数据"), h("button", {
|
|
2006
2330
|
className: "dsh-github-btn-sm",
|
|
2007
2331
|
onClick: () => setIsSettingsModalOpen(true),
|
|
2008
|
-
title: "
|
|
2332
|
+
title: "配置数据同步节奏、本地缓存与网络代理",
|
|
2009
2333
|
style: { padding: "6px 12px" },
|
|
2010
|
-
}, "⚙️
|
|
2334
|
+
}, "⚙️ 设置")));
|
|
2011
2335
|
if (loading && !data) {
|
|
2012
2336
|
return h("div", { className: "dsh-github-panel" }, headerEl, h("div", { className: "dsh-github-empty" }, "正在加载全局 GitHub 账号与工作区数据..."));
|
|
2013
2337
|
}
|
|
@@ -2017,7 +2341,11 @@ body[data-ds-dark-theme] .dsh-github-radio {
|
|
|
2017
2341
|
: null;
|
|
2018
2342
|
var settingsModalEl = h(GlobalSyncSettingsModal, {
|
|
2019
2343
|
isOpen: isSettingsModalOpen,
|
|
2020
|
-
onClose: () =>
|
|
2344
|
+
onClose: () => {
|
|
2345
|
+
setIsSettingsModalOpen(false);
|
|
2346
|
+
// 弹窗内可能刚保存过代理配置,关闭时同步刷新标题栏徽章
|
|
2347
|
+
refreshProxyBadge();
|
|
2348
|
+
},
|
|
2021
2349
|
currentSettings: syncSettings,
|
|
2022
2350
|
onSave: (newSettings) => {
|
|
2023
2351
|
setSyncSettings(newSettings);
|
package/lib/executor.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GhExecutionOptions, GhResult, AuthStatus, RepoMetadata, PluginConfig } from './types.js';
|
|
2
|
+
import type { ProxyManager } from './proxy.js';
|
|
2
3
|
/**
|
|
3
4
|
* 按「字符数 + UTF-8 字节数」双口径截断输出。
|
|
4
5
|
* 抽成纯函数是刻意的:截断逻辑是崩溃高发区(切碎多字节字符、误伤 JSON、把二进制流截成垃圾),
|
|
@@ -14,10 +15,26 @@ export declare class GhExecutor {
|
|
|
14
15
|
maxOutputChars: number;
|
|
15
16
|
/** UTF-8 字节口径的硬上限;未配置时按 maxOutputChars × 4 推导(覆盖 CJK 3 字节与 emoji 4 字节) */
|
|
16
17
|
maxOutputBytes: number;
|
|
18
|
+
/**
|
|
19
|
+
* 列表类查询的默认条数上限。
|
|
20
|
+
* 为什么挂在 executor 而不是给每个工具工厂加 config 参数:executor 是全部
|
|
21
|
+
* 工具共享的依赖注入点,配置语义本就属于「执行层默认值」;工厂签名零改动,
|
|
22
|
+
* 且热更新路径 updateConfig 能同步刷新。工具内以 `?? 20` 兜底保证旧配置兼容。
|
|
23
|
+
*/
|
|
24
|
+
defaultListLimit: number;
|
|
25
|
+
/**
|
|
26
|
+
* 代理管理器引用(可选依赖)。
|
|
27
|
+
* 注入后每次 gh 子进程拉起都会合并代理环境变量——这是「工具调用 + Web 页面数据
|
|
28
|
+
* 全部走代理」的唯一咽喉(两条链路共用本 executor)。未注入时零干预,
|
|
29
|
+
* gh 自然继承宿主系统环境变量(系统级代理或直连),即「默认走系统设置」语义。
|
|
30
|
+
*/
|
|
31
|
+
private proxyManager?;
|
|
17
32
|
/** 认证状态缓存。`gh auth status` 实测 5.4 秒,而它位于全局驾驶舱关键路径的最前面 */
|
|
18
33
|
private authCache;
|
|
19
34
|
constructor(config?: PluginConfig);
|
|
20
35
|
updateConfig(config?: PluginConfig): void;
|
|
36
|
+
/** 注入代理管理器(main.ts 装配时调用一次;测试可注入 mock) */
|
|
37
|
+
attachProxyManager(manager: ProxyManager): void;
|
|
21
38
|
/**
|
|
22
39
|
* 智能解析最可靠的工作区物理路径:
|
|
23
40
|
* 1. 优先使用显式指定的有效 cwd(若包含 .git 目录)
|