dsh-github-flow 0.1.7 → 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.
Files changed (65) hide show
  1. package/README.en.md +287 -69
  2. package/README.md +290 -68
  3. package/docs/architecture.md +71 -14
  4. package/docs/images/1.png +0 -0
  5. package/docs/images/2.png +0 -0
  6. package/docs/images/3.png +0 -0
  7. package/docs/images/4.png +0 -0
  8. package/docs/npm-publish-guide.md +12 -0
  9. package/lib/api/route-helpers.d.ts +47 -0
  10. package/lib/api/route-helpers.js +134 -0
  11. package/lib/api/routes-actions.d.ts +9 -0
  12. package/lib/api/routes-actions.js +115 -0
  13. package/lib/api/routes-lifecycle.d.ts +9 -0
  14. package/lib/api/routes-lifecycle.js +75 -0
  15. package/lib/api/routes-overview.d.ts +11 -0
  16. package/lib/api/routes-overview.js +227 -0
  17. package/lib/api/routes-proxy.d.ts +18 -0
  18. package/lib/api/routes-proxy.js +63 -0
  19. package/lib/api/routes.d.ts +17 -5
  20. package/lib/api/routes.js +18 -417
  21. package/lib/client.js +1179 -40
  22. package/lib/commands/gh.d.ts +2 -1
  23. package/lib/commands/gh.js +40 -3
  24. package/lib/executor.d.ts +17 -0
  25. package/lib/executor.js +40 -2
  26. package/lib/main.d.ts +12 -0
  27. package/lib/main.js +73 -4
  28. package/lib/proxy.d.ts +87 -0
  29. package/lib/proxy.js +275 -0
  30. package/lib/renderers/markdown.d.ts +24 -0
  31. package/lib/renderers/markdown.js +493 -0
  32. package/lib/tools/api.d.ts +4 -0
  33. package/lib/tools/api.js +14 -4
  34. package/lib/tools/help.d.ts +31 -0
  35. package/lib/tools/help.js +212 -0
  36. package/lib/tools/issue.d.ts +32 -1
  37. package/lib/tools/issue.js +94 -17
  38. package/lib/tools/pr.d.ts +22 -1
  39. package/lib/tools/pr.js +67 -15
  40. package/lib/tools/release.d.ts +89 -0
  41. package/lib/tools/release.js +219 -0
  42. package/lib/tools/repo.d.ts +13 -1
  43. package/lib/tools/repo.js +46 -14
  44. package/lib/tools/run.d.ts +22 -1
  45. package/lib/tools/run.js +74 -14
  46. package/lib/tools/secret.d.ts +60 -0
  47. package/lib/tools/secret.js +175 -0
  48. package/lib/tools/skill.d.ts +63 -0
  49. package/lib/tools/skill.js +146 -0
  50. package/lib/types.d.ts +57 -0
  51. package/lib/updater.d.ts +49 -0
  52. package/lib/updater.js +169 -0
  53. package/lib/upgrade-manager.d.ts +58 -0
  54. package/lib/upgrade-manager.js +309 -0
  55. package/lib/version.d.ts +13 -0
  56. package/lib/version.js +13 -0
  57. package/package.json +3 -2
  58. package/lib/client/icons.d.ts +0 -13
  59. package/lib/client/icons.js +0 -41
  60. package/lib/client/index.d.ts +0 -3
  61. package/lib/client/index.js +0 -36
  62. package/lib/client/panel.d.ts +0 -1
  63. package/lib/client/panel.js +0 -102
  64. package/lib/client/style.d.ts +0 -1
  65. package/lib/client/style.js +0 -555
@@ -1,36 +0,0 @@
1
- import { GITHUB_PANEL_CSS } from './style.js';
2
- import { createGithubPanelComponent } from './panel.js';
3
- export const name = 'dsh-github-flow';
4
- export const inject = ['slots'];
5
- export function apply(ctx) {
6
- // 1. 注入样式
7
- if (typeof styles !== 'undefined' && styles.insert) {
8
- styles.insert(GITHUB_PANEL_CSS);
9
- }
10
- else if (typeof document !== 'undefined') {
11
- const styleEl = document.createElement('style');
12
- styleEl.textContent = GITHUB_PANEL_CSS;
13
- document.head.appendChild(styleEl);
14
- }
15
- // 2. 侧边栏图标组件
16
- function GithubSidebarIcon() {
17
- return React.createElement('div', { className: 'dsh-github-icon', title: 'GitHub 工作台' }, React.createElement('svg', { viewBox: '0 0 16 16', width: 18, height: 18, fill: 'currentColor' }, React.createElement('path', {
18
- d: 'M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z',
19
- })));
20
- }
21
- // 3. 注册到 sidebar.panellist(排在 schedules 自动任务后,workspaces 工作区前)
22
- if (ctx.slots && typeof ctx.slots.register === 'function') {
23
- ctx.slots.register({
24
- slot: 'sidebar.panellist',
25
- id: 'github',
26
- order: 20,
27
- label: 'GitHub',
28
- }, GithubSidebarIcon);
29
- // 4. 注册中央主视图(main slot, key: 'github')
30
- const GithubWorkspacePanel = createGithubPanelComponent();
31
- ctx.slots.register({
32
- slot: 'main',
33
- key: 'github',
34
- }, GithubWorkspacePanel);
35
- }
36
- }
@@ -1 +0,0 @@
1
- export declare function createGithubPanelComponent(): () => any;
@@ -1,102 +0,0 @@
1
- export function createGithubPanelComponent() {
2
- return function GithubWorkspacePanel() {
3
- const [loading, setLoading] = React.useState(true);
4
- const [data, setData] = React.useState(null);
5
- const [error, setError] = React.useState(null);
6
- const loadData = React.useCallback(async (forceRefresh = false) => {
7
- setLoading(true);
8
- setError(null);
9
- try {
10
- if (forceRefresh) {
11
- await fetch('/api/github/refresh', { method: 'POST' }).catch(() => { });
12
- }
13
- const res = await fetch('/api/github/overview');
14
- const json = await res.json();
15
- if (json.ok && json.data) {
16
- setData(json.data);
17
- }
18
- else {
19
- setError(json.error || json.message || '获取 GitHub 概览失败');
20
- }
21
- }
22
- catch (err) {
23
- setError(err.message || '网络连接异常');
24
- }
25
- finally {
26
- setLoading(false);
27
- }
28
- }, []);
29
- React.useEffect(() => {
30
- loadData(false);
31
- // 60秒自动温和轮询
32
- const timer = setInterval(() => loadData(false), 60_000);
33
- return () => clearInterval(timer);
34
- }, [loadData]);
35
- const h = React.createElement;
36
- // 头部区域
37
- const headerEl = h('div', { className: 'dsh-github-header' }, h('div', { className: 'dsh-github-title' }, h('svg', { viewBox: '0 0 16 16', width: 22, height: 22, fill: 'currentColor' }, h('path', {
38
- d: 'M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z',
39
- })), h('h2', null, 'GitHub 工作台')), h('button', {
40
- className: 'dsh-github-refresh-btn',
41
- onClick: () => loadData(true),
42
- disabled: loading,
43
- }, loading ? '刷新中...' : '🔄 刷新状态'));
44
- if (loading && !data) {
45
- return h('div', { className: 'dsh-github-panel' }, headerEl, h('div', { className: 'dsh-github-empty' }, '正在连接 GitHub CLI 并获取仓库状态...'));
46
- }
47
- if (error && !data) {
48
- return h('div', { className: 'dsh-github-panel' }, headerEl, h('div', { className: 'dsh-github-empty', style: { borderColor: '#f85149', color: '#f85149' } }, `⚠️ ${error}`));
49
- }
50
- const auth = data?.auth;
51
- const repo = data?.repo;
52
- const prs = data?.pullRequests || [];
53
- const issues = data?.issues || [];
54
- const runs = data?.runs || [];
55
- // 概览卡片区
56
- const cardsEl = h('div', { className: 'dsh-github-overview-cards' }, h('div', { className: 'dsh-github-card' }, h('div', { className: 'dsh-github-card-title' }, '认证账号'), h('div', { className: 'dsh-github-card-value' }, auth?.loggedIn ? `👤 ${auth.user || '已登录'}` : '❌ 未登录', auth?.loggedIn ? h('span', { className: 'dsh-github-badge dsh-badge-green' }, 'Active') : null)), h('div', { className: 'dsh-github-card' }, h('div', { className: 'dsh-github-card-title' }, '当前关联仓库'), h('div', { className: 'dsh-github-card-value' }, repo
57
- ? h('a', { href: repo.url, target: '_blank', style: { color: 'inherit', textDecoration: 'none' } }, repo.nameWithOwner)
58
- : '未关联 GitHub 仓库')), h('div', { className: 'dsh-github-card' }, h('div', { className: 'dsh-github-card-title' }, '待审 PR / 活跃任务'), h('div', { className: 'dsh-github-card-value' }, `${prs.length} PRs · ${issues.length} Issues`)));
59
- // Pull Requests 区域
60
- const prsSectionEl = h('div', { className: 'dsh-github-section' }, h('div', { className: 'dsh-github-section-header' }, h('h3', null, `🔀 Pull Requests (${prs.length})`)), prs.length === 0
61
- ? h('div', { className: 'dsh-github-empty' }, '当前无开放的 Pull Request')
62
- : h('div', { className: 'dsh-github-list' }, prs.map((pr) => h('div', { key: pr.number, className: 'dsh-github-item' }, h('div', { className: 'dsh-github-item-main' }, h('a', { className: 'dsh-github-item-title', href: pr.url, target: '_blank' }, `#${pr.number} ${pr.title}`), h('div', { className: 'dsh-github-item-meta' }, h('span', null, `由 ${pr.author?.login || '未知'} 提交`), h('span', null, `${pr.headRefName} → ${pr.baseRefName}`), pr.mergeable === 'CONFLICTING'
63
- ? h('span', { className: 'dsh-github-badge dsh-badge-red' }, '冲突 Conflicting')
64
- : h('span', { className: 'dsh-github-badge dsh-badge-green' }, '可合并 Mergeable'))), h('div', { className: 'dsh-github-item-actions' }, h('a', { className: 'dsh-github-btn-sm', href: pr.url, target: '_blank', style: { textDecoration: 'none' } }, '在 GitHub 打开'))))));
65
- // Issues 区域
66
- const issuesSectionEl = h('div', { className: 'dsh-github-section' }, h('div', { className: 'dsh-github-section-header' }, h('h3', null, `📋 仓库 Issues (${issues.length})`), repo?.url
67
- ? h('a', {
68
- href: `${repo.url}/issues`,
69
- target: '_blank',
70
- style: { fontSize: '11px', color: 'var(--dsw-alias-link, #0969da)', textDecoration: 'none' },
71
- }, '全部 ↗')
72
- : null), issues.length === 0
73
- ? h('div', { className: 'dsh-github-empty' }, '当前无开放中的 Issue')
74
- : h('div', { className: 'dsh-github-list' }, issues.map((issue) => {
75
- const cats = issue.categories || [];
76
- const badges = [];
77
- if (cats.includes('reported')) {
78
- badges.push(h('span', { key: 'rep', className: 'dsh-github-badge dsh-badge-purple' }, '用户反馈'));
79
- }
80
- if (cats.includes('assigned')) {
81
- badges.push(h('span', { key: 'asn', className: 'dsh-github-badge dsh-badge-blue' }, '已分配'));
82
- }
83
- if (cats.includes('created')) {
84
- badges.push(h('span', { key: 'crt', className: 'dsh-github-badge dsh-badge-green' }, '我发起的'));
85
- }
86
- return h('div', { key: issue.number, className: 'dsh-github-item' }, h('div', { className: 'dsh-github-item-main' }, h('div', { style: { display: 'flex', alignItems: 'center', gap: '6px', flexWrap: 'wrap' } }, h('a', { className: 'dsh-github-item-title', href: issue.url, target: '_blank' }, `#${issue.number} ${issue.title}`), ...badges), h('div', { className: 'dsh-github-item-meta' }, h('span', null, `由 ${issue.author?.login || '未知'} 提出`), issue.assignees && issue.assignees.length > 0
87
- ? h('span', null, `指派: ${issue.assignees.map((a) => a.login).join(', ')}`)
88
- : null, issue.labels && issue.labels.length > 0
89
- ? issue.labels.map((lbl) => h('span', { key: lbl.name, className: 'dsh-github-badge dsh-badge-yellow' }, lbl.name))
90
- : null)), h('div', { className: 'dsh-github-item-actions' }, h('a', { className: 'dsh-github-btn-sm', href: issue.url, target: '_blank', style: { textDecoration: 'none' } }, '在 GitHub 打开')));
91
- })));
92
- // GitHub Actions 区域
93
- const runsSectionEl = h('div', { className: 'dsh-github-section' }, h('div', { className: 'dsh-github-section-header' }, h('h3', null, `⚡ GitHub Actions 最近流水线 (${runs.length})`)), runs.length === 0
94
- ? h('div', { className: 'dsh-github-empty' }, '暂无工作流运行记录')
95
- : h('div', { className: 'dsh-github-list' }, runs.map((r) => h('div', { key: r.databaseId, className: 'dsh-github-item' }, h('div', { className: 'dsh-github-item-main' }, h('a', { className: 'dsh-github-item-title', href: r.url, target: '_blank' }, r.name), h('div', { className: 'dsh-github-item-meta' }, h('span', null, `分支: ${r.headBranch}`), h('span', null, `触发事件: ${r.event}`), r.conclusion === 'success'
96
- ? h('span', { className: 'dsh-github-badge dsh-badge-green' }, '成功 Success')
97
- : r.conclusion === 'failure'
98
- ? h('span', { className: 'dsh-github-badge dsh-badge-red' }, '失败 Failure')
99
- : h('span', { className: 'dsh-github-badge dsh-badge-yellow' }, r.status || '进行中'))), h('div', { className: 'dsh-github-item-actions' }, h('a', { className: 'dsh-github-btn-sm', href: r.url, target: '_blank', style: { textDecoration: 'none' } }, '查看流水线'))))));
100
- return h('div', { className: 'dsh-github-panel' }, headerEl, cardsEl, prsSectionEl, issuesSectionEl, runsSectionEl);
101
- };
102
- }
@@ -1 +0,0 @@
1
- export declare const GITHUB_PANEL_CSS = "\n/* ==========================================================================\n DSH GitHub Flow - \u4E3B\u9898\u81EA\u9002\u5E94\u6837\u5F0F\u7CFB\u7EDF (Light / Dark \u52A8\u6001\u8054\u52A8)\n \u9075\u5FAA DSH \u539F\u751F DSW (DeepSeek Web) \u8BBE\u8BA1\u8BED\u8A00\u89C4\u8303\n ========================================================================== */\n\n/* 1. \u4FA7\u8FB9\u680F\u56FE\u6807\u4E0E\u5916\u58F3 */\n.dsh-github-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary, #656d76);\n transition: color 0.15s ease;\n}\n.dsh-github-icon:hover {\n color: var(--dsw-alias-label-primary, #1f2328);\n}\n.dsh-github-icon-inner {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 7px;\n background: transparent;\n color: inherit;\n border: 1px solid transparent;\n transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);\n}\n.dsh-github-icon-inner.active {\n background: var(--dsw-alias-bg-module-platform, rgba(9, 105, 218, 0.08));\n color: var(--dsw-alias-link, #0969da);\n border-color: var(--dsw-alias-border-l2, rgba(9, 105, 218, 0.2));\n}\n\nbody[data-ds-dark-theme] .dsh-github-icon {\n color: var(--dsw-alias-label-secondary, #9ca3af);\n}\nbody[data-ds-dark-theme] .dsh-github-icon:hover {\n color: var(--dsw-alias-label-primary, #ffffff);\n}\nbody[data-ds-dark-theme] .dsh-github-icon-inner.active {\n background: linear-gradient(135deg, rgba(46, 160, 67, 0.3) 0%, rgba(31, 111, 235, 0.45) 100%);\n color: #ffffff;\n box-shadow: 0 0 12px rgba(31, 111, 235, 0.4);\n border-color: rgba(88, 166, 255, 0.45);\n}\n\n/* 2. Octocat \u79D1\u6280\u52CB\u7AE0 Badge */\n.dsh-octocat-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #1f6feb 0%, #0969da 60%, #8957e5 100%);\n box-shadow: 0 2px 6px rgba(9, 105, 218, 0.25);\n flex-shrink: 0;\n}\nbody[data-ds-dark-theme] .dsh-octocat-badge {\n background: linear-gradient(135deg, #2ea043 0%, #1f6feb 60%, #8957e5 100%);\n box-shadow: 0 2px 8px rgba(31, 111, 235, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n\n/* 3. \u5BB9\u5668\u89C6\u56FE\uFF08\u4E3B\u9762\u677F\u4E0E\u53F3\u4FA7\u62BD\u5C49\u680F\uFF09 */\n.dsh-github-panel {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow-y: auto;\n padding: 24px 32px;\n box-sizing: border-box;\n background: var(--dsw-alias-bg-base, #ffffff);\n color: var(--dsw-alias-label-primary, #1f2328);\n font-family: var(--dsw-font-family, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);\n}\n\n.dsh-github-rightbar-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow-y: auto;\n padding: 16px 18px;\n box-sizing: border-box;\n background: var(--dsw-alias-bg-base, #ffffff);\n color: var(--dsw-alias-label-primary, #1f2328);\n font-family: var(--dsw-font-family, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);\n}\n\nbody[data-ds-dark-theme] .dsh-github-panel,\nbody[data-ds-dark-theme] .dsh-github-rightbar-container {\n background: var(--dsw-alias-bg-base, #151517);\n color: var(--dsw-alias-label-primary, #ececec);\n}\n\n/* 4. \u5934\u90E8\u533A\u57DF */\n.dsh-github-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 20px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n}\nbody[data-ds-dark-theme] .dsh-github-header {\n border-bottom-color: var(--dsw-alias-border-l1, #2c2c2e);\n}\n.dsh-github-title {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n.dsh-github-title h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary, #1f2328);\n}\nbody[data-ds-dark-theme] .dsh-github-title h2 {\n color: var(--dsw-alias-label-primary, #f0f6fc);\n}\n\n/* 5. \u5237\u65B0\u6309\u94AE */\n.dsh-github-refresh-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n font-size: 12px;\n font-weight: 500;\n border-radius: 6px;\n border: 1px solid var(--dsw-alias-border-l2, #e1e4e8);\n background: var(--dsw-alias-bg-module-platform, #f6f8fa);\n color: var(--dsw-alias-label-primary, #1f2328);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.dsh-github-refresh-btn:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, #ebeef2);\n border-color: var(--dsw-alias-border-l3, #d0d7de);\n}\n.dsh-github-refresh-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\nbody[data-ds-dark-theme] .dsh-github-refresh-btn {\n border-color: var(--dsw-alias-border-l1, #38383c);\n background: var(--dsw-alias-bg-layer-2, #242528);\n color: var(--dsw-alias-label-primary, #f0f6fc);\n}\nbody[data-ds-dark-theme] .dsh-github-refresh-btn:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, #2f3034);\n border-color: rgba(255, 255, 255, 0.25);\n}\n\n/* 6. \u6982\u89C8\u5361\u7247\u4E0E\u7F51\u683C */\n.dsh-github-overview-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 14px;\n margin-bottom: 20px;\n}\n.dsh-github-card {\n padding: 14px 16px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n background: var(--dsw-alias-bg-layer-1, #fcfcfd);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n margin-bottom: 12px;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\nbody[data-ds-dark-theme] .dsh-github-card {\n border-color: var(--dsw-alias-border-l1, #303034);\n background: var(--dsw-alias-bg-layer-2, #212124);\n box-shadow: none;\n}\n.dsh-github-card-title {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--dsw-alias-label-tertiary, #656d76);\n margin-bottom: 6px;\n font-weight: 500;\n}\nbody[data-ds-dark-theme] .dsh-github-card-title {\n color: var(--dsw-alias-label-tertiary, #888);\n}\n.dsh-github-card-value {\n font-size: 15px;\n font-weight: 600;\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n color: var(--dsw-alias-label-primary, #1f2328);\n}\nbody[data-ds-dark-theme] .dsh-github-card-value {\n color: var(--dsw-alias-label-primary, #f0f6fc);\n}\n.dsh-github-card-desc {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary, #656d76);\n margin-top: 4px;\n line-height: 1.4;\n}\nbody[data-ds-dark-theme] .dsh-github-card-desc {\n color: var(--dsw-alias-label-secondary, #bbb);\n}\n.dsh-github-card-subtext {\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary, #8c959f);\n margin-top: 6px;\n}\nbody[data-ds-dark-theme] .dsh-github-card-subtext {\n color: var(--dsw-alias-label-tertiary, #888);\n}\n\n/* 7. \u5FBD\u7AE0\uFF08Badges\uFF09 */\n.dsh-github-badge {\n display: inline-flex;\n align-items: center;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 12px;\n font-weight: 500;\n line-height: 16px;\n}\n.dsh-badge-green {\n background: rgba(46, 160, 67, 0.12);\n color: #1a7f37;\n border: 1px solid rgba(46, 160, 67, 0.2);\n}\n.dsh-badge-red {\n background: rgba(207, 34, 46, 0.12);\n color: #cf222e;\n border: 1px solid rgba(207, 34, 46, 0.2);\n}\n.dsh-badge-yellow {\n background: rgba(154, 103, 0, 0.12);\n color: #9a6700;\n border: 1px solid rgba(154, 103, 0, 0.2);\n}\nbody[data-ds-dark-theme] .dsh-badge-green {\n background: rgba(46, 160, 67, 0.22);\n color: #3fb950;\n border-color: rgba(46, 160, 67, 0.3);\n}\nbody[data-ds-dark-theme] .dsh-badge-red {\n background: rgba(248, 81, 73, 0.22);\n color: #f85149;\n border-color: rgba(248, 81, 73, 0.3);\n}\nbody[data-ds-dark-theme] .dsh-badge-yellow {\n background: rgba(210, 153, 34, 0.22);\n color: #d29922;\n border-color: rgba(210, 153, 34, 0.3);\n}\n\n/* 8. \u5FEB\u6377\u64CD\u4F5C\u7F51\u683C */\n.dsh-github-quick-actions {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n margin-bottom: 16px;\n}\n.dsh-github-action-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 8px 10px;\n border-radius: 6px;\n border: 1px solid var(--dsw-alias-border-l2, #e1e4e8);\n background: var(--dsw-alias-bg-module-platform, #f6f8fa);\n color: var(--dsw-alias-label-primary, #1f2328);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.dsh-github-action-btn:hover {\n background: var(--dsw-alias-interactive-bg-hover, #ebeef2);\n border-color: var(--dsw-alias-link, #0969da);\n color: var(--dsw-alias-link, #0969da);\n}\nbody[data-ds-dark-theme] .dsh-github-action-btn {\n border-color: var(--dsw-alias-border-l1, #444);\n background: var(--dsw-alias-bg-layer-2, #28282b);\n color: var(--dsw-alias-label-primary, #fff);\n}\nbody[data-ds-dark-theme] .dsh-github-action-btn:hover {\n background: var(--dsw-alias-interactive-bg-hover, #343438);\n border-color: #58a6ff;\n color: #58a6ff;\n}\n\n/* 9. \u6A21\u5757\u5206\u533A\u4E0E\u5217\u8868 */\n.dsh-github-section {\n margin-bottom: 20px;\n}\n.dsh-github-section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n}\n.dsh-github-section-header h3 {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-label-secondary, #656d76);\n}\nbody[data-ds-dark-theme] .dsh-github-section-header h3 {\n color: var(--dsw-alias-label-secondary, #ccc);\n}\n.dsh-github-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.dsh-github-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 10px 14px;\n border-radius: 6px;\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n background: var(--dsw-alias-bg-layer-1, #fcfcfd);\n transition: border-color 0.15s ease, background 0.15s ease;\n}\n.dsh-github-item:hover {\n border-color: var(--dsw-alias-border-l3, #d0d7de);\n background: var(--dsw-alias-interactive-bg-hover, #f6f8fa);\n}\nbody[data-ds-dark-theme] .dsh-github-item {\n border-color: var(--dsw-alias-border-l1, #333336);\n background: var(--dsw-alias-bg-layer-2, #252528);\n}\nbody[data-ds-dark-theme] .dsh-github-item:hover {\n border-color: var(--dsw-alias-border-l2, #555);\n background: var(--dsw-alias-interactive-bg-hover, #2c2c30);\n}\n.dsh-github-item-title {\n font-size: 13px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2328);\n text-decoration: none;\n transition: color 0.15s ease;\n}\n.dsh-github-item-title:hover {\n color: var(--dsw-alias-link, #0969da);\n text-decoration: underline;\n}\nbody[data-ds-dark-theme] .dsh-github-item-title {\n color: var(--dsw-alias-label-primary, #f0f6fc);\n}\nbody[data-ds-dark-theme] .dsh-github-item-title:hover {\n color: #58a6ff;\n}\n.dsh-github-item-desc {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary, #656d76);\n line-height: 1.4;\n}\nbody[data-ds-dark-theme] .dsh-github-item-desc {\n color: var(--dsw-alias-label-secondary, #bbb);\n}\n.dsh-github-item-meta {\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary, #656d76);\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n}\nbody[data-ds-dark-theme] .dsh-github-item-meta {\n color: var(--dsw-alias-label-secondary, #8c8c8c);\n}\n\n/* 10. \u5C0F\u6309\u94AE\u6837\u5F0F\uFF08\u5728 GitHub \u6253\u5F00\u7B49\uFF09 */\n.dsh-github-btn-sm {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid var(--dsw-alias-border-l2, #d0d7de);\n background: var(--dsw-alias-bg-module-platform, #f6f8fa);\n color: var(--dsw-alias-label-primary, #1f2328);\n cursor: pointer;\n text-decoration: none !important;\n transition: all 0.15s ease;\n}\n.dsh-github-btn-sm:hover {\n background: var(--dsw-alias-interactive-bg-hover, #ebeef2);\n border-color: var(--dsw-alias-border-l3, #b0b8c1);\n color: var(--dsw-alias-link, #0969da);\n}\nbody[data-ds-dark-theme] .dsh-github-btn-sm {\n border-color: var(--dsw-alias-border-l1, #444);\n background: var(--dsw-alias-bg-layer-2, #26272b);\n color: var(--dsw-alias-label-primary, #f0f6fc);\n}\nbody[data-ds-dark-theme] .dsh-github-btn-sm:hover {\n background: var(--dsw-alias-interactive-bg-hover, #33343a);\n border-color: rgba(255, 255, 255, 0.25);\n color: #58a6ff;\n}\n\n/* 11. \u7A7A\u72B6\u6001 */\n.dsh-github-empty {\n padding: 24px;\n text-align: center;\n font-size: 12px;\n color: var(--dsw-alias-label-tertiary, #656d76);\n border: 1px dashed var(--dsw-alias-border-l2, #d0d7de);\n border-radius: 8px;\n background: rgba(0, 0, 0, 0.01);\n}\nbody[data-ds-dark-theme] .dsh-github-empty {\n color: var(--dsw-alias-label-tertiary, #888);\n border-color: var(--dsw-alias-border-l1, #38383c);\n background: rgba(255, 255, 255, 0.01);\n}\n\n/* 12. Tabs \u5BFC\u822A\u680F */\n.dsh-github-tabs {\n display: flex;\n gap: 8px;\n margin-bottom: 18px;\n border-bottom: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n padding-bottom: 8px;\n}\nbody[data-ds-dark-theme] .dsh-github-tabs {\n border-bottom-color: var(--dsw-alias-border-l1, #303034);\n}\n.dsh-github-tab-btn {\n padding: 6px 14px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n border: 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #656d76);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.dsh-github-tab-btn:hover {\n color: var(--dsw-alias-label-primary, #1f2328);\n background: var(--dsw-alias-interactive-bg-hover, rgba(0, 0, 0, 0.05));\n}\n.dsh-github-tab-btn.active {\n color: var(--dsw-alias-link, #0969da);\n background: rgba(9, 105, 218, 0.1);\n font-weight: 600;\n}\nbody[data-ds-dark-theme] .dsh-github-tab-btn {\n color: var(--dsw-alias-label-secondary, #8c8c8c);\n}\nbody[data-ds-dark-theme] .dsh-github-tab-btn:hover {\n color: var(--dsw-alias-label-primary, #fff);\n background: var(--dsw-alias-interactive-bg-hover, rgba(255, 255, 255, 0.06));\n}\nbody[data-ds-dark-theme] .dsh-github-tab-btn.active {\n color: #58a6ff;\n background: rgba(88, 166, 255, 0.15);\n}\n\n/* 13. \u641C\u7D22\u8F93\u5165\u6846 */\n.dsh-github-search-input {\n width: 100%;\n max-width: 320px;\n padding: 6px 12px;\n font-size: 12px;\n border-radius: 6px;\n border: 1px solid var(--dsw-alias-border-l2, #d0d7de);\n background: var(--dsw-alias-bg-base, #ffffff);\n color: var(--dsw-alias-label-primary, #1f2328);\n outline: none;\n margin-bottom: 14px;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n.dsh-github-search-input:focus {\n border-color: var(--dsw-alias-link, #0969da);\n box-shadow: 0 0 0 3px rgba(9, 105, 218, 0.15);\n}\nbody[data-ds-dark-theme] .dsh-github-search-input {\n border-color: var(--dsw-alias-border-l1, #444);\n background: var(--dsw-alias-bg-layer-2, #212124);\n color: var(--dsw-alias-label-primary, #f0f6fc);\n}\nbody[data-ds-dark-theme] .dsh-github-search-input:focus {\n border-color: #58a6ff;\n box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.2);\n}\n\n/* 14. \u5DE5\u4F5C\u533A\u77E9\u9635\u6761\u76EE\u4E13\u5C5E\u7C7B */\n.dsh-github-workspace-card {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n}\n.dsh-github-ws-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary, #1f2328);\n}\nbody[data-ds-dark-theme] .dsh-github-ws-title {\n color: var(--dsw-alias-label-primary, #f0f6fc);\n}\n.dsh-github-ws-path {\n font-size: 12px;\n color: var(--dsw-alias-label-tertiary, #656d76);\n font-family: var(--ds-font-family-code, monospace);\n}\nbody[data-ds-dark-theme] .dsh-github-ws-path {\n color: var(--dsw-alias-label-tertiary, #888);\n}\n.dsh-github-ws-repo-link {\n color: var(--dsw-alias-link, #0969da);\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font-weight: 500;\n}\nbody[data-ds-dark-theme] .dsh-github-ws-repo-link {\n color: #58a6ff;\n}\n.dsh-github-repo-link {\n color: var(--dsw-alias-link, #0969da);\n text-decoration: none;\n font-weight: 600;\n}\n.dsh-github-repo-link:hover {\n text-decoration: underline;\n}\nbody[data-ds-dark-theme] .dsh-github-repo-link {\n color: #58a6ff;\n}\n.dsh-github-subheading {\n font-size: 14px;\n font-weight: 600;\n margin: 0 0 10px 0;\n color: var(--dsw-alias-label-primary, #1f2328);\n}\nbody[data-ds-dark-theme] .dsh-github-subheading {\n color: var(--dsw-alias-label-primary, #f0f6fc);\n}\n";