dsh-github-flow 0.3.0 → 0.5.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 +287 -143
- package/README.md +270 -125
- package/docs/UPGRADE-NOTES.md +12 -9
- package/docs/architecture.md +126 -126
- package/lib/api/routes-actions.js +249 -0
- package/lib/api/routes-overview.js +94 -2
- package/lib/cache.d.ts +4 -0
- package/lib/cache.js +14 -0
- package/lib/client.d.ts +14 -1
- package/lib/client.js +4287 -2500
- package/lib/commands/gh.d.ts +6 -1
- package/lib/commands/gh.js +144 -71
- package/lib/executor/git-parser.d.ts +57 -0
- package/lib/executor/git-parser.js +255 -0
- package/lib/executor/platform-guide.d.ts +14 -0
- package/lib/executor/platform-guide.js +40 -0
- package/lib/executor/process-utils.d.ts +51 -0
- package/lib/executor/process-utils.js +162 -0
- package/lib/executor/version-utils.d.ts +12 -0
- package/lib/executor/version-utils.js +27 -0
- package/lib/executor.d.ts +70 -48
- package/lib/executor.js +371 -356
- package/lib/git-watcher.d.ts +36 -0
- package/lib/git-watcher.js +91 -0
- package/lib/main.js +37 -3
- package/lib/renderers/agent-task.d.ts +16 -0
- package/lib/renderers/agent-task.js +107 -0
- package/lib/renderers/cache.d.ts +8 -0
- package/lib/renderers/cache.js +66 -0
- package/lib/renderers/codespace.d.ts +16 -0
- package/lib/renderers/codespace.js +103 -0
- package/lib/renderers/common.d.ts +24 -0
- package/lib/renderers/common.js +88 -0
- package/lib/renderers/discussion.d.ts +16 -0
- package/lib/renderers/discussion.js +101 -0
- package/lib/renderers/gist.d.ts +15 -0
- package/lib/renderers/gist.js +99 -0
- package/lib/renderers/issue.d.ts +4 -0
- package/lib/renderers/issue.js +70 -0
- package/lib/renderers/label.d.ts +4 -0
- package/lib/renderers/label.js +48 -0
- package/lib/renderers/markdown.d.ts +19 -32
- package/lib/renderers/markdown.js +19 -624
- package/lib/renderers/pr.d.ts +4 -0
- package/lib/renderers/pr.js +107 -0
- package/lib/renderers/project.d.ts +20 -0
- package/lib/renderers/project.js +128 -0
- package/lib/renderers/release.d.ts +4 -0
- package/lib/renderers/release.js +74 -0
- package/lib/renderers/repo.d.ts +4 -0
- package/lib/renderers/repo.js +149 -0
- package/lib/renderers/ruleset.d.ts +4 -0
- package/lib/renderers/ruleset.js +74 -0
- package/lib/renderers/run.d.ts +4 -0
- package/lib/renderers/run.js +79 -0
- package/lib/renderers/skill.d.ts +34 -0
- package/lib/renderers/skill.js +241 -0
- package/lib/renderers/status.d.ts +28 -0
- package/lib/renderers/status.js +176 -0
- package/lib/telemetry.d.ts +70 -0
- package/lib/telemetry.js +161 -0
- package/lib/tools/agent-task.d.ts +54 -0
- package/lib/tools/agent-task.js +135 -0
- package/lib/tools/cache.d.ts +64 -0
- package/lib/tools/cache.js +186 -0
- package/lib/tools/codespace.d.ts +51 -0
- package/lib/tools/codespace.js +154 -0
- package/lib/tools/discussion.d.ts +70 -0
- package/lib/tools/discussion.js +195 -0
- package/lib/tools/gist.d.ts +155 -0
- package/lib/tools/gist.js +190 -0
- package/lib/tools/help.js +214 -13
- package/lib/tools/image-utils.d.ts +8 -0
- package/lib/tools/image-utils.js +34 -0
- package/lib/tools/issue.d.ts +8 -1
- package/lib/tools/issue.js +26 -4
- package/lib/tools/label.d.ts +80 -0
- package/lib/tools/label.js +237 -0
- package/lib/tools/pr.d.ts +8 -0
- package/lib/tools/pr.js +48 -3
- package/lib/tools/project.d.ts +80 -0
- package/lib/tools/project.js +241 -0
- package/lib/tools/repo.js +13 -1
- package/lib/tools/ruleset.d.ts +80 -0
- package/lib/tools/ruleset.js +177 -0
- package/lib/tools/skill.d.ts +24 -1
- package/lib/tools/skill.js +115 -5
- package/lib/tools/status.d.ts +40 -0
- package/lib/tools/status.js +58 -0
- package/lib/types.d.ts +44 -0
- package/lib/ui/auth-guide-card.d.ts +4 -0
- package/lib/ui/auth-guide-card.js +161 -0
- package/lib/ui/branch-selector.d.ts +10 -0
- package/lib/ui/branch-selector.js +163 -0
- package/lib/ui/commit-modal.d.ts +8 -0
- package/lib/ui/commit-modal.js +219 -0
- package/lib/ui/help-modal.d.ts +15 -0
- package/lib/ui/help-modal.js +202 -0
- package/lib/ui/icons.d.ts +7 -0
- package/lib/ui/icons.js +53 -0
- package/lib/ui/network-banner.d.ts +10 -0
- package/lib/ui/network-banner.js +54 -0
- package/lib/ui/storage.d.ts +35 -0
- package/lib/ui/storage.js +158 -0
- package/lib/ui/styles.d.ts +6 -0
- package/lib/ui/styles.js +1544 -0
- package/lib/ui/sync-settings-modal.d.ts +11 -0
- package/lib/ui/sync-settings-modal.js +350 -0
- package/lib/ui/sync-status-badge.d.ts +8 -0
- package/lib/ui/sync-status-badge.js +64 -0
- package/lib/ui/upgrade-card.d.ts +7 -0
- package/lib/ui/upgrade-card.js +222 -0
- package/lib/ui/utils.d.ts +45 -0
- package/lib/ui/utils.js +226 -0
- package/lib/ui/workspace-panel.d.ts +4 -0
- package/lib/ui/workspace-panel.js +489 -0
- package/lib/upgrade-manager.d.ts +5 -1
- package/lib/upgrade-manager.js +24 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 全景驾驶舱「⚙️ 设置」模态弹窗组件:左侧分区导航(数据同步 / 网络代理 / 更新设置 / 关于)+ 右侧内容区
|
|
3
|
+
*/
|
|
4
|
+
export declare function GlobalSyncSettingsModal(props: {
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
currentSettings: any;
|
|
8
|
+
onSave: (newSettings: any) => void;
|
|
9
|
+
onClearCache: () => void;
|
|
10
|
+
initialSection?: string;
|
|
11
|
+
}): any;
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 全景驾驶舱「⚙️ 设置」模态弹窗组件:左侧分区导航(数据同步 / 网络代理 / 更新设置 / 关于)+ 右侧内容区
|
|
3
|
+
*/
|
|
4
|
+
export function GlobalSyncSettingsModal(props) {
|
|
5
|
+
if (!props.isOpen)
|
|
6
|
+
return null;
|
|
7
|
+
var [activeSection, setActiveSection] = React.useState(props.initialSection || "sync");
|
|
8
|
+
var [strategy, setStrategy] = React.useState(props.currentSettings.strategy || "swr");
|
|
9
|
+
var [localGitWatch, setLocalGitWatch] = React.useState(props.currentSettings.localGitWatch !== false);
|
|
10
|
+
var [cloudSyncIntervalMs, setCloudSyncIntervalMs] = React.useState(Number(props.currentSettings.cloudSyncIntervalMs) || 600000);
|
|
11
|
+
var [cacheMeta, setCacheMeta] = React.useState(getCacheStorageMeta());
|
|
12
|
+
var [clearTip, setClearTip] = React.useState("");
|
|
13
|
+
React.useEffect(function () {
|
|
14
|
+
if (props.isOpen && props.currentSettings) {
|
|
15
|
+
setStrategy(props.currentSettings.strategy || "swr");
|
|
16
|
+
setLocalGitWatch(props.currentSettings.localGitWatch !== false);
|
|
17
|
+
setCloudSyncIntervalMs(Number(props.currentSettings.cloudSyncIntervalMs) || 600000);
|
|
18
|
+
}
|
|
19
|
+
}, [props.isOpen, props.currentSettings]);
|
|
20
|
+
var [updateMode, setUpdateMode] = React.useState("official");
|
|
21
|
+
var [updateBusy, setUpdateBusy] = React.useState(false);
|
|
22
|
+
var [updateMsg, setUpdateMsg] = React.useState(null);
|
|
23
|
+
var [aboutVersion, setAboutVersion] = React.useState(null);
|
|
24
|
+
React.useEffect(function () {
|
|
25
|
+
if (!props.isOpen)
|
|
26
|
+
return;
|
|
27
|
+
fetch("/api/github/update-settings")
|
|
28
|
+
.then(function (r) { return r.json(); })
|
|
29
|
+
.then(function (j) {
|
|
30
|
+
if (j && j.ok && j.data && j.data.mode) {
|
|
31
|
+
setUpdateMode(j.data.mode);
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
.catch(function () { });
|
|
35
|
+
fetch("/api/github/check-update")
|
|
36
|
+
.then(function (r) { return r.json(); })
|
|
37
|
+
.then(function (j) {
|
|
38
|
+
if (j && j.ok && j.data && j.data.currentVersion)
|
|
39
|
+
setAboutVersion(j.data.currentVersion);
|
|
40
|
+
})
|
|
41
|
+
.catch(function () { });
|
|
42
|
+
}, [props.isOpen]);
|
|
43
|
+
var [proxyEnabled, setProxyEnabled] = React.useState(false);
|
|
44
|
+
var [proxyUrl, setProxyUrl] = React.useState("");
|
|
45
|
+
var [proxyNoProxy, setProxyNoProxy] = React.useState("localhost,127.0.0.1");
|
|
46
|
+
var [proxyApplyNpm, setProxyApplyNpm] = React.useState(true);
|
|
47
|
+
var [proxyBusy, setProxyBusy] = React.useState(false);
|
|
48
|
+
var [proxyMsg, setProxyMsg] = React.useState(null);
|
|
49
|
+
var [proxyProbe, setProxyProbe] = React.useState(null);
|
|
50
|
+
React.useEffect(function () {
|
|
51
|
+
if (!props.isOpen)
|
|
52
|
+
return;
|
|
53
|
+
fetch("/api/github/proxy")
|
|
54
|
+
.then(function (r) { return r.json(); })
|
|
55
|
+
.then(function (j) {
|
|
56
|
+
if (j && j.ok && j.state) {
|
|
57
|
+
setProxyEnabled(Boolean(j.state.config && j.state.config.url));
|
|
58
|
+
setProxyUrl((j.state.config && j.state.config.url) || "");
|
|
59
|
+
setProxyNoProxy((j.state.config && j.state.config.noProxy) || "localhost,127.0.0.1");
|
|
60
|
+
setProxyApplyNpm(j.state.config ? j.state.config.applyToPackageManager !== false : true);
|
|
61
|
+
if (j.state.lastProbe)
|
|
62
|
+
setProxyProbe(j.state.lastProbe);
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
.catch(function () { });
|
|
66
|
+
}, [props.isOpen]);
|
|
67
|
+
React.useEffect(function () {
|
|
68
|
+
var onKeyDown = function (e) {
|
|
69
|
+
if (e.key === "Escape" || e.keyCode === 27) {
|
|
70
|
+
props.onClose();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
window.addEventListener("keydown", onKeyDown);
|
|
74
|
+
return function () { window.removeEventListener("keydown", onKeyDown); };
|
|
75
|
+
}, [props.onClose]);
|
|
76
|
+
React.useEffect(function () {
|
|
77
|
+
if (props.isOpen && props.initialSection) {
|
|
78
|
+
setActiveSection(props.initialSection);
|
|
79
|
+
}
|
|
80
|
+
}, [props.isOpen, props.initialSection]);
|
|
81
|
+
var handleUpdateSave = function () {
|
|
82
|
+
setUpdateBusy(true);
|
|
83
|
+
setUpdateMsg(null);
|
|
84
|
+
fetch("/api/github/update-settings", {
|
|
85
|
+
method: "POST",
|
|
86
|
+
headers: { "Content-Type": "application/json" },
|
|
87
|
+
body: JSON.stringify({ mode: updateMode }),
|
|
88
|
+
})
|
|
89
|
+
.then(function (r) { return r.json(); })
|
|
90
|
+
.then(function (j) {
|
|
91
|
+
setUpdateBusy(false);
|
|
92
|
+
if (j && j.ok && j.data) {
|
|
93
|
+
var d = j.data;
|
|
94
|
+
var text = "";
|
|
95
|
+
if (d.mode === "off") {
|
|
96
|
+
text = "✅ 已关闭自动检查更新(/gh upgrade 与一键升级仍可用),无需重启";
|
|
97
|
+
}
|
|
98
|
+
else if (d.probe && d.probe.latestVersion) {
|
|
99
|
+
text = "✅ 已切换至" + d.description + ",当前最新版本 v" + d.probe.latestVersion
|
|
100
|
+
+ (d.probe.hasUpdate ? "(有可用更新)" : "(已是最新)") + ",无需重启";
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
text = "✅ 已切换至" + d.description + ",但新源暂时不可达(版本探测失败,稍后会自动重试);设置已生效,无需重启";
|
|
104
|
+
}
|
|
105
|
+
if (d.persisted === false) {
|
|
106
|
+
text += ";⚠️ 设置写盘失败,重启后需重新选择";
|
|
107
|
+
}
|
|
108
|
+
setUpdateMsg({ kind: "ok", text: text });
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
setUpdateMsg({ kind: "err", text: (j && j.message) || "保存失败" });
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
.catch(function (e) {
|
|
115
|
+
setUpdateBusy(false);
|
|
116
|
+
setUpdateMsg({ kind: "err", text: "网络请求失败: " + (e && e.message ? e.message : e) });
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
var h = React.createElement;
|
|
120
|
+
var handleSave = function () {
|
|
121
|
+
var updated = {
|
|
122
|
+
strategy: strategy,
|
|
123
|
+
localGitWatch: localGitWatch,
|
|
124
|
+
cloudSyncIntervalMs: Number(cloudSyncIntervalMs) || 600000,
|
|
125
|
+
};
|
|
126
|
+
saveLocalSyncSettings(updated);
|
|
127
|
+
props.onSave(updated);
|
|
128
|
+
props.onClose();
|
|
129
|
+
};
|
|
130
|
+
var handleClear = function () {
|
|
131
|
+
clearStoredGlobalOverview();
|
|
132
|
+
props.onClearCache();
|
|
133
|
+
setCacheMeta({ exists: false, sizeKb: 0, savedAt: 0 });
|
|
134
|
+
setClearTip("本地缓存已彻底清空!");
|
|
135
|
+
setTimeout(function () { setClearTip(""); }, 2000);
|
|
136
|
+
};
|
|
137
|
+
var handleProxySave = function () {
|
|
138
|
+
setProxyBusy(true);
|
|
139
|
+
setProxyMsg(null);
|
|
140
|
+
fetch("/api/github/proxy", {
|
|
141
|
+
method: "POST",
|
|
142
|
+
headers: { "Content-Type": "application/json" },
|
|
143
|
+
body: JSON.stringify({
|
|
144
|
+
url: proxyEnabled ? proxyUrl.trim() : "",
|
|
145
|
+
noProxy: proxyNoProxy,
|
|
146
|
+
applyToPackageManager: proxyApplyNpm,
|
|
147
|
+
}),
|
|
148
|
+
})
|
|
149
|
+
.then(function (r) { return r.json(); })
|
|
150
|
+
.then(function (j) {
|
|
151
|
+
setProxyBusy(false);
|
|
152
|
+
if (j && j.ok) {
|
|
153
|
+
setProxyMsg({
|
|
154
|
+
kind: "ok",
|
|
155
|
+
text: j.state && j.state.config && j.state.config.url
|
|
156
|
+
? "🌐 代理已保存并全局生效(驾驶舱 / 右侧栏 / Agent 工具 / 升级链路),无需重启"
|
|
157
|
+
: "已切换为系统默认网络(直连或系统环境代理),无需重启",
|
|
158
|
+
});
|
|
159
|
+
if (j.state && j.state.lastProbe)
|
|
160
|
+
setProxyProbe(j.state.lastProbe);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
setProxyMsg({ kind: "err", text: (j && j.message) || "保存失败" });
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
.catch(function (e) {
|
|
167
|
+
setProxyBusy(false);
|
|
168
|
+
setProxyMsg({ kind: "err", text: "网络请求失败: " + (e && e.message ? e.message : e) });
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
var handleProxyProbe = function () {
|
|
172
|
+
setProxyBusy(true);
|
|
173
|
+
setProxyMsg(null);
|
|
174
|
+
fetch("/api/github/proxy/probe", { method: "POST" })
|
|
175
|
+
.then(function (r) { return r.json(); })
|
|
176
|
+
.then(function (j) {
|
|
177
|
+
setProxyBusy(false);
|
|
178
|
+
if (j && j.ok && j.probe) {
|
|
179
|
+
setProxyProbe(j.probe);
|
|
180
|
+
setProxyMsg(j.probe.ok
|
|
181
|
+
? { kind: "ok", text: "✅ GitHub API 可达 (" + j.probe.latencyMs + "ms)" }
|
|
182
|
+
: { kind: "err", text: "❌ " + (j.probe.error || "探测失败") });
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
setProxyMsg({ kind: "err", text: (j && j.message) || "探测失败" });
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
.catch(function (e) {
|
|
189
|
+
setProxyBusy(false);
|
|
190
|
+
setProxyMsg({ kind: "err", text: "探测请求失败: " + (e && e.message ? e.message : e) });
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
return h("div", { className: "dsh-github-modal-overlay", onClick: props.onClose }, h("div", {
|
|
194
|
+
className: "dsh-github-modal-dialog",
|
|
195
|
+
onClick: function (e) { e.stopPropagation(); },
|
|
196
|
+
}, h("div", { className: "dsh-github-modal-header" }, h("h3", { style: { margin: 0, fontSize: "16px", fontWeight: 600 } }, "⚙️ 设置"), h("button", {
|
|
197
|
+
style: { background: "none", border: "none", cursor: "pointer", fontSize: "18px", color: "var(--dsw-alias-label-secondary, #656d76)" },
|
|
198
|
+
onClick: props.onClose,
|
|
199
|
+
}, "✕")), h("div", { className: "dsh-github-modal-body" }, h("div", { className: "dsh-github-settings-nav" }, h("button", {
|
|
200
|
+
className: "dsh-github-settings-nav-item" + (activeSection === "sync" ? " active" : ""),
|
|
201
|
+
onClick: function () { setActiveSection("sync"); },
|
|
202
|
+
}, "🔄 数据同步"), h("button", {
|
|
203
|
+
className: "dsh-github-settings-nav-item" + (activeSection === "proxy" ? " active" : ""),
|
|
204
|
+
onClick: function () { setActiveSection("proxy"); },
|
|
205
|
+
}, "🌐 网络代理"), h("button", {
|
|
206
|
+
className: "dsh-github-settings-nav-item" + (activeSection === "update" ? " active" : ""),
|
|
207
|
+
onClick: function () { setActiveSection("update"); },
|
|
208
|
+
}, "⬆️ 更新设置"), h("button", {
|
|
209
|
+
className: "dsh-github-settings-nav-item" + (activeSection === "about" ? " active" : ""),
|
|
210
|
+
onClick: function () { setActiveSection("about"); },
|
|
211
|
+
}, "ℹ️ 关于")), 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 全景驾驶舱的数据拉取节奏。启用秒开模式可利用本地持久化缓存消除每次打开时的漫长等待。"), h("div", { style: { marginBottom: "16px" } }, h("div", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "8px" } }, "数据刷新策略(三选一)"), h("div", {
|
|
212
|
+
className: "dsh-github-radio-card" + (strategy === "swr" ? " active" : ""),
|
|
213
|
+
onClick: function () { setStrategy("swr"); },
|
|
214
|
+
}, h("input", { type: "radio", name: "sync-strategy", className: "dsh-github-radio", checked: strategy === "swr", readOnly: true }), h("div", null, h("div", { style: { fontWeight: 600, fontSize: "13px" } }, "⚡ 秒开展示旧数据 (SWR, 强烈推荐)"), h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginTop: "2px" } }, "打开立即展示上次本地缓存(0ms秒开),后台静默同步一次最新状态。"))), h("div", {
|
|
215
|
+
className: "dsh-github-radio-card" + (strategy === "auto" ? " active" : ""),
|
|
216
|
+
onClick: function () { setStrategy("auto"); },
|
|
217
|
+
}, h("input", { type: "radio", name: "sync-strategy", className: "dsh-github-radio", checked: strategy === "auto", readOnly: true }), h("div", { style: { flex: 1 } }, h("div", { style: { fontWeight: 600, fontSize: "13px" } }, "☁️ 云端数据定时自动同步 (SWR + 定时轮询)"), h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginTop: "2px" } }, "首屏秒开旧数据并立即拉新,拉取完成后开始计时;循环静默更新 PR、Issue 与 Actions。内置窗口息屏自动避让,防止耗尽配额。"), strategy === "auto"
|
|
218
|
+
? h("div", {
|
|
219
|
+
style: { display: "flex", alignItems: "center", gap: "8px", marginTop: "8px" },
|
|
220
|
+
onClick: function (e) { e.stopPropagation(); },
|
|
221
|
+
}, h("span", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", fontWeight: 500 } }, "同步周期:"), h("select", {
|
|
222
|
+
className: "dsh-github-btn-sm",
|
|
223
|
+
style: { padding: "4px 8px", fontSize: "12px", cursor: "pointer", background: "var(--dsw-alias-bg-base, #fff)" },
|
|
224
|
+
value: cloudSyncIntervalMs,
|
|
225
|
+
onChange: function (e) { setCloudSyncIntervalMs(Number(e.target.value)); },
|
|
226
|
+
}, h("option", { value: 300000 }, "5 分钟 (高频感知)"), h("option", { value: 600000 }, "10 分钟 (标准推荐)"), h("option", { value: 1800000 }, "30 分钟 (轻量节省)"), h("option", { value: 3600000 }, "1 小时 (极低频)")))
|
|
227
|
+
: null)), h("div", {
|
|
228
|
+
className: "dsh-github-radio-card" + (strategy === "manual" ? " active" : ""),
|
|
229
|
+
onClick: function () { setStrategy("manual"); },
|
|
230
|
+
}, h("input", { type: "radio", name: "sync-strategy", 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 进程,最省电、最省资源;想更新时点击「🔄 刷新」即可。")))), h("div", { style: { marginBottom: "16px", borderTop: "1px solid var(--dsw-alias-border-l2, #e1e4e8)", paddingTop: "14px" } }, h("div", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "8px" } }, "高级自动化与状态感知"), h("label", {
|
|
231
|
+
style: { display: "flex", alignItems: "flex-start", gap: "8px", cursor: "pointer", padding: "6px 8px", borderRadius: "6px", background: localGitWatch ? "var(--dsw-alias-bg-module-platform, rgba(9, 105, 218, 0.06))" : "transparent" },
|
|
232
|
+
}, h("input", {
|
|
233
|
+
type: "checkbox",
|
|
234
|
+
style: { marginTop: "3px" },
|
|
235
|
+
checked: localGitWatch,
|
|
236
|
+
onChange: function (e) { setLocalGitWatch(e.target.checked); },
|
|
237
|
+
}), h("div", null, h("div", { style: { fontWeight: 600, fontSize: "12px" } }, "📁 本地 Git 改动实时感知 (仅右侧栏生效)"), h("div", { style: { fontSize: "11px", color: "var(--dsw-alias-label-secondary, #656d76)", marginTop: "2px" } }, "定向监听当前仓库的 .git 核心元数据,代码修改、暂存与分支切换毫秒级自动对齐右侧栏,零网络流量消耗;全景首页不挂载,保持轻量。")))), h("div", {
|
|
238
|
+
className: "dsh-github-cache-info-box",
|
|
239
|
+
}, h("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" } }, h("span", null, cacheMeta.exists
|
|
240
|
+
? `📦 本地缓存: 约 ${cacheMeta.sizeKb} KB (上次保存: ${new Date(cacheMeta.savedAt).toLocaleTimeString()})`
|
|
241
|
+
: "📦 暂无本地持久化缓存"), cacheMeta.exists ? h("button", {
|
|
242
|
+
className: "dsh-github-btn-sm",
|
|
243
|
+
style: { padding: "3px 8px", fontSize: "11px", color: "var(--dsw-alias-state-error-primary, #cf222e)" },
|
|
244
|
+
onClick: handleClear,
|
|
245
|
+
}, "🗑️ 清空缓存") : null), clearTip ? h("div", { style: { color: "var(--dsw-alias-state-success, #2ea043)", marginTop: "4px", fontWeight: 500 } }, clearTip) : null)) : activeSection === "update" ? h("div", null, h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginBottom: "14px", lineHeight: "1.5" } }, "选择插件新版本检测所用的 npm 源。检测与升级流量均遵循「🌐 网络代理」分区设置:启用 http/https 代理时自动经代理访问;socks5 代理下 npm 检测为直连(gh 与升级子进程链路仍走代理)。无论选择哪个源,安装与升级流程本身不受影响。"), h("div", { style: { marginBottom: "16px" } }, h("div", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "8px" } }, "更新源"), h("div", {
|
|
246
|
+
className: "dsh-github-radio-card" + (updateMode === "official" ? " active" : ""),
|
|
247
|
+
onClick: function () { setUpdateMode("official"); },
|
|
248
|
+
}, h("input", { type: "radio", className: "dsh-github-radio", checked: updateMode === "official", readOnly: true }), h("div", null, h("div", { style: { fontWeight: 600, fontSize: "13px" } }, "🌍 npm 官方源 (推荐)"), h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginTop: "2px" } }, "版本全球首发最及时,刚发布的新版立即可见;国内直连可能较慢。"))), h("div", {
|
|
249
|
+
className: "dsh-github-radio-card" + (updateMode === "mirror" ? " active" : ""),
|
|
250
|
+
onClick: function () { setUpdateMode("mirror"); },
|
|
251
|
+
}, h("input", { type: "radio", className: "dsh-github-radio", checked: updateMode === "mirror", readOnly: true }), h("div", null, h("div", { style: { fontWeight: 600, fontSize: "13px" } }, "🇨🇳 国内镜像 (npmmirror)"), h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginTop: "2px" } }, "阿里云镜像,国内访问快;同步存在分钟级延迟,刚发布的新版可能暂时查不到。"))), h("div", {
|
|
252
|
+
className: "dsh-github-radio-card" + (updateMode === "off" ? " active" : ""),
|
|
253
|
+
onClick: function () { setUpdateMode("off"); },
|
|
254
|
+
}, h("input", { type: "radio", className: "dsh-github-radio", checked: updateMode === "off", readOnly: true }), h("div", null, h("div", { style: { fontWeight: 600, fontSize: "13px" } }, "⛔ 不检查更新"), h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginTop: "2px" } }, "关闭自动检查与新版提示横幅;/gh upgrade 命令与一键升级仍然可用。")))), h("div", { style: { display: "flex", alignItems: "center", gap: "8px", flexWrap: "wrap" } }, h("button", {
|
|
255
|
+
className: "dsh-github-btn-sm dsh-github-primary-btn",
|
|
256
|
+
disabled: updateBusy,
|
|
257
|
+
onClick: handleUpdateSave,
|
|
258
|
+
}, updateBusy ? "验证中..." : "💾 保存并全局应用"), updateMsg ? h("span", {
|
|
259
|
+
style: {
|
|
260
|
+
fontSize: "12px",
|
|
261
|
+
lineHeight: "1.5",
|
|
262
|
+
color: updateMsg.kind === "ok"
|
|
263
|
+
? "var(--dsw-alias-state-success, #2ea043)"
|
|
264
|
+
: updateMsg.kind === "err"
|
|
265
|
+
? "var(--dsw-alias-state-error-primary, #cf222e)"
|
|
266
|
+
: "var(--dsw-alias-label-secondary, #656d76)",
|
|
267
|
+
},
|
|
268
|
+
}, updateMsg.text) : null)) : activeSection === "about" ? h("div", null, h("div", { style: { display: "flex", alignItems: "center", gap: "10px", marginBottom: "14px" } }, renderOctocatBadge(40), h("div", null, h("div", { style: { fontSize: "15px", fontWeight: 600 } }, "DSH GitHub Flow"), h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginTop: "2px" } }, "当前版本: v" + (aboutVersion || "…")))), h("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #656d76)", marginBottom: "14px", lineHeight: "1.6" } }, "让 DeepSeek Harness Agent 拥有操作 GitHub 的原生手脚。原生复用宿主机 gh CLI 安全凭据,深度打通本地 Git 工作区与云端协作,提供 18 大领域 Agent 工具、人类 Slash 指令、Web 全景驾驶舱与一键跨平台升级。"), h("div", { style: { display: "flex", flexDirection: "column", gap: "8px", marginBottom: "14px" } }, h("div", { style: { display: "flex", alignItems: "center", gap: "8px", fontSize: "12px" } }, h("span", { style: { minWidth: "64px", color: "var(--dsw-alias-label-secondary, #656d76)" } }, "仓库地址"), h("a", { href: "https://github.com/ItQianChen/dsh-github-flow", target: "_blank", rel: "noopener noreferrer", style: { color: "var(--dsw-alias-link, #0969da)" } }, "github.com/ItQianChen/dsh-github-flow")), h("div", { style: { display: "flex", alignItems: "center", gap: "8px", fontSize: "12px" } }, h("span", { style: { minWidth: "64px", color: "var(--dsw-alias-label-secondary, #656d76)" } }, "npm 包"), h("a", { href: "https://www.npmjs.com/package/dsh-github-flow", target: "_blank", rel: "noopener noreferrer", style: { color: "var(--dsw-alias-link, #0969da)" } }, "npmjs.com/package/dsh-github-flow")), h("div", { style: { display: "flex", alignItems: "center", gap: "8px", fontSize: "12px" } }, h("span", { style: { minWidth: "64px", color: "var(--dsw-alias-label-secondary, #656d76)" } }, "开源协议"), h("a", { href: "https://github.com/ItQianChen/dsh-github-flow/blob/master/LICENSE", target: "_blank", rel: "noopener noreferrer", style: { color: "var(--dsw-alias-link, #0969da)" } }, "MIT License"))), h("div", {
|
|
269
|
+
className: "dsh-github-about-star-box",
|
|
270
|
+
style: {
|
|
271
|
+
display: "flex",
|
|
272
|
+
alignItems: "center",
|
|
273
|
+
gap: "10px",
|
|
274
|
+
},
|
|
275
|
+
}, h("span", { style: { fontSize: "18px" } }, "⭐"), h("div", { style: { flex: 1, fontSize: "12px", lineHeight: "1.5" } }, "如果这个插件对你的日常研发有帮助,欢迎到 GitHub 仓库点个 Star 支持一下——你的 Star 是持续迭代的动力!也欢迎提交 Issue 与 PR。"), h("a", {
|
|
276
|
+
target: "_blank",
|
|
277
|
+
href: "https://github.com/ItQianChen/dsh-github-flow",
|
|
278
|
+
rel: "noopener noreferrer",
|
|
279
|
+
className: "dsh-github-btn-sm dsh-github-primary-btn",
|
|
280
|
+
}, "🌟 去点 Star"))) : h("div", null, 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", {
|
|
281
|
+
type: "checkbox",
|
|
282
|
+
checked: proxyEnabled,
|
|
283
|
+
onChange: function (e) { setProxyEnabled(Boolean(e.target.checked)); },
|
|
284
|
+
}), "启用代理"), proxyEnabled ? h("div", null, h("div", { style: { fontSize: "12px", marginBottom: "4px" } }, "代理地址"), h("input", {
|
|
285
|
+
className: "dsh-github-input",
|
|
286
|
+
style: { width: "100%", boxSizing: "border-box", padding: "6px 10px", fontSize: "13px", marginBottom: "10px" },
|
|
287
|
+
placeholder: "http://127.0.0.1:7890 或 socks5h://127.0.0.1:1080(DNS 由代理解析)",
|
|
288
|
+
value: proxyUrl,
|
|
289
|
+
onChange: function (e) { setProxyUrl(e.target.value); },
|
|
290
|
+
}), h("div", { style: { fontSize: "12px", marginBottom: "4px" } }, "NO_PROXY 排除列表(逗号分隔,localhost 与 127.0.0.1 强制包含)"), h("input", {
|
|
291
|
+
className: "dsh-github-input",
|
|
292
|
+
style: { width: "100%", boxSizing: "border-box", padding: "6px 10px", fontSize: "12px", marginBottom: "10px" },
|
|
293
|
+
value: proxyNoProxy,
|
|
294
|
+
onChange: function (e) { setProxyNoProxy(e.target.value); },
|
|
295
|
+
}), h("label", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "8px", cursor: "pointer", fontSize: "12px" } }, h("input", {
|
|
296
|
+
type: "checkbox",
|
|
297
|
+
checked: proxyApplyNpm,
|
|
298
|
+
onChange: function (e) { setProxyApplyNpm(Boolean(e.target.checked)); },
|
|
299
|
+
}), "同时应用于 npm 版本探测与一键升级")) : null, h("div", { style: { display: "flex", alignItems: "center", gap: "8px", flexWrap: "wrap" } }, h("button", {
|
|
300
|
+
className: "dsh-github-btn-sm",
|
|
301
|
+
style: { padding: "5px 12px", fontSize: "12px" },
|
|
302
|
+
disabled: proxyBusy || !proxyEnabled,
|
|
303
|
+
onClick: handleProxyProbe,
|
|
304
|
+
title: "经当前配置探测 GitHub API 连通性(约 2.5 秒)",
|
|
305
|
+
}, "🧪 测试连通性"), h("button", {
|
|
306
|
+
className: "dsh-github-btn-sm",
|
|
307
|
+
style: {
|
|
308
|
+
padding: "5px 14px",
|
|
309
|
+
fontSize: "12px",
|
|
310
|
+
background: "var(--dsw-alias-link, #0969da)",
|
|
311
|
+
color: "#ffffff",
|
|
312
|
+
borderColor: "var(--dsw-alias-link, #0969da)",
|
|
313
|
+
fontWeight: 600,
|
|
314
|
+
},
|
|
315
|
+
disabled: proxyBusy,
|
|
316
|
+
onClick: handleProxySave,
|
|
317
|
+
}, proxyBusy ? "处理中..." : "💾 保存并全局应用"), proxyProbe ? h("span", {
|
|
318
|
+
style: {
|
|
319
|
+
fontSize: "12px",
|
|
320
|
+
fontWeight: 500,
|
|
321
|
+
color: proxyProbe.ok ? "var(--dsw-alias-state-success, #2ea043)" : "var(--dsw-alias-state-error-primary, #cf222e)",
|
|
322
|
+
},
|
|
323
|
+
title: proxyProbe.error || "",
|
|
324
|
+
}, proxyProbe.ok ? "✅ " + proxyProbe.latencyMs + "ms" : "❌ 探测失败") : null), proxyMsg ? h("div", {
|
|
325
|
+
style: {
|
|
326
|
+
marginTop: "8px",
|
|
327
|
+
fontSize: "12px",
|
|
328
|
+
lineHeight: "1.5",
|
|
329
|
+
color: proxyMsg.kind === "ok"
|
|
330
|
+
? "var(--dsw-alias-state-success, #2ea043)"
|
|
331
|
+
: proxyMsg.kind === "err"
|
|
332
|
+
? "var(--dsw-alias-state-error-primary, #cf222e)"
|
|
333
|
+
: "var(--dsw-alias-label-secondary, #656d76)",
|
|
334
|
+
},
|
|
335
|
+
}, proxyMsg.text) : null))), h("div", { className: "dsh-github-modal-footer" }, activeSection === "sync" ? h("button", {
|
|
336
|
+
className: "dsh-github-btn-sm",
|
|
337
|
+
style: {
|
|
338
|
+
padding: "6px 16px",
|
|
339
|
+
background: "var(--dsw-alias-link, #0969da)",
|
|
340
|
+
color: "#ffffff",
|
|
341
|
+
borderColor: "var(--dsw-alias-link, #0969da)",
|
|
342
|
+
fontWeight: 600,
|
|
343
|
+
},
|
|
344
|
+
onClick: handleSave,
|
|
345
|
+
}, "保存同步设置") : null, h("button", {
|
|
346
|
+
className: "dsh-github-btn-sm",
|
|
347
|
+
style: { padding: "6px 14px" },
|
|
348
|
+
onClick: props.onClose,
|
|
349
|
+
}, activeSection === "sync" ? "取消" : "完成"))));
|
|
350
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 数据新鲜度与同步状态微标组件
|
|
3
|
+
*/
|
|
4
|
+
export function SyncStatusBadge(props) {
|
|
5
|
+
var syncStatus = props.syncStatus;
|
|
6
|
+
var lastSyncedAt = props.lastSyncedAt;
|
|
7
|
+
var isRightbar = Boolean(props.isRightbar);
|
|
8
|
+
var text = "";
|
|
9
|
+
var bg = "rgba(101, 109, 118, 0.1)";
|
|
10
|
+
var color = "var(--dsw-alias-label-secondary, #656d76)";
|
|
11
|
+
var formatTimeAgo = function (ts) {
|
|
12
|
+
if (!ts)
|
|
13
|
+
return "刚刚";
|
|
14
|
+
var diffSec = Math.floor((Date.now() - ts) / 1000);
|
|
15
|
+
if (diffSec < 60)
|
|
16
|
+
return "刚刚";
|
|
17
|
+
var diffMin = Math.floor(diffSec / 60);
|
|
18
|
+
if (diffMin < 60)
|
|
19
|
+
return diffMin + "分钟前";
|
|
20
|
+
var diffHour = Math.floor(diffMin / 60);
|
|
21
|
+
if (diffHour < 24)
|
|
22
|
+
return diffHour + "小时前";
|
|
23
|
+
var diffDay = Math.floor(diffHour / 24);
|
|
24
|
+
return diffDay + "天前";
|
|
25
|
+
};
|
|
26
|
+
if (syncStatus === "syncing") {
|
|
27
|
+
text = isRightbar ? "⏳ 同步中..." : "⏳ 后台同步中...";
|
|
28
|
+
bg = "rgba(9, 105, 218, 0.12)";
|
|
29
|
+
color = "var(--dsw-alias-link, #0969da)";
|
|
30
|
+
}
|
|
31
|
+
else if (syncStatus === "fresh") {
|
|
32
|
+
var timeStr = lastSyncedAt ? new Date(lastSyncedAt).toLocaleTimeString() : "";
|
|
33
|
+
text = "✅ " + (isRightbar ? "最新" : "已是最新") + (timeStr ? " (" + timeStr + ")" : "");
|
|
34
|
+
bg = "rgba(46, 160, 67, 0.12)";
|
|
35
|
+
color = "var(--dsw-alias-state-success, #2ea043)";
|
|
36
|
+
}
|
|
37
|
+
else if (syncStatus === "cached") {
|
|
38
|
+
text = "📦 本地快照 (" + formatTimeAgo(lastSyncedAt) + ")";
|
|
39
|
+
bg = "rgba(101, 109, 118, 0.12)";
|
|
40
|
+
color = "var(--dsw-alias-label-secondary, #656d76)";
|
|
41
|
+
}
|
|
42
|
+
else if (syncStatus === "failed") {
|
|
43
|
+
text = isRightbar ? "❌ 刷新失败 (离线)" : "❌ 网络断开 (展示离线数据)";
|
|
44
|
+
bg = "rgba(207, 34, 46, 0.12)";
|
|
45
|
+
color = "var(--dsw-alias-state-error-primary, #cf222e)";
|
|
46
|
+
}
|
|
47
|
+
if (!text)
|
|
48
|
+
return null;
|
|
49
|
+
return React.createElement("span", {
|
|
50
|
+
className: "dsh-github-sync-badge",
|
|
51
|
+
style: {
|
|
52
|
+
fontSize: isRightbar ? "10px" : "11px",
|
|
53
|
+
padding: isRightbar ? "2px 6px" : "3px 8px",
|
|
54
|
+
borderRadius: "12px",
|
|
55
|
+
background: bg,
|
|
56
|
+
color: color,
|
|
57
|
+
marginLeft: isRightbar ? "6px" : "10px",
|
|
58
|
+
fontWeight: 500,
|
|
59
|
+
display: "inline-flex",
|
|
60
|
+
alignItems: "center",
|
|
61
|
+
whiteSpace: "nowrap",
|
|
62
|
+
},
|
|
63
|
+
}, text);
|
|
64
|
+
}
|