@civilization/dsh-git-workbench 0.4.2 → 0.4.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@civilization/dsh-git-workbench",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "IntelliJ IDEA-grade Git Workbench, DAG topology graph, branch switcher, tag manager and agent tools for DeepSeek Harness.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -1,4 +1,4 @@
1
- /* Status bar Git branch pill and popover branch switcher (unified DSH design) */
1
+ /* Status bar Git branch pill and popover branch switcher (Clean & Elegant UI) */
2
2
 
3
3
  .anchor {
4
4
  position: relative;
@@ -14,13 +14,14 @@
14
14
  gap: 6px;
15
15
  box-sizing: border-box;
16
16
  max-width: 100%;
17
- padding: 1px 8px;
18
- border: 0.5px solid var(--dsw-alias-border-l2);
19
- border-radius: var(--dsw-radius-sm);
20
- background: var(--dsw-alias-bg-layer-1, #ffffff);
21
- color: var(--dsw-alias-label-secondary);
17
+ padding: 2px 8px;
18
+ border: 0.5px solid var(--dsw-alias-border-l2, #cbd5e1);
19
+ border-radius: var(--dsw-radius-sm, 6px);
20
+ background: var(--dsw-alias-interactive-bg-hover, #f1f5f9);
21
+ color: var(--dsw-alias-label-primary, #0f172a);
22
22
  font: inherit;
23
- font-weight: 500;
23
+ font-weight: 600;
24
+ font-size: 12px;
24
25
  font-variant-numeric: tabular-nums;
25
26
  line-height: inherit;
26
27
  white-space: nowrap;
@@ -30,21 +31,16 @@
30
31
 
31
32
  .pill:hover,
32
33
  .pill[aria-expanded='true'] {
33
- background: var(--dsw-alias-interactive-bg-hover);
34
- border-color: var(--dsw-alias-border-l1);
35
- color: var(--dsw-alias-label-primary);
34
+ background: var(--dsw-alias-interactive-bg-active, #e2e8f0);
35
+ border-color: var(--dsw-alias-border-l1, #94a3b8);
36
+ color: var(--dsw-alias-label-primary, #0f172a);
36
37
  }
37
38
 
38
39
  .icon {
39
40
  width: 14px;
40
41
  height: 14px;
41
42
  flex: none;
42
- color: var(--dsw-alias-label-tertiary);
43
- }
44
-
45
- .pill:hover .icon,
46
- .pill[aria-expanded='true'] .icon {
47
- color: var(--dsw-alias-state-business-primary);
43
+ color: var(--dsw-alias-state-business-primary, #2563eb);
48
44
  }
49
45
 
50
46
  .branchName {
@@ -62,35 +58,36 @@
62
58
  font-size: 11px;
63
59
  line-height: 14px;
64
60
  font-weight: 500;
65
- background: var(--dsw-alias-interactive-bg-hover);
66
- color: var(--dsw-alias-label-secondary);
61
+ background: rgba(0, 0, 0, 0.06);
62
+ color: var(--dsw-alias-label-secondary, #475569);
67
63
  }
68
64
 
69
65
  .badgeAhead {
70
- color: var(--dsw-alias-state-business-primary);
66
+ color: var(--dsw-alias-state-business-primary, #2563eb);
71
67
  }
72
68
 
73
69
  .badgeBehind {
74
- color: var(--dsw-alias-state-warn-primary);
70
+ color: var(--dsw-alias-state-warn-primary, #d97706);
75
71
  }
76
72
 
77
73
  /* Branch switch popover panel (wrapped in MenuSurface) */
78
74
  .popover {
79
75
  position: fixed;
80
76
  z-index: 1100;
81
- width: 310px;
82
- max-height: 440px;
77
+ width: 320px;
78
+ max-height: 480px;
83
79
  display: flex;
84
80
  flex-direction: column;
85
81
  box-sizing: border-box;
86
82
  background: var(--dsw-alias-bg-overlay, var(--dsw-alias-bg-layer-1, #ffffff));
87
- border: 0.5px solid var(--dsw-alias-border-l1);
88
- border-radius: var(--dsw-radius-lg);
89
- --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);
90
- box-shadow: var(--dsw-elevation-prominent);
91
- color: var(--dsw-alias-label-primary);
92
- font-size: 12px;
83
+ border: 1px solid var(--dsw-alias-border-l1, #e2e8f0);
84
+ border-radius: var(--dsw-radius-xl, 14px);
85
+ --dsw-elevation-stroke-color: var(--dsw-alias-border-l1, #e2e8f0);
86
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(0, 0, 0, 0.04);
87
+ color: var(--dsw-alias-label-primary, #0f172a);
88
+ font-size: 13px;
93
89
  line-height: 18px;
90
+ padding: 10px;
94
91
  overflow: hidden;
95
92
  cursor: default;
96
93
  animation: popoverFadeIn 0.15s cubic-bezier(0.16, 1, 0.3, 1);
@@ -99,7 +96,7 @@
99
96
  @keyframes popoverFadeIn {
100
97
  from {
101
98
  opacity: 0;
102
- transform: translateY(4px) scale(0.98);
99
+ transform: translateY(6px) scale(0.98);
103
100
  }
104
101
  to {
105
102
  opacity: 1;
@@ -108,48 +105,42 @@
108
105
  }
109
106
 
110
107
  .header {
111
- padding: 8px 10px 6px;
112
- border-bottom: 0.5px solid var(--dsw-alias-border-l2);
113
108
  display: flex;
114
109
  flex-direction: column;
115
- gap: 6px;
110
+ gap: 8px;
111
+ padding-bottom: 8px;
112
+ border-bottom: 0.5px solid var(--dsw-alias-border-l2, #e2e8f0);
116
113
  }
117
114
 
118
115
  .searchRow {
119
116
  display: flex;
120
117
  align-items: center;
121
118
  gap: 6px;
122
- padding: 4px 8px;
123
- border-radius: var(--dsw-radius-sm);
124
- background: var(--dsw-alias-interactive-bg-hover);
125
- border: 0.5px solid var(--dsw-alias-border-l2);
126
- }
127
-
128
- .searchIcon {
129
- width: 13px;
130
- height: 13px;
131
- color: var(--dsw-alias-label-tertiary);
132
- flex: none;
119
+ padding: 6px 10px;
120
+ border-radius: var(--dsw-radius-md, 8px);
121
+ background: var(--dsw-alias-bg-base, #f8fafc);
122
+ border: 1px solid var(--dsw-alias-border-l2, #e2e8f0);
133
123
  }
134
124
 
135
125
  .searchInput {
136
126
  flex: 1;
137
127
  border: none;
138
128
  background: transparent;
139
- color: var(--dsw-alias-label-primary);
140
- font-size: 12px;
129
+ color: var(--dsw-alias-label-primary, #0f172a);
130
+ font-size: 13px;
131
+ line-height: 18px;
141
132
  outline: none;
142
133
  }
143
134
 
144
135
  .searchInput::placeholder {
145
- color: var(--dsw-alias-label-tertiary);
136
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
146
137
  }
147
138
 
148
139
  .actionBar {
149
140
  display: flex;
150
141
  align-items: center;
151
142
  justify-content: space-between;
152
- gap: 4px;
143
+ gap: 6px;
153
144
  }
154
145
 
155
146
  .toolBtnGroup {
@@ -161,13 +152,14 @@
161
152
  .toolBtn {
162
153
  display: inline-flex;
163
154
  align-items: center;
155
+ justify-content: center;
164
156
  gap: 4px;
165
- padding: 3px 8px;
166
- border: 0.5px solid var(--dsw-alias-border-l2);
167
- border-radius: var(--dsw-radius-sm);
168
- background: var(--dsw-alias-interactive-bg-hover);
169
- color: var(--dsw-alias-label-secondary);
170
- font-size: 11px;
157
+ padding: 4px 10px;
158
+ border: none;
159
+ border-radius: var(--dsw-radius-sm, 6px);
160
+ background: var(--dsw-alias-interactive-bg-hover, #f1f5f9);
161
+ color: var(--dsw-alias-label-secondary, #475569);
162
+ font-size: 12px;
171
163
  font-family: inherit;
172
164
  font-weight: 500;
173
165
  cursor: pointer;
@@ -175,8 +167,29 @@
175
167
  }
176
168
 
177
169
  .toolBtn:hover {
178
- background: var(--dsw-alias-interactive-bg-active);
179
- color: var(--dsw-alias-label-primary);
170
+ background: var(--dsw-alias-interactive-bg-active, #e2e8f0);
171
+ color: var(--dsw-alias-label-primary, #0f172a);
172
+ }
173
+
174
+ .toolBtnPrimary {
175
+ display: inline-flex;
176
+ align-items: center;
177
+ gap: 4px;
178
+ padding: 4px 10px;
179
+ border: none;
180
+ border-radius: var(--dsw-radius-sm, 6px);
181
+ background: var(--dsw-alias-interactive-bg-hover, #f1f5f9);
182
+ color: var(--dsw-alias-label-primary, #334155);
183
+ font-size: 12px;
184
+ font-family: inherit;
185
+ font-weight: 500;
186
+ cursor: pointer;
187
+ transition: background 0.15s ease, color 0.15s ease;
188
+ }
189
+
190
+ .toolBtnPrimary:hover {
191
+ background: var(--dsw-alias-interactive-bg-active, #e2e8f0);
192
+ color: var(--dsw-alias-label-primary, #0f172a);
180
193
  }
181
194
 
182
195
  .btnIcon {
@@ -193,33 +206,36 @@
193
206
 
194
207
  .newBranchInput {
195
208
  flex: 1;
196
- padding: 4px 8px;
197
- border-radius: var(--dsw-radius-sm);
198
- border: 0.5px solid var(--dsw-alias-state-business-primary);
199
- background: var(--dsw-alias-interactive-bg-hover);
200
- color: var(--dsw-alias-label-primary);
209
+ padding: 5px 10px;
210
+ border-radius: var(--dsw-radius-sm, 6px);
211
+ border: 1px solid var(--dsw-alias-state-business-primary, #2563eb);
212
+ background: var(--dsw-alias-bg-base, #f8fafc);
213
+ color: var(--dsw-alias-label-primary, #0f172a);
201
214
  font-size: 12px;
202
215
  outline: none;
203
216
  }
204
217
 
205
218
  .newBranchInput::placeholder {
206
- color: var(--dsw-alias-label-tertiary);
219
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
207
220
  }
208
221
 
209
222
  .branchList {
210
223
  flex: 1;
211
224
  overflow-y: auto;
212
- padding: 4px;
225
+ display: flex;
226
+ flex-direction: column;
227
+ gap: 2px;
228
+ padding: 4px 0 0 0;
213
229
  }
214
230
 
215
231
  .groupLabel {
216
232
  display: flex;
217
233
  align-items: center;
218
234
  gap: 6px;
219
- padding: 6px 8px 3px;
220
- font-size: 11px;
221
- font-weight: 500;
222
- color: var(--dsw-alias-label-tertiary);
235
+ padding: 8px 8px 4px 8px;
236
+ font-size: 12px;
237
+ font-weight: 400;
238
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
223
239
  }
224
240
 
225
241
  .branchItem {
@@ -227,50 +243,52 @@
227
243
  align-items: center;
228
244
  justify-content: space-between;
229
245
  width: 100%;
230
- padding: 5px 8px;
231
- border-radius: var(--dsw-radius-sm);
246
+ box-sizing: border-box;
247
+ padding: 7px 10px;
248
+ border-radius: var(--dsw-radius-sm, 8px);
232
249
  border: none;
233
250
  background: transparent;
234
- color: var(--dsw-alias-label-secondary);
251
+ color: var(--dsw-alias-label-secondary, #334155);
235
252
  font: inherit;
236
- font-size: 12px;
253
+ font-size: 13px;
254
+ font-weight: 400;
237
255
  text-align: left;
238
256
  cursor: pointer;
239
257
  transition: background 0.12s ease, color 0.12s ease;
240
258
  }
241
259
 
242
- .branchItem:hover {
243
- background: var(--dsw-alias-interactive-bg-hover);
244
- color: var(--dsw-alias-label-primary);
260
+ .branchItem:hover:not(.currentBranch) {
261
+ background: var(--dsw-alias-bg-base, #f8fafc);
262
+ color: var(--dsw-alias-label-primary, #0f172a);
245
263
  }
246
264
 
247
265
  .currentBranch {
248
- background: var(--dsw-alias-interactive-bg-active);
249
- color: var(--dsw-alias-state-business-primary);
250
- font-weight: 500;
266
+ background: var(--dsw-alias-state-business-muted, #eff6ff) !important;
267
+ color: var(--dsw-alias-state-business-primary, #2563eb) !important;
268
+ font-weight: 600 !important;
251
269
  }
252
270
 
253
271
  .currentBranch:hover {
254
- background: var(--dsw-alias-interactive-bg-active);
272
+ background: var(--dsw-alias-state-business-muted, #eff6ff) !important;
255
273
  }
256
274
 
257
275
  .branchItemLeft {
258
276
  display: flex;
259
277
  align-items: center;
260
- gap: 6px;
278
+ gap: 8px;
261
279
  min-width: 0;
262
280
  flex: 1;
263
281
  }
264
282
 
265
283
  .itemIcon {
266
- width: 13px;
267
- height: 13px;
284
+ width: 14px;
285
+ height: 14px;
268
286
  flex: none;
269
- color: var(--dsw-alias-label-tertiary);
287
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
270
288
  }
271
289
 
272
290
  .currentBranch .itemIcon {
273
- color: var(--dsw-alias-state-business-primary);
291
+ color: var(--dsw-alias-state-business-primary, #2563eb);
274
292
  }
275
293
 
276
294
  .itemText {
@@ -280,15 +298,15 @@
280
298
  }
281
299
 
282
300
  .checkMark {
283
- width: 14px;
284
- height: 14px;
285
- color: var(--dsw-alias-state-business-primary);
301
+ width: 15px;
302
+ height: 15px;
303
+ color: var(--dsw-alias-state-business-primary, #2563eb);
286
304
  flex: none;
287
305
  }
288
306
 
289
307
  .emptyTip {
290
- padding: 16px 8px;
308
+ padding: 20px 8px;
291
309
  text-align: center;
292
- color: var(--dsw-alias-label-tertiary);
310
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
293
311
  font-size: 12px;
294
312
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Status bar Git branch pill and popover branch switcher (IDEA / VS Code style).
2
+ * Status bar Git branch pill and popover branch switcher (Clean & Elegant UI).
3
3
  * Injected into the 'conversation.composer.dock' slot at order: -1.
4
4
  */
5
5
 
@@ -28,40 +28,21 @@ function IconBranchOutlineRegular({ className }: { className?: string }): React.
28
28
 
29
29
  function IconCheckOutlineRegular({ className }: { className?: string }): React.ReactElement {
30
30
  return (
31
- <svg className={className} width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
31
+ <svg className={className} width="15" height="15" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
32
32
  <polyline points="3 8 7 12 13 4" />
33
33
  </svg>
34
34
  )
35
35
  }
36
36
 
37
- function IconPlusOutlineRegular({ className }: { className?: string }): React.ReactElement {
38
- return (
39
- <svg className={className} width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
40
- <line x1="8" y1="3" x2="8" y2="13" />
41
- <line x1="3" y1="8" x2="13" y2="8" />
42
- </svg>
43
- )
44
- }
45
-
46
37
  function IconRefreshOutlineRegular({ className }: { className?: string }): React.ReactElement {
47
38
  return (
48
- <svg className={className} width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
39
+ <svg className={className} width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
49
40
  <path d="M2.5 8a5.5 5.5 0 1 0 1.6-3.9L2 6" />
50
41
  <path d="M2 2v4h4" />
51
42
  </svg>
52
43
  )
53
44
  }
54
45
 
55
- function IconSearchOutlineRegular({ className }: { className?: string }): React.ReactElement {
56
- return (
57
- <svg className={className} width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
58
- <circle cx="7" cy="7" r="4.5" />
59
- <line x1="10.5" y1="10.5" x2="14" y2="14" />
60
- </svg>
61
- )
62
- }
63
-
64
-
65
46
  export interface GitBranchPillProps {
66
47
  getStatus?: ((sessionId?: string) => Promise<GitStatusSummary>) | undefined
67
48
  getBranches?: ((sessionId?: string) => Promise<GitBranchesSummary>) | undefined
@@ -123,8 +104,8 @@ export const GitBranchPill = memo(function GitBranchPill({
123
104
  if (!anchorRef.current) return
124
105
  const rect = anchorRef.current.getBoundingClientRect()
125
106
  setPopoverPos({
126
- bottom: window.innerHeight - rect.top + 6,
127
- left: Math.max(8, Math.min(rect.left, window.innerWidth - 330)),
107
+ bottom: window.innerHeight - rect.top + 8,
108
+ left: Math.max(12, Math.min(rect.left, window.innerWidth - 340)),
128
109
  })
129
110
  }, [])
130
111
 
@@ -220,7 +201,7 @@ export const GitBranchPill = memo(function GitBranchPill({
220
201
  return null
221
202
  }
222
203
 
223
- const currentBranchName = status?.branch || 'master'
204
+ const currentBranchName = status?.branch || 'main'
224
205
 
225
206
  return (
226
207
  <span ref={anchorRef} className={css.anchor} data-composer-stat="git-branch">
@@ -246,7 +227,6 @@ export const GitBranchPill = memo(function GitBranchPill({
246
227
  >
247
228
  <div className={css.header}>
248
229
  <div className={css.searchRow}>
249
- <IconSearchOutlineRegular className={css.searchIcon} />
250
230
  <input
251
231
  autoFocus
252
232
  className={css.searchInput}
@@ -259,18 +239,15 @@ export const GitBranchPill = memo(function GitBranchPill({
259
239
  <div className={css.actionBar}>
260
240
  <button
261
241
  type="button"
262
- className={css.toolBtn}
263
- title="新建分支"
242
+ className={css.toolBtnPrimary}
264
243
  onClick={() => { setCreatingBranch(prev => !prev) }}
265
244
  >
266
- <IconPlusOutlineRegular className={css.btnIcon} />
267
- <span>新建分支</span>
245
+ <span>+ 新建分支</span>
268
246
  </button>
269
247
  <div className={css.toolBtnGroup}>
270
248
  <button
271
249
  type="button"
272
250
  className={css.toolBtn}
273
- title="拉取 (Pull)"
274
251
  onClick={() => { void handlePull() }}
275
252
  >
276
253
  Pull
@@ -278,7 +255,6 @@ export const GitBranchPill = memo(function GitBranchPill({
278
255
  <button
279
256
  type="button"
280
257
  className={css.toolBtn}
281
- title="推送 (Push)"
282
258
  onClick={() => { void handlePush() }}
283
259
  >
284
260
  Push
@@ -325,32 +301,29 @@ export const GitBranchPill = memo(function GitBranchPill({
325
301
  <IconBranchOutlineRegular className={css.itemIcon} />
326
302
  <span className={css.itemText}>{b.name}</span>
327
303
  </div>
328
- {b.isCurrent ? (
329
- <IconCheckOutlineRegular className={css.checkMark} />
330
- ) : (
331
- b.ahead !== undefined && b.ahead > 0 && <span className={css.badge}>↑{b.ahead}</span>
332
- )}
304
+ {b.isCurrent && <IconCheckOutlineRegular className={css.checkMark} />}
333
305
  </button>
334
306
  ))}
335
307
 
336
308
  {/* Remote Branches */}
337
309
  {filteredRemote.length > 0 && (
338
310
  <>
339
- <div className={css.groupLabel} style={{ marginTop: '6px' }}>
340
- 远程分支 ({filteredRemote.length})
341
- </div>
311
+ <div className={css.groupLabel}>远程分支 ({filteredRemote.length})</div>
342
312
  {filteredRemote.map(b => (
343
313
  <button
344
314
  key={b.name}
345
315
  type="button"
346
- className={css.branchItem}
316
+ className={`${css.branchItem} ${b.isCurrent ? css.currentBranch : ''}`}
347
317
  disabled={switching}
348
- onClick={() => { void handleCheckout(b.name) }}
318
+ onClick={() => {
319
+ if (!b.isCurrent) void handleCheckout(b.name)
320
+ }}
349
321
  >
350
322
  <div className={css.branchItemLeft}>
351
323
  <IconBranchOutlineRegular className={css.itemIcon} />
352
324
  <span className={css.itemText}>{b.name}</span>
353
325
  </div>
326
+ {b.isCurrent && <IconCheckOutlineRegular className={css.checkMark} />}
354
327
  </button>
355
328
  ))}
356
329
  </>
@@ -6,14 +6,14 @@ export const NS = 'gitView'
6
6
 
7
7
  export const zh = {
8
8
  'type.label': 'Git',
9
- 'guide.title': 'Git 版本控制',
10
- 'guide.description': '查看项目代码变更、分支、提交历史与差异对比',
9
+ 'guide.title': 'Git 源代码管理',
10
+ 'guide.description': '查看项目代码变更、分支、提交历史与代码对比',
11
11
  'shortcut.noSession': '没有激活的会话',
12
12
  'tabs.changes': '更改',
13
13
  'tabs.history': '提交历史',
14
- 'tabs.tree': '提交图谱树',
15
- 'tabs.branches': '分支管理',
16
- 'tabs.tags': '标签管理',
14
+ 'tabs.tree': '提交图谱',
15
+ 'tabs.branches': '分支',
16
+ 'tabs.tags': '标签',
17
17
  'actions.refresh': '刷新状态',
18
18
  'actions.viewDiff': '查看差异',
19
19
  'actions.closeDiff': '收起差异',
@@ -27,68 +27,68 @@ export const zh = {
27
27
  'actions.checkout': '检出分支',
28
28
  'actions.newBranch': '新建分支',
29
29
  'actions.fetch': '获取远程',
30
- 'actions.pull': '拉取',
31
- 'actions.push': '推送',
32
- 'commit.placeholder': '输入提交信息 (Ctrl+Enter 提交)...',
30
+ 'actions.pull': '拉取 (Pull)',
31
+ 'actions.push': '推送 (Push)',
32
+ 'commit.placeholder': '提交说明信息 (Ctrl+Enter 提交)...',
33
33
  'commit.emptyWarning': '请输入提交说明',
34
34
  'commit.success': '提交成功',
35
- 'branch.filter': '搜索过滤分支...',
35
+ 'branch.filter': '搜索或过滤分支...',
36
36
  'branch.local': '本地分支',
37
37
  'branch.remote': '远程分支',
38
38
  'branch.current': '当前分支',
39
- 'branch.newPrompt': '输入新分支名称...',
39
+ 'branch.newPrompt': '新分支名称 (按 Enter 创建)...',
40
40
  'branch.createAndCheckout': '创建并检出',
41
41
  'tree.author': '作者',
42
42
  'tree.date': '时间',
43
43
  'tree.hash': '哈希',
44
44
  'tree.changedFiles': '变更文件',
45
- 'tree.selectCommit': '点击任意提交查看详情与代码差异',
46
- 'status.clean': '工作树干净,无任何未提交更改',
45
+ 'tree.selectCommit': '选择一次提交以查看详情与代码差异',
46
+ 'status.clean': '工作区干净,无未提交的更改',
47
47
  'status.notRepo': '当前工作区不是 Git 仓库',
48
- 'status.staged': '已暂存更改',
49
- 'status.unstaged': '工作区修改',
48
+ 'status.staged': '暂存的更改',
49
+ 'status.unstaged': '更改',
50
50
  'status.untracked': '未跟踪文件',
51
51
  'status.ahead': '领先 {count} 个提交',
52
52
  'status.behind': '落后 {count} 个提交',
53
53
  'diff.additions': '+{count}',
54
54
  'diff.deletions': '-{count}',
55
55
  'diff.empty': '无内容变动',
56
- 'tag.filter': '搜索过滤标签 (名称、Hash、提交说明)...',
56
+ 'tag.filter': '过滤标签 (名称、Hash或提交说明)...',
57
57
  'tag.newPrompt': '新建标签 (Tag)',
58
58
  'tag.nameLabel': '标签名称',
59
- 'tag.namePlaceholder': '输入标签名称 (例如 v1.0.0)...',
60
- 'tag.targetCommitLabel': '目标 Commit Hash (可选,留空为 HEAD)',
61
- 'tag.messageLabel': '说明信息 (可选附注内容)',
62
- 'tag.messagePrompt': '输入附注说明信息 (可选)...',
59
+ 'tag.namePlaceholder': '输入标签名称 (如 v1.0.0)...',
60
+ 'tag.targetCommitLabel': '目标 Commit Hash (可选,默认 HEAD)',
61
+ 'tag.messageLabel': '附注说明信息 (可选)',
62
+ 'tag.messagePrompt': '请输入附注说明信息 (可选)...',
63
63
  'tag.createBtn': '创建标签',
64
64
  'tag.cancelBtn': '取消',
65
65
  'tag.locateBtn': '在图谱中定位',
66
66
  'tag.copyName': '复制标签名',
67
67
  'tag.deleteBtn': '删除',
68
68
  'tag.deleteConfirm': '确定要删除标签 "{name}" 吗?',
69
- 'tag.empty': '暂无任何 Git 标签',
70
- 'tag.annotated': '附注',
71
- 'tag.locatedNotice': '已定位到标签 "{name}" 所在的提交',
69
+ 'tag.empty': '未找到任何 Git 标签',
70
+ 'tag.annotated': '含附注',
71
+ 'tag.locatedNotice': '已定位到标签 "{name}" 所在提交',
72
72
  'actions.locate': '定位',
73
73
  'tree.colGraph': '图谱',
74
- 'tree.colSubject': '提交说明与分支标记',
74
+ 'tree.colSubject': '提交说明与分支引用',
75
75
  'tree.colAuthor': '作者',
76
76
  'tree.colTime': '时间',
77
77
  'tree.colSha': 'Commit SHA',
78
78
  'tree.searchPlaceholder': '搜索提交说明、SHA 或作者...',
79
- 'tree.filterAll': '全部',
80
- 'tree.filterMainline': '仅主线',
79
+ 'tree.filterAll': '全部提交',
80
+ 'tree.filterMainline': '主线分支',
81
81
  'detail.title': '提交详情 (COMMIT DETAILS)',
82
- 'detail.references': '包含引用 (REFERENCES)',
83
- 'detail.author': '作者 (Author)',
82
+ 'detail.references': '分支引用 (REFERENCES)',
83
+ 'detail.author': '提交作者 (Author)',
84
84
  'detail.date': '提交时间 (Date)',
85
85
  'detail.parent': '父级提交 (Parent)',
86
86
  'detail.checkout': '检出分支 (Checkout)',
87
- 'detail.createBranchOrTag': '创建分支 / 标签',
88
- 'footer.showingCount': '已显示 {count} 条提交 (共 {total} 条)',
87
+ 'detail.createBranchOrTag': '从此检出分支 / 标签',
88
+ 'footer.showingCount': '显示 {count} 条提交 (共 {total} 条)',
89
89
  'footer.loadMore': '加载更多',
90
- 'footer.syncNormal': '分支同步正常',
91
- 'footer.ahead': '本地领先 {count} 个提交',
90
+ 'footer.syncNormal': '分支已与远程同步',
91
+ 'footer.ahead': '领先远程 {count} 个提交',
92
92
  'footer.behind': '落后远程 {count} 个提交',
93
93
  } satisfies Record<string, string>
94
94