Census.list 文本解析器修复
问题描述
用户报告在角色页面看不到组织,尽管通过 directory 操作可以看到两个组织:
- rolex (RoleX) - 系统组织
- 火花堆栈人工智能有限公司 - 用户创建的组织
根本原因
RoleX 1.1.0 的 census.list 返回的是文本格式的输出,而不是 JSON 结构化数据。原代码期望的是 JSON 格式,导致解析失败。
census.list 输出格式示例
rolex (RoleX)
nuwa (女娲, nvwa) — individual-manager, organization-manager, position-manager
火花堆栈人工智能有限公司
Node全栈工程师 — Node全栈工程师岗位
测试工程师 — 测试工程师岗位
AI系统架构师 — AI系统架构师岗位
UI设计师 — UI设计师岗位
产品经理 — 产品经理岗位
解决方案
1. 添加文本解析器
在 RolexBridge.js 中添加 _parseCensusOutput() 方法,将文本格式转换为结构化 JSON:
_parseCensusOutput(text) {
const result = {
roles: [],
organizations: []
}
// 解析逻辑:
// 1. 识别组织行(无缩进)
// 2. 识别角色行(有缩进,描述包含 manager 等关键词)
// 3. 识别职位行(有缩进,描述是职位说明)
return result
}
2. 区分角色和职位
关键判断逻辑:
- 角色:描述包含多个逗号分隔的职位,或包含 "manager"、"individual"、"organization"、"position" 等关键词
- 职位:描述是职位说明文本(如"Node全栈工程师岗位")
3. 输出结构
{
"roles": [
{
"name": "nuwa",
"org": "rolex (RoleX)",
"position": "individual-manager"
}
],
"organizations": [
{
"name": "rolex (RoleX)",
"members": [
{
"name": "nuwa",
"position": "individual-manager"
}
],
"positions": []
},
{
"name": "火花堆栈人工智能有限公司",
"members": [],
"positions": [
{
"name": "Node全栈工程师",
"description": "Node全栈工程师岗位"
},
...
]
}
]
}
文件改动
1. packages/core/src/rolex/RolexBridge.js
- 修改
directory()方法,调用_parseCensusOutput()解析文本 - 添加
_parseCensusOutput()私有方法
2. apps/desktop/src/main/windows/ResourceListWindow.ts
- 移除
rolex:directoryhandler 中的JSON.parse() - 移除
resources:getV2RoleDatahandler 中的JSON.parse()
3. apps/desktop/src/view/pages/roles-window/index.tsx
- 移除前端的
JSON.parse()
测试结果
解析前(错误)
角色列表包含职位定义:
- nuwa
- Node全栈工程师 ❌ 这是职位,不是角色
- 测试工程师 ❌ 这是职位,不是角色
...
解析后(正确)
角色列表:
- nuwa (rolex (RoleX) - individual-manager) ✅
组织列表:
- rolex (RoleX)
成员: nuwa [individual-manager] ✅
- 火花堆栈人工智能有限公司
职位: Node全栈工程师, 测试工程师, ... ✅
成员: (空,因为还没有任命角色到职位)
为什么看不到"火花堆栈人工智能有限公司"组织?
原因:该组织没有成员!
虽然组织定义了 5 个职位,但还没有任命任何角色到这些职位。树状列表只显示有成员的组织。
如何让组织显示在列表中?
需要任命角色到职位:
// 1. 创建一个新角色(或使用现有角色)
// 假设已有角色 "alice"
// 2. 任命角色到职位
{
"operation": "require",
"role": "nuwa",
"orgName": "火花堆栈人工智能有限公司",
"position": "Node全栈工程师",
"individual": "alice"
}
任命后,census.list 输出会变成:
火花堆栈人工智能有限公司
alice — Node全栈工程师
Node全栈工程师 — Node全栈工程师岗位
...
此时解析器会识别:
alice是角色(因为描述是职位名称,不是职位说明)Node全栈工程师是职位定义
下一步
- 重启 PromptX Desktop
- 打开角色窗口
- 切换到 V2 Rolex 标签
- 应该能看到 "rolex (RoleX)" 组织,展开后看到 nuwa
- 任命角色到"火花堆栈人工智能有限公司"的职位
- 刷新后应该能看到该组织
调试命令
查看解析后的目录数据
window.electronAPI?.invoke("rolex:directory", {}).then(result => {
console.log('Directory:', result.data)
console.log('Organizations:', result.data.organizations)
console.log('Roles:', result.data.roles)
})
查看原始 census.list 输出
通过 MCP action 工具:
{
"role": "nuwa",
"operation": "directory"
}
注意事项
- 职位 vs 角色:census.list 中同时包含职位定义和角色任命,需要正确区分
- 空组织:没有成员的组织不会显示在树状列表中(这是设计行为)
- 组织名称:包含括号的组织名称(如 "rolex (RoleX)")会被完整保留
- 多职位角色:如果角色担任多个职位,只显示第一个职位
已知限制
- 解析启发式:使用关键词判断是否为角色,可能在某些边缘情况下误判
- 职位描述格式:假设职位描述不包含逗号和 manager 等关键词
- 文本格式依赖:依赖 census.list 的固定文本格式,如果 RoleX 更新格式可能需要调整解析器
改进建议
如果 RoleX 未来提供结构化 API(返回 JSON),应该:
- 优先使用结构化 API
- 保留文本解析器作为后备方案
- 添加版本检测逻辑