@zhin.js/cli 1.0.0 → 1.0.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +21 -0
  3. package/README.md +248 -56
  4. package/{dist → lib}/cli.js +1 -1
  5. package/{dist → lib}/commands/build.d.ts.map +1 -1
  6. package/{dist → lib}/commands/build.js +3 -2
  7. package/lib/commands/build.js.map +1 -0
  8. package/{dist → lib}/commands/dev.d.ts.map +1 -1
  9. package/{dist → lib}/commands/dev.js +3 -2
  10. package/lib/commands/dev.js.map +1 -0
  11. package/{dist → lib}/commands/init.js +209 -151
  12. package/lib/commands/init.js.map +1 -0
  13. package/{dist → lib}/utils/logger.d.ts +1 -0
  14. package/lib/utils/logger.d.ts.map +1 -0
  15. package/lib/utils/logger.js +79 -0
  16. package/lib/utils/logger.js.map +1 -0
  17. package/{dist → lib}/utils/process.d.ts.map +1 -1
  18. package/{dist → lib}/utils/process.js +2 -1
  19. package/lib/utils/process.js.map +1 -0
  20. package/package.json +9 -7
  21. package/src/cli.ts +1 -1
  22. package/src/commands/build.ts +3 -2
  23. package/src/commands/dev.ts +3 -2
  24. package/src/commands/init.ts +215 -151
  25. package/src/commands/start.ts +1 -1
  26. package/src/utils/logger.ts +81 -10
  27. package/src/utils/process.ts +2 -1
  28. package/tsconfig.json +3 -4
  29. package/dist/commands/build.js.map +0 -1
  30. package/dist/commands/dev.js.map +0 -1
  31. package/dist/commands/init.js.map +0 -1
  32. package/dist/utils/logger.d.ts.map +0 -1
  33. package/dist/utils/logger.js +0 -18
  34. package/dist/utils/logger.js.map +0 -1
  35. package/dist/utils/process.js.map +0 -1
  36. package/tsconfig.tsbuildinfo +0 -1
  37. /package/{dist → lib}/cli.d.ts +0 -0
  38. /package/{dist → lib}/cli.d.ts.map +0 -0
  39. /package/{dist → lib}/cli.js.map +0 -0
  40. /package/{dist → lib}/commands/build.d.ts +0 -0
  41. /package/{dist → lib}/commands/dev.d.ts +0 -0
  42. /package/{dist → lib}/commands/init.d.ts +0 -0
  43. /package/{dist → lib}/commands/init.d.ts.map +0 -0
  44. /package/{dist → lib}/commands/start.d.ts +0 -0
  45. /package/{dist → lib}/commands/start.d.ts.map +0 -0
  46. /package/{dist → lib}/commands/start.js +0 -0
  47. /package/{dist → lib}/commands/start.js.map +0 -0
  48. /package/{dist → lib}/commands/stop.d.ts +0 -0
  49. /package/{dist → lib}/commands/stop.d.ts.map +0 -0
  50. /package/{dist → lib}/commands/stop.js +0 -0
  51. /package/{dist → lib}/commands/stop.js.map +0 -0
  52. /package/{dist → lib}/index.d.ts +0 -0
  53. /package/{dist → lib}/index.d.ts.map +0 -0
  54. /package/{dist → lib}/index.js +0 -0
  55. /package/{dist → lib}/index.js.map +0 -0
  56. /package/{dist → lib}/utils/env.d.ts +0 -0
  57. /package/{dist → lib}/utils/env.d.ts.map +0 -0
  58. /package/{dist → lib}/utils/env.js +0 -0
  59. /package/{dist → lib}/utils/env.js.map +0 -0
  60. /package/{dist → lib}/utils/process.d.ts +0 -0
@@ -17,13 +17,13 @@ export const initCommand = new Command('init')
17
17
  .argument('[project-name]', '项目名称')
18
18
  .option('-c, --config <format>', '配置文件格式 (json|yaml|toml|ts|js)', 'js')
19
19
  .option('-p, --package-manager <manager>', '包管理器 (npm|yarn|pnpm)', 'pnpm')
20
- .option('-r, --runtime <runtime>', '运行时 (node|bun)', 'bun')
20
+ .option('-r, --runtime <runtime>', '运行时 (node|bun)', 'node')
21
21
  .option('-y, --yes', '自动回答所有问题')
22
22
  .action(async (projectName: string, options: InitOptions) => {
23
23
  if(options.yes) {
24
24
  options.config = 'js';
25
25
  options.packageManager = 'pnpm';
26
- options.runtime = 'bun';
26
+ options.runtime = 'node';
27
27
  }
28
28
  try {
29
29
  let name = projectName;
@@ -55,10 +55,10 @@ export const initCommand = new Command('init')
55
55
  name: 'runtime',
56
56
  message: '选择运行时:',
57
57
  choices: [
58
- { name: 'Bun (推荐)', value: 'bun' },
59
- { name: 'Node.js', value: 'node' }
58
+ { name: 'Node.js (推荐)', value: 'node' },
59
+ { name: 'Bun', value: 'bun' }
60
60
  ],
61
- default: options.runtime || 'bun'
61
+ default: options.runtime || 'node'
62
62
  },
63
63
  ])
64
64
  options.runtime=inputRuntime;
@@ -152,27 +152,41 @@ async function createProjectStructure(projectPath: string, projectName: string,
152
152
  await fs.ensureDir(path.join(projectPath, 'dist'));
153
153
  await fs.ensureDir(path.join(projectPath, 'data'));
154
154
 
155
+ // 检查是否在工作区中
156
+ const isInWorkspace = await checkIfInWorkspace();
157
+ const versionSuffix = isInWorkspace ? 'workspace:*' : 'latest';
158
+
155
159
  // 创建 package.json
156
160
  const packageJson = {
157
161
  name: projectName,
162
+ private: true,
158
163
  version: '0.1.0',
159
164
  description: `${projectName} 机器人`,
160
165
  type: 'module',
161
166
  main: 'src/index.ts',
162
167
  scripts: {
163
- dev: options.runtime === 'bun' ? 'zhin dev --bun' : 'zhin dev',
168
+ dev: 'zhin dev',
164
169
  start: options.runtime === 'bun' ? 'zhin start --bun' : 'zhin start',
165
170
  daemon: options.runtime === 'bun' ? 'zhin start --bun --daemon' : 'zhin start --daemon',
166
171
  build: 'zhin build',
167
172
  stop: 'zhin stop'
168
173
  },
169
174
  dependencies: {
170
- '@zhin.js/core': 'workspace:*'
175
+ 'zhin.js': versionSuffix,
176
+ '@zhin.js/adapter-process': versionSuffix,
177
+ '@zhin.js/http': versionSuffix,
178
+ '@zhin.js/console': versionSuffix
171
179
  },
172
180
  devDependencies: {
173
- '@zhin.js/cli': 'workspace:*',
174
- 'typescript': '^5.0.0',
175
- ...(options.runtime === 'node' && { 'tsx': '^4.0.0' })
181
+ '@zhin.js/cli': versionSuffix,
182
+ '@zhin.js/types': versionSuffix,
183
+ "@types/node": "latest",
184
+ 'typescript': 'latest',
185
+ ...(options.runtime === 'bun' ? {
186
+ 'bun': 'latest'
187
+ } : {
188
+ 'tsx': 'latest'
189
+ })
176
190
  },
177
191
  engines: {
178
192
  node: '>=18.0.0'
@@ -200,10 +214,13 @@ async function createProjectStructure(projectPath: string, projectName: string,
200
214
  declaration: false,
201
215
  sourceMap: true,
202
216
  baseUrl: './src',
203
- paths: {
204
- '@zhin.js/core': ['../../packages/core/src/index.ts'],
205
- '@zhin.js/core/*': ['../../packages/core/src/*']
206
- }
217
+ jsx: 'react-jsx',
218
+ jsxImportSource: 'zhin.js',
219
+ types: [
220
+ '@types/node',
221
+ '@zhin.js/types',
222
+ 'zhin.js'
223
+ ]
207
224
  },
208
225
  include: ['src/**/*'],
209
226
  exclude: ['dist', 'node_modules']
@@ -215,7 +232,7 @@ async function createProjectStructure(projectPath: string, projectName: string,
215
232
  await createConfigFile(projectPath, options.config!);
216
233
 
217
234
  // 创建主入口文件
218
- const indexContent = `import { createApp } from '@zhin.js/core';
235
+ const indexContent = `import { createApp } from 'zhin.js';
219
236
 
220
237
  // 启动机器人
221
238
  async function main() {
@@ -230,10 +247,10 @@ async function main() {
230
247
  process.exit(0);
231
248
  };
232
249
 
233
- process.on('SIGINT', shutdown);
234
- process.on('SIGTERM', shutdown);
250
+ process.on('SIGINT', () => shutdown('SIGINT'));
251
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
235
252
  } catch (error) {
236
- console.error('机器人启动失败:', error);
253
+ // console.error 已替换为注释
237
254
  process.exit(1);
238
255
  }
239
256
  }
@@ -246,45 +263,75 @@ main().catch(console.error);
246
263
 
247
264
  // 创建示例插件
248
265
  const pluginContent = `import {
266
+ useLogger,
267
+ onMessage,
268
+ addCommand,
269
+ addMiddleware,
270
+ MessageCommand,
271
+ useContext,
249
272
  onDispose,
250
- addMiddleware, useContext, sendMessage, beforeSend, onGroupMessage,
251
- } from '@zhin.js/core';
252
- import * as process from "node:process";
253
-
254
- onDispose(async ()=>{
255
- console.log('插件已销毁')
256
- })
257
-
258
- addMiddleware(async (message, next)=>{ // 添加中间件到插件
259
- // 在这里处理消息
260
- return next()
261
- })
262
-
263
- let hasChanged=false
264
- beforeSend((options)=>{
265
- if(!hasChanged){
266
- options.content='bar'
267
- hasChanged=true
268
- }
269
- return options
270
- })
273
+ } from 'zhin.js';
271
274
 
272
- onGroupMessage((m)=>{
273
- if(m.channel.id==='629336764'){
274
- m.reply('hello')
275
- }
276
- })
277
-
278
- // 依赖process上下文
279
- useContext('process',()=>{
280
- sendMessage({
281
- context:'process',
282
- bot:\`\${process.pid}\`,
283
- id:process.title,
284
- type:'private',
285
- content:'foo'
275
+ const logger = useLogger();
276
+
277
+ // 添加命令
278
+ addCommand(new MessageCommand('hello')
279
+ .action(async (message) => {
280
+ logger.info('Hello command called by:', message.sender.name);
281
+ return '你好!欢迎使用 Zhin 机器人框架!';
286
282
  })
287
- })
283
+ );
284
+
285
+ addCommand(new MessageCommand('status')
286
+ .action(() => {
287
+ const uptime = process.uptime() * 1000;
288
+ const memory = process.memoryUsage();
289
+ return [
290
+ '🤖 机器人状态',
291
+ \`⏱️ 运行时间: \${formatTime(uptime)}\`,
292
+ \`📊 内存使用: \${(memory.rss / 1024 / 1024).toFixed(2)}MB\`,
293
+ \`🔧 Node.js: \${process.version}\`
294
+ ].join('\\n');
295
+ })
296
+ );
297
+
298
+ // 添加中间件
299
+ addMiddleware(async (message, next) => {
300
+ logger.info(\`收到消息: \${message.raw}\`);
301
+ await next();
302
+ });
303
+
304
+ // 监听消息
305
+ onMessage(async (message) => {
306
+ if (message.raw.includes('帮助')) {
307
+ await message.reply('可用命令:hello, status\\n输入命令即可使用!');
308
+ }
309
+ });
310
+
311
+ // 使用 process 上下文
312
+ useContext('process', () => {
313
+ logger.info('Process 适配器已就绪,可以在控制台输入消息进行测试');
314
+ });
315
+
316
+ // 插件销毁时的清理
317
+ onDispose(() => {
318
+ logger.info('测试插件已销毁');
319
+ });
320
+
321
+ // 工具函数
322
+ function formatTime(ms: number): string {
323
+ const seconds = Math.floor(ms / 1000);
324
+ const minutes = Math.floor(seconds / 60);
325
+ const hours = Math.floor(minutes / 60);
326
+ const days = Math.floor(hours / 24);
327
+
328
+ if (days > 0) return \`\${days}天 \${hours % 24}小时\`;
329
+ if (hours > 0) return \`\${hours}小时 \${minutes % 60}分钟\`;
330
+ if (minutes > 0) return \`\${minutes}分钟 \${seconds % 60}秒\`;
331
+ return \`\${seconds}秒\`;
332
+ }
333
+
334
+ logger.info('测试插件已加载');
288
335
  `;
289
336
 
290
337
  await fs.writeFile(path.join(projectPath, 'src', 'plugins', 'test-plugin.ts'), pluginContent);
@@ -487,6 +534,30 @@ MIT License
487
534
  `;
488
535
  await fs.writeFile(path.join(projectPath, 'pnpm-workspace.yaml'), workspaceContent);
489
536
  }
537
+
538
+ // 创建环境变量示例文件
539
+ const envExampleContent = `# Zhin Bot 环境变量配置示例
540
+ # 复制为 .env 文件并根据需要修改
541
+
542
+ # 调试模式
543
+ DEBUG=true
544
+
545
+ # 插件目录 (可选)
546
+ # PLUGIN_DIR=./src/plugins
547
+
548
+ # KOOK 机器人配置 (如果使用 KOOK 适配器)
549
+ # KOOK_TOKEN=your-kook-token
550
+
551
+ # ICQQ 机器人配置 (如果使用 ICQQ 适配器)
552
+ # ICQQ_SCAN_UIN=your-qq-number
553
+ # ICQQ_LOGIN_UIN=your-qq-number
554
+ # ICQQ_SIGN_ADDR=http://localhost:8080
555
+
556
+ # OneBot 机器人配置 (如果使用 OneBot 适配器)
557
+ # BOT_URL=ws://localhost:8080
558
+ # ACCESS_TOKEN=your-access-token
559
+ `;
560
+ await fs.writeFile(path.join(projectPath, '.env.example'), envExampleContent);
490
561
  }
491
562
 
492
563
  async function createConfigFile(projectPath: string, format: string) {
@@ -498,7 +569,7 @@ async function createConfigFile(projectPath: string, format: string) {
498
569
  fileName = 'zhin.config.ts';
499
570
  break;
500
571
  case 'js':
501
- fileName = 'zhin.config.js';
572
+ fileName = 'zhin.config.ts';
502
573
  break;
503
574
  default:
504
575
  fileName = `zhin.config.${format}`;
@@ -515,21 +586,17 @@ function getConfigContent(format: string): string {
515
586
  {
516
587
  name: `${process.pid}`,
517
588
  context: 'process'
518
- },
519
- {
520
- name: '1689919782',
521
- context: 'icqq',
522
- log_level: 'off',
523
- platform: 4
524
589
  }
525
590
  ],
526
591
  plugin_dirs: [
527
592
  './src/plugins',
528
- 'node_modules'
593
+ 'node_modules',
594
+ 'node_modules/@zhin.js'
529
595
  ],
530
596
  plugins: [
531
- 'icqq',
532
- 'process',
597
+ 'adapter-process',
598
+ 'http',
599
+ 'console',
533
600
  'test-plugin'
534
601
  ],
535
602
  debug: false
@@ -542,20 +609,17 @@ function getConfigContent(format: string): string {
542
609
  bots:
543
610
  - name: \${process.pid}
544
611
  context: process
545
- - name: '1689919782'
546
- context: icqq
547
- log_level: off
548
- platform: 4
549
612
 
550
613
  # 插件目录
551
614
  plugin_dirs:
552
615
  - ./src/plugins
553
616
  - node_modules
554
-
617
+ - node_modules/@zhin.js
555
618
  # 要加载的插件列表
556
619
  plugins:
557
- - icqq
558
- - process
620
+ - adapter-process
621
+ - http
622
+ - console
559
623
  - test-plugin
560
624
 
561
625
  # 调试模式
@@ -570,92 +634,82 @@ debug: false
570
634
  name = "\${process.pid}"
571
635
  context = "process"
572
636
 
573
- [[bots]]
574
- name = "1689919782"
575
- context = "icqq"
576
- log_level = "off"
577
- platform = 4
578
-
579
637
  # 插件目录
580
- plugin_dirs = ["./src/plugins", "node_modules"]
638
+ plugin_dirs = ["./src/plugins", "node_modules", "node_modules/@zhin.js"]
581
639
 
582
640
  # 要加载的插件列表
583
- plugins = ["icqq", "process", "test-plugin"]
641
+ plugins = ["adapter-process", "http", "console", "test-plugin"]
584
642
 
585
643
  # 调试模式
586
644
  debug = false
587
645
  `;
588
646
 
589
647
  case 'ts':
590
- return `import { defineConfig } from '@zhin.js/core';
648
+ return `import { defineConfig } from 'zhin.js';
591
649
 
592
- export default defineConfig(async (env)=>{
650
+ export default defineConfig(async (env) => {
593
651
  return {
594
652
  // 机器人配置
595
653
  bots: [
596
654
  {
597
655
  name: \`\${process.pid}\`,
598
656
  context: 'process'
599
- },
600
- {
601
- name: '1689919782',
602
- context: 'icqq',
603
- log_level: 'off',
604
- platform: 4
605
657
  }
606
658
  ],
659
+
607
660
  // 插件目录
608
661
  plugin_dirs: [
609
662
  env.PLUGIN_DIR || './src/plugins',
610
- 'node_modules'
663
+ 'node_modules',
664
+ 'node_modules/@zhin.js'
611
665
  ],
666
+
612
667
  // 要加载的插件列表
613
668
  plugins: [
614
- 'icqq',
615
- 'process',
669
+ 'adapter-process',
670
+ 'http',
671
+ 'console',
616
672
  'test-plugin'
617
673
  ],
618
674
 
619
675
  // 调试模式
620
676
  debug: env.DEBUG === 'true'
621
- }
622
- })
677
+ };
678
+ });
623
679
  `;
624
680
 
625
681
  case 'js':
626
- return `import { defineConfig } from '@zhin.js/core';
682
+ return `import { defineConfig } from 'zhin.js';
627
683
 
628
- export default defineConfig(async (env)=>{
684
+ export default defineConfig(async (env) => {
629
685
  return {
630
686
  // 机器人配置
631
687
  bots: [
632
688
  {
633
689
  name: \`\${process.pid}\`,
634
690
  context: 'process'
635
- },
636
- {
637
- name: '1689919782',
638
- context: 'icqq',
639
- log_level: 'off',
640
- platform: 4
641
691
  }
642
692
  ],
693
+
643
694
  // 插件目录
644
695
  plugin_dirs: [
645
696
  env.PLUGIN_DIR || './src/plugins',
646
- 'node_modules'
697
+ 'node_modules',
698
+ 'node_modules/@zhin.js'
647
699
  ],
700
+
648
701
  // 要加载的插件列表
649
702
  plugins: [
650
- 'icqq',
651
- 'process',
703
+ 'adapter-process',
704
+ 'http',
705
+ 'console',
652
706
  'test-plugin'
653
707
  ],
654
708
 
655
709
  // 调试模式
656
710
  debug: env.DEBUG === 'true'
657
- }
658
- })
711
+ };
712
+ });
659
713
  `;
660
714
 
661
715
  default:
@@ -672,21 +726,17 @@ function getConfigExample(format: string): string {
672
726
  {
673
727
  "name": "\${process.pid}",
674
728
  "context": "process"
675
- },
676
- {
677
- "name": "1689919782",
678
- "context": "icqq",
679
- "log_level": "off",
680
- "platform": 4
681
729
  }
682
730
  ],
683
731
  "plugin_dirs": [
684
732
  "./src/plugins",
685
- "node_modules"
733
+ "node_modules",
734
+ "node_modules/@zhin.js"
686
735
  ],
687
736
  "plugins": [
688
- "icqq",
689
- "process",
737
+ "adapter-process",
738
+ "http",
739
+ "console",
690
740
  "test-plugin"
691
741
  ],
692
742
  "debug": false
@@ -701,10 +751,6 @@ function getConfigExample(format: string): string {
701
751
  bots:
702
752
  - name: \${process.pid}
703
753
  context: process
704
- - name: '1689919782'
705
- context: icqq
706
- log_level: off
707
- platform: 4
708
754
 
709
755
  # 插件目录
710
756
  plugin_dirs:
@@ -713,8 +759,9 @@ plugin_dirs:
713
759
 
714
760
  # 要加载的插件列表
715
761
  plugins:
716
- - icqq
717
- - process
762
+ - adapter-process
763
+ - http
764
+ - console
718
765
  - test-plugin
719
766
 
720
767
  # 调试模式
@@ -730,17 +777,11 @@ debug: false
730
777
  name = "\${process.pid}"
731
778
  context = "process"
732
779
 
733
- [[bots]]
734
- name = "1689919782"
735
- context = "icqq"
736
- log_level = "off"
737
- platform = 4
738
-
739
780
  # 插件目录
740
781
  plugin_dirs = ["./src/plugins", "node_modules"]
741
782
 
742
783
  # 要加载的插件列表
743
- plugins = ["icqq", "process", "test-plugin"]
784
+ plugins = ["adapter-process", "http", "console", "test-plugin"]
744
785
 
745
786
  # 调试模式
746
787
  debug = false
@@ -748,79 +789,102 @@ debug = false
748
789
  `;
749
790
  case 'ts':
750
791
  return `\`\`\`typescript
751
- import { defineConfig } from '@zhin.js/core';
792
+ import { defineConfig } from 'zhin.js';
752
793
 
753
- export default defineConfig(async (env)=>{
794
+ export default defineConfig(async (env) => {
754
795
  return {
755
796
  // 机器人配置
756
797
  bots: [
757
798
  {
758
799
  name: \`\${process.pid}\`,
759
800
  context: 'process'
760
- },
761
- {
762
- name: '1689919782',
763
- context: 'icqq',
764
- log_level: 'off',
765
- platform: 4
766
801
  }
767
802
  ],
803
+
768
804
  // 插件目录
769
805
  plugin_dirs: [
770
806
  env.PLUGIN_DIR || './src/plugins',
771
807
  'node_modules'
772
808
  ],
809
+
773
810
  // 要加载的插件列表
774
811
  plugins: [
775
- 'icqq',
776
- 'process',
812
+ 'adapter-process',
813
+ 'http',
814
+ 'console',
777
815
  'test-plugin'
778
816
  ],
779
817
 
780
818
  // 调试模式
781
819
  debug: env.DEBUG === 'true'
782
- }
783
- })
820
+ };
821
+ });
784
822
  \`\`\`
785
823
  `;
786
824
  case 'js':
787
825
  return `\`\`\`javascript
788
- import { defineConfig } from '@zhin.js/core';
826
+ import { defineConfig } from 'zhin.js';
789
827
 
790
- export default defineConfig(async (env)=>{
828
+ export default defineConfig(async (env) => {
791
829
  return {
792
830
  // 机器人配置
793
831
  bots: [
794
832
  {
795
833
  name: \`\${process.pid}\`,
796
834
  context: 'process'
797
- },
798
- {
799
- name: '1689919782',
800
- context: 'icqq',
801
- log_level: 'off',
802
- platform: 4
803
835
  }
804
836
  ],
837
+
805
838
  // 插件目录
806
839
  plugin_dirs: [
807
840
  env.PLUGIN_DIR || './src/plugins',
808
841
  'node_modules'
809
842
  ],
843
+
810
844
  // 要加载的插件列表
811
845
  plugins: [
812
- 'icqq',
813
- 'process',
846
+ 'adapter-process',
847
+ 'http',
848
+ 'console',
814
849
  'test-plugin'
815
850
  ],
816
851
 
817
852
  // 调试模式
818
853
  debug: env.DEBUG === 'true'
819
- }
820
- })
854
+ };
855
+ });
821
856
  \`\`\`
822
857
  `;
823
858
  default:
824
859
  throw new Error(`不支持的配置格式: ${format}`);
825
860
  }
861
+ }
862
+
863
+ async function checkIfInWorkspace(): Promise<boolean> {
864
+ let currentDir = process.cwd();
865
+
866
+ while (currentDir !== path.dirname(currentDir)) {
867
+ // 检查 pnpm-workspace.yaml
868
+ const pnpmWorkspacePath = path.join(currentDir, 'pnpm-workspace.yaml');
869
+ if (fs.existsSync(pnpmWorkspacePath)) {
870
+ return true;
871
+ }
872
+
873
+ // 检查 package.json 中的 workspaces 字段
874
+ const packageJsonPath = path.join(currentDir, 'package.json');
875
+ if (fs.existsSync(packageJsonPath)) {
876
+ try {
877
+ const packageJson = fs.readJsonSync(packageJsonPath);
878
+ if (packageJson.workspaces) {
879
+ return true;
880
+ }
881
+ } catch {
882
+ // 忽略错误,继续向上查找
883
+ }
884
+ }
885
+
886
+ currentDir = path.dirname(currentDir);
887
+ }
888
+
889
+ return false;
826
890
  }
@@ -1,7 +1,7 @@
1
1
  import { Command } from 'commander';
2
2
  import { logger } from '../utils/logger.js';
3
3
  import { loadEnvFiles } from '../utils/env.js';
4
- import { spawn, ChildProcess } from 'child_process';
4
+ import { ChildProcess } from 'child_process';
5
5
  import fs from 'fs-extra';
6
6
  import path from 'path';
7
7
  import { startProcess } from '../utils/process.js';