dshmarket 1.0.2 → 1.0.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/client/client.js +2 -2
- package/lib/routes.js +28 -4
- package/package.json +1 -1
- package/src/routes.ts +30 -4
package/client/client.js
CHANGED
|
@@ -133,7 +133,7 @@ const CSS = `
|
|
|
133
133
|
.dshm-top{position:absolute;right:18px;bottom:18px;z-index:20;width:38px;height:38px;border-radius:99px;border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);color:var(--dsw-alias-label-secondary,#6b7280);font-size:16px;cursor:pointer;box-shadow:0 4px 14px rgba(0,0,0,.12)}
|
|
134
134
|
.dshm-top:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}
|
|
135
135
|
.dshm-chip{font:inherit;font-size:12px;border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);border-radius:99px;padding:3px 11px;cursor:pointer;color:var(--dsw-alias-label-secondary,#6b7280)}
|
|
136
|
-
.dshm-chip.on{background:var(--dsw-alias-
|
|
136
|
+
.dshm-chip.on{background:var(--dsw-alias-button-primary-fill,#4f6ef7);border-color:var(--dsw-alias-button-primary-fill,#4f6ef7);color:var(--dsw-alias-label-primary-foreground,#fff)}
|
|
137
137
|
.dshm-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:10px}
|
|
138
138
|
.dshm-card{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l1,#e5e7eb);border-radius:10px;padding:12px 14px;display:flex;flex-direction:column;gap:6px}
|
|
139
139
|
.dshm-row1{display:flex;align-items:center;gap:9px;min-width:0}
|
|
@@ -147,7 +147,7 @@ const CSS = `
|
|
|
147
147
|
.dshm-src{font-size:11px;color:var(--dsw-alias-label-secondary,#9ca3af);text-decoration:none}
|
|
148
148
|
.dshm-src:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}
|
|
149
149
|
.dshm-btn{border:none;border-radius:7px;padding:5px 14px;font:inherit;font-size:12px;cursor:pointer;font-weight:600}
|
|
150
|
-
.dshm-btn.install{background:var(--dsw-alias-
|
|
150
|
+
.dshm-btn.install{background:var(--dsw-alias-button-primary-fill,#4f6ef7);color:var(--dsw-alias-label-primary-foreground,#fff)}
|
|
151
151
|
.dshm-btn.busy{opacity:.65;cursor:default}
|
|
152
152
|
.dshm-btn.done{background:transparent;color:var(--dsw-alias-state-success-primary,#16a34a);cursor:default}
|
|
153
153
|
.dshm-btn.ghost{background:var(--dsw-alias-bg-layer-2,#f3f4f6);color:var(--dsw-alias-label-secondary,#6b7280)}
|
package/lib/routes.js
CHANGED
|
@@ -33,11 +33,31 @@ function dshArgv() {
|
|
|
33
33
|
}
|
|
34
34
|
/** Whether `pnpm` resolves on PATH; success is cached, absence is re-probed. */
|
|
35
35
|
let pnpmReady = false;
|
|
36
|
+
/**
|
|
37
|
+
* Windows npm/corepack/pnpm are `.cmd` shims. Node's `spawn` without a shell
|
|
38
|
+
* cannot start them (ENOENT / EINVAL). Same pattern as dsh's `plugin` forwarder.
|
|
39
|
+
*/
|
|
40
|
+
const winCmdShim = process.platform === 'win32';
|
|
41
|
+
/**
|
|
42
|
+
* Kill a spawned child and, on Windows, its whole process tree — `kill()`
|
|
43
|
+
* there only terminates the wrapper, leaving pnpm children running.
|
|
44
|
+
* (Contributed in #7 by @mraing.)
|
|
45
|
+
*/
|
|
46
|
+
function killChild(child) {
|
|
47
|
+
if (process.platform === 'win32' && child.pid !== undefined) {
|
|
48
|
+
try {
|
|
49
|
+
spawn('taskkill', ['/pid', String(child.pid), '/t', '/f'], { stdio: 'ignore' });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
catch { /* fall through */ }
|
|
53
|
+
}
|
|
54
|
+
child.kill('SIGKILL');
|
|
55
|
+
}
|
|
36
56
|
function probePnpm() {
|
|
37
57
|
if (pnpmReady)
|
|
38
58
|
return Promise.resolve(true);
|
|
39
59
|
return new Promise((resolvePromise) => {
|
|
40
|
-
const child = spawn('pnpm', ['--version'], { stdio: 'ignore' });
|
|
60
|
+
const child = spawn('pnpm', ['--version'], { stdio: 'ignore', shell: winCmdShim });
|
|
41
61
|
child.on('error', () => resolvePromise(false));
|
|
42
62
|
child.on('close', (code) => {
|
|
43
63
|
pnpmReady = code === 0;
|
|
@@ -47,9 +67,13 @@ function probePnpm() {
|
|
|
47
67
|
}
|
|
48
68
|
function runQuiet(file, args, timeoutMs) {
|
|
49
69
|
return new Promise((resolvePromise) => {
|
|
50
|
-
const child = spawn(file, args, {
|
|
70
|
+
const child = spawn(file, args, {
|
|
71
|
+
env: { ...process.env, CI: 'true' },
|
|
72
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
73
|
+
shell: winCmdShim,
|
|
74
|
+
});
|
|
51
75
|
let output = '';
|
|
52
|
-
const timer = setTimeout(() => child
|
|
76
|
+
const timer = setTimeout(() => killChild(child), timeoutMs);
|
|
53
77
|
const collect = (chunk) => { output = (output + chunk.toString()).slice(-8 * 1024); };
|
|
54
78
|
child.stdout.on('data', collect);
|
|
55
79
|
child.stderr.on('data', collect);
|
|
@@ -99,7 +123,7 @@ function runDshPlugin(profile, pluginArgs) {
|
|
|
99
123
|
let timedOut = false;
|
|
100
124
|
const timer = setTimeout(() => {
|
|
101
125
|
timedOut = true;
|
|
102
|
-
child
|
|
126
|
+
killChild(child);
|
|
103
127
|
}, INSTALL_TIMEOUT_MS);
|
|
104
128
|
child.stdout.on('data', (chunk) => {
|
|
105
129
|
const text = chunk.toString();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dshmarket",
|
|
3
3
|
"description": "Visual plugin market inside DeepSeek Harness — browse, search, and one-click install community plugins. · DSH 可视化插件市场:逛一逛,点一下,装好。",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/types/index.d.ts",
|
package/src/routes.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { spawn } from 'node:child_process'
|
|
10
|
+
import type { ChildProcess } from 'node:child_process'
|
|
10
11
|
import { readFileSync } from 'node:fs'
|
|
11
12
|
import { homedir } from 'node:os'
|
|
12
13
|
import { dirname, join } from 'node:path'
|
|
@@ -65,10 +66,31 @@ interface InstallResult {
|
|
|
65
66
|
/** Whether `pnpm` resolves on PATH; success is cached, absence is re-probed. */
|
|
66
67
|
let pnpmReady = false
|
|
67
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Windows npm/corepack/pnpm are `.cmd` shims. Node's `spawn` without a shell
|
|
71
|
+
* cannot start them (ENOENT / EINVAL). Same pattern as dsh's `plugin` forwarder.
|
|
72
|
+
*/
|
|
73
|
+
const winCmdShim = process.platform === 'win32'
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Kill a spawned child and, on Windows, its whole process tree — `kill()`
|
|
77
|
+
* there only terminates the wrapper, leaving pnpm children running.
|
|
78
|
+
* (Contributed in #7 by @mraing.)
|
|
79
|
+
*/
|
|
80
|
+
function killChild(child: ChildProcess): void {
|
|
81
|
+
if (process.platform === 'win32' && child.pid !== undefined) {
|
|
82
|
+
try {
|
|
83
|
+
spawn('taskkill', ['/pid', String(child.pid), '/t', '/f'], { stdio: 'ignore' })
|
|
84
|
+
return
|
|
85
|
+
} catch { /* fall through */ }
|
|
86
|
+
}
|
|
87
|
+
child.kill('SIGKILL')
|
|
88
|
+
}
|
|
89
|
+
|
|
68
90
|
function probePnpm(): Promise<boolean> {
|
|
69
91
|
if (pnpmReady) return Promise.resolve(true)
|
|
70
92
|
return new Promise((resolvePromise) => {
|
|
71
|
-
const child = spawn('pnpm', ['--version'], { stdio: 'ignore' })
|
|
93
|
+
const child = spawn('pnpm', ['--version'], { stdio: 'ignore', shell: winCmdShim })
|
|
72
94
|
child.on('error', () => resolvePromise(false))
|
|
73
95
|
child.on('close', (code) => {
|
|
74
96
|
pnpmReady = code === 0
|
|
@@ -79,9 +101,13 @@ function probePnpm(): Promise<boolean> {
|
|
|
79
101
|
|
|
80
102
|
function runQuiet(file: string, args: string[], timeoutMs: number): Promise<{ code: number | null; output: string }> {
|
|
81
103
|
return new Promise((resolvePromise) => {
|
|
82
|
-
const child = spawn(file, args, {
|
|
104
|
+
const child = spawn(file, args, {
|
|
105
|
+
env: { ...process.env, CI: 'true' },
|
|
106
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
107
|
+
shell: winCmdShim,
|
|
108
|
+
})
|
|
83
109
|
let output = ''
|
|
84
|
-
const timer = setTimeout(() => child
|
|
110
|
+
const timer = setTimeout(() => killChild(child), timeoutMs)
|
|
85
111
|
const collect = (chunk: Buffer): void => { output = (output + chunk.toString()).slice(-8 * 1024) }
|
|
86
112
|
child.stdout.on('data', collect)
|
|
87
113
|
child.stderr.on('data', collect)
|
|
@@ -142,7 +168,7 @@ function runDshPlugin(profile: string, pluginArgs: string[]): Promise<InstallRes
|
|
|
142
168
|
let timedOut = false
|
|
143
169
|
const timer = setTimeout(() => {
|
|
144
170
|
timedOut = true
|
|
145
|
-
child
|
|
171
|
+
killChild(child)
|
|
146
172
|
}, INSTALL_TIMEOUT_MS)
|
|
147
173
|
child.stdout.on('data', (chunk: Buffer) => {
|
|
148
174
|
const text = chunk.toString()
|