dsh-git-changes 0.0.0-stage → 0.1.1

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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +119 -0
  3. package/README.md +137 -2
  4. package/THIRD_PARTY_NOTICES.md +12 -0
  5. package/assets/vendor/monaco/LICENSE +21 -0
  6. package/assets/vendor/monaco/ThirdPartyNotices.txt +448 -0
  7. package/assets/vendor/monaco/vs/base/browser/ui/codicons/codicon/codicon.ttf +0 -0
  8. package/assets/vendor/monaco/vs/base/common/worker/simpleWorker.nls.js +7 -0
  9. package/assets/vendor/monaco/vs/base/common/worker/simpleWorker.nls.zh-cn.js +7 -0
  10. package/assets/vendor/monaco/vs/base/worker/workerMain.js +26 -0
  11. package/assets/vendor/monaco/vs/basic-languages/abap/abap.js +10 -0
  12. package/assets/vendor/monaco/vs/basic-languages/apex/apex.js +10 -0
  13. package/assets/vendor/monaco/vs/basic-languages/azcli/azcli.js +10 -0
  14. package/assets/vendor/monaco/vs/basic-languages/bat/bat.js +10 -0
  15. package/assets/vendor/monaco/vs/basic-languages/bicep/bicep.js +11 -0
  16. package/assets/vendor/monaco/vs/basic-languages/cameligo/cameligo.js +10 -0
  17. package/assets/vendor/monaco/vs/basic-languages/clojure/clojure.js +10 -0
  18. package/assets/vendor/monaco/vs/basic-languages/coffee/coffee.js +10 -0
  19. package/assets/vendor/monaco/vs/basic-languages/cpp/cpp.js +10 -0
  20. package/assets/vendor/monaco/vs/basic-languages/csharp/csharp.js +10 -0
  21. package/assets/vendor/monaco/vs/basic-languages/csp/csp.js +10 -0
  22. package/assets/vendor/monaco/vs/basic-languages/css/css.js +12 -0
  23. package/assets/vendor/monaco/vs/basic-languages/cypher/cypher.js +10 -0
  24. package/assets/vendor/monaco/vs/basic-languages/dart/dart.js +10 -0
  25. package/assets/vendor/monaco/vs/basic-languages/dockerfile/dockerfile.js +10 -0
  26. package/assets/vendor/monaco/vs/basic-languages/ecl/ecl.js +10 -0
  27. package/assets/vendor/monaco/vs/basic-languages/elixir/elixir.js +10 -0
  28. package/assets/vendor/monaco/vs/basic-languages/flow9/flow9.js +10 -0
  29. package/assets/vendor/monaco/vs/basic-languages/freemarker2/freemarker2.js +12 -0
  30. package/assets/vendor/monaco/vs/basic-languages/fsharp/fsharp.js +10 -0
  31. package/assets/vendor/monaco/vs/basic-languages/go/go.js +10 -0
  32. package/assets/vendor/monaco/vs/basic-languages/graphql/graphql.js +10 -0
  33. package/assets/vendor/monaco/vs/basic-languages/handlebars/handlebars.js +10 -0
  34. package/assets/vendor/monaco/vs/basic-languages/hcl/hcl.js +10 -0
  35. package/assets/vendor/monaco/vs/basic-languages/html/html.js +10 -0
  36. package/assets/vendor/monaco/vs/basic-languages/ini/ini.js +10 -0
  37. package/assets/vendor/monaco/vs/basic-languages/java/java.js +10 -0
  38. package/assets/vendor/monaco/vs/basic-languages/javascript/javascript.js +10 -0
  39. package/assets/vendor/monaco/vs/basic-languages/julia/julia.js +10 -0
  40. package/assets/vendor/monaco/vs/basic-languages/kotlin/kotlin.js +10 -0
  41. package/assets/vendor/monaco/vs/basic-languages/less/less.js +11 -0
  42. package/assets/vendor/monaco/vs/basic-languages/lexon/lexon.js +10 -0
  43. package/assets/vendor/monaco/vs/basic-languages/liquid/liquid.js +10 -0
  44. package/assets/vendor/monaco/vs/basic-languages/lua/lua.js +10 -0
  45. package/assets/vendor/monaco/vs/basic-languages/m3/m3.js +10 -0
  46. package/assets/vendor/monaco/vs/basic-languages/markdown/markdown.js +10 -0
  47. package/assets/vendor/monaco/vs/basic-languages/mdx/mdx.js +10 -0
  48. package/assets/vendor/monaco/vs/basic-languages/mips/mips.js +10 -0
  49. package/assets/vendor/monaco/vs/basic-languages/msdax/msdax.js +10 -0
  50. package/assets/vendor/monaco/vs/basic-languages/mysql/mysql.js +10 -0
  51. package/assets/vendor/monaco/vs/basic-languages/objective-c/objective-c.js +10 -0
  52. package/assets/vendor/monaco/vs/basic-languages/pascal/pascal.js +10 -0
  53. package/assets/vendor/monaco/vs/basic-languages/pascaligo/pascaligo.js +10 -0
  54. package/assets/vendor/monaco/vs/basic-languages/perl/perl.js +10 -0
  55. package/assets/vendor/monaco/vs/basic-languages/pgsql/pgsql.js +10 -0
  56. package/assets/vendor/monaco/vs/basic-languages/php/php.js +10 -0
  57. package/assets/vendor/monaco/vs/basic-languages/pla/pla.js +10 -0
  58. package/assets/vendor/monaco/vs/basic-languages/postiats/postiats.js +10 -0
  59. package/assets/vendor/monaco/vs/basic-languages/powerquery/powerquery.js +10 -0
  60. package/assets/vendor/monaco/vs/basic-languages/powershell/powershell.js +10 -0
  61. package/assets/vendor/monaco/vs/basic-languages/protobuf/protobuf.js +11 -0
  62. package/assets/vendor/monaco/vs/basic-languages/pug/pug.js +10 -0
  63. package/assets/vendor/monaco/vs/basic-languages/python/python.js +10 -0
  64. package/assets/vendor/monaco/vs/basic-languages/qsharp/qsharp.js +10 -0
  65. package/assets/vendor/monaco/vs/basic-languages/r/r.js +10 -0
  66. package/assets/vendor/monaco/vs/basic-languages/razor/razor.js +10 -0
  67. package/assets/vendor/monaco/vs/basic-languages/redis/redis.js +10 -0
  68. package/assets/vendor/monaco/vs/basic-languages/redshift/redshift.js +10 -0
  69. package/assets/vendor/monaco/vs/basic-languages/restructuredtext/restructuredtext.js +10 -0
  70. package/assets/vendor/monaco/vs/basic-languages/ruby/ruby.js +10 -0
  71. package/assets/vendor/monaco/vs/basic-languages/rust/rust.js +10 -0
  72. package/assets/vendor/monaco/vs/basic-languages/sb/sb.js +10 -0
  73. package/assets/vendor/monaco/vs/basic-languages/scala/scala.js +10 -0
  74. package/assets/vendor/monaco/vs/basic-languages/scheme/scheme.js +10 -0
  75. package/assets/vendor/monaco/vs/basic-languages/scss/scss.js +12 -0
  76. package/assets/vendor/monaco/vs/basic-languages/shell/shell.js +10 -0
  77. package/assets/vendor/monaco/vs/basic-languages/solidity/solidity.js +10 -0
  78. package/assets/vendor/monaco/vs/basic-languages/sophia/sophia.js +10 -0
  79. package/assets/vendor/monaco/vs/basic-languages/sparql/sparql.js +10 -0
  80. package/assets/vendor/monaco/vs/basic-languages/sql/sql.js +10 -0
  81. package/assets/vendor/monaco/vs/basic-languages/st/st.js +10 -0
  82. package/assets/vendor/monaco/vs/basic-languages/swift/swift.js +13 -0
  83. package/assets/vendor/monaco/vs/basic-languages/systemverilog/systemverilog.js +10 -0
  84. package/assets/vendor/monaco/vs/basic-languages/tcl/tcl.js +10 -0
  85. package/assets/vendor/monaco/vs/basic-languages/twig/twig.js +10 -0
  86. package/assets/vendor/monaco/vs/basic-languages/typescript/typescript.js +10 -0
  87. package/assets/vendor/monaco/vs/basic-languages/vb/vb.js +10 -0
  88. package/assets/vendor/monaco/vs/basic-languages/wgsl/wgsl.js +307 -0
  89. package/assets/vendor/monaco/vs/basic-languages/xml/xml.js +10 -0
  90. package/assets/vendor/monaco/vs/basic-languages/yaml/yaml.js +10 -0
  91. package/assets/vendor/monaco/vs/editor/editor.main.css +6 -0
  92. package/assets/vendor/monaco/vs/editor/editor.main.js +744 -0
  93. package/assets/vendor/monaco/vs/editor/editor.main.nls.js +28 -0
  94. package/assets/vendor/monaco/vs/editor/editor.main.nls.zh-cn.js +30 -0
  95. package/assets/vendor/monaco/vs/language/css/cssMode.js +13 -0
  96. package/assets/vendor/monaco/vs/language/css/cssWorker.js +81 -0
  97. package/assets/vendor/monaco/vs/language/html/htmlMode.js +13 -0
  98. package/assets/vendor/monaco/vs/language/html/htmlWorker.js +453 -0
  99. package/assets/vendor/monaco/vs/language/json/jsonMode.js +15 -0
  100. package/assets/vendor/monaco/vs/language/json/jsonWorker.js +36 -0
  101. package/assets/vendor/monaco/vs/language/typescript/tsMode.js +20 -0
  102. package/assets/vendor/monaco/vs/language/typescript/tsWorker.js +37016 -0
  103. package/assets/vendor/monaco/vs/loader.js +10 -0
  104. package/cordis.patch.yml +3 -0
  105. package/docs/images/git-changes-diff.png +0 -0
  106. package/docs/regression-checklist.md +47 -0
  107. package/icon.svg +10 -0
  108. package/lib/client.js +9418 -0
  109. package/lib/host/assets.js +161 -0
  110. package/lib/host/commit-message.js +158 -0
  111. package/lib/host/files-index.js +206 -0
  112. package/lib/host/git-write.js +194 -0
  113. package/lib/host/git.js +1147 -0
  114. package/lib/host/lsp.js +842 -0
  115. package/lib/host/routes.js +976 -0
  116. package/lib/host/session.js +84 -0
  117. package/lib/host/util.js +107 -0
  118. package/lib/index.js +33 -0
  119. package/licenses/dsh-vscode-mode-LICENSE +21 -0
  120. package/licenses/vscode-theme-seti-LICENSE +21 -0
  121. package/licenses/vscode-theme-seti-ThirdPartyNotices.txt +32 -0
  122. package/locale/en.json +6 -0
  123. package/locale/zh.json +6 -0
  124. package/package.json +65 -4
  125. package/src/client/00-const.js +79 -0
  126. package/src/client/05-utils.js +277 -0
  127. package/src/client/10-i18n.js +548 -0
  128. package/src/client/12-vscode-icons.js +460 -0
  129. package/src/client/15-theme.js +509 -0
  130. package/src/client/20-monaco.js +1404 -0
  131. package/src/client/22-lsp.js +592 -0
  132. package/src/client/25-tree.js +563 -0
  133. package/src/client/28-changes.js +1163 -0
  134. package/src/client/30-page.js +2259 -0
  135. package/src/client/35-pill.js +185 -0
  136. package/src/client/40-commands.js +248 -0
  137. package/src/client/45-css.js +357 -0
  138. package/src/client/47-pickers.js +457 -0
  139. package/src/client/50-apply.js +207 -0
  140. package/src/client/99-footer.js +62 -0
@@ -0,0 +1,84 @@
1
+ /** Live-session lookups, working-directory access, and the latest turn announcement. */
2
+
3
+ /**
4
+ * @typedef {object} LiveSession
5
+ * @property {{ id: string, cwd?: string }} header
6
+ * @property {number} seq
7
+ * @property {() => readonly any[]} ownEvents
8
+ */
9
+
10
+ /**
11
+ * Look up a live Host session without throwing on unknown ids.
12
+ * @param {{ sessions: { get(id: string): unknown } }} ctx host context
13
+ * @param {string} sessionId session identity
14
+ * @returns {LiveSession | undefined}
15
+ */
16
+ export function liveSession(ctx, sessionId) {
17
+ if (typeof sessionId !== 'string' || sessionId.length === 0 || sessionId.length > 256) return undefined
18
+ try {
19
+ return /** @type {LiveSession | undefined} */ (ctx.sessions.get(sessionId))
20
+ } catch {
21
+ return undefined
22
+ }
23
+ }
24
+
25
+ /**
26
+ * The session's working directory, when it has one.
27
+ * @param {LiveSession | undefined} session live session
28
+ * @returns {string | undefined}
29
+ */
30
+ export function cwdOf(session) {
31
+ const cwd = session?.header?.cwd
32
+ return typeof cwd === 'string' && cwd.length > 0 ? cwd : undefined
33
+ }
34
+
35
+ /**
36
+ * Scan a live session's own events backwards for its latest `workspace/changes`
37
+ * announcement. Used only as a fallback when the live tracker missed one.
38
+ * @param {LiveSession} session live session
39
+ * @returns {any | undefined} the event record
40
+ */
41
+ export function lastChangesEvent(session) {
42
+ let events
43
+ try {
44
+ events = session.ownEvents()
45
+ } catch {
46
+ return undefined
47
+ }
48
+ if (!Array.isArray(events)) return undefined
49
+ for (let index = events.length - 1; index >= 0; index -= 1) {
50
+ const event = events[index]
51
+ if (event?.type !== 'workspace/changes') continue
52
+ if (Number.isSafeInteger(event.data?.turn) && event.data.turn >= 1) return event
53
+ }
54
+ return undefined
55
+ }
56
+
57
+ /**
58
+ * Track the latest `workspace/changes` event per live session, so the review
59
+ * routes do not rescan long session logs on every request.
60
+ * @param {object} ctx host context
61
+ * @returns {WeakMap<object, any>} session → event record
62
+ */
63
+ export function createChangesTracker(ctx) {
64
+ const latest = new WeakMap()
65
+ try {
66
+ const dispose = ctx.on('session/event', (session, event) => {
67
+ if (event?.type !== 'workspace/changes') return
68
+ if (!Number.isSafeInteger(event.data?.turn) || event.data.turn < 1) return
69
+ latest.set(session, event)
70
+ })
71
+ if (typeof dispose === 'function') {
72
+ ctx.effect(() => () => {
73
+ try {
74
+ dispose()
75
+ } catch {
76
+ /* the connection may already be torn down */
77
+ }
78
+ }, 'dsh-git-changes: workspace/changes tracker')
79
+ }
80
+ } catch {
81
+ /* A missing event bridge only costs a rescan. */
82
+ }
83
+ return latest
84
+ }
@@ -0,0 +1,107 @@
1
+ /** JSON response and query-coordinate helpers for the read-only review routes. */
2
+
3
+ /**
4
+ * Build a no-store JSON response.
5
+ * @param {unknown} body serializable payload
6
+ * @param {number} [status] HTTP status
7
+ * @returns {Response}
8
+ */
9
+ export function jsonResponse(body, status = 200) {
10
+ return new Response(JSON.stringify(body), {
11
+ status,
12
+ headers: { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' },
13
+ })
14
+ }
15
+
16
+ /**
17
+ * Build the SPEC error envelope.
18
+ * @param {string} code stable machine code
19
+ * @param {string} message human readable message
20
+ * @param {number} status HTTP status
21
+ * @returns {Response}
22
+ */
23
+ export function failure(code, message, status) {
24
+ return jsonResponse({ error: { code, message } }, status)
25
+ }
26
+
27
+ /**
28
+ * Parse a non-negative safe-integer query coordinate.
29
+ * @param {string | number | null} value query string or JSON numeric coordinate
30
+ * @returns {number | undefined}
31
+ */
32
+ export function coordinate(value) {
33
+ if (typeof value === 'number') return Number.isSafeInteger(value) && value >= 0 ? value : undefined
34
+ if (typeof value !== 'string' || !/^\d+$/.test(value)) return undefined
35
+ const parsed = Number(value)
36
+ return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : undefined
37
+ }
38
+
39
+ /**
40
+ * Read a bounded opaque identifier query value.
41
+ * @param {string | null} value raw query value
42
+ * @param {number} [maxLength] length bound
43
+ * @returns {string | undefined}
44
+ */
45
+ export function identifier(value, maxLength = 256) {
46
+ if (typeof value !== 'string') return undefined
47
+ if (value.length === 0 || value.length > maxLength) return undefined
48
+ return value
49
+ }
50
+
51
+ /**
52
+ * Reject relative workspace paths that could escape the workspace or confuse the
53
+ * filesystem provider: empty segments, `.`/`..`, drive letters, control chars.
54
+ * @param {string} value workspace-relative path using either separator
55
+ * @returns {boolean} whether the path is a safe non-empty relative path
56
+ */
57
+ export function safeRelativePath(value) {
58
+ if (typeof value !== 'string' || value.length === 0 || value.length > 4096) return false
59
+ if (/[\u0000-\u001f\u007f]/.test(value)) return false
60
+ if (/^[a-zA-Z]:/.test(value) || value.startsWith('/') || value.startsWith('\\')) return false
61
+ const segments = value.split(/[\\/]+/)
62
+ if (segments.length === 0) return false
63
+ for (const segment of segments) {
64
+ if (segment === '' || segment === '.' || segment === '..') return false
65
+ }
66
+ return true
67
+ }
68
+
69
+ /**
70
+ * Validate a browser-supplied git revision expression (no spaces, no leading dash).
71
+ * @param {unknown} value raw query value
72
+ * @returns {string | undefined} trimmed revision expression, or undefined when unsafe
73
+ */
74
+ export function safeRevision(value) {
75
+ if (typeof value !== 'string') return undefined
76
+ const trimmed = value.trim()
77
+ if (trimmed.length === 0 || trimmed.length > 200) return undefined
78
+ if (/[\u0000-\u0020\u007f]/.test(trimmed)) return undefined
79
+ if (trimmed.startsWith('-')) return undefined
80
+ if (!/^[A-Za-z0-9_./~^@{}:+-]+$/.test(trimmed)) return undefined
81
+ return trimmed
82
+ }
83
+
84
+ /**
85
+ * Strip the internal recorder fields the browser should not depend on.
86
+ * @param {object} summary WorkspaceChangesSummary
87
+ * @returns {{turn:number,total:number,added:number,deleted:number,files:Array<object>}}
88
+ */
89
+ export function publicSummary(summary) {
90
+ const files = Array.isArray(summary?.files)
91
+ ? summary.files.map((file) => ({
92
+ path: String(file.path),
93
+ display: String(file.display ?? file.path),
94
+ added: Number(file.added) || 0,
95
+ deleted: Number(file.deleted) || 0,
96
+ ...(file.binary === true ? { binary: true } : {}),
97
+ ...(file.oversized === true ? { oversized: true } : {}),
98
+ }))
99
+ : []
100
+ return {
101
+ turn: Number(summary?.turn) || 0,
102
+ total: Number(summary?.total ?? files.length) || 0,
103
+ added: Number(summary?.added) || 0,
104
+ deleted: Number(summary?.deleted) || 0,
105
+ files,
106
+ }
107
+ }
package/lib/index.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * dsh-git-changes — Host half.
3
+ *
4
+ * Review data plane for the right-sidebar "代码审查" tab:
5
+ * - /api/git-changes.* authenticated JSON routes: turn snapshots from the
6
+ * builtin workspace-changes recorder, workspace file reads/directory
7
+ * listings from workspaceFiles, git status/diff through the subprocess
8
+ * capability, and a bounded workspace index/search;
9
+ * - four git write routes (stage / unstage / commit / push) that only touch
10
+ * the repository index and commits — they never rewrite files, never run
11
+ * arbitrary commands and never force push;
12
+ * - an authenticated prefix route serving the vendored Monaco AMD assets.
13
+ *
14
+ * Parts of the git-changes rendering approach are adapted from the MIT
15
+ * licensed `dsh-vscode-mode` reference implementation
16
+ * (https://github.com/Lenonss/DSH_VsCodeMode, © 2026 LiuZiLong / ddj).
17
+ */
18
+ import { registerApiRoutes } from './host/routes.js'
19
+ import { registerVendorRoute } from './host/assets.js'
20
+
21
+ export const name = 'dsh-git-changes'
22
+
23
+ /** Hard dependencies: every one is a shipped Host service in DSH 0.2.x. */
24
+ export const inject = ['connection', 'webServer', 'workspaceFiles', 'workspaceChanges', 'sessions', 'subprocess']
25
+
26
+ /**
27
+ * Register the review data plane and the static Monaco route.
28
+ * @param {import('./host/context.d.ts').HostContext} ctx host plugin context
29
+ */
30
+ export function apply(ctx) {
31
+ registerApiRoutes(ctx)
32
+ registerVendorRoute(ctx)
33
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LiuZiLong
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) Microsoft Corporation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,32 @@
1
+
2
+ THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
3
+ For Microsoft vscode-theme-seti
4
+
5
+ This file is based on or incorporates material from the projects listed below ("Third Party OSS"). The original copyright
6
+ notice and the license under which Microsoft received such Third Party OSS, are set forth below. Such licenses and notice
7
+ are provided for informational purposes only. Microsoft licenses the Third Party OSS to you under the licensing terms for
8
+ the Microsoft product or service. Microsoft reserves all other rights not expressly granted under this agreement, whether
9
+ by implication, estoppel or otherwise.†
10
+
11
+ 1. Seti UI - A subtle dark colored UI theme for Atom. (https://github.com/jesseweed/seti-ui)
12
+
13
+ Copyright (c) 2014 Jesse Weed
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining
16
+ a copy of this software and associated documentation files (the
17
+ "Software"), to deal in the Software without restriction, including
18
+ without limitation the rights to use, copy, modify, merge, publish,
19
+ distribute, sublicense, and/or sell copies of the Software, and to
20
+ permit persons to whom the Software is furnished to do so, subject to
21
+ the following conditions:
22
+
23
+ The above copyright notice and this permission notice shall be
24
+ included in all copies or substantial portions of the Software.
25
+
26
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/locale/en.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Code Review Panel",
4
+ "description": "Cursor-style read-only code review: full source files with inline line-level diffs in a right-sidebar tab, with Agent turn, uncommitted and arbitrary git-version (historical commit) baselines, plus a workspace file tree, editor tabs, quick open and VS Code-style navigation; opens from the composer pill above the chat input."
5
+ }
6
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "代码审查面板",
4
+ "description": "Cursor 式只读代码审查:在右侧栏独立标签页里查看完整源码与行级内联差异,支持 Agent 本轮、Git 未提交与任意 Git 版本(历史提交)对比,配合工作区文件树、标签页、Quick Open 与 VS Code 风格快捷键;可从聊天输入框上方的「本轮修改」入口打开。"
5
+ }
6
+ }
package/package.json CHANGED
@@ -1,6 +1,67 @@
1
1
  {
2
2
  "name": "dsh-git-changes",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "description": "Cursor-style Git changes panel for the DSH right sidebar: staged/unstaged trees, stage/unstage, commit & push, inline or side-by-side diffs, AI commit messages, blame, commit graph and full-source review.",
7
+ "keywords": [
8
+ "dsh",
9
+ "dsh-plugin",
10
+ "deepseek-harness",
11
+ "git",
12
+ "diff",
13
+ "code-review",
14
+ "source-control",
15
+ "staged-changes",
16
+ "commit",
17
+ "push",
18
+ "blame",
19
+ "monaco"
20
+ ],
21
+ "main": "./lib/index.js",
22
+ "scripts": {
23
+ "build": "node scripts/build-client.mjs",
24
+ "test": "node scripts/build-client.mjs && node --check lib/client.js && node scripts/smoke-client.mjs && node scripts/smoke-host.mjs && node scripts/test-client-state.mjs && node scripts/test-shortcuts.mjs && node scripts/test-git.mjs && node scripts/test-lsp.mjs && node scripts/test-git-extras.mjs && node scripts/check-hooks.mjs",
25
+ "verify": "node scripts/verify.mjs",
26
+ "test:client": "node scripts/test-client-state.mjs",
27
+ "test:git": "node scripts/test-git.mjs",
28
+ "test:shortcuts": "node scripts/test-shortcuts.mjs",
29
+ "prepack": "node scripts/build-client.mjs",
30
+ "test:lsp:real": "node scripts/test-lsp.mjs --real"
31
+ },
32
+ "exports": {
33
+ ".": "./lib/index.js",
34
+ "./client": "./lib/client.js",
35
+ "./locale/*.json": "./locale/*.json",
36
+ "./icon": "./icon.svg",
37
+ "./package.json": "./package.json"
38
+ },
39
+ "files": [
40
+ "lib",
41
+ "src",
42
+ "assets",
43
+ "cordis.patch.yml",
44
+ "locale/*.json",
45
+ "icon.svg",
46
+ "README.md",
47
+ "LICENSE",
48
+ "THIRD_PARTY_NOTICES.md",
49
+ "licenses",
50
+ "docs/images",
51
+ "docs/regression-checklist.md"
52
+ ],
53
+ "dsh": {
54
+ "bundle": {
55
+ "patch": "./cordis.patch.yml"
56
+ },
57
+ "client": {
58
+ "platform": "web",
59
+ "immediately": true,
60
+ "inject": [
61
+ "@deepseek-ai/dsh-client-ui-conversation",
62
+ "@deepseek-ai/dsh-client-ui-sidebar-right"
63
+ ]
64
+ }
65
+ },
66
+ "author": "dsh-git-changes contributors"
67
+ }
@@ -0,0 +1,79 @@
1
+ /* dsh-git-changes client half — shared constants (no imports/exports). */
2
+
3
+ /** Locale namespace owned by this plugin. */
4
+ const NS = 'dsh-git-changes'
5
+ /** Tab type identity; also the keyed body-slot key (must equal the definition id). */
6
+ const TAB_ID = 'dsh-git-changes'
7
+ /** Tab kind discriminator. */
8
+ const TAB_KIND = 'git-changes'
9
+ /** Commit graph section in the changes panel; hidden on request (flip to true to restore). */
10
+ const SHOW_COMMIT_GRAPH = false
11
+ /** Resource-address prefix of this plugin's review pages. */
12
+ const ADDRESS_PREFIX = 'dsh-resource://git-changes/session/'
13
+ /** Builtin file-preview resource prefix (used for non-code handoff). */
14
+ const FILE_ADDRESS_PREFIX = 'dsh-resource://file/session/'
15
+ /** Builtin hunk-review resource prefix (reused, never re-registered). */
16
+ const CHANGES_REVIEW_PREFIX = 'dsh-resource://changes-review/session/'
17
+ /** Vendor AMD root (absolute application path; served by the Host plugin). */
18
+ const VENDOR_BASE = '/dsh-git-changes/monaco/vs'
19
+ /** Document-relative authenticated JSON routes (Host registers them under /api/). */
20
+ const ROUTES = {
21
+ latest: 'api/git-changes.latest',
22
+ summary: 'api/git-changes.summary',
23
+ diff: 'api/git-changes.diff',
24
+ file: 'api/git-changes.file',
25
+ tree: 'api/git-changes.tree',
26
+ config: 'api/git-changes.config',
27
+ gitStatus: 'api/git-changes.git-status',
28
+ gitFile: 'api/git-changes.git-file',
29
+ gitRevisions: 'api/git-changes.git-revisions',
30
+ gitCompare: 'api/git-changes.git-compare',
31
+ files: 'api/git-changes.files',
32
+ search: 'api/git-changes.search',
33
+ lsp: 'api/git-changes.lsp',
34
+ gitDiff: 'api/git-changes.git-diff',
35
+ stage: 'api/git-changes.stage',
36
+ unstage: 'api/git-changes.unstage',
37
+ commit: 'api/git-changes.commit',
38
+ push: 'api/git-changes.push',
39
+ discard: 'api/git-changes.discard',
40
+ blame: 'api/git-changes.blame',
41
+ log: 'api/git-changes.log',
42
+ generateMessage: 'api/git-changes.generate-message',
43
+ }
44
+ /** Maximum diff lines drawn by the code area (matches the builtin review policy). */
45
+ const MAX_RENDER_LINES = 5000
46
+ /** Default widths (CSS px) of the in-page workspace tree. */
47
+ const TREE_WIDTH_DEFAULT = 230
48
+ const TREE_WIDTH_MIN = 160
49
+ const TREE_WIDTH_MAX = 300
50
+ /** Below this page width the tree becomes an overlay drawer. */
51
+ const NARROW_WIDTH = 560
52
+
53
+ /** Extension → Monaco language id. */
54
+ const LANG_BY_EXT = {
55
+ js: 'javascript', jsx: 'javascript', mjs: 'javascript', cjs: 'javascript',
56
+ ts: 'typescript', tsx: 'typescript', mts: 'typescript', cts: 'typescript',
57
+ json: 'json', jsonc: 'jsonc', json5: 'json', md: 'markdown', markdown: 'markdown', mdx: 'markdown',
58
+ css: 'css', scss: 'scss', less: 'less', html: 'html', htm: 'html', vue: 'html', svelte: 'html', xml: 'xml',
59
+ svg: 'xml', yaml: 'yaml', yml: 'yaml', toml: 'ini', ini: 'ini', cfg: 'ini', conf: 'ini', env: 'ini',
60
+ py: 'python', pyi: 'python', sh: 'shell', bash: 'shell', zsh: 'shell', ps1: 'powershell', psm1: 'powershell',
61
+ bat: 'bat', cmd: 'bat', lua: 'lua', java: 'java', c: 'c', h: 'c', cpp: 'cpp', cc: 'cpp', cxx: 'cpp',
62
+ hpp: 'cpp', hh: 'cpp', cs: 'csharp', go: 'go', rs: 'rust', rb: 'ruby', php: 'php', sql: 'sql',
63
+ swift: 'swift', kt: 'kotlin', kts: 'kotlin', dart: 'dart', ex: 'plaintext', exs: 'plaintext',
64
+ dockerfile: 'dockerfile', graphql: 'graphql', gql: 'graphql', proto: 'proto', r: 'r', jl: 'julia',
65
+ pl: 'perl', pm: 'perl', scala: 'scala', groovy: 'java', gradle: 'java', vim: 'plaintext',
66
+ }
67
+
68
+ /** Extensions rendered by the code viewer; everything else is handed to DSH preview. */
69
+ const CODE_EXT = new Set(Object.keys(LANG_BY_EXT))
70
+
71
+ /** Files without an extension that are still code. */
72
+ const CODE_BASENAMES = new Set([
73
+ 'dockerfile', 'makefile', 'cmakelists.txt', 'jenkinsfile', 'procfile', 'gemfile', 'rakefile',
74
+ 'cargo.lock', 'go.sum', 'justfile', 'vagrantfile', '.gitignore', '.gitattributes', '.editorconfig',
75
+ '.npmrc', '.nvmrc', '.prettierrc', '.eslintrc', '.babelrc', '.dockerignore',
76
+ ])
77
+
78
+ /** A short label per diff mode. */
79
+ const MODES = ['turn', 'git', 'code']