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.
Files changed (121) hide show
  1. package/README.en.md +287 -143
  2. package/README.md +270 -125
  3. package/docs/UPGRADE-NOTES.md +12 -9
  4. package/docs/architecture.md +126 -126
  5. package/lib/api/routes-actions.js +249 -0
  6. package/lib/api/routes-overview.js +94 -2
  7. package/lib/cache.d.ts +4 -0
  8. package/lib/cache.js +14 -0
  9. package/lib/client.d.ts +14 -1
  10. package/lib/client.js +4287 -2500
  11. package/lib/commands/gh.d.ts +6 -1
  12. package/lib/commands/gh.js +144 -71
  13. package/lib/executor/git-parser.d.ts +57 -0
  14. package/lib/executor/git-parser.js +255 -0
  15. package/lib/executor/platform-guide.d.ts +14 -0
  16. package/lib/executor/platform-guide.js +40 -0
  17. package/lib/executor/process-utils.d.ts +51 -0
  18. package/lib/executor/process-utils.js +162 -0
  19. package/lib/executor/version-utils.d.ts +12 -0
  20. package/lib/executor/version-utils.js +27 -0
  21. package/lib/executor.d.ts +70 -48
  22. package/lib/executor.js +371 -356
  23. package/lib/git-watcher.d.ts +36 -0
  24. package/lib/git-watcher.js +91 -0
  25. package/lib/main.js +37 -3
  26. package/lib/renderers/agent-task.d.ts +16 -0
  27. package/lib/renderers/agent-task.js +107 -0
  28. package/lib/renderers/cache.d.ts +8 -0
  29. package/lib/renderers/cache.js +66 -0
  30. package/lib/renderers/codespace.d.ts +16 -0
  31. package/lib/renderers/codespace.js +103 -0
  32. package/lib/renderers/common.d.ts +24 -0
  33. package/lib/renderers/common.js +88 -0
  34. package/lib/renderers/discussion.d.ts +16 -0
  35. package/lib/renderers/discussion.js +101 -0
  36. package/lib/renderers/gist.d.ts +15 -0
  37. package/lib/renderers/gist.js +99 -0
  38. package/lib/renderers/issue.d.ts +4 -0
  39. package/lib/renderers/issue.js +70 -0
  40. package/lib/renderers/label.d.ts +4 -0
  41. package/lib/renderers/label.js +48 -0
  42. package/lib/renderers/markdown.d.ts +19 -32
  43. package/lib/renderers/markdown.js +19 -624
  44. package/lib/renderers/pr.d.ts +4 -0
  45. package/lib/renderers/pr.js +107 -0
  46. package/lib/renderers/project.d.ts +20 -0
  47. package/lib/renderers/project.js +128 -0
  48. package/lib/renderers/release.d.ts +4 -0
  49. package/lib/renderers/release.js +74 -0
  50. package/lib/renderers/repo.d.ts +4 -0
  51. package/lib/renderers/repo.js +149 -0
  52. package/lib/renderers/ruleset.d.ts +4 -0
  53. package/lib/renderers/ruleset.js +74 -0
  54. package/lib/renderers/run.d.ts +4 -0
  55. package/lib/renderers/run.js +79 -0
  56. package/lib/renderers/skill.d.ts +34 -0
  57. package/lib/renderers/skill.js +241 -0
  58. package/lib/renderers/status.d.ts +28 -0
  59. package/lib/renderers/status.js +176 -0
  60. package/lib/telemetry.d.ts +70 -0
  61. package/lib/telemetry.js +161 -0
  62. package/lib/tools/agent-task.d.ts +54 -0
  63. package/lib/tools/agent-task.js +135 -0
  64. package/lib/tools/cache.d.ts +64 -0
  65. package/lib/tools/cache.js +186 -0
  66. package/lib/tools/codespace.d.ts +51 -0
  67. package/lib/tools/codespace.js +154 -0
  68. package/lib/tools/discussion.d.ts +70 -0
  69. package/lib/tools/discussion.js +195 -0
  70. package/lib/tools/gist.d.ts +155 -0
  71. package/lib/tools/gist.js +190 -0
  72. package/lib/tools/help.js +214 -13
  73. package/lib/tools/image-utils.d.ts +8 -0
  74. package/lib/tools/image-utils.js +34 -0
  75. package/lib/tools/issue.d.ts +8 -1
  76. package/lib/tools/issue.js +26 -4
  77. package/lib/tools/label.d.ts +80 -0
  78. package/lib/tools/label.js +237 -0
  79. package/lib/tools/pr.d.ts +8 -0
  80. package/lib/tools/pr.js +48 -3
  81. package/lib/tools/project.d.ts +80 -0
  82. package/lib/tools/project.js +241 -0
  83. package/lib/tools/repo.js +13 -1
  84. package/lib/tools/ruleset.d.ts +80 -0
  85. package/lib/tools/ruleset.js +177 -0
  86. package/lib/tools/skill.d.ts +24 -1
  87. package/lib/tools/skill.js +115 -5
  88. package/lib/tools/status.d.ts +40 -0
  89. package/lib/tools/status.js +58 -0
  90. package/lib/types.d.ts +44 -0
  91. package/lib/ui/auth-guide-card.d.ts +4 -0
  92. package/lib/ui/auth-guide-card.js +161 -0
  93. package/lib/ui/branch-selector.d.ts +10 -0
  94. package/lib/ui/branch-selector.js +163 -0
  95. package/lib/ui/commit-modal.d.ts +8 -0
  96. package/lib/ui/commit-modal.js +219 -0
  97. package/lib/ui/help-modal.d.ts +15 -0
  98. package/lib/ui/help-modal.js +202 -0
  99. package/lib/ui/icons.d.ts +7 -0
  100. package/lib/ui/icons.js +53 -0
  101. package/lib/ui/network-banner.d.ts +10 -0
  102. package/lib/ui/network-banner.js +54 -0
  103. package/lib/ui/storage.d.ts +35 -0
  104. package/lib/ui/storage.js +158 -0
  105. package/lib/ui/styles.d.ts +6 -0
  106. package/lib/ui/styles.js +1544 -0
  107. package/lib/ui/sync-settings-modal.d.ts +11 -0
  108. package/lib/ui/sync-settings-modal.js +350 -0
  109. package/lib/ui/sync-status-badge.d.ts +8 -0
  110. package/lib/ui/sync-status-badge.js +64 -0
  111. package/lib/ui/upgrade-card.d.ts +7 -0
  112. package/lib/ui/upgrade-card.js +222 -0
  113. package/lib/ui/utils.d.ts +45 -0
  114. package/lib/ui/utils.js +226 -0
  115. package/lib/ui/workspace-panel.d.ts +4 -0
  116. package/lib/ui/workspace-panel.js +489 -0
  117. package/lib/upgrade-manager.d.ts +5 -1
  118. package/lib/upgrade-manager.js +24 -1
  119. package/lib/version.d.ts +1 -1
  120. package/lib/version.js +1 -1
  121. 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,8 @@
1
+ /**
2
+ * 数据新鲜度与同步状态微标组件
3
+ */
4
+ export declare function SyncStatusBadge(props: {
5
+ syncStatus: string;
6
+ lastSyncedAt: number;
7
+ isRightbar?: boolean;
8
+ }): any;
@@ -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
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 通用升级通知与一键升级卡片组件(自适应右侧栏紧凑模式与全景大面板模式)
3
+ */
4
+ export declare function UpgradeNotificationCard(props: {
5
+ updateInfo: any;
6
+ isRightbar?: boolean;
7
+ }): any;