@rooode/dsh-suite 0.1.1 → 0.1.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/bin/cli.js +135 -25
- package/cordis.patch.yml +3 -50
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -13,7 +13,6 @@ import { fileURLToPath } from 'url';
|
|
|
13
13
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
14
|
const __dirname = path.dirname(__filename);
|
|
15
15
|
const rootDir = path.resolve(__dirname, '..');
|
|
16
|
-
const patchPath = path.join(rootDir, 'cordis.patch.yml');
|
|
17
16
|
const pkgPath = path.join(rootDir, 'package.json');
|
|
18
17
|
|
|
19
18
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
@@ -34,6 +33,112 @@ function printBanner() {
|
|
|
34
33
|
`);
|
|
35
34
|
}
|
|
36
35
|
|
|
36
|
+
function copyFolderSync(src, dest) {
|
|
37
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
38
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
if (entry.name === 'node_modules' || entry.name === '.git') continue;
|
|
41
|
+
const srcPath = path.join(src, entry.name);
|
|
42
|
+
const destPath = path.join(dest, entry.name);
|
|
43
|
+
if (entry.isDirectory()) {
|
|
44
|
+
copyFolderSync(srcPath, destPath);
|
|
45
|
+
} else {
|
|
46
|
+
fs.copyFileSync(srcPath, destPath);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Automatically reconcile ~/.dsh/profiles/web/package.json
|
|
53
|
+
* to ensure all 4 plugins are registered in dsh.profile.bundles without duplicates.
|
|
54
|
+
*/
|
|
55
|
+
function ensureProfileConfigured() {
|
|
56
|
+
const userHome = process.env.USERPROFILE || process.env.HOME || '';
|
|
57
|
+
if (!userHome) return;
|
|
58
|
+
|
|
59
|
+
const dshDir = path.join(userHome, '.dsh');
|
|
60
|
+
const webProfileDir = path.join(dshDir, 'profiles', 'web');
|
|
61
|
+
const profilePkgPath = path.join(webProfileDir, 'package.json');
|
|
62
|
+
const profileNodeModules = path.join(webProfileDir, 'node_modules');
|
|
63
|
+
|
|
64
|
+
fs.mkdirSync(webProfileDir, { recursive: true });
|
|
65
|
+
fs.mkdirSync(profileNodeModules, { recursive: true });
|
|
66
|
+
|
|
67
|
+
const requiredPlugins = [
|
|
68
|
+
'@rooode/dsh-plugin-automation',
|
|
69
|
+
'@rooode/dsh-plugin-git',
|
|
70
|
+
'@rooode/dsh-plugin-preview',
|
|
71
|
+
'@rooode/dsh-plugin-quickbar',
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
let profilePkg = {
|
|
75
|
+
name: 'dsh-profile-web',
|
|
76
|
+
private: true,
|
|
77
|
+
dependencies: {},
|
|
78
|
+
dsh: {
|
|
79
|
+
profile: {
|
|
80
|
+
bundles: [
|
|
81
|
+
'@deepseek-ai/dsh-base',
|
|
82
|
+
'@deepseek-ai/dsh-web-app',
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
if (fs.existsSync(profilePkgPath)) {
|
|
89
|
+
try {
|
|
90
|
+
profilePkg = JSON.parse(fs.readFileSync(profilePkgPath, 'utf-8'));
|
|
91
|
+
} catch (e) {}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
profilePkg.dependencies = profilePkg.dependencies || {};
|
|
95
|
+
profilePkg.dsh = profilePkg.dsh || {};
|
|
96
|
+
profilePkg.dsh.profile = profilePkg.dsh.profile || {};
|
|
97
|
+
|
|
98
|
+
let bundles = profilePkg.dsh.profile.bundles || ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app'];
|
|
99
|
+
|
|
100
|
+
// Clean up any stale bundle references
|
|
101
|
+
bundles = bundles.filter(b => b !== '@rooode/dsh-suite');
|
|
102
|
+
|
|
103
|
+
for (const plugin of requiredPlugins) {
|
|
104
|
+
if (!profilePkg.dependencies[plugin]) {
|
|
105
|
+
profilePkg.dependencies[plugin] = pkg.dependencies?.[plugin] || '*';
|
|
106
|
+
}
|
|
107
|
+
if (!bundles.includes(plugin)) {
|
|
108
|
+
bundles.push(plugin);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Ensure default bundles are always at the start
|
|
113
|
+
const baseBundles = ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app'];
|
|
114
|
+
const customBundles = bundles.filter(b => !baseBundles.includes(b));
|
|
115
|
+
profilePkg.dsh.profile.bundles = [...baseBundles, ...customBundles];
|
|
116
|
+
|
|
117
|
+
fs.writeFileSync(profilePkgPath, JSON.stringify(profilePkg, null, 2), 'utf-8');
|
|
118
|
+
|
|
119
|
+
// Copy plugin files from suite dependencies into profile node_modules
|
|
120
|
+
for (const plugin of requiredPlugins) {
|
|
121
|
+
const pluginShortName = plugin.split('/')[1];
|
|
122
|
+
const targetPluginDir = path.join(profileNodeModules, '@rooode', pluginShortName);
|
|
123
|
+
|
|
124
|
+
const candidates = [
|
|
125
|
+
path.join(rootDir, 'node_modules', '@rooode', pluginShortName),
|
|
126
|
+
path.join(rootDir, '..', pluginShortName),
|
|
127
|
+
path.join(rootDir, '..', '@rooode', pluginShortName),
|
|
128
|
+
path.resolve(__dirname, '..', '..', pluginShortName),
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
for (const cand of candidates) {
|
|
132
|
+
if (fs.existsSync(cand) && fs.existsSync(path.join(cand, 'package.json'))) {
|
|
133
|
+
try {
|
|
134
|
+
copyFolderSync(cand, targetPluginDir);
|
|
135
|
+
} catch (e) {}
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
37
142
|
// Check for help or version flags
|
|
38
143
|
if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
|
|
39
144
|
printBanner();
|
|
@@ -44,7 +149,7 @@ if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
|
|
|
44
149
|
\x1b[32mweb\x1b[0m 启动 DSH Web 浏览器界面并加载全套插件 (默认模式)
|
|
45
150
|
\x1b[32mcli\x1b[0m 启动 DSH 交互式命令行终端会话 (含全套增强能力)
|
|
46
151
|
\x1b[32mheadless\x1b[0m 启动 DSH Headless 无头后台运行模式
|
|
47
|
-
\x1b[32minstall\x1b[0m
|
|
152
|
+
\x1b[32minstall\x1b[0m 一键将全套插件固化安装到当前用户的 web profile
|
|
48
153
|
\x1b[32mplugin\x1b[0m 管理 DSH 插件 (透传至 dsh plugin 命令)
|
|
49
154
|
\x1b[32mprofile\x1b[0m 管理 DSH Profile 配置文件 (透传至 dsh profile 命令)
|
|
50
155
|
|
|
@@ -52,7 +157,7 @@ if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
|
|
|
52
157
|
--port, -p <port> 指定 Web 监听端口 (默认 3080,例如: --port 8080)
|
|
53
158
|
--host, -H <host> 指定 Web 监听地址 (例如: --host 0.0.0.0 或 127.0.0.1)
|
|
54
159
|
--workspace, -w <path> 指定初始打开的工作空间目录绝对或相对路径
|
|
55
|
-
--patch <file> 附加额外的 Cordis Patch 配置文件
|
|
160
|
+
--patch <file> 附加额外的 Cordis Patch 配置文件
|
|
56
161
|
--open 启动后自动在默认浏览器中打开 Web 页面
|
|
57
162
|
|
|
58
163
|
\x1b[1m示例 (Examples):\x1b[0m
|
|
@@ -93,49 +198,54 @@ if (rawArgs.length > 0 && !rawArgs[0].startsWith('-')) {
|
|
|
93
198
|
|
|
94
199
|
// 1. Handle 'install' mode
|
|
95
200
|
if (subcommand === 'install' || rawArgs.includes('--install')) {
|
|
96
|
-
console.log('\x1b[33m📦
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
} else {
|
|
107
|
-
console.error(`\n\x1b[31m❌ Installation failed with exit code ${code}\x1b[0m`);
|
|
108
|
-
}
|
|
109
|
-
process.exit(code || 0);
|
|
110
|
-
});
|
|
201
|
+
console.log('\x1b[33m📦 Reconciling & installing suite plugins into DSH web profile...\x1b[0m\n');
|
|
202
|
+
try {
|
|
203
|
+
ensureProfileConfigured();
|
|
204
|
+
console.log('\x1b[32m✅ Successfully registered and synchronized all suite plugins to web profile!\x1b[0m');
|
|
205
|
+
console.log(' You can now run: \x1b[1mnpx @deepseek-ai/dsh web\x1b[0m\n');
|
|
206
|
+
} catch (err) {
|
|
207
|
+
console.error(`\x1b[31m❌ Installation failed: ${err.message}\x1b[0m`);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
process.exit(0);
|
|
111
211
|
}
|
|
112
212
|
// 2. Handle 'plugin' or 'profile' pass-through commands
|
|
113
213
|
else if (subcommand === 'plugin' || subcommand === 'profile') {
|
|
214
|
+
const isWin = process.platform === 'win32';
|
|
215
|
+
const executable = isWin ? 'npx.cmd' : 'npx';
|
|
114
216
|
const passthroughArgs = ['@deepseek-ai/dsh', subcommand, ...remainingArgs];
|
|
115
|
-
const child = spawn(
|
|
217
|
+
const child = spawn(executable, passthroughArgs, {
|
|
116
218
|
stdio: 'inherit',
|
|
117
|
-
shell:
|
|
219
|
+
shell: false,
|
|
118
220
|
});
|
|
119
221
|
child.on('exit', (code) => {
|
|
120
222
|
process.exit(code || 0);
|
|
121
223
|
});
|
|
122
224
|
}
|
|
123
|
-
// 3. Handle 'web', 'cli', 'headless' execution
|
|
225
|
+
// 3. Handle 'web', 'cli', 'headless' execution
|
|
124
226
|
else {
|
|
227
|
+
// Ensure profile bundles are configured cleanly without duplicate inserts
|
|
228
|
+
try {
|
|
229
|
+
ensureProfileConfigured();
|
|
230
|
+
} catch (err) {
|
|
231
|
+
// Non-fatal if offline/restricted
|
|
232
|
+
}
|
|
233
|
+
|
|
125
234
|
const modeName = subcommand.toUpperCase();
|
|
126
235
|
console.log(`\x1b[32m✨ Starting DeepSeek Harness in \x1b[1m${modeName}\x1b[22m mode with All-in-One Suite...\x1b[0m\n`);
|
|
127
236
|
|
|
237
|
+
const isWin = process.platform === 'win32';
|
|
238
|
+
const executable = isWin ? 'npx.cmd' : 'npx';
|
|
239
|
+
|
|
128
240
|
const dshArgs = [
|
|
129
241
|
'@deepseek-ai/dsh',
|
|
130
242
|
subcommand,
|
|
131
|
-
'--patch',
|
|
132
|
-
`"${patchPath}"`,
|
|
133
243
|
...remainingArgs,
|
|
134
244
|
];
|
|
135
245
|
|
|
136
|
-
const child = spawn(
|
|
246
|
+
const child = spawn(executable, dshArgs, {
|
|
137
247
|
stdio: 'inherit',
|
|
138
|
-
shell:
|
|
248
|
+
shell: false,
|
|
139
249
|
});
|
|
140
250
|
|
|
141
251
|
child.on('exit', (code) => {
|
package/cordis.patch.yml
CHANGED
|
@@ -1,53 +1,6 @@
|
|
|
1
1
|
# ==============================================================================
|
|
2
2
|
# DeepSeek Harness - All-in-One Plugin Suite Bundle Patch (@rooode/dsh-suite)
|
|
3
3
|
# ==============================================================================
|
|
4
|
-
|
|
5
|
-
-
|
|
6
|
-
|
|
7
|
-
- id: ui-quickbar
|
|
8
|
-
name: '@rooode/dsh-plugin-quickbar'
|
|
9
|
-
config:
|
|
10
|
-
allowCustomIcons: true
|
|
11
|
-
|
|
12
|
-
# 2. 自动化任务与调度中心插件 (24/7 Node Server-Side Scheduler)
|
|
13
|
-
- id: ui-automation
|
|
14
|
-
name: '@rooode/dsh-plugin-automation'
|
|
15
|
-
config:
|
|
16
|
-
defaultPollingIntervalMs: 5000
|
|
17
|
-
maxStoredRecords: 100
|
|
18
|
-
|
|
19
|
-
# 3. 多功能文档与工作空间代码预览插件 (FileTabs & Tree Explorer)
|
|
20
|
-
- id: ui-preview
|
|
21
|
-
name: '@rooode/dsh-plugin-preview'
|
|
22
|
-
config:
|
|
23
|
-
autoPreviewExtensions:
|
|
24
|
-
- .md
|
|
25
|
-
- .markdown
|
|
26
|
-
- .txt
|
|
27
|
-
- .json
|
|
28
|
-
- .yaml
|
|
29
|
-
- .yml
|
|
30
|
-
- .js
|
|
31
|
-
- .ts
|
|
32
|
-
- .java
|
|
33
|
-
- .cpp
|
|
34
|
-
- .c
|
|
35
|
-
- .h
|
|
36
|
-
- .hpp
|
|
37
|
-
- .py
|
|
38
|
-
- .go
|
|
39
|
-
- .rs
|
|
40
|
-
- .sh
|
|
41
|
-
- .sql
|
|
42
|
-
maxFileSizeMb: 10
|
|
43
|
-
defaultViewMode: 'preview'
|
|
44
|
-
defaultPanelWidth: 560
|
|
45
|
-
|
|
46
|
-
# 4. WebStorm 风格 Git 提交与差异对比插件 (Side-by-Side Diff & Conventional Commits)
|
|
47
|
-
- id: ui-git
|
|
48
|
-
name: '@rooode/dsh-plugin-git'
|
|
49
|
-
config:
|
|
50
|
-
enableCommitDockButton: true
|
|
51
|
-
autoRefreshIntervalMs: 10000
|
|
52
|
-
defaultDiffViewMode: 'split'
|
|
53
|
-
commitAiStyle: 'conventional'
|
|
4
|
+
# Sub-plugins (@rooode/dsh-plugin-*) export their own bundle patches.
|
|
5
|
+
# This patch provides global profile-level overrides if needed.
|
|
6
|
+
[]
|