px2cc 1.1.0 → 2.0.0

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/cli.js CHANGED
@@ -7,85 +7,117 @@
7
7
 
8
8
  import { resource } from '@promptx/core';
9
9
  import { ClaudeCodeBuilder } from 'claude-code-builder';
10
+ import { PromptXActionProcessor } from './src/PromptXActionProcessor.js';
10
11
  import inquirer from 'inquirer';
11
12
  import chalk from 'chalk';
12
13
  import path from 'path';
13
14
  import fs from 'fs';
14
15
  import { execSync } from 'child_process';
15
16
 
16
- // 获取所有可用工具
17
- async function discoverAllTools() {
18
- const tools = {
17
+ // 注意:原有的parsePromptXRole函数已被PromptXActionProcessor替代
18
+ // 新的处理器实现完整的PromptX Action流程,包括:
19
+ // 1. RoleLoader - 加载角色定义
20
+ // 2. DependencyAnalyzer - 分析资源依赖
21
+ // 3. CognitionLoader - 加载认知网络
22
+ // 4. LayerAssembler - 三层内容组装
23
+
24
+ // 发现MCP服务器
25
+ async function discoverMCPServers() {
26
+ const servers = {
19
27
  defaultTools: ['Read', 'Write', 'Edit', 'Bash'],
20
- mcpTools: []
28
+ mcpServers: []
21
29
  };
22
30
 
23
31
  try {
24
- // 使用claude mcp命令获取所有可用工具
25
- const mcpOutput = execSync('claude mcp list-tools', {
32
+ console.log(chalk.gray(' 检查MCP服务器状态(可能需要一些时间)...'));
33
+ // 使用claude mcp list获取所有MCP服务器(增加超时时间)
34
+ const mcpOutput = execSync('claude mcp list', {
26
35
  encoding: 'utf8',
27
- timeout: 10000
36
+ timeout: 30000 // 增加到30秒
28
37
  });
29
38
 
30
- // 解析输出,提取工具名称
39
+ // 解析输出,提取服务器信息
31
40
  const lines = mcpOutput.split('\n');
41
+
32
42
  for (const line of lines) {
33
43
  const trimmedLine = line.trim();
34
- // 匹配工具名称格式(通常以mcp__开头)
35
- if (trimmedLine.startsWith('mcp__') || trimmedLine.includes('__')) {
36
- tools.mcpTools.push(trimmedLine.split(/\s+/)[0]);
44
+ // 匹配服务器名称(格式:serverName: command - status)
45
+ const match = trimmedLine.match(/^([^:]+):\s+(.+)\s+-\s+(✓|✗)\s+(.*)$/);
46
+ if (match && !trimmedLine.includes('Checking MCP server health')) {
47
+ const [, name, command, status, statusText] = match;
48
+ servers.mcpServers.push({
49
+ name: name.trim(),
50
+ command: command.trim(),
51
+ connected: status === '✓',
52
+ status: statusText.trim()
53
+ });
37
54
  }
38
55
  }
39
56
 
40
- console.log(chalk.green(`✅ 发现 ${tools.mcpTools.length} 个MCP工具`));
57
+ console.log(chalk.green(`✅ 发现 ${servers.mcpServers.length} 个MCP服务器`));
41
58
 
42
59
  } catch (error) {
43
- console.log(chalk.yellow('⚠️ 无法获取MCP工具列表,使用默认配置'));
44
- console.log(chalk.gray(` 原因: ${error.message}`));
60
+ if (error.code === 'ETIMEDOUT') {
61
+ console.error(chalk.red('❌ MCP服务器检查超时'));
62
+ console.error(chalk.gray(' 请检查网络连接或MCP服务器配置'));
63
+ } else {
64
+ console.error(chalk.red('❌ 无法获取MCP服务器列表'));
65
+ console.error(chalk.gray(` 原因: ${error.message}`));
66
+ }
67
+ throw error;
45
68
  }
46
69
 
47
- return tools;
70
+ return servers;
48
71
  }
49
72
 
50
- // 显示工具选择界面
51
- async function selectTools(roleName, availableTools) {
52
- const choices = [
53
- new inquirer.Separator(chalk.green('🔧 默认工具(必选)')),
54
- ...availableTools.defaultTools.map(tool => ({
55
- name: `✓ ${tool}`,
56
- value: tool,
57
- checked: true,
58
- disabled: '(必需)'
59
- }))
60
- ];
73
+ // 显示MCP服务器选择界面
74
+ async function selectMCPServers(roleName, availableServers) {
75
+ // 如果没有MCP服务器,直接返回undefined(继承所有工具)
76
+ if (availableServers.mcpServers.length === 0) {
77
+ console.log(chalk.gray(' 没有发现MCP服务器,将继承所有可用工具'));
78
+ return undefined;
79
+ }
61
80
 
62
- if (availableTools.mcpTools.length > 0) {
63
- 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
- }))
70
- );
81
+ // 只显示MCP服务器选择
82
+ const choices = [];
83
+
84
+ for (const server of availableServers.mcpServers) {
85
+ const statusIcon = server.connected ? '✓' : '✗';
86
+ const statusColor = server.connected ? chalk.green : chalk.red;
87
+ choices.push({
88
+ name: `${statusColor(statusIcon)} ${server.name} ${chalk.gray(`(${server.status})`)}`,
89
+ value: server.name,
90
+ checked: false, // 默认不选中任何MCP服务器
91
+ disabled: !server.connected ? '(未连接)' : false
92
+ });
71
93
  }
72
94
 
95
+ console.log(chalk.blue('\n🔧 默认工具(自动包含):'), availableServers.defaultTools.join(', '));
96
+
73
97
  const answer = await inquirer.prompt([{
74
98
  type: 'checkbox',
75
- name: 'selectedTools',
76
- message: `为 ${roleName} 选择可用工具:`,
77
- choices: choices,
78
- validate: (input) => {
79
- // 确保包含所有默认工具
80
- const hasAllDefaults = availableTools.defaultTools.every(tool => input.includes(tool));
81
- if (!hasAllDefaults) {
82
- return '必须包含所有默认工具';
83
- }
84
- return true;
85
- }
99
+ name: 'selectedServers',
100
+ message: `为 ${roleName} 选择额外的MCP服务器(可选):`,
101
+ choices: choices
86
102
  }]);
87
103
 
88
- return answer.selectedTools;
104
+ // 处理选中的MCP服务器
105
+ const selectedMCPServers = answer.selectedServers || [];
106
+
107
+ if (selectedMCPServers.length === 0) {
108
+ console.log(chalk.gray(' 将继承所有可用工具(Claude Code默认行为)'));
109
+ return undefined; // Claude Code会继承所有工具
110
+ }
111
+
112
+ // 如果选择了特定服务器,只包含默认工具+选中服务器的工具
113
+ const selectedTools = availableServers.defaultTools.slice();
114
+ for (const serverName of selectedMCPServers) {
115
+ // 添加该服务器的所有工具(使用通配符或具体工具名)
116
+ selectedTools.push(`mcp__${serverName}__*`);
117
+ }
118
+
119
+ console.log(chalk.blue(` 已选择 ${selectedMCPServers.length} 个MCP服务器: ${selectedMCPServers.join(', ')}`));
120
+ return selectedTools;
89
121
  }
90
122
 
91
123
  // 获取PromptX角色
@@ -112,7 +144,7 @@ function showWelcome() {
112
144
  }
113
145
 
114
146
  // 显示角色选择菜单
115
- async function showRoleMenu(systemRoles, userRoles, availableTools) {
147
+ async function showRoleMenu(systemRoles, userRoles, availableServers) {
116
148
  const choices = [
117
149
  ...systemRoles.map(role => ({
118
150
  name: `📦 ${role.id} ${chalk.gray('(系统角色)')}`,
@@ -166,8 +198,8 @@ async function showRoleMenu(systemRoles, userRoles, availableTools) {
166
198
 
167
199
  let selectedTools = [];
168
200
  if (typeAnswer.confirm) {
169
- // 选择工具
170
- selectedTools = await selectTools(roleAnswer.selectedRole.role, availableTools);
201
+ // 选择MCP服务器和工具
202
+ selectedTools = await selectMCPServers(roleAnswer.selectedRole.role, availableServers);
171
203
  }
172
204
 
173
205
  return {
@@ -199,27 +231,31 @@ async function installRole(selectedRole, installType, claudeDir, manager, select
199
231
  const results = {};
200
232
 
201
233
  try {
202
- // 1. 从PromptX加载角色内容
203
- console.log(chalk.cyan(`📖 加载 ${roleName} 角色定义...`));
204
- const roleContent = await manager.loadResource(`@role://${roleName}`);
234
+ // 使用新的PromptXActionProcessor执行完整的action流程
235
+ const processor = new PromptXActionProcessor();
236
+ const mode = installType === 'agents' ? 'subagent' : 'command';
237
+ const processedContent = await processor.processRole(roleName, mode);
205
238
 
206
- if (!roleContent || !roleContent.content) {
207
- throw new Error(`无法加载角色 ${roleName} 的内容`);
208
- }
209
-
210
- // 2. 根据安装目录创建相应文件
239
+ // 根据安装模式创建相应文件
211
240
  if (installType === 'agents') {
212
- console.log(chalk.cyan(`🔧 生成 ${roleName} agent文件...`));
213
- const subagentResult = await ClaudeCodeBuilder.createSubagent({
241
+ console.log(chalk.cyan(`🔧 生成 ${roleName} subagent文件...`));
242
+ const agentConfig = {
214
243
  name: roleName,
215
- description: `基于PromptX ${roleName}角色的专业AI助手`,
216
- content: roleContent.content,
217
- tools: selectedTools,
244
+ description: `基于PromptX ${roleName}角色的专业AI助手 - 完整action实现`,
245
+ content: processedContent,
218
246
  targetDir: claudeDir
219
- });
247
+ };
248
+
249
+ // 设置工具配置 - 如果用户没有选择特定工具,则继承所有可用工具
250
+ if (selectedTools) {
251
+ agentConfig.tools = selectedTools;
252
+ }
253
+ // 如果没有选择特定工具,Claude Code会自动继承所有可用工具
254
+
255
+ const subagentResult = await ClaudeCodeBuilder.createSubagent(agentConfig);
220
256
 
221
257
  if (!subagentResult.success) {
222
- throw new Error(`创建Agent失败: ${subagentResult.error}`);
258
+ throw new Error(`创建Subagent失败: ${subagentResult.error}`);
223
259
  }
224
260
  results.agentFile = `${roleName}.md`;
225
261
  results.usage = `/subagent ${roleName}`;
@@ -227,20 +263,21 @@ async function installRole(selectedRole, installType, claudeDir, manager, select
227
263
 
228
264
  if (installType === 'commands') {
229
265
  console.log(chalk.cyan(`📋 生成 ${roleName} command文件...`));
230
- const commandContent = `# ${roleName}
231
- 基于PromptX ${roleName}角色的专业助手。
232
-
233
- ${roleContent.content}
234
-
235
- 现在开始处理用户需求。`;
236
-
237
- const commandResult = await ClaudeCodeBuilder.createCommand({
266
+
267
+ const commandConfig = {
238
268
  name: roleName,
239
- description: `基于PromptX ${roleName}角色的专业助手`,
240
- content: commandContent,
241
- allowedTools: selectedTools,
269
+ description: `基于PromptX ${roleName}角色的专业助手 - 完整action实现`,
270
+ content: processedContent,
242
271
  targetDir: claudeDir
243
- });
272
+ };
273
+
274
+ // 设置工具配置 - 如果用户没有选择特定工具,则继承所有可用工具
275
+ if (selectedTools) {
276
+ commandConfig.allowedTools = selectedTools;
277
+ }
278
+ // 如果没有选择特定工具,Claude Code会自动继承所有可用工具
279
+
280
+ const commandResult = await ClaudeCodeBuilder.createCommand(commandConfig);
244
281
 
245
282
  if (!commandResult.success) {
246
283
  throw new Error(`创建Command失败: ${commandResult.error}`);
@@ -263,9 +300,21 @@ async function main() {
263
300
  try {
264
301
  showWelcome();
265
302
 
266
- // 发现可用工具
267
- console.log(chalk.cyan('🔍 正在发现可用工具...\n'));
268
- const availableTools = await discoverAllTools();
303
+ // 检查是否跳过MCP发现(用于快速测试)
304
+ const skipMCP = process.argv.includes('--skip-mcp');
305
+
306
+ let availableServers;
307
+ if (skipMCP) {
308
+ console.log(chalk.yellow('⚠️ 跳过MCP发现(测试模式)'));
309
+ availableServers = {
310
+ defaultTools: ['Read', 'Write', 'Edit', 'Bash'],
311
+ mcpServers: []
312
+ };
313
+ } else {
314
+ // 发现MCP服务器
315
+ console.log(chalk.cyan('🔍 正在发现MCP服务器...\n'));
316
+ availableServers = await discoverMCPServers();
317
+ }
269
318
 
270
319
  // 加载角色
271
320
  console.log(chalk.cyan('🔍 正在从PromptX系统加载角色...\n'));
@@ -275,7 +324,7 @@ async function main() {
275
324
  console.log(`📊 发现 ${chalk.bold(systemRoles.length)} 个系统角色,${chalk.bold(userRoles.length)} 个用户角色\n`);
276
325
 
277
326
  // 显示角色选择
278
- const { selectedRole, installType, confirm, selectedTools } = await showRoleMenu(systemRoles, userRoles, availableTools);
327
+ const { selectedRole, installType, confirm, selectedTools } = await showRoleMenu(systemRoles, userRoles, availableServers);
279
328
 
280
329
  if (!confirm) {
281
330
  console.log(chalk.yellow('\n👋 安装已取消'));
@@ -314,6 +363,9 @@ async function main() {
314
363
  }
315
364
 
316
365
  // 运行主程序
317
- if (import.meta.url === `file://${process.argv[1]}`) {
318
- main();
366
+ if (import.meta.url === new URL(process.argv[1], 'file:').href) {
367
+ main().catch(error => {
368
+ console.error(chalk.red('❌ 程序异常:'), error.message);
369
+ process.exit(1);
370
+ });
319
371
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "px2cc",
3
- "version": "1.1.0",
4
- "description": "CLI tool to quickly install PromptX roles into Claude Code as agents or commands",
3
+ "version": "2.0.0",
4
+ "description": "CLI tool that implements complete PromptX Action flow in Claude Code - role activation, dependency loading, cognition networks & memory systems",
5
5
  "main": "cli.js",
6
6
  "type": "module",
7
7
  "bin": {
@@ -22,6 +22,7 @@
22
22
  "files": [
23
23
  "cli.js",
24
24
  "bin.js",
25
+ "src/",
25
26
  "README.md",
26
27
  "package.json"
27
28
  ],
@@ -0,0 +1,490 @@
1
+ /**
2
+ * PromptXActionProcessor - 实现完整的PromptX Action流程
3
+ *
4
+ * 替代简单的parsePromptXRole函数,实现:
5
+ * 1. 角色加载器 (RoleLoader)
6
+ * 2. 依赖分析器 (DependencyAnalyzer)
7
+ * 3. 认知网络加载器 (CognitionLoader)
8
+ * 4. 三层组装器 (LayerAssembler)
9
+ */
10
+
11
+ import { resource } from '@promptx/core';
12
+ import fs from 'fs/promises';
13
+ import path from 'path';
14
+ import os from 'os';
15
+ import chalk from 'chalk';
16
+
17
+ /**
18
+ * 角色加载器 - 替代PromptX的ResourceManager
19
+ */
20
+ class RoleLoader {
21
+ constructor(resourceManager) {
22
+ this.resourceManager = resourceManager;
23
+ }
24
+
25
+ /**
26
+ * 加载角色定义
27
+ * @param {string} roleId - 角色ID
28
+ * @returns {Object} 角色信息
29
+ */
30
+ async loadRole(roleId) {
31
+ console.log(chalk.cyan(`📖 加载角色定义: ${roleId}`));
32
+
33
+ try {
34
+ // 确保ResourceManager已初始化
35
+ if (!this.resourceManager.initialized) {
36
+ await this.resourceManager.initializeWithNewArchitecture();
37
+ }
38
+
39
+ // 加载角色资源
40
+ const result = await this.resourceManager.loadResource(`@role://${roleId}`);
41
+
42
+ if (!result || !result.success || !result.content) {
43
+ throw new Error(`无法加载角色 ${roleId} 的内容`);
44
+ }
45
+
46
+ // 解析DPML内容
47
+ const parsedContent = this.parseDPMLContent(result.content);
48
+
49
+ return {
50
+ id: roleId,
51
+ raw: result.content,
52
+ sections: parsedContent,
53
+ metadata: result.metadata || {}
54
+ };
55
+
56
+ } catch (error) {
57
+ console.error(chalk.red(`❌ 角色加载失败: ${error.message}`));
58
+ throw error;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * 解析DPML角色文档
64
+ * @param {string} content - 原始内容
65
+ * @returns {Object} 解析后的sections
66
+ */
67
+ parseDPMLContent(content) {
68
+ const sections = {};
69
+
70
+ // 解析 <role> 标签
71
+ const roleMatch = content.match(/<role>([\s\S]*?)<\/role>/);
72
+ if (roleMatch) {
73
+ const roleContent = roleMatch[1];
74
+
75
+ // 提取各个部分
76
+ sections.personality = this.extractSection(roleContent, 'personality');
77
+ sections.principle = this.extractSection(roleContent, 'principle');
78
+ sections.knowledge = this.extractSection(roleContent, 'knowledge');
79
+ }
80
+
81
+ return sections;
82
+ }
83
+
84
+ /**
85
+ * 提取XML标签内容
86
+ * @param {string} content - 内容
87
+ * @param {string} tagName - 标签名
88
+ * @returns {string|null} 提取的内容
89
+ */
90
+ extractSection(content, tagName) {
91
+ const regex = new RegExp(`<${tagName}>([\\s\\S]*?)<\\/${tagName}>`, 'i');
92
+ const match = content.match(regex);
93
+ return match ? match[1].trim() : null;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * 依赖分析器 - 分析和加载资源依赖
99
+ */
100
+ class DependencyAnalyzer {
101
+ constructor(resourceManager) {
102
+ this.resourceManager = resourceManager;
103
+ }
104
+
105
+ /**
106
+ * 分析角色依赖
107
+ * @param {Object} roleInfo - 角色信息
108
+ * @returns {Object} 依赖资源
109
+ */
110
+ async analyzeDependencies(roleInfo) {
111
+ console.log(chalk.cyan(`🔍 分析资源依赖...`));
112
+
113
+ const dependencies = {
114
+ thoughts: [],
115
+ executions: [],
116
+ knowledges: []
117
+ };
118
+
119
+ if (!roleInfo.sections) {
120
+ return dependencies;
121
+ }
122
+
123
+ // 收集所有资源引用
124
+ const allRefs = this.extractResourceReferences(roleInfo.sections);
125
+
126
+ console.log(chalk.gray(` 发现 ${allRefs.length} 个资源引用`));
127
+
128
+ // 并发加载所有依赖
129
+ const loadPromises = allRefs.map(ref => this.loadDependency(ref));
130
+ const results = await Promise.allSettled(loadPromises);
131
+
132
+ // 分类处理结果
133
+ results.forEach((result, index) => {
134
+ if (result.status === 'fulfilled' && result.value) {
135
+ const ref = allRefs[index];
136
+ const content = result.value;
137
+
138
+ switch (ref.protocol) {
139
+ case 'thought':
140
+ dependencies.thoughts.push({ id: ref.resource, content });
141
+ break;
142
+ case 'execution':
143
+ dependencies.executions.push({ id: ref.resource, content });
144
+ break;
145
+ case 'knowledge':
146
+ dependencies.knowledges.push({ id: ref.resource, content });
147
+ break;
148
+ }
149
+ }
150
+ });
151
+
152
+ console.log(chalk.green(`✅ 依赖分析完成: thoughts=${dependencies.thoughts.length}, executions=${dependencies.executions.length}, knowledges=${dependencies.knowledges.length}`));
153
+
154
+ return dependencies;
155
+ }
156
+
157
+ /**
158
+ * 提取资源引用
159
+ * @param {Object} sections - 角色sections
160
+ * @returns {Array} 引用列表
161
+ */
162
+ extractResourceReferences(sections) {
163
+ const refs = [];
164
+
165
+ const extractFromText = (text) => {
166
+ if (!text) return [];
167
+ // 匹配 @protocol://resource 格式
168
+ const matches = text.matchAll(/@([^:]+):\/\/([^\\s\\>\\<]+)/g);
169
+ return Array.from(matches).map(match => ({
170
+ protocol: match[1],
171
+ resource: match[2]
172
+ }));
173
+ };
174
+
175
+ // 从所有sections中提取引用
176
+ Object.values(sections).forEach(section => {
177
+ refs.push(...extractFromText(section));
178
+ });
179
+
180
+ return refs;
181
+ }
182
+
183
+ /**
184
+ * 加载单个依赖
185
+ * @param {Object} ref - 引用对象
186
+ * @returns {Promise<string>} 内容
187
+ */
188
+ async loadDependency(ref) {
189
+ try {
190
+ const resourceUrl = `@${ref.protocol}://${ref.resource}`;
191
+ const result = await this.resourceManager.loadResource(resourceUrl);
192
+
193
+ if (result && result.success && result.content) {
194
+ return result.content;
195
+ }
196
+
197
+ console.warn(chalk.yellow(`⚠️ 无法加载依赖: ${resourceUrl}`));
198
+ return null;
199
+ } catch (error) {
200
+ console.warn(chalk.yellow(`⚠️ 依赖加载失败: @${ref.protocol}://${ref.resource} - ${error.message}`));
201
+ return null;
202
+ }
203
+ }
204
+ }
205
+
206
+ /**
207
+ * 认知网络加载器 - 加载PromptX认知数据
208
+ */
209
+ class CognitionLoader {
210
+ constructor() {
211
+ this.basePath = path.join(os.homedir(), '.promptx', 'cognition');
212
+ }
213
+
214
+ /**
215
+ * 加载认知网络
216
+ * @param {string} roleId - 角色ID
217
+ * @returns {Object} Mind对象和可视化
218
+ */
219
+ async loadCognitionNetwork(roleId) {
220
+ console.log(chalk.cyan(`🧠 加载认知网络: ${roleId}`));
221
+
222
+ try {
223
+ const networkFilePath = path.join(this.basePath, roleId, 'network.json');
224
+
225
+ // 检查文件是否存在
226
+ try {
227
+ await fs.access(networkFilePath);
228
+ } catch (error) {
229
+ console.log(chalk.gray(` 未找到认知网络文件: ${roleId}`));
230
+ return {
231
+ mind: null,
232
+ mindmap: null,
233
+ hasNetwork: false
234
+ };
235
+ }
236
+
237
+ // 读取网络数据
238
+ const networkData = JSON.parse(await fs.readFile(networkFilePath, 'utf8'));
239
+
240
+ // 生成mindmap
241
+ const mindmap = this.generateMindmap(networkData);
242
+
243
+ // 构建Mind对象
244
+ const mind = this.buildMindObject(networkData);
245
+
246
+ console.log(chalk.green(`✅ 认知网络加载成功: ${mind.nodeCount} 个节点, ${mind.connectionCount} 个连接`));
247
+
248
+ return {
249
+ mind,
250
+ mindmap,
251
+ hasNetwork: true,
252
+ networkData
253
+ };
254
+
255
+ } catch (error) {
256
+ console.warn(chalk.yellow(`⚠️ 认知网络加载失败: ${error.message}`));
257
+ return {
258
+ mind: null,
259
+ mindmap: null,
260
+ hasNetwork: false
261
+ };
262
+ }
263
+ }
264
+
265
+ /**
266
+ * 生成Mermaid mindmap
267
+ * @param {Object} networkData - 网络数据
268
+ * @returns {string} mindmap代码
269
+ */
270
+ generateMindmap(networkData) {
271
+ if (!networkData.cues || Object.keys(networkData.cues).length === 0) {
272
+ return 'mindmap\n root((暂无认知数据))';
273
+ }
274
+
275
+ // 找到权重最高的概念作为根节点
276
+ const cues = Object.entries(networkData.cues);
277
+ const rootCue = cues.reduce((max, [word, cue]) => {
278
+ const totalWeight = (cue.connections || []).reduce((sum, conn) => sum + (conn.weight || 0), 0);
279
+ return totalWeight > (max.totalWeight || 0) ? { word, totalWeight } : max;
280
+ }, {});
281
+
282
+ let mindmap = 'mindmap\n';
283
+ mindmap += ` root((${rootCue.word || '认知中心'}))\n`;
284
+
285
+ // 添加相关概念(取权重前10的连接)
286
+ if (rootCue.word && networkData.cues[rootCue.word]?.connections) {
287
+ const connections = networkData.cues[rootCue.word].connections
288
+ .sort((a, b) => (b.weight || 0) - (a.weight || 0))
289
+ .slice(0, 10);
290
+
291
+ connections.forEach(conn => {
292
+ if (conn.target) {
293
+ mindmap += ` ${conn.target}\n`;
294
+ }
295
+ });
296
+ }
297
+
298
+ return mindmap;
299
+ }
300
+
301
+ /**
302
+ * 构建Mind对象
303
+ * @param {Object} networkData - 网络数据
304
+ * @returns {Object} Mind对象
305
+ */
306
+ buildMindObject(networkData) {
307
+ const cues = networkData.cues || {};
308
+ const nodeCount = Object.keys(cues).length;
309
+ let connectionCount = 0;
310
+
311
+ Object.values(cues).forEach(cue => {
312
+ connectionCount += (cue.connections || []).length;
313
+ });
314
+
315
+ return {
316
+ nodeCount,
317
+ connectionCount,
318
+ activatedCues: Object.keys(cues),
319
+ timestamp: networkData.timestamp,
320
+ version: networkData.version
321
+ };
322
+ }
323
+ }
324
+
325
+ /**
326
+ * 三层组装器 - 组装最终输出内容
327
+ */
328
+ class LayerAssembler {
329
+ /**
330
+ * 组装完整内容
331
+ * @param {Object} roleInfo - 角色信息
332
+ * @param {Object} dependencies - 依赖资源
333
+ * @param {Object} cognitionData - 认知数据
334
+ * @param {string} mode - 模式 (command|subagent)
335
+ * @returns {string} 组装后的内容
336
+ */
337
+ assembleContent(roleInfo, dependencies, cognitionData, mode = 'command') {
338
+ const parts = [];
339
+
340
+ // 标题部分
341
+ parts.push(`# 🧠 [Consciousness Prime] ${roleInfo.id}${mode === 'subagent' ? '专业助手' : '角色已激活'}`);
342
+ parts.push('');
343
+
344
+ // CognitionLayer - 认知网络可视化
345
+ if (cognitionData.hasNetwork && cognitionData.mindmap) {
346
+ parts.push('## 💭 Hippocampus网络');
347
+ parts.push('```mermaid');
348
+ parts.push(cognitionData.mindmap);
349
+ parts.push('```');
350
+ parts.push('');
351
+
352
+ if (cognitionData.mind) {
353
+ parts.push(`**网络状态**: ${cognitionData.mind.nodeCount} 个概念节点,${cognitionData.mind.connectionCount} 个关联连接`);
354
+ parts.push('');
355
+ }
356
+ }
357
+
358
+ // RoleLayer - 角色定义
359
+ if (roleInfo.sections.personality) {
360
+ parts.push('## 🎭 角色人格');
361
+ parts.push(this.cleanContent(roleInfo.sections.personality));
362
+ parts.push('');
363
+ }
364
+
365
+ if (roleInfo.sections.principle) {
366
+ parts.push('## 🔧 工作原则');
367
+ parts.push(this.cleanContent(roleInfo.sections.principle));
368
+ parts.push('');
369
+ }
370
+
371
+ if (roleInfo.sections.knowledge) {
372
+ parts.push('## 📚 专业知识');
373
+ parts.push(this.cleanContent(roleInfo.sections.knowledge));
374
+ parts.push('');
375
+ }
376
+
377
+ // 依赖资源
378
+ if (dependencies.thoughts.length > 0) {
379
+ parts.push('## 💡 思维模式');
380
+ dependencies.thoughts.forEach(thought => {
381
+ parts.push(`### ${thought.id}`);
382
+ parts.push(this.cleanContent(thought.content));
383
+ parts.push('');
384
+ });
385
+ }
386
+
387
+ if (dependencies.executions.length > 0) {
388
+ parts.push('## ⚡ 执行技能');
389
+ dependencies.executions.forEach(execution => {
390
+ parts.push(`### ${execution.id}`);
391
+ parts.push(this.cleanContent(execution.content));
392
+ parts.push('');
393
+ });
394
+ }
395
+
396
+ // StateLayer - 状态信息
397
+ parts.push('---');
398
+ parts.push('');
399
+
400
+ if (mode === 'command') {
401
+ parts.push(`🎉 ${roleInfo.id}角色激活完成!我现在以该角色身份为你服务。`);
402
+ } else {
403
+ parts.push('## 🤖 助手说明');
404
+ parts.push(`我是基于PromptX ${roleInfo.id}角色的专业AI助手。我会:`);
405
+ parts.push(`- 始终保持${roleInfo.id}的专业身份和思维模式`);
406
+ parts.push('- 利用完整的PromptX工具生态提供专业服务');
407
+ parts.push('- 在我们的对话过程中持续学习和记忆');
408
+ parts.push('');
409
+ parts.push('请告诉我你需要什么帮助?');
410
+ }
411
+
412
+ parts.push('');
413
+ parts.push('💡 **可用的PromptX工具生态**:');
414
+ parts.push('- 使用PromptX的 `recall` 工具激活相关记忆和经验');
415
+ parts.push('- 使用PromptX的 `remember` 工具保存新的学习成果');
416
+ parts.push('- 使用PromptX的 `learn` 工具学习新的资源和知识');
417
+ parts.push('- 使用PromptX的 `toolx` 工具执行专业工具');
418
+ parts.push('- 具体工具名称取决于你的MCP配置');
419
+ parts.push('');
420
+
421
+ if (mode === 'command') {
422
+ parts.push('现在开始处理用户需求。');
423
+ }
424
+
425
+ return parts.join('\n');
426
+ }
427
+
428
+ /**
429
+ * 清理内容格式
430
+ * @param {string} content - 原始内容
431
+ * @returns {string} 清理后的内容
432
+ */
433
+ cleanContent(content) {
434
+ if (!content) return '';
435
+
436
+ return content
437
+ // 移除PromptX资源引用标签(但保留引用内容的展开结果)
438
+ .replace(/<reference[^>]*>/g, '')
439
+ .replace(/<\/reference>/g, '')
440
+ // 清理多余空行
441
+ .replace(/\n\s*\n\s*\n/g, '\n\n')
442
+ // 移除开头结尾空白
443
+ .trim();
444
+ }
445
+ }
446
+
447
+ /**
448
+ * PromptX Action处理器主类
449
+ */
450
+ export class PromptXActionProcessor {
451
+ constructor() {
452
+ this.resourceManager = resource.getGlobalResourceManager();
453
+ this.roleLoader = new RoleLoader(this.resourceManager);
454
+ this.dependencyAnalyzer = new DependencyAnalyzer(this.resourceManager);
455
+ this.cognitionLoader = new CognitionLoader();
456
+ this.layerAssembler = new LayerAssembler();
457
+ }
458
+
459
+ /**
460
+ * 执行完整的PromptX Action流程
461
+ * @param {string} roleId - 角色ID
462
+ * @param {string} mode - 模式 (command|subagent)
463
+ * @returns {string} 处理后的内容
464
+ */
465
+ async processRole(roleId, mode = 'command') {
466
+ try {
467
+ console.log(chalk.blue(`\n🎭 开始执行 ${roleId} 的 PromptX Action 流程 (${mode} 模式)`));
468
+
469
+ // 1. 加载角色定义
470
+ const roleInfo = await this.roleLoader.loadRole(roleId);
471
+
472
+ // 2. 分析依赖资源
473
+ const dependencies = await this.dependencyAnalyzer.analyzeDependencies(roleInfo);
474
+
475
+ // 3. 加载认知网络
476
+ const cognitionData = await this.cognitionLoader.loadCognitionNetwork(roleId);
477
+
478
+ // 4. 三层组装
479
+ const content = this.layerAssembler.assembleContent(roleInfo, dependencies, cognitionData, mode);
480
+
481
+ console.log(chalk.green(`✅ PromptX Action 流程完成!`));
482
+
483
+ return content;
484
+
485
+ } catch (error) {
486
+ console.error(chalk.red(`❌ PromptX Action 流程失败: ${error.message}`));
487
+ throw error;
488
+ }
489
+ }
490
+ }