@wzwjustdoit/dsh-plugin-git-bash 0.0.0-stage → 0.4.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.
- package/LICENSE +21 -0
- package/README.md +154 -2
- package/client.js +736 -0
- package/cordis.patch.yml +27 -0
- package/lib/agents.d.ts +5 -0
- package/lib/agents.d.ts.map +1 -0
- package/lib/agents.js +56 -0
- package/lib/agents.js.map +1 -0
- package/lib/discovery.d.ts +21 -0
- package/lib/discovery.d.ts.map +1 -0
- package/lib/discovery.js +122 -0
- package/lib/discovery.js.map +1 -0
- package/lib/index.d.ts +55 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +369 -0
- package/lib/index.js.map +1 -0
- package/native/CMakeLists.txt +58 -0
- package/native/bin/win32-x64/msys-token-guard-hook.dll +0 -0
- package/native/bin/win32-x64/msys-token-guard.exe +0 -0
- package/native/msys-token-guard-hook.cpp +470 -0
- package/native/msys-token-guard.cpp +671 -0
- package/native/vendor/detours/LICENSE.md +23 -0
- package/native/vendor/detours/README.dsh.md +13 -0
- package/native/vendor/detours/creatwth.cpp +1577 -0
- package/native/vendor/detours/detours.cpp +2364 -0
- package/native/vendor/detours/detours.h +1059 -0
- package/native/vendor/detours/detver.h +27 -0
- package/native/vendor/detours/disasm.cpp +4236 -0
- package/native/vendor/detours/image.cpp +2251 -0
- package/native/vendor/detours/modules.cpp +929 -0
- package/native/vendor/detours/uimports.cpp +269 -0
- package/package.json +120 -4
- package/scripts/build-native.mjs +35 -0
- package/scripts/dsh.desktop.startup/README.md +27 -0
- package/scripts/dsh.desktop.startup/dsh.desktop.startup.gitbash.bat +28 -0
- package/scripts/dsh.desktop.startup/dsh.desktop.startup.gitbash.sh +46 -0
- package/scripts/dsh.desktop.startup/dsh.desktop.startup.gitbash.vbs +0 -0
- package/scripts/dsh.web.startup/README.md +33 -0
- package/scripts/dsh.web.startup/dsh.web.startup.gitbash.bat +28 -0
- package/scripts/dsh.web.startup/dsh.web.startup.gitbash.sh +48 -0
- package/scripts/dsh.web.startup/dsh.web.startup.gitbash.vbs +0 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
//////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// Add DLLs to a module import table (uimports.cpp of detours.lib)
|
|
4
|
+
//
|
|
5
|
+
// Microsoft Research Detours Package, Version 4.0.1
|
|
6
|
+
//
|
|
7
|
+
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
8
|
+
//
|
|
9
|
+
// Note that this file is included into creatwth.cpp one or more times
|
|
10
|
+
// (once for each supported module format).
|
|
11
|
+
//
|
|
12
|
+
|
|
13
|
+
#if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH
|
|
14
|
+
#error detours.h version mismatch
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
// UpdateImports32 aka UpdateImports64
|
|
18
|
+
static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess,
|
|
19
|
+
HMODULE hModule,
|
|
20
|
+
__in_ecount(nDlls) LPCSTR *plpDlls,
|
|
21
|
+
DWORD nDlls)
|
|
22
|
+
{
|
|
23
|
+
BOOL fSucceeded = FALSE;
|
|
24
|
+
DWORD cbNew = 0;
|
|
25
|
+
|
|
26
|
+
BYTE * pbNew = NULL;
|
|
27
|
+
DWORD i;
|
|
28
|
+
SIZE_T cbRead;
|
|
29
|
+
DWORD n;
|
|
30
|
+
|
|
31
|
+
PBYTE pbModule = (PBYTE)hModule;
|
|
32
|
+
|
|
33
|
+
IMAGE_DOS_HEADER idh;
|
|
34
|
+
ZeroMemory(&idh, sizeof(idh));
|
|
35
|
+
if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), &cbRead)
|
|
36
|
+
|| cbRead < sizeof(idh)) {
|
|
37
|
+
|
|
38
|
+
DETOUR_TRACE(("ReadProcessMemory(idh@%p..%p) failed: %d\n",
|
|
39
|
+
pbModule, pbModule + sizeof(idh), GetLastError()));
|
|
40
|
+
|
|
41
|
+
finish:
|
|
42
|
+
if (pbNew != NULL) {
|
|
43
|
+
delete[] pbNew;
|
|
44
|
+
pbNew = NULL;
|
|
45
|
+
}
|
|
46
|
+
return fSucceeded;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
IMAGE_NT_HEADERS_XX inh;
|
|
50
|
+
ZeroMemory(&inh, sizeof(inh));
|
|
51
|
+
|
|
52
|
+
if (!ReadProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), &cbRead)
|
|
53
|
+
|| cbRead < sizeof(inh)) {
|
|
54
|
+
DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p) failed: %d\n",
|
|
55
|
+
pbModule + idh.e_lfanew,
|
|
56
|
+
pbModule + idh.e_lfanew + sizeof(inh),
|
|
57
|
+
GetLastError()));
|
|
58
|
+
goto finish;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (inh.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC_XX) {
|
|
62
|
+
DETOUR_TRACE(("Wrong size image (%04x != %04x).\n",
|
|
63
|
+
inh.OptionalHeader.Magic, IMAGE_NT_OPTIONAL_HDR_MAGIC_XX));
|
|
64
|
+
SetLastError(ERROR_INVALID_BLOCK);
|
|
65
|
+
goto finish;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Zero out the bound table so loader doesn't use it instead of our new table.
|
|
69
|
+
inh.BOUND_DIRECTORY.VirtualAddress = 0;
|
|
70
|
+
inh.BOUND_DIRECTORY.Size = 0;
|
|
71
|
+
|
|
72
|
+
// Find the size of the mapped file.
|
|
73
|
+
DWORD dwSec = idh.e_lfanew +
|
|
74
|
+
FIELD_OFFSET(IMAGE_NT_HEADERS_XX, OptionalHeader) +
|
|
75
|
+
inh.FileHeader.SizeOfOptionalHeader;
|
|
76
|
+
|
|
77
|
+
for (i = 0; i < inh.FileHeader.NumberOfSections; i++) {
|
|
78
|
+
IMAGE_SECTION_HEADER ish;
|
|
79
|
+
ZeroMemory(&ish, sizeof(ish));
|
|
80
|
+
|
|
81
|
+
if (!ReadProcessMemory(hProcess, pbModule + dwSec + sizeof(ish) * i, &ish,
|
|
82
|
+
sizeof(ish), &cbRead)
|
|
83
|
+
|| cbRead < sizeof(ish)) {
|
|
84
|
+
|
|
85
|
+
DETOUR_TRACE(("ReadProcessMemory(ish@%p..%p) failed: %d\n",
|
|
86
|
+
pbModule + dwSec + sizeof(ish) * i,
|
|
87
|
+
pbModule + dwSec + sizeof(ish) * (i + 1),
|
|
88
|
+
GetLastError()));
|
|
89
|
+
goto finish;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
DETOUR_TRACE(("ish[%d] : va=%08x sr=%d\n", i, ish.VirtualAddress, ish.SizeOfRawData));
|
|
93
|
+
|
|
94
|
+
// If the file didn't have an IAT_DIRECTORY, we assign it...
|
|
95
|
+
if (inh.IAT_DIRECTORY.VirtualAddress == 0 &&
|
|
96
|
+
inh.IMPORT_DIRECTORY.VirtualAddress >= ish.VirtualAddress &&
|
|
97
|
+
inh.IMPORT_DIRECTORY.VirtualAddress < ish.VirtualAddress + ish.SizeOfRawData) {
|
|
98
|
+
|
|
99
|
+
inh.IAT_DIRECTORY.VirtualAddress = ish.VirtualAddress;
|
|
100
|
+
inh.IAT_DIRECTORY.Size = ish.SizeOfRawData;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
DETOUR_TRACE((" Imports: %p..%p\n",
|
|
105
|
+
(DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,
|
|
106
|
+
(DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress +
|
|
107
|
+
inh.IMPORT_DIRECTORY.Size));
|
|
108
|
+
|
|
109
|
+
DWORD nOldDlls = inh.IMPORT_DIRECTORY.Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
|
|
110
|
+
DWORD obRem = sizeof(IMAGE_IMPORT_DESCRIPTOR) * nDlls;
|
|
111
|
+
DWORD obOld = obRem + sizeof(IMAGE_IMPORT_DESCRIPTOR) * nOldDlls;
|
|
112
|
+
DWORD obTab = PadToDwordPtr(obOld);
|
|
113
|
+
DWORD obDll = obTab + sizeof(DWORD_XX) * 4 * nDlls;
|
|
114
|
+
DWORD obStr = obDll;
|
|
115
|
+
cbNew = obStr;
|
|
116
|
+
for (n = 0; n < nDlls; n++) {
|
|
117
|
+
cbNew += PadToDword((DWORD)strlen(plpDlls[n]) + 1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
_Analysis_assume_(cbNew >
|
|
121
|
+
sizeof(IMAGE_IMPORT_DESCRIPTOR) * (nDlls + nOldDlls)
|
|
122
|
+
+ sizeof(DWORD_XX) * 4 * nDlls);
|
|
123
|
+
pbNew = new BYTE [cbNew];
|
|
124
|
+
if (pbNew == NULL) {
|
|
125
|
+
DETOUR_TRACE(("new BYTE [cbNew] failed.\n"));
|
|
126
|
+
goto finish;
|
|
127
|
+
}
|
|
128
|
+
ZeroMemory(pbNew, cbNew);
|
|
129
|
+
|
|
130
|
+
PBYTE pbBase = pbModule;
|
|
131
|
+
PBYTE pbNext = pbBase
|
|
132
|
+
+ inh.OptionalHeader.BaseOfCode
|
|
133
|
+
+ inh.OptionalHeader.SizeOfCode
|
|
134
|
+
+ inh.OptionalHeader.SizeOfInitializedData
|
|
135
|
+
+ inh.OptionalHeader.SizeOfUninitializedData;
|
|
136
|
+
if (pbBase < pbNext) {
|
|
137
|
+
pbBase = pbNext;
|
|
138
|
+
}
|
|
139
|
+
DETOUR_TRACE(("pbBase = %p\n", pbBase));
|
|
140
|
+
|
|
141
|
+
PBYTE pbNewIid = FindAndAllocateNearBase(hProcess, pbBase, cbNew);
|
|
142
|
+
if (pbNewIid == NULL) {
|
|
143
|
+
DETOUR_TRACE(("FindAndAllocateNearBase failed.\n"));
|
|
144
|
+
goto finish;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
PIMAGE_IMPORT_DESCRIPTOR piid = (PIMAGE_IMPORT_DESCRIPTOR)pbNew;
|
|
148
|
+
DWORD_XX *pt;
|
|
149
|
+
|
|
150
|
+
DWORD obBase = (DWORD)(pbNewIid - pbModule);
|
|
151
|
+
DWORD dwProtect = 0;
|
|
152
|
+
|
|
153
|
+
if (inh.IMPORT_DIRECTORY.VirtualAddress != 0) {
|
|
154
|
+
// Read the old import directory if it exists.
|
|
155
|
+
DETOUR_TRACE(("IMPORT_DIRECTORY perms=%x\n", dwProtect));
|
|
156
|
+
|
|
157
|
+
if (!ReadProcessMemory(hProcess,
|
|
158
|
+
pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,
|
|
159
|
+
&piid[nDlls],
|
|
160
|
+
nOldDlls * sizeof(IMAGE_IMPORT_DESCRIPTOR), &cbRead)
|
|
161
|
+
|| cbRead < nOldDlls * sizeof(IMAGE_IMPORT_DESCRIPTOR)) {
|
|
162
|
+
|
|
163
|
+
DETOUR_TRACE(("ReadProcessMemory(imports) failed: %d\n", GetLastError()));
|
|
164
|
+
goto finish;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
for (n = 0; n < nDlls; n++) {
|
|
169
|
+
HRESULT hrRet = StringCchCopyA((char*)pbNew + obStr, cbNew - obStr, plpDlls[n]);
|
|
170
|
+
if (FAILED(hrRet)) {
|
|
171
|
+
DETOUR_TRACE(("StringCchCopyA failed: %d\n", GetLastError()));
|
|
172
|
+
goto finish;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// After copying the string, we patch up the size "??" bits if any.
|
|
176
|
+
hrRet = ReplaceOptionalSizeA((char*)pbNew + obStr,
|
|
177
|
+
cbNew - obStr,
|
|
178
|
+
DETOURS_STRINGIFY(DETOURS_BITS_XX));
|
|
179
|
+
if (FAILED(hrRet)) {
|
|
180
|
+
DETOUR_TRACE(("ReplaceOptionalSizeA failed: %d\n", GetLastError()));
|
|
181
|
+
goto finish;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
DWORD nOffset = obTab + (sizeof(DWORD_XX) * (4 * n));
|
|
185
|
+
piid[n].OriginalFirstThunk = obBase + nOffset;
|
|
186
|
+
pt = ((DWORD_XX*)(pbNew + nOffset));
|
|
187
|
+
pt[0] = IMAGE_ORDINAL_FLAG_XX + 1;
|
|
188
|
+
pt[1] = 0;
|
|
189
|
+
|
|
190
|
+
nOffset = obTab + (sizeof(DWORD_XX) * ((4 * n) + 2));
|
|
191
|
+
piid[n].FirstThunk = obBase + nOffset;
|
|
192
|
+
pt = ((DWORD_XX*)(pbNew + nOffset));
|
|
193
|
+
pt[0] = IMAGE_ORDINAL_FLAG_XX + 1;
|
|
194
|
+
pt[1] = 0;
|
|
195
|
+
piid[n].TimeDateStamp = 0;
|
|
196
|
+
piid[n].ForwarderChain = 0;
|
|
197
|
+
piid[n].Name = obBase + obStr;
|
|
198
|
+
|
|
199
|
+
obStr += PadToDword((DWORD)strlen(plpDlls[n]) + 1);
|
|
200
|
+
}
|
|
201
|
+
_Analysis_assume_(obStr <= cbNew);
|
|
202
|
+
|
|
203
|
+
#if 0
|
|
204
|
+
for (i = 0; i < nDlls + nOldDlls; i++) {
|
|
205
|
+
DETOUR_TRACE(("%8d. Look=%08x Time=%08x Fore=%08x Name=%08x Addr=%08x\n",
|
|
206
|
+
i,
|
|
207
|
+
piid[i].OriginalFirstThunk,
|
|
208
|
+
piid[i].TimeDateStamp,
|
|
209
|
+
piid[i].ForwarderChain,
|
|
210
|
+
piid[i].Name,
|
|
211
|
+
piid[i].FirstThunk));
|
|
212
|
+
if (piid[i].OriginalFirstThunk == 0 && piid[i].FirstThunk == 0) {
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
#endif
|
|
217
|
+
|
|
218
|
+
if (!WriteProcessMemory(hProcess, pbNewIid, pbNew, obStr, NULL)) {
|
|
219
|
+
DETOUR_TRACE(("WriteProcessMemory(iid) failed: %d\n", GetLastError()));
|
|
220
|
+
goto finish;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
DETOUR_TRACE(("obBaseBef = %08x..%08x\n",
|
|
224
|
+
inh.IMPORT_DIRECTORY.VirtualAddress,
|
|
225
|
+
inh.IMPORT_DIRECTORY.VirtualAddress + inh.IMPORT_DIRECTORY.Size));
|
|
226
|
+
DETOUR_TRACE(("obBaseAft = %08x..%08x\n", obBase, obBase + obStr));
|
|
227
|
+
|
|
228
|
+
// If the file doesn't have an IAT_DIRECTORY, we create it...
|
|
229
|
+
if (inh.IAT_DIRECTORY.VirtualAddress == 0) {
|
|
230
|
+
inh.IAT_DIRECTORY.VirtualAddress = obBase;
|
|
231
|
+
inh.IAT_DIRECTORY.Size = cbNew;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
inh.IMPORT_DIRECTORY.VirtualAddress = obBase;
|
|
235
|
+
inh.IMPORT_DIRECTORY.Size = cbNew;
|
|
236
|
+
|
|
237
|
+
/////////////////////// Update the NT header for the new import directory.
|
|
238
|
+
//
|
|
239
|
+
if (!DetourVirtualProtectSameExecuteEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders,
|
|
240
|
+
PAGE_EXECUTE_READWRITE, &dwProtect)) {
|
|
241
|
+
DETOUR_TRACE(("VirtualProtectEx(inh) write failed: %d\n", GetLastError()));
|
|
242
|
+
goto finish;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
inh.OptionalHeader.CheckSum = 0;
|
|
246
|
+
|
|
247
|
+
if (!WriteProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {
|
|
248
|
+
DETOUR_TRACE(("WriteProcessMemory(idh) failed: %d\n", GetLastError()));
|
|
249
|
+
goto finish;
|
|
250
|
+
}
|
|
251
|
+
DETOUR_TRACE(("WriteProcessMemory(idh:%p..%p)\n", pbModule, pbModule + sizeof(idh)));
|
|
252
|
+
|
|
253
|
+
if (!WriteProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), NULL)) {
|
|
254
|
+
DETOUR_TRACE(("WriteProcessMemory(inh) failed: %d\n", GetLastError()));
|
|
255
|
+
goto finish;
|
|
256
|
+
}
|
|
257
|
+
DETOUR_TRACE(("WriteProcessMemory(inh:%p..%p)\n",
|
|
258
|
+
pbModule + idh.e_lfanew,
|
|
259
|
+
pbModule + idh.e_lfanew + sizeof(inh)));
|
|
260
|
+
|
|
261
|
+
if (!VirtualProtectEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders,
|
|
262
|
+
dwProtect, &dwProtect)) {
|
|
263
|
+
DETOUR_TRACE(("VirtualProtectEx(idh) restore failed: %d\n", GetLastError()));
|
|
264
|
+
goto finish;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
fSucceeded = TRUE;
|
|
268
|
+
goto finish;
|
|
269
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,122 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wzwjustdoit/dsh-plugin-git-bash",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Use Git for Windows Bash as the default DSH shell with restricted-mode support",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"deepseek-harness",
|
|
7
|
+
"dsh",
|
|
8
|
+
"plugin",
|
|
9
|
+
"git-bash",
|
|
10
|
+
"sandbox",
|
|
11
|
+
"windows"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/wzwjustdoit/dsh-git-bash#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/wzwjustdoit/dsh-git-bash/issues"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/wzwjustdoit/dsh-git-bash.git"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "lib/index.js",
|
|
23
|
+
"types": "lib/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./lib/index.d.ts",
|
|
27
|
+
"default": "./lib/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./agents": {
|
|
30
|
+
"types": "./lib/agents.d.ts",
|
|
31
|
+
"default": "./lib/agents.js"
|
|
32
|
+
},
|
|
33
|
+
"./discovery": {
|
|
34
|
+
"types": "./lib/discovery.d.ts",
|
|
35
|
+
"default": "./lib/discovery.js"
|
|
36
|
+
},
|
|
37
|
+
"./client": "./client.js",
|
|
38
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
39
|
+
"./package.json": "./package.json"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"lib",
|
|
43
|
+
"client.js",
|
|
44
|
+
"native/bin/win32-x64/msys-token-guard.exe",
|
|
45
|
+
"native/bin/win32-x64/msys-token-guard-hook.dll",
|
|
46
|
+
"native/CMakeLists.txt",
|
|
47
|
+
"native/*.cpp",
|
|
48
|
+
"native/vendor/detours",
|
|
49
|
+
"scripts/build-native.mjs",
|
|
50
|
+
"scripts/dsh.web.startup",
|
|
51
|
+
"scripts/dsh.desktop.startup",
|
|
52
|
+
"cordis.patch.yml",
|
|
53
|
+
"README.md",
|
|
54
|
+
"LICENSE"
|
|
55
|
+
],
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
},
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=24"
|
|
62
|
+
},
|
|
63
|
+
"dsh": {
|
|
64
|
+
"bundle": {
|
|
65
|
+
"patch": "./cordis.patch.yml"
|
|
66
|
+
},
|
|
67
|
+
"client": {
|
|
68
|
+
"platform": "web",
|
|
69
|
+
"inject": [
|
|
70
|
+
"@deepseek-ai/dsh-client-ui-tool",
|
|
71
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins",
|
|
72
|
+
"@deepseek-ai/dsh-client-ui-settings",
|
|
73
|
+
"@deepseek-ai/dsh-client-ui-primitives",
|
|
74
|
+
"@deepseek-ai/dsh-client-locale",
|
|
75
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
76
|
+
"@deepseek-ai/dsh-client-connection",
|
|
77
|
+
"@deepseek-ai/dsh-api-remotes"
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"scripts": {
|
|
82
|
+
"clean": "node -e \"require('node:fs').rmSync('lib', { recursive: true, force: true })\"",
|
|
83
|
+
"build:native": "node scripts/build-native.mjs",
|
|
84
|
+
"build": "pnpm run build:native && pnpm run clean && tsc -p tsconfig.json",
|
|
85
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
86
|
+
"test": "pnpm run build && node --test",
|
|
87
|
+
"pack:check": "npm pack --dry-run",
|
|
88
|
+
"prepack": "pnpm run build",
|
|
89
|
+
"prepublishOnly": "pnpm test"
|
|
90
|
+
},
|
|
91
|
+
"peerDependencies": {
|
|
92
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
93
|
+
"@deepseek-ai/dsh-agent": "^0.2.0-rc.0",
|
|
94
|
+
"@deepseek-ai/dsh-bash-local": "^0.2.0-rc.0",
|
|
95
|
+
"@deepseek-ai/dsh-sandbox": "^0.2.0-rc.0",
|
|
96
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.2.0-rc.0",
|
|
97
|
+
"@deepseek-ai/dsh-shell": "^0.2.0-rc.0",
|
|
98
|
+
"@deepseek-ai/dsh-system-prompt": "^0.2.0-rc.0",
|
|
99
|
+
"@deepseek-ai/dsh-tools": "^0.2.0-rc.0"
|
|
100
|
+
},
|
|
101
|
+
"dependencies": {
|
|
102
|
+
"@deepseek-ai/schemastery": "3.18.2"
|
|
103
|
+
},
|
|
104
|
+
"devDependencies": {
|
|
105
|
+
"@deepseek-ai/cordis": "4.0.2",
|
|
106
|
+
"@deepseek-ai/dsh-agent": "0.2.0-rc.2",
|
|
107
|
+
"@deepseek-ai/dsh-bash-local": "0.2.0-rc.2",
|
|
108
|
+
"@deepseek-ai/dsh-sandbox": "0.2.0-rc.2",
|
|
109
|
+
"@deepseek-ai/dsh-sandbox-local": "0.2.0-rc.2",
|
|
110
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.2.0-rc.2",
|
|
111
|
+
"@deepseek-ai/dsh-sandbox-windows-acl": "0.2.0-rc.2",
|
|
112
|
+
"@deepseek-ai/dsh-shell": "0.2.0-rc.2",
|
|
113
|
+
"@deepseek-ai/dsh-subprocess": "0.2.0-rc.2",
|
|
114
|
+
"@deepseek-ai/dsh-subprocess-local": "0.2.0-rc.2",
|
|
115
|
+
"@deepseek-ai/dsh-system-prompt": "0.2.0-rc.2",
|
|
116
|
+
"@deepseek-ai/dsh-timeout": "0.2.0-rc.2",
|
|
117
|
+
"@deepseek-ai/dsh-tools": "0.2.0-rc.2",
|
|
118
|
+
"@types/node": "24.10.1",
|
|
119
|
+
"typescript": "5.9.3"
|
|
120
|
+
},
|
|
121
|
+
"packageManager": "pnpm@11.9.0"
|
|
122
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
5
|
+
|
|
6
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
7
|
+
const sourceDir = resolve(root, "native");
|
|
8
|
+
const buildDir = resolve(sourceDir, "build", "win32-x64");
|
|
9
|
+
const executable = resolve(sourceDir, "bin", "win32-x64", "msys-token-guard.exe");
|
|
10
|
+
const hook = resolve(sourceDir, "bin", "win32-x64", "msys-token-guard-hook.dll");
|
|
11
|
+
|
|
12
|
+
function run(command, args) {
|
|
13
|
+
const result = spawnSync(command, args, { cwd: root, stdio: "inherit", windowsHide: true });
|
|
14
|
+
if (result.error) throw result.error;
|
|
15
|
+
if (result.status !== 0) process.exit(result.status ?? 1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (process.platform !== "win32") {
|
|
19
|
+
if (!existsSync(executable) || !existsSync(hook)) {
|
|
20
|
+
throw new Error("prebuilt token guard artifacts are missing: " + executable + ", " + hook);
|
|
21
|
+
}
|
|
22
|
+
console.log("using prebuilt token guard artifacts: " + executable + ", " + hook);
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
if (process.arch !== "x64") {
|
|
26
|
+
throw new Error("native token guard currently supports win32-x64, received " + process.platform + "-" + process.arch);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
mkdirSync(buildDir, { recursive: true });
|
|
30
|
+
run("cmake", ["--fresh", "-S", sourceDir, "-B", buildDir, "-A", "x64"]);
|
|
31
|
+
run("cmake", ["--build", buildDir, "--config", "Release", "--target", "msys-token-guard", "msys-token-guard-hook"]);
|
|
32
|
+
if (!existsSync(executable) || !existsSync(hook)) {
|
|
33
|
+
throw new Error("native build did not produce " + executable + " and " + hook);
|
|
34
|
+
}
|
|
35
|
+
console.log("built " + executable + " and " + hook);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# dsh.desktop.startup —— 经 Git Bash 启动 DSH Desktop (Electron GUI 程序)
|
|
2
|
+
|
|
3
|
+
## 为什么需要它
|
|
4
|
+
|
|
5
|
+
DSH 的 Windows ACL sandbox 需要 DSH 主进程的 token **default DACL 含当前用户 SID**。由 `explorer.exe` / `cmd.exe` 直接派生的进程通常不含用户 SID,会导致受限模式(`read-only` / `workspace-write`)所有命令 `exit 125`:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
msys-token-guard: OpenProcessToken(child default DACL) failed (Win32 5) # exit 125
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
从 Git Bash 启动可以让 MSYS2 把该 DACL 重置为含用户 SID 的标准形状,受限模式随即恢复正常。
|
|
12
|
+
|
|
13
|
+
## 文件
|
|
14
|
+
|
|
15
|
+
| 文件 | 用途 |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `dsh.desktop.startup.gitbash.vbs` | 隐藏窗口启动 |
|
|
18
|
+
| `dsh.desktop.startup.gitbash.bat` | 前台启动 / 排查问题 |
|
|
19
|
+
| `dsh.desktop.startup.gitbash.sh` | 实际启动逻辑,由 `.bat` 调用 |
|
|
20
|
+
|
|
21
|
+
## 用法
|
|
22
|
+
|
|
23
|
+
1. 把**整个目录**复制到任意位置(脚本内部按相对路径互相引用,可整体移动)。
|
|
24
|
+
2. 设置环境变量 `DSH_GIT_BASH_PATH`,指向你日常使用的 Git for Windows 的 `bash.exe`。`.bat` 会在变量缺失或路径不存在时报错退出。
|
|
25
|
+
3. 需要时设置 `DSH_DESKTOP_EXE`,指向 `DeepSeek Harness.exe` 的绝对路径。路径可用 Windows 形式或 `/c/...` 形式。
|
|
26
|
+
4. 双击 `dsh.desktop.startup.gitbash.bat` 或 `dsh.desktop.startup.gitbash.vbs` 启动
|
|
27
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
setlocal
|
|
3
|
+
|
|
4
|
+
set "THE_SH_FILE=%~dp0dsh.desktop.startup.gitbash.sh"
|
|
5
|
+
set "THE_SH_FILE_2=%THE_SH_FILE:\=/%"
|
|
6
|
+
|
|
7
|
+
if not defined DSH_GIT_BASH_PATH (
|
|
8
|
+
echo [dsh.desktop.startup.gitbash.bat] the env var DSH_GIT_BASH_PATH is not defined.
|
|
9
|
+
echo [dsh.desktop.startup.gitbash.bat] REQUIRED: You MUST manually set env var DSH_GIT_BASH_PATH to your Git for Windows bash.exe, e.g. C:\Program Files\Git\bin\bash.exe
|
|
10
|
+
exit /b 1
|
|
11
|
+
)
|
|
12
|
+
if not exist "%DSH_GIT_BASH_PATH%" (
|
|
13
|
+
echo [dsh.desktop.startup.gitbash.bat] Git Bash Not Found: DSH_GIT_BASH_PATH : %DSH_GIT_BASH_PATH%
|
|
14
|
+
exit /b 1
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if not exist "%THE_SH_FILE%" (
|
|
18
|
+
echo [dsh.desktop.startup.gitbash.bat] .sh File Not Found: %THE_SH_FILE%
|
|
19
|
+
exit /b 1
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
"%DSH_GIT_BASH_PATH%" --login "%THE_SH_FILE_2%" %*
|
|
23
|
+
set "THE_RETURN_CODE=%ERRORLEVEL%"
|
|
24
|
+
|
|
25
|
+
if not "%THE_RETURN_CODE%"=="0" (
|
|
26
|
+
echo [dsh.desktop.startup.gitbash.bat] bash exited with code: %THE_RETURN_CODE%
|
|
27
|
+
)
|
|
28
|
+
endlocal & exit /b %THE_RETURN_CODE%
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# dsh.desktop.startup.gitbash.sh — 经 Git Bash 启动 DSH Desktop (Electron GUI 程序)
|
|
4
|
+
#
|
|
5
|
+
# 【为什么必须经过 Git Bash 启动】
|
|
6
|
+
# DSH 的 Windows ACL 沙箱在受限模式(read-only / workspace-write)下, 会用
|
|
7
|
+
# msys-token-guard.exe 在受限 token 内启动 Git Bash。guard 需要以
|
|
8
|
+
# TOKEN_QUERY | TOKEN_ADJUST_DEFAULT
|
|
9
|
+
# 打开子进程 token, 而 TOKEN_ADJUST_DEFAULT 属于"写"类权限, 在
|
|
10
|
+
# WRITE_RESTRICTED token 下必须两趟权限检查都通过。
|
|
11
|
+
#
|
|
12
|
+
# 若 DSH 主进程 token 的 default DACL 缺当前用户 SID(由 explorer.exe /
|
|
13
|
+
# cmd.exe 派生的进程往往如此), 第一趟检查就会失败:
|
|
14
|
+
# msys-token-guard: OpenProcessToken(child default DACL) failed (Win32 5)
|
|
15
|
+
# 后果是受限模式下所有命令 exit 125 / SandboxUnavailableError。
|
|
16
|
+
#
|
|
17
|
+
# MSYS2 运行时在 bash.exe 启动时, 会把自己的 token default DACL 重置为含用户
|
|
18
|
+
# SID 的标准形状 [用户 ALL, Administrators ALL, SYSTEM ALL]。凡是从 bash 派生的
|
|
19
|
+
# 进程都继承这个形状, 沙箱随即恢复正常。
|
|
20
|
+
# 详见 https://github.com/wzwjustdoit/dsh-git-bash 的 README "启动方式" 一节。
|
|
21
|
+
#
|
|
22
|
+
# 【用法】
|
|
23
|
+
# 双击同目录的 dsh.desktop.startup.gitbash.bat 或 dsh.desktop.startup.gitbash.vbs
|
|
24
|
+
#
|
|
25
|
+
# =============================================================================
|
|
26
|
+
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
|
|
29
|
+
# Desktop 可执行文件位置。想换安装位置就改这里, 或事先设置 DSH_DESKTOP_EXE。
|
|
30
|
+
DSH_DESKTOP_EXE="${DSH_DESKTOP_EXE:-/c/Program Files/DeepSeek Harness/DeepSeek Harness.exe}"
|
|
31
|
+
|
|
32
|
+
echo "[dsh.desktop.startup.gitbash.sh] bash = $BASH"
|
|
33
|
+
echo "[dsh.desktop.startup.gitbash.sh] msystem = $MSYSTEM"
|
|
34
|
+
echo "[dsh.desktop.startup.gitbash.sh] DSH_GIT_BASH_PATH = $DSH_GIT_BASH_PATH"
|
|
35
|
+
echo "[dsh.desktop.startup.gitbash.sh] desktop exe = $DSH_DESKTOP_EXE"
|
|
36
|
+
echo "[dsh.desktop.startup.gitbash.sh] cwd = $PWD"
|
|
37
|
+
|
|
38
|
+
if [ ! -f "$DSH_DESKTOP_EXE" ]; then
|
|
39
|
+
echo "[dsh.desktop.startup.gitbash.sh] DeepSeek Harness Desktop EXE Not Found: $DSH_DESKTOP_EXE" >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# =============================================================================
|
|
44
|
+
# 启动命令
|
|
45
|
+
# =============================================================================
|
|
46
|
+
exec "$DSH_DESKTOP_EXE"
|
|
Binary file
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# dsh.web.startup —— 经 Git Bash 启动 `dsh web` (node 进程)
|
|
2
|
+
|
|
3
|
+
## 为什么需要它
|
|
4
|
+
|
|
5
|
+
DSH 的 Windows ACL sandbox 需要 `dsh web` (node 进程) 的 token **default DACL 含当前用户 SID**。由 `explorer.exe` / `cmd.exe` 直接派生的进程通常不含用户 SID,会导致受限模式(`read-only` / `workspace-write`)所有命令 `exit 125`:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
msys-token-guard: OpenProcessToken(child default DACL) failed (Win32 5) # exit 125
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
从 Git Bash 启动可以让 MSYS2 把该 DACL 重置为含用户 SID 的标准形状,受限模式随即恢复正常。
|
|
12
|
+
|
|
13
|
+
## 文件
|
|
14
|
+
|
|
15
|
+
| 文件 | 用途 |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `dsh.web.startup.gitbash.vbs` | 隐藏窗口启动 |
|
|
18
|
+
| `dsh.web.startup.gitbash.bat` | 前台启动 / 排查问题 |
|
|
19
|
+
| `dsh.web.startup.gitbash.sh` | 实际启动逻辑,由 `.bat` 调用 |
|
|
20
|
+
|
|
21
|
+
## 用法
|
|
22
|
+
|
|
23
|
+
1. 把**整个目录**复制到任意位置(脚本内部按相对路径互相引用,可整体移动)。
|
|
24
|
+
2. 设置环境变量 `DSH_GIT_BASH_PATH`,指向你日常使用的 Git for Windows 的 `bash.exe`。`.bat` 会在变量缺失或路径不存在时报错退出。
|
|
25
|
+
3. 双击 `dsh.web.startup.gitbash.bat` 或 `dsh.web.startup.gitbash.vbs` 启动
|
|
26
|
+
|
|
27
|
+
## 参数
|
|
28
|
+
|
|
29
|
+
| 位置 | 名称 | 默认值 | 说明 |
|
|
30
|
+
| --- | --- | --- | --- |
|
|
31
|
+
| 环境变量 | `DSH_WEB_PORT` | `1688` | 命令行参数优先 |
|
|
32
|
+
| 环境变量 | `DSH_WEB_WORKDIR` | `$HOME` | 启动目录,会成为 Web 会话的默认 workspace 根目录 |
|
|
33
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
setlocal
|
|
3
|
+
|
|
4
|
+
set "THE_SH_FILE=%~dp0dsh.web.startup.gitbash.sh"
|
|
5
|
+
set "THE_SH_FILE_2=%THE_SH_FILE:\=/%"
|
|
6
|
+
|
|
7
|
+
if not defined DSH_GIT_BASH_PATH (
|
|
8
|
+
echo [dsh.web.startup.gitbash.bat] the env var DSH_GIT_BASH_PATH is not defined.
|
|
9
|
+
echo [dsh.web.startup.gitbash.bat] REQUIRED: You MUST manually set env var DSH_GIT_BASH_PATH to your Git for Windows bash.exe, e.g. C:\Program Files\Git\bin\bash.exe
|
|
10
|
+
exit /b 1
|
|
11
|
+
)
|
|
12
|
+
if not exist "%DSH_GIT_BASH_PATH%" (
|
|
13
|
+
echo [dsh.web.startup.gitbash.bat] Git Bash Not Found: DSH_GIT_BASH_PATH : %DSH_GIT_BASH_PATH%
|
|
14
|
+
exit /b 1
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if not exist "%THE_SH_FILE%" (
|
|
18
|
+
echo [dsh.web.startup.gitbash.bat] .sh File Not Found: %THE_SH_FILE%
|
|
19
|
+
exit /b 1
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
"%DSH_GIT_BASH_PATH%" --login "%THE_SH_FILE_2%" %*
|
|
23
|
+
set "THE_RETURN_CODE=%ERRORLEVEL%"
|
|
24
|
+
|
|
25
|
+
if not "%THE_RETURN_CODE%"=="0" (
|
|
26
|
+
echo [dsh.web.startup.gitbash.bat] bash exited with code: %THE_RETURN_CODE%
|
|
27
|
+
)
|
|
28
|
+
endlocal & exit /b %THE_RETURN_CODE%
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# dsh.web.startup.gitbash.sh — 经 Git Bash 启动 `dsh web` (node 进程)
|
|
4
|
+
#
|
|
5
|
+
# 【为什么必须经过 Git Bash 启动】
|
|
6
|
+
# DSH 的 Windows ACL 沙箱在受限模式(read-only / workspace-write)下, 会用
|
|
7
|
+
# msys-token-guard.exe 在受限 token 内启动 Git Bash。guard 需要以
|
|
8
|
+
# TOKEN_QUERY | TOKEN_ADJUST_DEFAULT
|
|
9
|
+
# 打开子进程 token, 而 TOKEN_ADJUST_DEFAULT 属于"写"类权限, 在
|
|
10
|
+
# WRITE_RESTRICTED token 下必须两趟权限检查都通过。
|
|
11
|
+
#
|
|
12
|
+
# 若 DSH 主进程 token 的 default DACL 缺当前用户 SID(由 explorer.exe /
|
|
13
|
+
# cmd.exe 派生的进程往往如此), 第一趟检查就会失败:
|
|
14
|
+
# msys-token-guard: OpenProcessToken(child default DACL) failed (Win32 5)
|
|
15
|
+
# 后果是受限模式下所有命令 exit 125 / SandboxUnavailableError。
|
|
16
|
+
#
|
|
17
|
+
# MSYS2 运行时在 bash.exe 启动时, 会把自己的 token default DACL 重置为含用户
|
|
18
|
+
# SID 的标准形状 [用户 ALL, Administrators ALL, SYSTEM ALL]。凡是从 bash 派生的
|
|
19
|
+
# 进程都继承这个形状, 沙箱随即恢复正常。
|
|
20
|
+
# 详见 https://github.com/wzwjustdoit/dsh-git-bash 的 README "启动方式" 一节。
|
|
21
|
+
#
|
|
22
|
+
# 【用法】
|
|
23
|
+
# 双击同目录的 dsh.web.startup.gitbash.bat 或 dsh.web.startup.gitbash.vbs
|
|
24
|
+
#
|
|
25
|
+
# =============================================================================
|
|
26
|
+
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
|
|
29
|
+
# 监听端口: 命令行第 1 个参数 > 环境变量 DSH_WEB_PORT > 默认 1688
|
|
30
|
+
PORT="${1:-${DSH_WEB_PORT:-1688}}"
|
|
31
|
+
|
|
32
|
+
# 启动目录。它会成为 Web 会话的默认 workspace 根目录。
|
|
33
|
+
# 想固定到别处就在调用前设置 DSH_WEB_WORKDIR。
|
|
34
|
+
WORKDIR="${DSH_WEB_WORKDIR:-$HOME}"
|
|
35
|
+
|
|
36
|
+
cd "$WORKDIR"
|
|
37
|
+
|
|
38
|
+
echo "[dsh.web.startup.gitbash.sh] bash = $BASH"
|
|
39
|
+
echo "[dsh.web.startup.gitbash.sh] msystem = $MSYSTEM"
|
|
40
|
+
echo "[dsh.web.startup.gitbash.sh] DSH_GIT_BASH_PATH = $DSH_GIT_BASH_PATH"
|
|
41
|
+
echo "[dsh.web.startup.gitbash.sh] dsh = $(command -v dsh)"
|
|
42
|
+
echo "[dsh.web.startup.gitbash.sh] cwd = $PWD"
|
|
43
|
+
echo "[dsh.web.startup.gitbash.sh] port = $PORT"
|
|
44
|
+
|
|
45
|
+
# =============================================================================
|
|
46
|
+
# 启动命令
|
|
47
|
+
# =============================================================================
|
|
48
|
+
exec dsh web --port "$PORT"
|
|
Binary file
|