@rooode/dsh-suite 0.1.1 → 0.1.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/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,126 @@ function printBanner() {
34
33
  `);
35
34
  }
36
35
 
36
+ function quoteArg(arg) {
37
+ if (typeof arg !== 'string') return String(arg);
38
+ if (/^[a-zA-Z0-9_\-\.\:\/\\]+$/.test(arg)) return arg;
39
+ return JSON.stringify(arg);
40
+ }
41
+
42
+ function execDsh(args) {
43
+ const fullCommand = ['npx', ...args.map(quoteArg)].join(' ');
44
+ return spawn(fullCommand, {
45
+ stdio: 'inherit',
46
+ shell: true,
47
+ });
48
+ }
49
+
50
+ function copyFolderSync(src, dest) {
51
+ fs.mkdirSync(dest, { recursive: true });
52
+ const entries = fs.readdirSync(src, { withFileTypes: true });
53
+ for (const entry of entries) {
54
+ if (entry.name === 'node_modules' || entry.name === '.git') continue;
55
+ const srcPath = path.join(src, entry.name);
56
+ const destPath = path.join(dest, entry.name);
57
+ if (entry.isDirectory()) {
58
+ copyFolderSync(srcPath, destPath);
59
+ } else {
60
+ fs.copyFileSync(srcPath, destPath);
61
+ }
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Automatically reconcile ~/.dsh/profiles/web/package.json
67
+ * to ensure all 4 plugins are registered in dsh.profile.bundles without duplicates.
68
+ */
69
+ function ensureProfileConfigured() {
70
+ const userHome = process.env.USERPROFILE || process.env.HOME || '';
71
+ if (!userHome) return;
72
+
73
+ const dshDir = path.join(userHome, '.dsh');
74
+ const webProfileDir = path.join(dshDir, 'profiles', 'web');
75
+ const profilePkgPath = path.join(webProfileDir, 'package.json');
76
+ const profileNodeModules = path.join(webProfileDir, 'node_modules');
77
+
78
+ fs.mkdirSync(webProfileDir, { recursive: true });
79
+ fs.mkdirSync(profileNodeModules, { recursive: true });
80
+
81
+ const requiredPlugins = [
82
+ '@rooode/dsh-plugin-automation',
83
+ '@rooode/dsh-plugin-git',
84
+ '@rooode/dsh-plugin-preview',
85
+ '@rooode/dsh-plugin-quickbar',
86
+ ];
87
+
88
+ let profilePkg = {
89
+ name: 'dsh-profile-web',
90
+ private: true,
91
+ dependencies: {},
92
+ dsh: {
93
+ profile: {
94
+ bundles: [
95
+ '@deepseek-ai/dsh-base',
96
+ '@deepseek-ai/dsh-web-app',
97
+ ],
98
+ },
99
+ },
100
+ };
101
+
102
+ if (fs.existsSync(profilePkgPath)) {
103
+ try {
104
+ profilePkg = JSON.parse(fs.readFileSync(profilePkgPath, 'utf-8'));
105
+ } catch (e) {}
106
+ }
107
+
108
+ profilePkg.dependencies = profilePkg.dependencies || {};
109
+ profilePkg.dsh = profilePkg.dsh || {};
110
+ profilePkg.dsh.profile = profilePkg.dsh.profile || {};
111
+
112
+ let bundles = profilePkg.dsh.profile.bundles || ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app'];
113
+
114
+ // Clean up any stale bundle references
115
+ bundles = bundles.filter(b => b !== '@rooode/dsh-suite');
116
+
117
+ for (const plugin of requiredPlugins) {
118
+ if (!profilePkg.dependencies[plugin]) {
119
+ profilePkg.dependencies[plugin] = pkg.dependencies?.[plugin] || '*';
120
+ }
121
+ if (!bundles.includes(plugin)) {
122
+ bundles.push(plugin);
123
+ }
124
+ }
125
+
126
+ // Ensure default bundles are always at the start
127
+ const baseBundles = ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app'];
128
+ const customBundles = bundles.filter(b => !baseBundles.includes(b));
129
+ profilePkg.dsh.profile.bundles = [...baseBundles, ...customBundles];
130
+
131
+ fs.writeFileSync(profilePkgPath, JSON.stringify(profilePkg, null, 2), 'utf-8');
132
+
133
+ // Copy plugin files from suite dependencies into profile node_modules
134
+ for (const plugin of requiredPlugins) {
135
+ const pluginShortName = plugin.split('/')[1];
136
+ const targetPluginDir = path.join(profileNodeModules, '@rooode', pluginShortName);
137
+
138
+ const candidates = [
139
+ path.join(rootDir, 'node_modules', '@rooode', pluginShortName),
140
+ path.join(rootDir, '..', pluginShortName),
141
+ path.join(rootDir, '..', '@rooode', pluginShortName),
142
+ path.resolve(__dirname, '..', '..', pluginShortName),
143
+ ];
144
+
145
+ for (const cand of candidates) {
146
+ if (fs.existsSync(cand) && fs.existsSync(path.join(cand, 'package.json'))) {
147
+ try {
148
+ copyFolderSync(cand, targetPluginDir);
149
+ } catch (e) {}
150
+ break;
151
+ }
152
+ }
153
+ }
154
+ }
155
+
37
156
  // Check for help or version flags
38
157
  if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
39
158
  printBanner();
@@ -44,7 +163,7 @@ if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
44
163
  \x1b[32mweb\x1b[0m 启动 DSH Web 浏览器界面并加载全套插件 (默认模式)
45
164
  \x1b[32mcli\x1b[0m 启动 DSH 交互式命令行终端会话 (含全套增强能力)
46
165
  \x1b[32mheadless\x1b[0m 启动 DSH Headless 无头后台运行模式
47
- \x1b[32minstall\x1b[0m 一键将 @rooode/dsh-suite 固化安装到当前用户的 web profile
166
+ \x1b[32minstall\x1b[0m 一键将全套插件固化安装到当前用户的 web profile
48
167
  \x1b[32mplugin\x1b[0m 管理 DSH 插件 (透传至 dsh plugin 命令)
49
168
  \x1b[32mprofile\x1b[0m 管理 DSH Profile 配置文件 (透传至 dsh profile 命令)
50
169
 
@@ -52,7 +171,7 @@ if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
52
171
  --port, -p <port> 指定 Web 监听端口 (默认 3080,例如: --port 8080)
53
172
  --host, -H <host> 指定 Web 监听地址 (例如: --host 0.0.0.0 或 127.0.0.1)
54
173
  --workspace, -w <path> 指定初始打开的工作空间目录绝对或相对路径
55
- --patch <file> 附加额外的 Cordis Patch 配置文件 (与 Suite Patch 叠加)
174
+ --patch <file> 附加额外的 Cordis Patch 配置文件
56
175
  --open 启动后自动在默认浏览器中打开 Web 页面
57
176
 
58
177
  \x1b[1m示例 (Examples):\x1b[0m
@@ -93,51 +212,44 @@ if (rawArgs.length > 0 && !rawArgs[0].startsWith('-')) {
93
212
 
94
213
  // 1. Handle 'install' mode
95
214
  if (subcommand === 'install' || rawArgs.includes('--install')) {
96
- console.log('\x1b[33m📦 Installing @rooode/dsh-suite into DSH web profile...\x1b[0m\n');
97
- const installArgs = ['@deepseek-ai/dsh', 'plugin', '--profile', 'web', 'add', '@rooode/dsh-suite'];
98
- const child = spawn('npx', installArgs, {
99
- stdio: 'inherit',
100
- shell: true,
101
- });
102
- child.on('exit', (code) => {
103
- if (code === 0) {
104
- console.log('\n\x1b[32m✅ Successfully installed @rooode/dsh-suite! You can now run:\x1b[0m');
105
- console.log(' \x1b[1mnpx @deepseek-ai/dsh web\x1b[0m\n');
106
- } else {
107
- console.error(`\n\x1b[31m❌ Installation failed with exit code ${code}\x1b[0m`);
108
- }
109
- process.exit(code || 0);
110
- });
215
+ console.log('\x1b[33m📦 Reconciling & installing suite plugins into DSH web profile...\x1b[0m\n');
216
+ try {
217
+ ensureProfileConfigured();
218
+ console.log('\x1b[32m✅ Successfully registered and synchronized all suite plugins to web profile!\x1b[0m');
219
+ console.log(' You can now run: \x1b[1mnpx @deepseek-ai/dsh web\x1b[0m\n');
220
+ } catch (err) {
221
+ console.error(`\x1b[31m❌ Installation failed: ${err.message}\x1b[0m`);
222
+ process.exit(1);
223
+ }
224
+ process.exit(0);
111
225
  }
112
226
  // 2. Handle 'plugin' or 'profile' pass-through commands
113
227
  else if (subcommand === 'plugin' || subcommand === 'profile') {
114
228
  const passthroughArgs = ['@deepseek-ai/dsh', subcommand, ...remainingArgs];
115
- const child = spawn('npx', passthroughArgs, {
116
- stdio: 'inherit',
117
- shell: true,
118
- });
229
+ const child = execDsh(passthroughArgs);
119
230
  child.on('exit', (code) => {
120
231
  process.exit(code || 0);
121
232
  });
122
233
  }
123
- // 3. Handle 'web', 'cli', 'headless' execution with bundle patch injected
234
+ // 3. Handle 'web', 'cli', 'headless' execution
124
235
  else {
236
+ // Ensure profile bundles are configured cleanly without duplicate inserts
237
+ try {
238
+ ensureProfileConfigured();
239
+ } catch (err) {
240
+ // Non-fatal if offline/restricted
241
+ }
242
+
125
243
  const modeName = subcommand.toUpperCase();
126
244
  console.log(`\x1b[32m✨ Starting DeepSeek Harness in \x1b[1m${modeName}\x1b[22m mode with All-in-One Suite...\x1b[0m\n`);
127
245
 
128
246
  const dshArgs = [
129
247
  '@deepseek-ai/dsh',
130
248
  subcommand,
131
- '--patch',
132
- `"${patchPath}"`,
133
249
  ...remainingArgs,
134
250
  ];
135
251
 
136
- const child = spawn('npx', dshArgs, {
137
- stdio: 'inherit',
138
- shell: true,
139
- });
140
-
252
+ const child = execDsh(dshArgs);
141
253
  child.on('exit', (code) => {
142
254
  process.exit(code || 0);
143
255
  });
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
- - insert:
6
- # 1. 对话快捷栏插件 (Workspace Quick Prompts Bar)
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
+ []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rooode/dsh-suite",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "DeepSeek Harness 一键全功能增强套件 (自动化调度 + WebStorm Git 提交对比 + 代码文档多标签预览 + 对话快捷栏)",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",