px2cc 1.1.0 → 1.1.1

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 (2) hide show
  1. package/cli.js +63 -35
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -13,45 +13,53 @@ import path from 'path';
13
13
  import fs from 'fs';
14
14
  import { execSync } from 'child_process';
15
15
 
16
- // 获取所有可用工具
17
- async function discoverAllTools() {
18
- const tools = {
16
+ // 发现MCP服务器
17
+ async function discoverMCPServers() {
18
+ const servers = {
19
19
  defaultTools: ['Read', 'Write', 'Edit', 'Bash'],
20
- mcpTools: []
20
+ mcpServers: []
21
21
  };
22
22
 
23
23
  try {
24
- // 使用claude mcp命令获取所有可用工具
25
- const mcpOutput = execSync('claude mcp list-tools', {
24
+ // 使用claude mcp list获取所有MCP服务器
25
+ const mcpOutput = execSync('claude mcp list', {
26
26
  encoding: 'utf8',
27
27
  timeout: 10000
28
28
  });
29
29
 
30
- // 解析输出,提取工具名称
30
+ // 解析输出,提取服务器信息
31
31
  const lines = mcpOutput.split('\n');
32
+
32
33
  for (const line of lines) {
33
34
  const trimmedLine = line.trim();
34
- // 匹配工具名称格式(通常以mcp__开头)
35
- if (trimmedLine.startsWith('mcp__') || trimmedLine.includes('__')) {
36
- tools.mcpTools.push(trimmedLine.split(/\s+/)[0]);
35
+ // 匹配服务器名称(格式:serverName: command - status)
36
+ const match = trimmedLine.match(/^([^:]+):\s+(.+)\s+-\s+(✓|✗)\s+(.*)$/);
37
+ if (match && !trimmedLine.includes('Checking MCP server health')) {
38
+ const [, name, command, status, statusText] = match;
39
+ servers.mcpServers.push({
40
+ name: name.trim(),
41
+ command: command.trim(),
42
+ connected: status === '✓',
43
+ status: statusText.trim()
44
+ });
37
45
  }
38
46
  }
39
47
 
40
- console.log(chalk.green(`✅ 发现 ${tools.mcpTools.length} 个MCP工具`));
48
+ console.log(chalk.green(`✅ 发现 ${servers.mcpServers.length} 个MCP服务器`));
41
49
 
42
50
  } catch (error) {
43
- console.log(chalk.yellow('⚠️ 无法获取MCP工具列表,使用默认配置'));
51
+ console.log(chalk.yellow('⚠️ 无法获取MCP服务器列表,使用默认配置'));
44
52
  console.log(chalk.gray(` 原因: ${error.message}`));
45
53
  }
46
54
 
47
- return tools;
55
+ return servers;
48
56
  }
49
57
 
50
- // 显示工具选择界面
51
- async function selectTools(roleName, availableTools) {
58
+ // 显示MCP服务器选择界面
59
+ async function selectMCPServers(roleName, availableServers) {
52
60
  const choices = [
53
- new inquirer.Separator(chalk.green('🔧 默认工具(必选)')),
54
- ...availableTools.defaultTools.map(tool => ({
61
+ new inquirer.Separator(chalk.green('🔧 默认工具(已包含)')),
62
+ ...availableServers.defaultTools.map(tool => ({
55
63
  name: `✓ ${tool}`,
56
64
  value: tool,
57
65
  checked: true,
@@ -59,25 +67,31 @@ async function selectTools(roleName, availableTools) {
59
67
  }))
60
68
  ];
61
69
 
62
- if (availableTools.mcpTools.length > 0) {
70
+ if (availableServers.mcpServers.length > 0) {
63
71
  choices.push(
64
- new inquirer.Separator(chalk.blue('🛠️ MCP工具(可选)')),
65
- ...availableTools.mcpTools.map(tool => ({
66
- name: tool,
67
- value: tool,
68
- checked: tool.includes('promptx') // PromptX工具默认选中
69
- }))
72
+ new inquirer.Separator(chalk.blue('🛠️ MCP服务器(选择后将获得该服务器的所有工具权限)'))
70
73
  );
74
+
75
+ for (const server of availableServers.mcpServers) {
76
+ const statusIcon = server.connected ? '✓' : '✗';
77
+ const statusColor = server.connected ? chalk.green : chalk.red;
78
+ choices.push({
79
+ name: `${statusColor(statusIcon)} ${server.name} ${chalk.gray(`(${server.status})`)}`,
80
+ value: server.name,
81
+ checked: server.name.includes('promptx'), // PromptX服务器默认选中
82
+ disabled: !server.connected ? '(未连接)' : false
83
+ });
84
+ }
71
85
  }
72
86
 
73
87
  const answer = await inquirer.prompt([{
74
88
  type: 'checkbox',
75
- name: 'selectedTools',
76
- message: `为 ${roleName} 选择可用工具:`,
89
+ name: 'selectedItems',
90
+ message: `为 ${roleName} 选择工具和服务器:`,
77
91
  choices: choices,
78
92
  validate: (input) => {
79
93
  // 确保包含所有默认工具
80
- const hasAllDefaults = availableTools.defaultTools.every(tool => input.includes(tool));
94
+ const hasAllDefaults = availableServers.defaultTools.every(tool => input.includes(tool));
81
95
  if (!hasAllDefaults) {
82
96
  return '必须包含所有默认工具';
83
97
  }
@@ -85,7 +99,21 @@ async function selectTools(roleName, availableTools) {
85
99
  }
86
100
  }]);
87
101
 
88
- return answer.selectedTools;
102
+ // 分离默认工具和选中的服务器
103
+ const selectedTools = availableServers.defaultTools.slice(); // 始终包含默认工具
104
+ const selectedServers = [];
105
+
106
+ for (const item of answer.selectedItems) {
107
+ if (availableServers.defaultTools.includes(item)) {
108
+ continue; // 默认工具已经包含
109
+ } else {
110
+ selectedServers.push(item);
111
+ // 为选中的服务器添加通配符权限
112
+ selectedTools.push(`mcp__${item}__*`);
113
+ }
114
+ }
115
+
116
+ return selectedTools;
89
117
  }
90
118
 
91
119
  // 获取PromptX角色
@@ -112,7 +140,7 @@ function showWelcome() {
112
140
  }
113
141
 
114
142
  // 显示角色选择菜单
115
- async function showRoleMenu(systemRoles, userRoles, availableTools) {
143
+ async function showRoleMenu(systemRoles, userRoles, availableServers) {
116
144
  const choices = [
117
145
  ...systemRoles.map(role => ({
118
146
  name: `📦 ${role.id} ${chalk.gray('(系统角色)')}`,
@@ -166,8 +194,8 @@ async function showRoleMenu(systemRoles, userRoles, availableTools) {
166
194
 
167
195
  let selectedTools = [];
168
196
  if (typeAnswer.confirm) {
169
- // 选择工具
170
- selectedTools = await selectTools(roleAnswer.selectedRole.role, availableTools);
197
+ // 选择MCP服务器和工具
198
+ selectedTools = await selectMCPServers(roleAnswer.selectedRole.role, availableServers);
171
199
  }
172
200
 
173
201
  return {
@@ -263,9 +291,9 @@ async function main() {
263
291
  try {
264
292
  showWelcome();
265
293
 
266
- // 发现可用工具
267
- console.log(chalk.cyan('🔍 正在发现可用工具...\n'));
268
- const availableTools = await discoverAllTools();
294
+ // 发现MCP服务器
295
+ console.log(chalk.cyan('🔍 正在发现MCP服务器...\n'));
296
+ const availableServers = await discoverMCPServers();
269
297
 
270
298
  // 加载角色
271
299
  console.log(chalk.cyan('🔍 正在从PromptX系统加载角色...\n'));
@@ -275,7 +303,7 @@ async function main() {
275
303
  console.log(`📊 发现 ${chalk.bold(systemRoles.length)} 个系统角色,${chalk.bold(userRoles.length)} 个用户角色\n`);
276
304
 
277
305
  // 显示角色选择
278
- const { selectedRole, installType, confirm, selectedTools } = await showRoleMenu(systemRoles, userRoles, availableTools);
306
+ const { selectedRole, installType, confirm, selectedTools } = await showRoleMenu(systemRoles, userRoles, availableServers);
279
307
 
280
308
  if (!confirm) {
281
309
  console.log(chalk.yellow('\n👋 安装已取消'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "px2cc",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "CLI tool to quickly install PromptX roles into Claude Code as agents or commands",
5
5
  "main": "cli.js",
6
6
  "type": "module",