dsh-ide-git 0.14.1 → 0.14.2

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/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-ide-git",
3
- "version": "0.14.1",
3
+ "version": "0.14.2",
4
4
  "main": "./src/index.js",
5
5
  "description": "IDE 级 Git 操作面板:分支树 + 提交图谱 + 变更/暂存/提交 + 提交详情。装了 dsh-better-sidebar 时挂成它的原生 tab(右侧栏 + 底部工作台);没装时直接挂 DSH 原生右侧栏,单独安装即可用。JetBrains 风格 Git 工具窗口 for DeepSeek Harness.",
6
6
  "engines": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-ide-git",
3
- "version": "0.14.1",
3
+ "version": "0.14.2",
4
4
  "description": "DSH plugin: an IDE-grade Git tool window as a native dsh-better-sidebar tab — branch tree, commit graph, changes, commit details, JetBrains-style actions, in the right sidebar and the bottom panel. | DSH 插件:IDE 级 Git 工具窗口,以 dsh-better-sidebar 原生 Tab 挂载——分支树 / 提交图谱 / 变更与提交详情 / JetBrains 风格操作,右侧栏与底部面板双布局自适应。",
5
5
  "type": "module",
6
6
  "repository": {
package/src/client.js CHANGED
@@ -40,6 +40,11 @@ window.__ModuleLoader__.load({
40
40
  of throwing at load time. Every consumer checks for null first. */
41
41
  let UIPrimitives = null
42
42
  try { UIPrimitives = require('@deepseek-ai/dsh-client-ui-primitives') } catch (error) { void error }
43
+ /* The shared lazy Shiki highlighter, bound once (v0.14.1): FileDiff in
44
+ ui-deliverables rides this same hook for its line highlighting. A stable
45
+ module-level reference keeps the LineDiff hook call unconditional. */
46
+ const useCodeHighlighterSeed = UIPrimitives !== null && typeof UIPrimitives.useCodeHighlighter === 'function' ? UIPrimitives.useCodeHighlighter : null
47
+ const languageForPathSeed = UIPrimitives !== null && typeof UIPrimitives.languageForPath === 'function' ? UIPrimitives.languageForPath : null
43
48
 
44
49
  /* API base is MOUNT-RELATIVE (no leading slash). dsh 0.1.7 serves the
45
50
  shell with <base href="./">, so document.baseURI is the mount the page
@@ -6223,6 +6228,72 @@ window.__ModuleLoader__.load({
6223
6228
  )))
6224
6229
  }
6225
6230
 
6231
+ /* The external preview tab's diff (v0.14.1): the FileDiff pattern the
6232
+ host's own workspace-changes review draws — dual old/new line-number
6233
+ gutters, @@ hunk headers, per-side Shiki highlighting — rebuilt on the
6234
+ SAME official seed blocks that component uses (useCodeHighlighter +
6235
+ languageForPath + the file-diff alias tokens). ui-deliverables' FileDiff
6236
+ itself is not requirable across the bundle boundary, but every block it
6237
+ composes is, so this reads like it and themes like it without any
6238
+ hand-rolled colors. */
6239
+ function LineDiff(props) {
6240
+ const rows = useMemo(() => {
6241
+ const parsed = diffLines(props.patch)
6242
+ /* The patch's trailing newline parses as one empty context row with a
6243
+ line number — the base's review drops it, and so does this. */
6244
+ while (parsed.length > 0) {
6245
+ const last = parsed[parsed.length - 1]
6246
+ if (last.kind === 'ctx' && last.text === '') parsed.pop()
6247
+ else break
6248
+ }
6249
+ return parsed
6250
+ }, [props.patch])
6251
+ const language = useMemo(() => {
6252
+ if (languageForPathSeed === null) return undefined
6253
+ for (const row of rows) {
6254
+ if (row.kind === 'meta' && row.text.indexOf('+++ ') === 0) {
6255
+ const filePath = row.text.slice(4).trim().replace(/^b\//, '')
6256
+ return filePath === '' ? undefined : languageForPathSeed(filePath)
6257
+ }
6258
+ }
6259
+ return undefined
6260
+ }, [rows])
6261
+ const highlighter = useCodeHighlighterSeed === null ? undefined : useCodeHighlighterSeed(language)
6262
+ /* Per-side alignment (the FileDiff rule): the NEW side (+ and context)
6263
+ is joined into one fragment, highlighted once, and the per-line spans
6264
+ map back onto their rows; the deleted side keeps its plain removal
6265
+ styling, which is what the unified view needs. */
6266
+ const spansByRow = useMemo(() => {
6267
+ if (highlighter === undefined || rows.length === 0) return null
6268
+ const seq = []
6269
+ for (const row of rows) {
6270
+ if (row.kind === 'add' || row.kind === 'ctx') seq.push([row, row.text === '' ? '' : row.text.slice(1)])
6271
+ }
6272
+ if (seq.length === 0) return null
6273
+ const highlighted = highlighter(seq.map((entry) => entry[1]).join('\n'))
6274
+ if (highlighted === undefined) return null
6275
+ const map = new Map()
6276
+ seq.forEach((entry, index) => map.set(entry[0], highlighted[index] || []))
6277
+ return map
6278
+ }, [rows, highlighter])
6279
+ if (props.loading === true) return E('div', { className: 'dig-empty' }, props.t('diff.loading'))
6280
+ if (rows.length === 0) return E('div', { className: 'dig-empty' }, props.t('diff.empty'))
6281
+ return E('div', { className: 'dig-linediff' }, rows.map((row, index) => {
6282
+ if (row.kind === 'hunk') return E('div', { key: index, className: 'dig-linediff-hunk' }, row.text)
6283
+ if (row.kind === 'meta') return E('div', { key: index, className: 'dig-linediff-meta' }, row.text)
6284
+ const sign = row.kind === 'add' ? '+' : row.kind === 'del' ? '\u2212' : ' '
6285
+ const body = (row.kind === 'ctx' ? row.text : row.text.slice(1)) || ' '
6286
+ const spans = row.kind === 'del' ? null : (spansByRow === null ? undefined : spansByRow.get(row))
6287
+ return E('div', { key: index, className: 'dig-linediff-row dig-linediff-' + row.kind },
6288
+ E('span', { className: 'dig-linediff-no' }, row.oldLine === null ? '' : String(row.oldLine)),
6289
+ E('span', { className: 'dig-linediff-no' }, row.newLine === null ? '' : String(row.newLine)),
6290
+ E('span', { className: 'dig-linediff-sign' }, sign),
6291
+ spans === undefined || spans === null || spans.length === 0
6292
+ ? E('span', { className: 'dig-linediff-text' }, body)
6293
+ : E('span', { className: 'dig-linediff-text' }, spans.map((span, sIndex) => E('span', { key: sIndex, style: span.style }, span.text))))
6294
+ }))
6295
+ }
6296
+
6226
6297
  /* The leading glyph of a change row (v0.14): the host's FileTypeIcon —
6227
6298
  classifyFileType runs inside when given a path. Directories (the
6228
6299
  trailing slash an `ls-files --directory` row carries) ask for the
@@ -9528,6 +9599,23 @@ window.__ModuleLoader__.load({
9528
9599
  '.dig-preview-actions{display:flex;align-items:center;gap:4px;flex:none}',
9529
9600
  '.dig-preview-btn{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;border-radius:var(--dsw-radius-sm,8px);background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer}',
9530
9601
  '.dig-preview-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}',
9602
+ /* LineDiff: the workspace-changes review's row anatomy on the same alias
9603
+ tokens that view uses (FileDiff.module.css), so themes and reading
9604
+ habits carry over untouched. */
9605
+ '.dig-linediff{display:flex;flex-direction:column;min-height:0;font:var(--dsw-font-markdown-code-block);color:var(--dsw-alias-label-primary)}',
9606
+ '.dig-linediff-hunk{padding:4px 16px;color:var(--dsw-alias-label-tertiary);white-space:pre}',
9607
+ '.dig-linediff-meta{padding:2px 16px;color:var(--dsw-alias-label-secondary);font-weight:600;white-space:pre;overflow:hidden;text-overflow:ellipsis}',
9608
+ '.dig-linediff-row{display:flex;padding-right:16px;white-space:pre}',
9609
+ '.dig-linediff-no{flex:none;min-width:2.5em;padding:0 6px;color:var(--dsw-alias-label-tertiary);text-align:right;user-select:none}',
9610
+ '.dig-linediff-sign{flex:none;width:1.4em;user-select:none}',
9611
+ '.dig-linediff-text{padding-right:16px}',
9612
+ '.dig-linediff-add{background:var(--dsw-alias-file-diff-added-bg)}',
9613
+ '.dig-linediff-add .dig-linediff-no{background:var(--dsw-alias-file-diff-added-gutter);color:var(--dsw-alias-file-diff-added-marker)}',
9614
+ '.dig-linediff-add .dig-linediff-sign{color:var(--dsw-alias-file-diff-added-marker)}',
9615
+ '.dig-linediff-del{background:var(--dsw-alias-file-diff-deleted-bg)}',
9616
+ '.dig-linediff-del .dig-linediff-no{background:var(--dsw-alias-file-diff-deleted-gutter);color:var(--dsw-alias-file-diff-deleted-marker)}',
9617
+ '.dig-linediff-del .dig-linediff-sign{color:var(--dsw-alias-file-diff-deleted-marker)}',
9618
+ '.dig-linediff-ctx .dig-linediff-text{color:var(--dsw-alias-label-secondary)}',
9531
9619
  ].join('\n')
9532
9620
 
9533
9621
  /* ============================== plugin ============================== */
@@ -9908,7 +9996,7 @@ window.__ModuleLoader__.load({
9908
9996
  ? E('div', { className: 'dig-preview-body' }, E('div', { className: 'dig-empty' }, t('preview.hint')))
9909
9997
  : state.error !== null
9910
9998
  ? E('div', { className: 'dig-preview-body' }, E('div', { className: 'dig-empty' }, state.error))
9911
- : E('div', { className: 'dig-preview-body' }, E(DiffBody, { patch: state.patch, loading: state.loading, binary: false, t: t })))
9999
+ : E('div', { className: 'dig-preview-body' }, E(LineDiff, { patch: state.patch, loading: state.loading, t: t })))
9912
10000
  }
9913
10001
 
9914
10002
  function apply(ctx) {