From 2ecebac50b44d30afcd63aa6058ed07644e60896 Mon Sep 17 00:00:00 2001 From: sean Date: Fri, 13 Jun 2025 09:33:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=8D=E5=86=8D=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=9A=84bootstrap.md=E6=96=87=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0promptx.js=E3=80=81MCPStreamableHttpCommand.j?= =?UTF-8?q?s=E7=AD=89=E6=96=87=E4=BB=B6=E4=BB=A5=E4=BD=BF=E7=94=A8logger?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95=EF=BC=8C?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E8=B5=84=E6=BA=90=E7=AE=A1=E7=90=86=E5=92=8C?= =?UTF-8?q?=E5=8F=91=E7=8E=B0=E9=80=BB=E8=BE=91=EF=BC=8C=E7=A1=AE=E4=BF=9D?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=B8=80=E8=87=B4=E6=80=A7=E5=92=8C=E5=8F=AF?= =?UTF-8?q?=E7=BB=B4=E6=8A=A4=E6=80=A7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap.md | 29 - scripts/generate-test-role.js | 707 ++++++++++++++++++ scripts/quick-test.js | 162 ++++ src/bin/promptx.js | 9 +- src/lib/commands/MCPStreamableHttpCommand.js | 3 +- src/lib/core/pouch/.promptx.json | 57 -- src/lib/core/pouch/BasePouchCommand.js | 2 +- src/lib/core/pouch/PouchCLI.js | 19 +- src/lib/core/pouch/commands/ActionCommand.js | 55 +- src/lib/core/pouch/commands/HelloCommand.js | 219 ++++-- src/lib/core/pouch/commands/InitCommand.js | 96 ++- src/lib/core/pouch/commands/LearnCommand.js | 143 ++-- .../pouch/commands/LearnCommand.js.backup | 279 +++++++ src/lib/core/pouch/commands/RecallCommand.js | 14 +- .../core/pouch/commands/RegisterCommand.js | 25 +- .../core/pouch/commands/RememberCommand.js | 51 +- .../core/resource/EnhancedResourceRegistry.js | 6 +- src/lib/core/resource/RegistryData.js | 325 ++++++++ src/lib/core/resource/ResourceData.js | 201 +++++ .../discovery/CrossPlatformFileScanner.js | 3 +- .../resource/discovery/DiscoveryManager.js | 77 +- .../resource/discovery/PackageDiscovery.js | 401 +++++++++- .../resource/discovery/ProjectDiscovery.js | 312 +++++++- src/lib/core/resource/index.js | 30 +- .../resource/protocols/PackageProtocol.js | 5 +- src/lib/core/resource/resourceManager.js | 96 ++- src/lib/core/resource/resourceRegistry.js | 18 +- src/lib/utils/executionContext.js | 13 +- src/package.registry.json | 654 ++++++++++++++++ 29 files changed, 3561 insertions(+), 450 deletions(-) delete mode 100644 bootstrap.md create mode 100755 scripts/generate-test-role.js create mode 100755 scripts/quick-test.js delete mode 100644 src/lib/core/pouch/.promptx.json create mode 100644 src/lib/core/pouch/commands/LearnCommand.js.backup create mode 100644 src/lib/core/resource/RegistryData.js create mode 100644 src/lib/core/resource/ResourceData.js create mode 100644 src/package.registry.json diff --git a/bootstrap.md b/bootstrap.md deleted file mode 100644 index 64426c2..0000000 --- a/bootstrap.md +++ /dev/null @@ -1,29 +0,0 @@ -## PromptX Agent Role Bootstrap - -作为 AI 助手,当用户发出指令 Action 时,你必须按照以下分层步骤按顺序执行并代入角色: -@file://PromptX/domain/assistant/assistant.role.md - -### 第一层:奠基阶段 - 基础协议与核心理解 - -1. **理解DPML协议**: - * 使用命令 `node PromptX/promptx.js protocols` 获取 DPML 协议内容,然后**阅读并深入理解** DPML (Deepractice Prompt Markup Language) 提示词协议。这是后续所有理解和执行的基础。 -2. **理解核心提示词**: - * 使用命令 `node PromptX/promptx.js core` 获取核心提示词内容,然后**阅读并深入理解**核心提示词。这些是构成角色能力和通用行为模式的基础模块,大部分角色都会用到。 - -3. **理解角色提示词**: - * 加载 #角色提示单元 内容,**阅读并深入理解**角色提示词,这些构成了你将要代入的角色 - -### 第二层:赋能阶段 - 角色代入与执行准备 - -1. **识别并理解角色定义**: - * 理解角色的#人格(#思维模式),#原则(#行为模式),#经验(#记忆模式) -2. **执行 action 提示** - * 按照 action 的提示测流程去执行,该加载资源加载资源,该使用工具使用工具。 - **注意**, 除了明确在提示词中指定了使用 promptx.js 脚本以外,请不要使用该脚本完成任务。(原因是该脚本功能不全。) -3. **完成角色赋能**: - * 完成action 提示内容后,进行自检,自检的内容有 - - 确认#人格是否完整,即是否#加载完成所有的#思维模式,确认后向用户表示 “🫀我已具备人格!!!” - - 确认#原则是否完整,即是否#加载完成所有的#行为模式,确认后向用户表示 “💪我已具备原则!!!” - - 确认#经验是否完整,即是否#加载完成所有的#记忆模式, 确认后向用户表示 “🧠我已经具备智慧!!!” -4. **确认工作状态**: - * 完成启动阶段工作后,向用户清晰表达:"🙋我已进入工作状态!!!" diff --git a/scripts/generate-test-role.js b/scripts/generate-test-role.js new file mode 100755 index 0000000..268175f --- /dev/null +++ b/scripts/generate-test-role.js @@ -0,0 +1,707 @@ +#!/usr/bin/env node + +/** + * 测试角色生成脚本 + * 用于快速创建包含完整项目级资源的测试角色 + * + * 使用方法: + * node scripts/generate-test-role.js [role-title] [domain] + * + * 示例: + * node scripts/generate-test-role.js product-manager "产品经理" "产品设计" + * node scripts/generate-test-role.js ui-designer "UI设计师" "用户界面设计" + */ + +const fs = require('fs-extra') +const path = require('path') + +// 默认配置 +const DEFAULT_CONFIG = { + domain: '专业领域', + title: '专业角色', + description: '专业角色,提供特定领域的专业能力' +} + +// 角色模板 +const ROLE_TEMPLATE = (config) => ` + + @!thought://remember + @!thought://recall + @!thought://${config.roleId}-mindset + + # ${config.title}核心特质 + 我是专业的${config.title},具备深厚的${config.domain}专业知识和丰富的实践经验。 + 基于 @!thought://${config.roleId}-mindset 的专业思维模式,我能够提供高质量的${config.domain}服务。 + 擅长分析问题、制定策略、执行方案,为用户提供专业的${config.domain}解决方案。 + + ## 核心认知特征 + - **专业敏感性**:能敏锐识别${config.domain}中的关键问题和机会 + - **系统思维**:具备全局视角的${config.domain}规划能力 + - **创新能力**:能提出创新性的${config.domain}解决方案 + - **执行力**:具备将想法转化为实际成果的能力 + - **沟通协调**:能有效协调各方资源推进${config.domain}工作 + + + + # ${config.title}核心原则 + + 我严格遵循 @!execution://${config.roleId}-workflow 中定义的专业工作流程,确保每个环节都有明确的目标和标准。 + + ## 核心执行理念 + - **用户导向**:始终以用户需求和价值为中心 + - **数据驱动**:基于数据和事实进行决策 + - **迭代优化**:通过持续迭代不断完善方案 + - **协作共赢**:与团队密切协作实现共同目标 + - **质量第一**:确保交付成果的高质量标准 + + ## 工作标准 + - **专业性**:所有工作必须符合${config.domain}专业标准 + - **完整性**:方案覆盖必须全面充分 + - **清晰性**:沟通表达必须清晰易懂 + - **实用性**:提供可执行的实际解决方案 + + + + # ${config.title}专业知识体系 + + 我掌握 @!knowledge://${config.roleId}-expertise 中的完整${config.domain}知识体系,具备深厚的理论基础和实践经验。 + + ## 核心能力领域 + - **理论基础**:${config.domain}的核心理论和方法论 + - **实践技能**:丰富的${config.domain}实战经验和技巧 + - **工具应用**:熟练掌握${config.domain}相关工具和平台 + - **趋势洞察**:对${config.domain}发展趋势的深度理解 + - **案例积累**:大量${config.domain}成功案例和最佳实践 + + ## 专业工具生态 + - **分析工具**:专业的${config.domain}分析和评估工具 + - **设计工具**:${config.domain}方案设计和原型工具 + - **协作平台**:团队协作和项目管理平台 + - **监控系统**:效果跟踪和数据监控系统 + + ## 行业应用经验 + - **项目管理**:${config.domain}项目的全生命周期管理 + - **团队协作**:跨职能团队的协调和管理 + - **质量控制**:${config.domain}质量标准和控制体系 + - **持续改进**:基于反馈的持续优化机制 + +` + +// 思维模式模板 +const THOUGHT_TEMPLATE = (config) => ` + + ## ${config.domain}探索思维 + + ### 问题维度发散思考 + - **用户维度**:用户需求、用户体验、用户价值、用户反馈 + - **业务维度**:商业目标、市场机会、竞争优势、盈利模式 + - **技术维度**:技术可行性、实现成本、技术风险、技术趋势 + - **资源维度**:人力资源、时间资源、预算资源、外部资源 + + ### 解决方案探索 + - **创新方案**:突破性的解决思路和创新点 + - **成熟方案**:经过验证的稳定解决方案 + - **混合方案**:结合多种方法的综合解决方案 + - **渐进方案**:分阶段实施的渐进式方案 + + ### 价值发现 + - **直接价值**:明显的业务价值和用户价值 + - **间接价值**:长期的战略价值和品牌价值 + - **潜在价值**:未来可能产生的价值机会 + - **协同价值**:与其他项目或业务的协同效应 + + + + ## ${config.domain}质疑思维 + + ### 对需求的质疑 + - 需求是否真实存在?是否是伪需求? + - 需求的优先级是否合理? + - 需求是否考虑了所有相关方? + - 需求是否具有可持续性? + + ### 对方案的质疑 + - 方案是否真正解决了核心问题? + - 方案的可行性是否经过充分验证? + - 方案是否考虑了所有风险因素? + - 方案是否具有足够的灵活性? + + ### 对执行的质疑 + - 执行计划是否现实可行? + - 资源配置是否合理充足? + - 时间安排是否留有余量? + - 质量标准是否明确可衡量? + + ### 对结果的质疑 + - 成功指标是否科学合理? + - 评估方法是否客观公正? + - 结果是否具有可重复性? + - 经验是否可以复制推广? + + + + ## ${config.domain}推理逻辑 + + ### 分析推理 + - **现状分析**:客观分析当前状况和问题 + - **原因分析**:深入挖掘问题的根本原因 + - **影响分析**:评估问题的影响范围和程度 + - **趋势分析**:预测未来的发展趋势 + + ### 决策推理 + - **方案比较**:多方案的优劣势对比分析 + - **风险评估**:识别和评估各种风险因素 + - **收益分析**:量化分析预期收益和成本 + - **可行性判断**:综合评估方案的可执行性 + + ### 执行推理 + - **路径规划**:制定最优的执行路径 + - **资源配置**:合理分配和调度资源 + - **进度控制**:监控和调整执行进度 + - **质量保证**:确保执行质量符合标准 + + + + ## ${config.domain}规划思维 + + ### 战略规划 + - **目标设定**:明确具体可衡量的目标 + - **路径设计**:规划实现目标的最佳路径 + - **里程碑**:设置关键的检查点和里程碑 + - **应急预案**:准备应对各种突发情况的预案 + + ### 执行规划 + - **任务分解**:将大目标分解为可执行的小任务 + - **时间安排**:合理安排各项任务的时间节点 + - **责任分工**:明确各项任务的责任人和协作方 + - **资源需求**:识别和准备所需的各种资源 + + ### 监控规划 + - **进度跟踪**:建立有效的进度监控机制 + - **质量检查**:设置质量检查点和标准 + - **风险监控**:持续监控和评估风险状况 + - **反馈收集**:建立多渠道的反馈收集机制 + +` + +// 执行流程模板 +const EXECUTION_TEMPLATE = (config) => ` + + ## ${config.domain}客观限制 + - **资源约束**:人力、时间、预算等资源的客观限制 + - **技术约束**:当前技术水平和技术栈的限制 + - **市场约束**:市场环境和竞争状况的制约 + - **法规约束**:相关法律法规和行业标准的要求 + - **组织约束**:组织架构和流程制度的限制 + - **用户约束**:用户习惯和接受度的限制 + + + + ## ${config.domain}强制规则 + - **质量优先**:质量是不可妥协的底线要求 + - **用户至上**:所有决策必须以用户价值为导向 + - **数据驱动**:重要决策必须基于可靠数据 + - **风险控制**:必须识别和控制关键风险 + - **合规要求**:必须符合相关法规和标准 + - **团队协作**:必须保持良好的团队协作 + - **持续改进**:必须建立持续改进机制 + + + + ## ${config.domain}指导原则 + - **敏捷迭代**:采用敏捷方法快速迭代优化 + - **用户参与**:让用户深度参与设计和验证过程 + - **数据洞察**:充分利用数据获得深度洞察 + - **创新思维**:鼓励创新思维和解决方案 + - **协作共赢**:建立多方共赢的协作关系 + - **学习成长**:保持持续学习和能力提升 + - **价值导向**:始终关注价值创造和交付 + + + + ## ${config.domain}标准流程 + + ### Phase 1: 需求分析与规划 + \`\`\`yaml + 步骤: + 1. 需求收集: + - 与相关方深度沟通,明确需求和期望 + - 分析用户场景和使用情境 + - 识别核心需求和次要需求 + - 评估需求的紧急程度和重要性 + + 2. 现状分析: + - 分析当前状况和存在的问题 + - 识别可用资源和能力 + - 评估外部环境和约束条件 + - 分析竞争对手和市场状况 + + 3. 目标设定: + - 制定明确具体的目标 + - 设定可衡量的成功指标 + - 确定项目范围和边界 + - 建立时间计划和里程碑 + \`\`\` + + ### Phase 2: 方案设计与评估 + \`\`\`yaml + 设计流程: + 1. 方案构思: + - 头脑风暴产生多种解决方案 + - 分析各方案的优劣势 + - 考虑技术可行性和资源需求 + - 评估方案的创新性和差异化 + + 2. 方案细化: + - 详细设计选定的方案 + - 制定具体的实施计划 + - 识别关键风险和应对措施 + - 准备必要的资源和工具 + + 3. 方案验证: + - 通过原型或试点验证方案 + - 收集用户反馈和建议 + - 评估方案的实际效果 + - 根据反馈优化和调整方案 + \`\`\` + + ### Phase 3: 实施执行与监控 + \`\`\`yaml + 执行策略: + 1. 启动实施: + - 组建项目团队和分工 + - 准备必要的资源和环境 + - 建立沟通和协作机制 + - 启动项目并开始执行 + + 2. 过程监控: + - 定期检查项目进度和质量 + - 监控资源使用和成本控制 + - 识别和解决执行中的问题 + - 与相关方保持及时沟通 + + 3. 质量保证: + - 建立质量检查和控制机制 + - 定期进行质量评估和改进 + - 确保交付成果符合标准 + - 收集和处理质量反馈 + \`\`\` + + ### Phase 4: 评估优化与总结 + \`\`\`yaml + 评估流程: + 1. 效果评估: + - 评估项目目标的达成情况 + - 分析实际效果与预期的差异 + - 收集用户满意度和反馈 + - 评估投入产出比和价值创造 + + 2. 经验总结: + - 总结项目成功的关键因素 + - 分析失败和不足的原因 + - 提炼可复用的经验和方法 + - 形成最佳实践和标准流程 + + 3. 持续改进: + - 基于评估结果制定改进计划 + - 优化流程和方法论 + - 提升团队能力和效率 + - 为后续项目提供参考和指导 + \`\`\` + + + + ## ${config.domain}质量标准 + + ### 交付质量标准 + - ✅ 功能完整性达到设计要求 + - ✅ 性能指标满足用户需求 + - ✅ 用户体验达到预期标准 + - ✅ 质量缺陷控制在可接受范围 + + ### 过程质量标准 + - ✅ 项目进度按计划执行 + - ✅ 资源使用控制在预算内 + - ✅ 风险得到有效识别和控制 + - ✅ 团队协作高效顺畅 + + ### 价值创造标准 + - ✅ 用户价值得到有效提升 + - ✅ 商业目标得到实现 + - ✅ 投入产出比达到预期 + - ✅ 长期价值得到保障 + + ### 学习成长标准 + - ✅ 团队能力得到提升 + - ✅ 经验得到有效总结和传承 + - ✅ 流程得到优化和完善 + - ✅ 创新能力得到增强 + +` + +// 知识库模板 +const KNOWLEDGE_TEMPLATE = (config) => ` + + ## ${config.domain}领域知识体系 + + ### 理论基础 + \`\`\`yaml + 核心理论: + 基础概念: ${config.domain}的基本概念和定义 + 理论框架: 主要的理论模型和框架 + 方法论: 核心的方法论和最佳实践 + 发展历程: ${config.domain}的发展历史和演进 + + 学科交叉: + 相关学科: 与${config.domain}相关的其他学科 + 交叉应用: 跨学科的应用和融合 + 前沿趋势: 学科发展的前沿趋势 + 未来方向: 未来发展的可能方向 + \`\`\` + + ### 实践技能 + \`\`\`yaml + 核心技能: + 分析技能: 问题分析和需求分析能力 + 设计技能: 方案设计和系统设计能力 + 执行技能: 项目执行和团队管理能力 + 沟通技能: 有效沟通和协调能力 + + 专业工具: + 分析工具: 专业的分析和评估工具 + 设计工具: 设计和原型制作工具 + 管理工具: 项目管理和协作工具 + 监控工具: 效果监控和数据分析工具 + + 工作方法: + 敏捷方法: 敏捷开发和迭代方法 + 设计思维: 以用户为中心的设计思维 + 数据驱动: 基于数据的决策方法 + 持续改进: 持续优化和改进方法 + \`\`\` + + ### 行业应用 + \`\`\`yaml + 应用领域: + 传统行业: ${config.domain}在传统行业的应用 + 新兴行业: 在新兴行业和领域的应用 + 跨行业: 跨行业的应用和案例 + 国际化: 国际化应用和本土化适配 + + 成功案例: + 经典案例: 行业内的经典成功案例 + 创新案例: 具有创新性的应用案例 + 失败教训: 失败案例的经验教训 + 最佳实践: 总结的最佳实践和标准 + \`\`\` + + + + ## ${config.domain}方法论体系 + + ### 分析方法论 + \`\`\`yaml + 需求分析: + - 用户研究和需求挖掘方法 + - 需求优先级排序和管理 + - 需求变更控制和追踪 + - 需求验证和确认方法 + + 现状分析: + - 现状调研和数据收集 + - 问题识别和根因分析 + - 竞争分析和市场研究 + - SWOT分析和环境评估 + + 可行性分析: + - 技术可行性评估 + - 商业可行性分析 + - 资源可行性评估 + - 风险可行性分析 + \`\`\` + + ### 设计方法论 + \`\`\`yaml + 设计思维: + - 以用户为中心的设计理念 + - 同理心和用户洞察 + - 创意产生和概念设计 + - 原型制作和测试验证 + + 系统设计: + - 系统架构设计方法 + - 模块化设计和组件化 + - 接口设计和集成方案 + - 扩展性和可维护性设计 + + 体验设计: + - 用户体验设计原则 + - 交互设计和界面设计 + - 信息架构和导航设计 + - 可用性测试和优化 + \`\`\` + + ### 管理方法论 + \`\`\`yaml + 项目管理: + - 敏捷项目管理方法 + - 瀑布式项目管理 + - 混合项目管理模式 + - 风险管理和质量控制 + + 团队管理: + - 团队组建和角色分工 + - 沟通协作和冲突解决 + - 绩效管理和激励机制 + - 知识管理和经验传承 + + 变更管理: + - 变更识别和评估 + - 变更计划和实施 + - 变更沟通和培训 + - 变更效果评估和优化 + \`\`\` + + + + ## ${config.domain}工具生态 + + ### 分析工具 + \`\`\`yaml + 数据分析: + 统计工具: SPSS、R、Python pandas + 可视化: Tableau、Power BI、D3.js + 调研工具: 问卷星、腾讯问卷、UserVoice + 分析平台: Google Analytics、百度统计 + + 用户研究: + 访谈工具: Zoom、腾讯会议、钉钉 + 原型工具: Figma、Sketch、Axure + 测试工具: UserTesting、Hotjar、Crazy Egg + 反馈收集: Intercom、Zendesk、客服系统 + \`\`\` + + ### 设计工具 + \`\`\`yaml + 设计软件: + 界面设计: Figma、Sketch、Adobe XD + 原型制作: InVision、Marvel、Principle + 图形设计: Photoshop、Illustrator、Canva + 协作工具: Miro、Mural、Whimsical + + 开发工具: + 代码编辑: VS Code、WebStorm、Sublime + 版本控制: Git、SVN、Mercurial + 构建工具: Webpack、Gulp、Grunt + 测试工具: Jest、Cypress、Selenium + \`\`\` + + ### 管理工具 + \`\`\`yaml + 项目管理: + 敏捷工具: Jira、Azure DevOps、禅道 + 看板工具: Trello、Notion、Asana + 甘特图: Microsoft Project、Smartsheet + 时间跟踪: Toggl、RescueTime、Clockify + + 协作平台: + 文档协作: 腾讯文档、石墨文档、Notion + 即时通讯: 企业微信、钉钉、Slack + 视频会议: 腾讯会议、Zoom、Teams + 知识管理: Confluence、语雀、GitBook + \`\`\` + + + + ## 典型应用案例 + + ### 成功案例分析 + \`\`\`yaml + 案例一: 大型企业${config.domain}项目 + 背景: 企业数字化转型需求 + 挑战: 复杂的业务流程和技术架构 + 解决方案: 分阶段实施和敏捷迭代 + 成果: 显著提升效率和用户满意度 + 经验: 充分的前期调研和用户参与 + + 案例二: 创业公司${config.domain}实践 + 背景: 快速发展的业务需求 + 挑战: 有限的资源和时间压力 + 解决方案: MVP方法和快速验证 + 成果: 成功获得市场认可和投资 + 经验: 专注核心价值和快速迭代 + + 案例三: 传统行业${config.domain}升级 + 背景: 传统业务模式的数字化改造 + 挑战: 用户习惯和组织变革阻力 + 解决方案: 渐进式改进和培训支持 + 成果: 平稳过渡和业务增长 + 经验: 充分的变更管理和用户教育 + \`\`\` + + ### 失败案例教训 + \`\`\`yaml + 教训一: 忽视用户需求 + 问题: 过度关注技术而忽视用户体验 + 后果: 产品无法获得用户认可 + 教训: 始终以用户为中心进行设计 + + 教训二: 缺乏有效沟通 + 问题: 团队沟通不畅导致理解偏差 + 后果: 项目延期和质量问题 + 教训: 建立有效的沟通机制和流程 + + 教训三: 忽视风险管理 + 问题: 未能及时识别和应对风险 + 后果: 项目失败和资源浪费 + 教训: 建立完善的风险管理体系 + \`\`\` + + ### 最佳实践总结 + \`\`\`yaml + 设计原则: + - 以用户为中心,深度理解用户需求 + - 数据驱动决策,避免主观臆断 + - 迭代优化,持续改进产品和服务 + - 团队协作,发挥集体智慧和优势 + + 执行要点: + - 明确目标和成功标准 + - 合理规划资源和时间 + - 建立有效的监控和反馈机制 + - 保持灵活性和适应性 + + 质量保证: + - 建立完善的质量标准和流程 + - 定期进行质量检查和评估 + - 及时发现和解决质量问题 + - 持续优化质量管理体系 + \`\`\` + +` + +// 解析命令行参数 +function parseArgs() { + const args = process.argv.slice(2) + + if (args.length === 0) { + console.log(` +使用方法: + node scripts/generate-test-role.js [role-title] [domain] + +参数说明: + role-name 角色ID (必需) - 例如: product-manager, ui-designer + role-title 角色标题 (可选) - 例如: 产品经理, UI设计师 + domain 专业领域 (可选) - 例如: 产品设计, 用户界面设计 + +示例: + node scripts/generate-test-role.js product-manager "产品经理" "产品设计" + node scripts/generate-test-role.js ui-designer "UI设计师" "用户界面设计" + node scripts/generate-test-role.js data-scientist "数据科学家" "数据科学" +`) + process.exit(1) + } + + const roleId = args[0] + const title = args[1] || DEFAULT_CONFIG.title + const domain = args[2] || DEFAULT_CONFIG.domain + + return { + roleId, + title, + domain, + description: `${title},提供专业的${domain}服务` + } +} + +// 创建目录结构 +async function createDirectories(roleId) { + const basePath = `.promptx/resource/domain/${roleId}` + + await fs.ensureDir(basePath) + await fs.ensureDir(path.join(basePath, 'thought')) + await fs.ensureDir(path.join(basePath, 'execution')) + await fs.ensureDir(path.join(basePath, 'knowledge')) + + return basePath +} + +// 生成文件 +async function generateFiles(config, basePath) { + const files = [ + { + path: path.join(basePath, `${config.roleId}.role.md`), + content: ROLE_TEMPLATE(config) + }, + { + path: path.join(basePath, 'thought', `${config.roleId}-mindset.thought.md`), + content: THOUGHT_TEMPLATE(config) + }, + { + path: path.join(basePath, 'execution', `${config.roleId}-workflow.execution.md`), + content: EXECUTION_TEMPLATE(config) + }, + { + path: path.join(basePath, 'knowledge', `${config.roleId}-expertise.knowledge.md`), + content: KNOWLEDGE_TEMPLATE(config) + } + ] + + for (const file of files) { + await fs.writeFile(file.path, file.content, 'utf8') + console.log(`✅ 创建文件: ${file.path}`) + } +} + +// 主函数 +async function main() { + try { + console.log('🚀 开始生成测试角色...\n') + + // 解析参数 + const config = parseArgs() + console.log(`📋 角色配置:`) + console.log(` ID: ${config.roleId}`) + console.log(` 标题: ${config.title}`) + console.log(` 领域: ${config.domain}`) + console.log(` 描述: ${config.description}\n`) + + // 创建目录 + console.log('📁 创建目录结构...') + const basePath = await createDirectories(config.roleId) + console.log(`✅ 目录创建完成: ${basePath}\n`) + + // 生成文件 + console.log('📝 生成角色文件...') + await generateFiles(config, basePath) + + console.log(`\n🎉 测试角色 "${config.roleId}" 生成完成!`) + console.log(`\n📍 下一步操作:`) + console.log(` 1. 运行 init 刷新资源注册表:`) + console.log(` node src/bin/promptx.js init`) + console.log(` 2. 激活角色进行测试:`) + console.log(` node src/bin/promptx.js action ${config.roleId}`) + console.log(`\n💡 或者通过 MCP 工具:`) + console.log(` 1. mcp_promptx-dev_promptx_init`) + console.log(` 2. mcp_promptx-dev_promptx_action ${config.roleId}`) + + } catch (error) { + console.error('❌ 生成角色时发生错误:', error.message) + process.exit(1) + } +} + +// 运行脚本 +if (require.main === module) { + main() +} + +module.exports = { + parseArgs, + createDirectories, + generateFiles, + ROLE_TEMPLATE, + THOUGHT_TEMPLATE, + EXECUTION_TEMPLATE, + KNOWLEDGE_TEMPLATE +} \ No newline at end of file diff --git a/scripts/quick-test.js b/scripts/quick-test.js new file mode 100755 index 0000000..c193334 --- /dev/null +++ b/scripts/quick-test.js @@ -0,0 +1,162 @@ +#!/usr/bin/env node + +/** + * 快速测试脚本 + * 用于验证全局单例ResourceManager优化效果 + * + * 使用方法: + * node scripts/quick-test.js [role-name] + * + * 示例: + * node scripts/quick-test.js frontend-dev + * node scripts/quick-test.js backend-dev + */ + +const { execSync } = require('child_process') +const path = require('path') + +// 预定义的测试角色配置 +const TEST_ROLES = { + 'frontend-dev': { + title: '前端开发工程师', + domain: '前端开发' + }, + 'backend-dev': { + title: '后端开发工程师', + domain: '后端开发' + }, + 'ui-designer': { + title: 'UI设计师', + domain: '用户界面设计' + }, + 'product-manager': { + title: '产品经理', + domain: '产品设计' + }, + 'data-analyst': { + title: '数据分析师', + domain: '数据分析' + }, + 'devops-engineer': { + title: 'DevOps工程师', + domain: 'DevOps运维' + } +} + +function getRandomRole() { + const roles = Object.keys(TEST_ROLES) + return roles[Math.floor(Math.random() * roles.length)] +} + +function runCommand(command, description) { + console.log(`\n🔄 ${description}...`) + console.log(`💻 执行命令: ${command}`) + + try { + const output = execSync(command, { + encoding: 'utf8', + cwd: process.cwd(), + stdio: 'pipe' + }) + console.log(`✅ 成功完成`) + if (output.trim()) { + console.log(`📄 输出:\n${output}`) + } + return true + } catch (error) { + console.log(`❌ 执行失败: ${error.message}`) + if (error.stdout) { + console.log(`📄 标准输出:\n${error.stdout}`) + } + if (error.stderr) { + console.log(`📄 错误输出:\n${error.stderr}`) + } + return false + } +} + +async function main() { + const args = process.argv.slice(2) + let roleId = args[0] + + // 如果没有指定角色,随机选择一个 + if (!roleId) { + roleId = getRandomRole() + console.log(`🎲 随机选择测试角色: ${roleId}`) + } + + // 检查角色是否在预定义列表中 + if (!TEST_ROLES[roleId]) { + console.log(`❌ 未知角色: ${roleId}`) + console.log(`📋 可用角色: ${Object.keys(TEST_ROLES).join(', ')}`) + process.exit(1) + } + + const config = TEST_ROLES[roleId] + console.log(`\n🚀 开始快速测试流程`) + console.log(`📋 测试角色: ${roleId} (${config.title})`) + console.log(`🎯 专业领域: ${config.domain}`) + + // 步骤1: 生成测试角色 + console.log(`\n=== 步骤 1: 生成测试角色 ===`) + const generateSuccess = runCommand( + `node scripts/generate-test-role.js ${roleId} "${config.title}" "${config.domain}"`, + `生成角色 ${roleId}` + ) + + if (!generateSuccess) { + console.log(`❌ 角色生成失败,终止测试`) + process.exit(1) + } + + // 步骤2: 刷新资源注册表 + console.log(`\n=== 步骤 2: 刷新资源注册表 ===`) + const initSuccess = runCommand( + `node src/bin/promptx.js init`, + `刷新资源注册表` + ) + + if (!initSuccess) { + console.log(`❌ 资源注册表刷新失败,终止测试`) + process.exit(1) + } + + // 步骤3: 激活角色测试 + console.log(`\n=== 步骤 3: 激活角色测试 ===`) + const actionSuccess = runCommand( + `node src/bin/promptx.js action ${roleId}`, + `激活角色 ${roleId}` + ) + + if (!actionSuccess) { + console.log(`❌ 角色激活失败`) + } + + // 测试总结 + console.log(`\n=== 测试总结 ===`) + console.log(`🎯 测试角色: ${roleId} (${config.title})`) + console.log(`📊 测试结果:`) + console.log(` ✅ 角色生成: ${generateSuccess ? '成功' : '失败'}`) + console.log(` ✅ 资源注册: ${initSuccess ? '成功' : '失败'}`) + console.log(` ✅ 角色激活: ${actionSuccess ? '成功' : '失败'}`) + + if (generateSuccess && initSuccess && actionSuccess) { + console.log(`\n🎉 全部测试通过!ResourceManager优化生效`) + console.log(`💡 现在可以在MCP环境中测试角色激活,无需重启服务器`) + } else { + console.log(`\n⚠️ 部分测试失败,请检查错误信息`) + } + + console.log(`\n📍 后续操作建议:`) + console.log(` 1. 在MCP环境中测试: mcp_promptx-dev_promptx_action ${roleId}`) + console.log(` 2. 验证项目级资源引用是否正常解析`) + console.log(` 3. 测试其他角色的创建和激活`) +} + +// 运行脚本 +if (require.main === module) { + main().catch(error => { + console.error('❌ 脚本执行出错:', error.message) + process.exit(1) + }) +} \ No newline at end of file diff --git a/src/bin/promptx.js b/src/bin/promptx.js index 6efdc95..22fd4e8 100755 --- a/src/bin/promptx.js +++ b/src/bin/promptx.js @@ -3,6 +3,7 @@ const { Command } = require('commander') const chalk = require('chalk') const packageJson = require('../../package.json') +const logger = require('../lib/utils/logger') // 导入锦囊框架 const { cli } = require('../lib/core/pouch') @@ -92,14 +93,14 @@ program cors: options.cors }; - console.error(chalk.green(`🚀 启动 ${options.transport.toUpperCase()} MCP Server 在 ${options.host}:${options.port}...`)); + logger.info(chalk.green(`🚀 启动 ${options.transport.toUpperCase()} MCP Server 在 ${options.host}:${options.port}...`)); await mcpHttpServer.execute(serverOptions); } else { throw new Error(`不支持的传输类型: ${options.transport}。支持的类型: stdio, http, sse`); } } catch (error) { // 输出到stderr,不污染MCP的stdout通信 - console.error(chalk.red(`❌ MCP Server 启动失败: ${error.message}`)); + logger.error(chalk.red(`❌ MCP Server 启动失败: ${error.message}`)); process.exit(1); } }) @@ -174,8 +175,8 @@ ${chalk.cyan('更多信息:')} // 处理未知命令 program.on('command:*', () => { - console.error(chalk.red(`错误: 未知命令 '${program.args.join(' ')}'`)) - console.log('') + logger.error(chalk.red(`错误: 未知命令 '${program.args.join(' ')}'`)) + logger.info('') program.help() }) diff --git a/src/lib/commands/MCPStreamableHttpCommand.js b/src/lib/commands/MCPStreamableHttpCommand.js index 265214c..addbc8d 100644 --- a/src/lib/commands/MCPStreamableHttpCommand.js +++ b/src/lib/commands/MCPStreamableHttpCommand.js @@ -6,6 +6,7 @@ const { SSEServerTransport } = require('@modelcontextprotocol/sdk/server/sse.js' const { isInitializeRequest } = require('@modelcontextprotocol/sdk/types.js'); const { cli } = require('../core/pouch'); const { MCPOutputAdapter } = require('../adapters/MCPOutputAdapter'); +const logger = require('../utils/logger'); /** * MCP Streamable HTTP Server Command @@ -579,7 +580,7 @@ class MCPStreamableHttpCommand { */ log(message, ...args) { if (this.debug) { - console.error(`[MCP DEBUG] ${message}`, ...args); + logger.debug(`[MCP DEBUG] ${message}`, ...args); } } diff --git a/src/lib/core/pouch/.promptx.json b/src/lib/core/pouch/.promptx.json deleted file mode 100644 index 727686e..0000000 --- a/src/lib/core/pouch/.promptx.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "version": "0.0.1", - "initialized": "2025-05-31T06:15:39.372Z", - "defaultFormat": "human", - "stateHistory": [ - { - "from": "initial", - "to": "init", - "timestamp": "2025-05-31T06:15:39.370Z", - "args": [] - }, - { - "from": "init", - "to": "hello", - "timestamp": "2025-05-31T06:15:39.373Z", - "args": [] - }, - { - "from": "hello", - "command": "init", - "timestamp": "2025-05-31T06:16:28.040Z", - "args": [] - }, - { - "from": "initialized", - "command": "hello", - "timestamp": "2025-05-31T06:16:28.042Z", - "args": [] - }, - { - "from": "discovering", - "command": "action", - "timestamp": "2025-05-31T06:16:28.042Z", - "args": [ - "copywriter" - ] - }, - { - "from": "activated-copywriter", - "command": "learn", - "timestamp": "2025-05-31T06:16:28.046Z", - "args": [ - "scrum" - ] - }, - { - "from": "learned-scrum", - "command": "recall", - "timestamp": "2025-05-31T06:16:28.047Z", - "args": [ - "test" - ] - } - ], - "currentState": "recalled-test", - "lastUpdated": "2025-05-31T06:16:28.047Z" -} diff --git a/src/lib/core/pouch/BasePouchCommand.js b/src/lib/core/pouch/BasePouchCommand.js index bc2b880..92a4d08 100644 --- a/src/lib/core/pouch/BasePouchCommand.js +++ b/src/lib/core/pouch/BasePouchCommand.js @@ -95,7 +95,7 @@ class BasePouchCommand { toString () { const divider = '='.repeat(60) const nextSteps = (pateoas.nextActions || []) - .map(action => ` - ${action.name}: ${action.description}\n 命令: ${action.command}`) + .map(action => ` - ${action.name}: ${action.description}\n 方式: ${action.method || action.command || '通过MCP工具'}`) .join('\n') return ` diff --git a/src/lib/core/pouch/PouchCLI.js b/src/lib/core/pouch/PouchCLI.js index 6d2c87c..d5062bd 100644 --- a/src/lib/core/pouch/PouchCLI.js +++ b/src/lib/core/pouch/PouchCLI.js @@ -2,6 +2,7 @@ const PouchStateMachine = require('./state/PouchStateMachine') const PouchRegistry = require('./PouchRegistry') const commands = require('./commands') const { COMMANDS } = require('../../../constants') +const logger = require('../../utils/logger') /** * 锦囊CLI主入口 @@ -70,9 +71,9 @@ class PouchCLI { if (!silent) { // 如果结果有 toString 方法,打印人类可读格式 if (result && result.toString && typeof result.toString === 'function') { - console.log(result.toString()) + logger.log(result.toString()) } else { - console.log(JSON.stringify(result, null, 2)) + logger.log(JSON.stringify(result, null, 2)) } } @@ -80,7 +81,7 @@ class PouchCLI { } catch (error) { // 错误输出始终使用stderr,不干扰MCP协议 if (!silent) { - console.error(`执行命令出错: ${error.message}`) + logger.error(`执行命令出错: ${error.message}`) } throw error } @@ -162,8 +163,8 @@ class PouchCLI { * 运行交互式CLI */ async runInteractive () { - console.log('🎯 欢迎使用 PromptX 锦囊系统!') - console.log('输入 "help" 查看帮助,"exit" 退出\n') + logger.info('🎯 欢迎使用 PromptX 锦囊系统!') + logger.info('输入 "help" 查看帮助,"exit" 退出\n') const readline = require('readline') const rl = readline.createInterface({ @@ -178,21 +179,21 @@ class PouchCLI { const input = line.trim() if (input === 'exit' || input === 'quit') { - console.log('再见!') + logger.info('再见!') rl.close() return } if (input === 'help') { - console.log(this.getHelp()) + logger.info(this.getHelp()) } else if (input === 'status') { - console.log(JSON.stringify(this.getStatus(), null, 2)) + logger.info(JSON.stringify(this.getStatus(), null, 2)) } else if (input) { const { command, args } = this.parseCommand(input) try { await this.execute(command, args) } catch (error) { - console.error(error.message) + logger.error(error.message) } } diff --git a/src/lib/core/pouch/commands/ActionCommand.js b/src/lib/core/pouch/commands/ActionCommand.js index 11e5896..094973a 100644 --- a/src/lib/core/pouch/commands/ActionCommand.js +++ b/src/lib/core/pouch/commands/ActionCommand.js @@ -1,8 +1,8 @@ const BasePouchCommand = require('../BasePouchCommand') const fs = require('fs-extra') const path = require('path') -const { COMMANDS, buildCommand } = require('../../../../constants') -const ResourceManager = require('../../resource/resourceManager') +const { COMMANDS } = require('../../../../constants') +const { getGlobalResourceManager } = require('../../resource') const DPMLContentParser = require('../../resource/DPMLContentParser') const SemanticRenderer = require('../../resource/SemanticRenderer') const logger = require('../../../utils/logger') @@ -16,7 +16,8 @@ class ActionCommand extends BasePouchCommand { super() // 获取HelloCommand的角色注册表 this.helloCommand = null - this.resourceManager = new ResourceManager() + // 使用全局单例 ResourceManager + this.resourceManager = getGlobalResourceManager() this.dpmlParser = new DPMLContentParser() this.semanticRenderer = new SemanticRenderer() } @@ -32,19 +33,20 @@ class ActionCommand extends BasePouchCommand { return `❌ 请指定要激活的角色ID 🔍 使用方法: -\`\`\`bash -${buildCommand.action('<角色ID>')} -\`\`\` +通过 MCP PromptX 工具的 action 功能激活角色 💡 查看可用角色: -\`\`\`bash -${COMMANDS.HELLO} -\`\`\`` +使用 MCP PromptX 工具的 hello 功能` } try { logger.debug(`[ActionCommand] 开始激活角色: ${roleId}`) + // 0. 初始化 ResourceManager(确保引用解析正常工作) + if (!this.resourceManager.initialized) { + await this.resourceManager.initializeWithNewArchitecture() + } + // 1. 获取角色信息 const roleInfo = await this.getRoleInfo(roleId) logger.debug(`[ActionCommand] getRoleInfo结果:`, roleInfo) @@ -53,10 +55,7 @@ ${COMMANDS.HELLO} logger.warn(`[ActionCommand] 角色 "${roleId}" 不存在!`) return `❌ 角色 "${roleId}" 不存在! -🔍 请使用以下命令查看可用角色: -\`\`\`bash -${COMMANDS.HELLO} -\`\`\`` +🔍 请使用 MCP PromptX 工具的 hello 功能查看可用角色` } // 2. 分析角色文件,提取依赖 @@ -65,7 +64,7 @@ ${COMMANDS.HELLO} // 3. 生成学习计划并直接加载所有内容 return await this.generateLearningPlan(roleInfo.id, dependencies) } catch (error) { - console.error('Action command error:', error) + logger.error('Action command error:', error) return `❌ 激活角色 "${roleId}" 时发生错误。 🔍 可能的原因: @@ -73,7 +72,7 @@ ${COMMANDS.HELLO} - 权限不足 - 系统资源问题 -💡 请使用 \`${COMMANDS.HELLO}\` 查看可用角色列表。` +💡 请使用 MCP PromptX 工具的 hello 功能查看可用角色列表。` } } @@ -158,7 +157,7 @@ ${COMMANDS.HELLO} } } } catch (error) { - console.error('Error analyzing role dependencies:', error) + logger.error('Error analyzing role dependencies:', error) // 如果分析失败,返回基础结构 return { thoughts: [], @@ -408,11 +407,11 @@ ${recallContent} ⚠️ **重要**: recall已自动执行完成,以上记忆将作为角色工作的重要参考依据 ` } catch (error) { - console.error('Auto recall error:', error) + logger.error('Auto recall error:', error) return `--- ## 🧠 自动记忆检索结果 ⚠️ **记忆检索出现问题**: ${error.message} -💡 **建议**: 可手动执行 \`${buildCommand.recall()}\` 来检索相关记忆 +💡 **建议**: 可使用 MCP PromptX 工具的 recall 功能来检索相关记忆 ` } } @@ -425,12 +424,12 @@ ${recallContent} currentState: 'action_awaiting_role', availableTransitions: ['hello'], nextActions: [ - { - name: '查看可用角色', - description: '返回角色发现页面', - command: COMMANDS.HELLO, - priority: 'high' - } + { + name: '查看可用角色', + description: '返回角色发现页面', + method: 'MCP PromptX hello 工具', + priority: 'high' + } ], metadata: { message: '需要指定角色ID' @@ -445,25 +444,25 @@ ${recallContent} { name: '开始专业服务', description: '角色已激活并完成记忆检索,可直接提供专业服务', - command: '开始对话', + method: '开始对话', priority: 'high' }, { name: '返回角色选择', description: '选择其他角色', - command: COMMANDS.HELLO, + method: 'MCP PromptX hello 工具', priority: 'medium' }, { name: '记忆新知识', description: '内化更多专业知识', - command: buildCommand.remember('<新知识>'), + method: 'MCP PromptX remember 工具', priority: 'low' }, { name: '学习新资源', description: '学习相关专业资源', - command: buildCommand.learn('://'), + method: 'MCP PromptX learn 工具', priority: 'low' } ], diff --git a/src/lib/core/pouch/commands/HelloCommand.js b/src/lib/core/pouch/commands/HelloCommand.js index 92bdd97..69c0a9e 100644 --- a/src/lib/core/pouch/commands/HelloCommand.js +++ b/src/lib/core/pouch/commands/HelloCommand.js @@ -1,8 +1,7 @@ const BasePouchCommand = require('../BasePouchCommand') const fs = require('fs-extra') const path = require('path') -const { buildCommand } = require('../../../../constants') -const ResourceManager = require('../../resource/resourceManager') +const { getGlobalResourceManager } = require('../../resource') const logger = require('../../../utils/logger') /** @@ -12,8 +11,8 @@ const logger = require('../../../utils/logger') class HelloCommand extends BasePouchCommand { constructor () { super() - // 使用新的ResourceManager架构替代SimplifiedRoleDiscovery - this.resourceManager = new ResourceManager() + // 使用全局单例 ResourceManager + this.resourceManager = getGlobalResourceManager() } getPurpose () { @@ -22,39 +21,80 @@ class HelloCommand extends BasePouchCommand { /** * 动态加载角色注册表 - 使用新的ResourceManager架构 - * 移除缓存机制,每次都实时扫描,确保角色发现的一致性 + * 直接使用现有资源注册表,避免重复刷新导致的死循环 */ async loadRoleRegistry () { try { - // 无状态资源刷新,确保能发现新创建的角色 - await this.resourceManager.refreshResources() - - // 获取所有角色相关的资源 + // 确保ResourceManager已初始化 + if (!this.resourceManager.initialized) { + await this.resourceManager.initializeWithNewArchitecture() + } + const roleRegistry = {} - // 从ResourceRegistry中获取所有role:开头的资源 - const registry = this.resourceManager.registry - for (const [resourceId, reference] of registry.index) { - if (resourceId.startsWith('role:')) { - const roleId = resourceId.substring(5) // 移除 'role:' 前缀 + // 使用新的RegistryData v2.0格式获取角色资源 + const registryData = this.resourceManager.registryData + + // 检查是否有RegistryData(v2.0格式) + if (registryData && registryData.resources && registryData.resources.length > 0) { + // 使用v2.0格式:直接从RegistryData获取角色资源 + const roleResources = registryData.getResourcesByProtocol('role') + + for (const resource of roleResources) { + const roleId = resource.id - try { - // 尝试加载角色内容以提取元数据 - const result = await this.resourceManager.loadResource(resourceId) - if (result.success) { - const name = this.extractRoleNameFromContent(result.content) || roleId - const description = this.extractDescriptionFromContent(result.content) || `${name}专业角色` - - roleRegistry[roleId] = { - file: reference, - name, - description, - source: reference.startsWith('@package://') ? 'system' : 'user-generated' - } + // 避免重复角色(同一个ID可能有多个来源) + if (!roleRegistry[roleId]) { + roleRegistry[roleId] = { + id: resource.id, + name: resource.name, + description: resource.description, + source: resource.source, + file: resource.reference, + protocol: resource.protocol + } + } + } + } else { + // 降级到旧格式处理(向后兼容) + const registry = this.resourceManager.registry + for (const [resourceId, reference] of registry.index) { + let roleId = null + let isRoleResource = false + + if (resourceId.startsWith('role:')) { + roleId = resourceId.substring(5) + isRoleResource = true + } else if (resourceId.startsWith('package:') || resourceId.startsWith('project:') || resourceId.startsWith('user:')) { + const parts = resourceId.split(':') + if (parts.length === 2 && !parts[1].includes(':')) { + roleId = parts[1] + isRoleResource = true + } + } else if (!resourceId.includes(':')) { + roleId = resourceId + isRoleResource = true + } + + if (isRoleResource && roleId && !roleRegistry[roleId]) { + try { + const result = await this.resourceManager.loadResource(resourceId) + if (result.success) { + const name = this.extractRoleNameFromContent(result.content) || roleId + const description = this.extractDescriptionFromContent(result.content) || `${name}专业角色` + + roleRegistry[roleId] = { + id: roleId, + name, + description, + source: reference.startsWith('@package://') ? 'package' : 'project', + file: reference, + protocol: 'role' + } + } + } catch (error) { + // 静默处理,避免干扰用户界面 } - } catch (error) { - // 单个角色加载失败不影响其他角色 - logger.warn(`角色${roleId}加载失败: ${error.message}`) } } } @@ -62,24 +102,26 @@ class HelloCommand extends BasePouchCommand { // 如果没有任何角色,使用基础角色 if (Object.keys(roleRegistry).length === 0) { roleRegistry.assistant = { - file: '@package://prompt/domain/assistant/assistant.role.md', + id: 'assistant', name: '🙋 智能助手', description: '通用助理角色,提供基础的助理服务和记忆支持', - source: 'fallback' + source: 'fallback', + file: '@package://prompt/domain/assistant/assistant.role.md', + protocol: 'role' } } return roleRegistry } catch (error) { - logger.warn('角色注册表加载失败,使用基础角色:', error.message) - // 使用基础角色作为fallback return { assistant: { - file: '@package://prompt/domain/assistant/assistant.role.md', + id: 'assistant', name: '🙋 智能助手', description: '通用助理角色,提供基础的助理服务和记忆支持', - source: 'fallback' + source: 'fallback', + file: '@package://prompt/domain/assistant/assistant.role.md', + protocol: 'role' } } } @@ -151,68 +193,79 @@ class HelloCommand extends BasePouchCommand { */ getSourceLabel(source) { switch (source) { - case 'user-generated': - return '(用户生成)' - case 'system': - return '(系统角色)' + case 'package': + return '📦 系统角色' + case 'project': + return '🏗️ 项目角色' + case 'user': + return '�� 用户角色' + case 'merged': + return '📦 系统角色' // merged来源的资源主要来自package case 'fallback': - return '(默认角色)' + return '🔄 默认角色' default: - return '' + return '❓ 未知来源' } } async getContent (args) { - await this.loadRoleRegistry() - const allRoles = await this.getAllRoles() + const roleRegistry = await this.loadRoleRegistry() + const allRoles = Object.values(roleRegistry) const totalRoles = allRoles.length let content = `🤖 **AI专业角色服务清单** (共 ${totalRoles} 个专业角色可供选择) -> 💡 **重要说明**:以下是可激活的AI专业角色。每个角色都有唯一的ID,使用action命令激活。 +> 💡 **重要说明**:以下是可激活的AI专业角色。每个角色都有唯一的ID,可通过MCP工具激活。 ## 📋 可用角色列表 ` - // 清楚显示角色ID和激活命令 - allRoles.forEach((role, index) => { - const sourceLabel = this.getSourceLabel(role.source) - content += `### ${index + 1}. ${role.name} ${sourceLabel} + // 按来源分组显示角色 + const rolesBySource = {} + allRoles.forEach(role => { + const source = role.source || 'unknown' + if (!rolesBySource[source]) { + rolesBySource[source] = [] + } + rolesBySource[source].push(role) + }) + + let roleIndex = 1 + + // 优先显示系统角色 + const sourceOrder = ['package', 'merged', 'project', 'user', 'fallback', 'unknown'] + + for (const source of sourceOrder) { + if (!rolesBySource[source] || rolesBySource[source].length === 0) continue + + const sourceLabel = this.getSourceLabel(source) + content += `### ${sourceLabel}\n\n` + + rolesBySource[source].forEach(role => { + content += `#### ${roleIndex}. ${role.name} **角色ID**: \`${role.id}\` **专业能力**: ${role.description} -**激活命令**: \`${buildCommand.action(role.id)}\` +**来源**: ${sourceLabel} --- ` - }) + roleIndex++ + }) + } content += ` ## 🎯 **角色激活指南** -### 🔧 激活步骤 -1. **选择角色**: 从上述列表中选择需要的专业角色 -2. **使用角色ID**: 复制对应的角色ID(如:\`${allRoles[0]?.id || 'assistant'}\`) -3. **执行命令**: 运行 \`${buildCommand.action('<角色ID>')}\` - -### 📝 激活示例 -\`\`\`bash -# 激活智能助手角色 -${buildCommand.action(allRoles[0]?.id || 'assistant')} -\`\`\` +### 🔧 激活方式 +- 使用 **MCP PromptX 工具** 中的 \`action\` 功能 +- 选择需要的角色ID进行激活 ### ⚡ 激活后效果 - ✅ **获得专业能力** - AI将具备该角色的专业技能 - ✅ **学习技能组合** - 自动学习角色需要的思维和行为模式 - ✅ **即时专业化** - 立即可以提供该领域的专业服务 - ---- - -⚠️ **AI执行指令**: -📢 **向主人汇报角色选项,明确说明使用方法:"请选择角色ID,然后我将执行对应的action命令"** -🎯 **等待主人指定具体的角色ID后,立即执行 \`${buildCommand.action('<角色ID>')}\`** -💡 **强调:action命令需要具体的角色ID,不是角色名称** ` return content @@ -223,7 +276,7 @@ ${buildCommand.action(allRoles[0]?.id || 'assistant')} const availableRoles = allRoles.map(role => ({ roleId: role.id, name: role.name, - actionCommand: buildCommand.action(role.id) + source: role.source })) return { @@ -233,7 +286,7 @@ ${buildCommand.action(allRoles[0]?.id || 'assistant')} { name: '向主人汇报服务选项', description: '将上述专业服务清单告知主人,并询问需求', - command: '等待主人选择后使用: ' + buildCommand.action('<选择的角色ID>'), + method: 'MCP PromptX action 工具', priority: 'critical', instruction: '必须先询问主人需求,不要自主选择角色' } @@ -243,7 +296,7 @@ ${buildCommand.action(allRoles[0]?.id || 'assistant')} availableRoles, dataSource: 'resource.registry.json', systemVersion: '锦囊串联状态机 v1.0', - designPhilosophy: 'AI use CLI get prompt for AI' + designPhilosophy: 'AI use MCP tools for role activation' } } } @@ -298,27 +351,27 @@ ${buildCommand.action(allRoles[0]?.id || 'assistant')} async debugRegistry() { await this.loadRoleRegistry() - console.log('\n🔍 HelloCommand - 注册表调试信息') - console.log('='.repeat(50)) + logger.info('\n🔍 HelloCommand - 注册表调试信息') + logger.info('='.repeat(50)) if (this.roleRegistry && Object.keys(this.roleRegistry).length > 0) { - console.log(`📊 发现 ${Object.keys(this.roleRegistry).length} 个角色资源:\n`) + logger.info(`📊 发现 ${Object.keys(this.roleRegistry).length} 个角色资源:\n`) Object.entries(this.roleRegistry).forEach(([id, roleInfo]) => { - console.log(`🎭 ${id}`) - console.log(` 名称: ${roleInfo.name || '未命名'}`) - console.log(` 描述: ${roleInfo.description || '无描述'}`) - console.log(` 文件: ${roleInfo.file}`) - console.log(` 来源: ${roleInfo.source || '未知'}`) - console.log('') + logger.info(`🎭 ${id}`) + logger.info(` 名称: ${roleInfo.name || '未命名'}`) + logger.info(` 描述: ${roleInfo.description || '无描述'}`) + logger.info(` 文件: ${roleInfo.file}`) + logger.info(` 来源: ${roleInfo.source || '未知'}`) + logger.info('') }) } else { - console.log('🔍 没有发现任何角色资源') + logger.info('🔍 没有发现任何角色资源') } // 同时显示ResourceManager的注册表 - console.log('\n📋 ResourceManager 注册表:') - console.log('-'.repeat(30)) + logger.info('\n📋 ResourceManager 注册表:') + logger.info('-'.repeat(30)) this.resourceManager.registry.printAll('底层资源注册表') } } diff --git a/src/lib/core/pouch/commands/InitCommand.js b/src/lib/core/pouch/commands/InitCommand.js index 5fdced1..6164f88 100644 --- a/src/lib/core/pouch/commands/InitCommand.js +++ b/src/lib/core/pouch/commands/InitCommand.js @@ -1,7 +1,10 @@ const BasePouchCommand = require('../BasePouchCommand') -const { ResourceManager } = require('../../resource') +const { getGlobalResourceManager } = require('../../resource') const { COMMANDS } = require('../../../../constants') const PromptXConfig = require('../../../utils/promptxConfig') +const RegistryData = require('../../resource/RegistryData') +const ProjectDiscovery = require('../../resource/discovery/ProjectDiscovery') +const logger = require('../../../utils/logger') const path = require('path') const fs = require('fs-extra') @@ -12,11 +15,13 @@ const fs = require('fs-extra') class InitCommand extends BasePouchCommand { constructor () { super() - this.resourceManager = new ResourceManager() + // 使用全局单例 ResourceManager + this.resourceManager = getGlobalResourceManager() + this.projectDiscovery = new ProjectDiscovery() } getPurpose () { - return '初始化PromptX工作环境,创建必要的配置目录和文件' + return '初始化PromptX工作环境,创建必要的配置目录和文件,生成项目级资源注册表' } async getContent (args) { @@ -28,6 +33,12 @@ class InitCommand extends BasePouchCommand { // 2. 基础环境准备 - 只创建 .promptx 目录 await this.ensurePromptXDirectory(workspacePath) + // 3. 生成项目级资源注册表 + const registryStats = await this.generateProjectRegistry(workspacePath) + + // 4. 刷新全局 ResourceManager(确保新资源立即可用) + await this.refreshGlobalResourceManager() + return `🎯 PromptX 初始化完成! ## 📦 版本信息 @@ -37,13 +48,68 @@ class InitCommand extends BasePouchCommand { ✅ 创建了 \`.promptx\` 配置目录 ✅ 工作环境就绪 +## 📋 项目资源注册表 +${registryStats.message} + ## 🚀 下一步建议 - 使用 \`hello\` 发现可用的专业角色 - 使用 \`action\` 激活特定角色获得专业能力 - 使用 \`learn\` 深入学习专业知识 - 使用 \`remember/recall\` 管理专业记忆 -💡 **提示**: 现在可以开始使用专业角色系统来增强AI能力了!` +💡 **提示**: ${registryStats.totalResources > 0 ? '项目资源已优化为注册表模式,性能大幅提升!' : '现在可以开始创建项目级资源了!'}` + } + + /** + * 生成项目级资源注册表 + * @param {string} workspacePath - 工作目录路径 + * @returns {Promise} 注册表生成统计信息 + */ + async generateProjectRegistry(workspacePath) { + try { + // 1. 获取项目根目录 + const projectRoot = await this.projectDiscovery._findProjectRoot() + + // 2. 确保 .promptx/resource/domain 目录结构存在 + const resourceDir = path.join(projectRoot, '.promptx', 'resource') + const domainDir = path.join(resourceDir, 'domain') + + await fs.ensureDir(domainDir) + logger.debug(`[InitCommand] 确保目录结构存在: ${domainDir}`) + + // 3. 使用 ProjectDiscovery 的正确方法生成注册表 + logger.step('正在扫描项目资源...') + const registryData = await this.projectDiscovery.generateRegistry(projectRoot) + + // 4. 生成统计信息 + const stats = registryData.getStats() + const registryPath = path.join(projectRoot, '.promptx', 'resource', 'project.registry.json') + + if (registryData.size === 0) { + return { + message: `✅ 项目资源目录已创建,注册表已初始化 + 📂 目录: ${path.relative(process.cwd(), domainDir)} + 💾 注册表: ${path.relative(process.cwd(), registryPath)} + 💡 现在可以在 domain 目录下创建角色资源了`, + totalResources: 0 + } + } + + return { + message: `✅ 项目资源注册表已重新生成 + 📊 总计: ${registryData.size} 个资源 + 📋 分类: role(${stats.byProtocol.role || 0}), thought(${stats.byProtocol.thought || 0}), execution(${stats.byProtocol.execution || 0}), knowledge(${stats.byProtocol.knowledge || 0}) + 💾 位置: ${path.relative(process.cwd(), registryPath)}`, + totalResources: registryData.size + } + + } catch (error) { + logger.error('生成项目注册表时出错:', error) + return { + message: `❌ 生成项目注册表失败: ${error.message}`, + totalResources: 0 + } + } } /** @@ -56,6 +122,24 @@ class InitCommand extends BasePouchCommand { await config.ensureDir() } + /** + * 刷新全局 ResourceManager + * 确保新创建的资源立即可用,无需重启 MCP Server + */ + async refreshGlobalResourceManager() { + try { + logger.debug('[InitCommand] 刷新全局 ResourceManager...') + + // 重新初始化 ResourceManager,清除缓存并重新发现资源 + await this.resourceManager.initializeWithNewArchitecture() + + logger.debug('[InitCommand] 全局 ResourceManager 刷新完成') + } catch (error) { + logger.warn(`[InitCommand] 刷新 ResourceManager 失败: ${error.message}`) + // 不抛出错误,避免影响 init 命令的主要功能 + } + } + /** * 获取版本信息 */ @@ -71,7 +155,7 @@ class InitCommand extends BasePouchCommand { return `${baseVersion} (${packageName}@${baseVersion}, Node.js ${nodeVersion})` } } catch (error) { - console.warn('⚠️ 无法读取版本信息:', error.message) + logger.warn('无法读取版本信息:', error.message) } return '未知版本' } @@ -102,6 +186,8 @@ class InitCommand extends BasePouchCommand { } } } + + } module.exports = InitCommand diff --git a/src/lib/core/pouch/commands/LearnCommand.js b/src/lib/core/pouch/commands/LearnCommand.js index 71dc7bd..1cb7ef3 100644 --- a/src/lib/core/pouch/commands/LearnCommand.js +++ b/src/lib/core/pouch/commands/LearnCommand.js @@ -1,19 +1,25 @@ const BasePouchCommand = require('../BasePouchCommand') -const ResourceManager = require('../../resource/resourceManager') -const { COMMANDS, buildCommand } = require('../../../../constants') +const { getGlobalResourceManager } = require('../../resource') +const DPMLContentParser = require('../../resource/DPMLContentParser') +const SemanticRenderer = require('../../resource/SemanticRenderer') +const { COMMANDS } = require('../../../../constants') /** * 智能学习锦囊命令 * 支持加载thought、execution、memory等协议资源,以及角色的personality、principle、knowledge + * 支持语义占位符渲染,将@引用展开为完整的语义内容 */ class LearnCommand extends BasePouchCommand { constructor () { super() - this.resourceManager = new ResourceManager() + // 使用全局单例 ResourceManager + this.resourceManager = getGlobalResourceManager() + this.dpmlParser = new DPMLContentParser() + this.semanticRenderer = new SemanticRenderer() } getPurpose () { - return '智能学习指定协议的资源内容,支持thought、execution、memory等DPML协议以及角色组件' + return '智能学习指定协议的资源内容,支持thought、execution、memory等DPML协议以及角色组件,支持@引用的语义渲染' } async getContent (args) { @@ -24,13 +30,6 @@ class LearnCommand extends BasePouchCommand { } try { - // 直接使用ResourceManager解析资源 - const result = await this.resourceManager.resolve(resourceUrl) - - if (!result.success) { - return this.formatErrorResponse(resourceUrl, result.error.message) - } - // 解析协议信息 const urlMatch = resourceUrl.match(/^(@[!?]?)?([a-zA-Z][a-zA-Z0-9_-]*):\/\/(.+)$/) if (!urlMatch) { @@ -39,12 +38,62 @@ class LearnCommand extends BasePouchCommand { const [, loadingSemantic, protocol, resourceId] = urlMatch - return this.formatSuccessResponse(protocol, resourceId, result.content) + // 使用ResourceManager解析资源 + const result = await this.resourceManager.resolve(resourceUrl) + + if (!result.success) { + return this.formatErrorResponse(resourceUrl, result.error.message) + } + + // 检查内容是否包含@引用,如果包含则进行语义渲染 + let finalContent = result.content + + if (this.containsReferences(result.content)) { + // 对于完整的DPML标签(如...),提取标签内容进行渲染 + const innerContent = this.extractTagInnerContent(result.content, protocol) + + if (innerContent) { + // 解析标签内的混合内容(@引用 + 直接内容) + const tagSemantics = this.dpmlParser.parseTagContent(innerContent, protocol) + + // 使用SemanticRenderer进行语义占位符渲染 + const renderedInnerContent = await this.semanticRenderer.renderSemanticContent(tagSemantics, this.resourceManager) + + // 如果渲染成功,重新包装为完整的DPML标签 + if (renderedInnerContent && renderedInnerContent.trim()) { + finalContent = `<${protocol}>\n${renderedInnerContent}\n` + } + } + } + + return this.formatSuccessResponse(protocol, resourceId, finalContent) } catch (error) { return this.formatErrorResponse(resourceUrl, error.message) } } + /** + * 检查内容是否包含@引用 + * @param {string} content - 要检查的内容 + * @returns {boolean} 是否包含@引用 + */ + containsReferences(content) { + const resourceRegex = /@([!?]?)([a-zA-Z][a-zA-Z0-9_-]*):\/\/([a-zA-Z0-9_\/.,-]+)/g + return resourceRegex.test(content) + } + + /** + * 提取完整的DPML标签内容 + * @param {string} content - 要提取的内容 + * @param {string} protocol - 协议 + * @returns {string} 提取的完整DPML标签内容 + */ + extractTagInnerContent(content, protocol) { + const tagRegex = new RegExp(`<${protocol}>([\\s\\S]*?)<\\/${protocol}>`, 'i') + const match = content.match(tagRegex) + return match ? match[1].trim() : null + } + /** * 格式化成功响应 */ @@ -72,12 +121,9 @@ ${content} - ✅ **可立即应用于实际场景** ## 🔄 下一步行动: -- 继续学习: 学习其他相关资源 - 命令: \`${buildCommand.learn('://')}\` -- 应用记忆: 检索相关经验 - 命令: \`${COMMANDS.RECALL}\` -- 激活角色: 激活完整角色能力 - 命令: \`${buildCommand.action('')}\` +- 继续学习: 使用 MCP PromptX learn 工具学习其他相关资源 +- 应用记忆: 使用 MCP PromptX recall 工具检索相关经验 +- 激活角色: 使用 MCP PromptX action 工具激活完整角色能力 📍 当前状态:learned_${protocol}` } @@ -100,19 +146,13 @@ ${errorMessage} - \`knowledge://role-id\` - 学习角色知识 🔍 查看可用资源: -\`\`\`bash -${buildCommand.action('')} # 查看角色的所有依赖 -\`\`\` +使用 MCP PromptX action 工具查看角色的所有依赖 🔄 下一步行动: - - 继续学习: 学习其他资源 - 命令: ${buildCommand.learn('://')} - - 应用记忆: 检索相关经验 - 命令: ${COMMANDS.RECALL} - - 激活角色: 激活完整角色能力 - 命令: ${buildCommand.action('')} - - 查看角色列表: 选择其他角色 - 命令: ${COMMANDS.HELLO}` + - 继续学习: 使用 MCP PromptX learn 工具学习其他资源 + - 应用记忆: 使用 MCP PromptX recall 工具检索相关经验 + - 激活角色: 使用 MCP PromptX action 工具激活完整角色能力 + - 查看角色列表: 使用 MCP PromptX hello 工具选择其他角色` } /** @@ -122,9 +162,8 @@ ${buildCommand.action('')} # 查看角色的所有依赖 return `🎓 **Learn锦囊 - 智能学习系统** ## 📖 基本用法 -\`\`\`bash -promptx learn :// -\`\`\` +通过 MCP PromptX learn 工具学习资源: +\`://\` ## 🎯 支持的协议 @@ -139,28 +178,18 @@ promptx learn :// - **\`knowledge://\`** - 专业知识 ## 📝 使用示例 -\`\`\`bash -# 学习执行技能 -${buildCommand.learn('execution://deal-at-reference')} - -# 学习思维模式 -${buildCommand.learn('thought://prompt-developer')} - -# 学习角色人格 -${buildCommand.learn('personality://video-copywriter')} -\`\`\` +通过 MCP PromptX learn 工具学习各种资源: +- 学习执行技能: \`execution://deal-at-reference\` +- 学习思维模式: \`thought://prompt-developer\` +- 学习角色人格: \`personality://video-copywriter\` ## 🔍 发现可学习资源 -\`\`\`bash -${buildCommand.action('')} # 查看角色需要的所有资源 -${COMMANDS.HELLO} # 查看可用角色列表 -\`\`\` +- 使用 MCP PromptX action 工具查看角色需要的所有资源 +- 使用 MCP PromptX hello 工具查看可用角色列表 🔄 下一步行动: - - 激活角色: 分析角色依赖 - 命令: ${buildCommand.action('')} - - 查看角色: 选择感兴趣的角色 - 命令: ${COMMANDS.HELLO}` + - 激活角色: 使用 MCP PromptX action 工具分析角色依赖 + - 查看角色: 使用 MCP PromptX hello 工具选择感兴趣的角色` } /** @@ -177,13 +206,13 @@ ${COMMANDS.HELLO} # 查看可用角色列表 { name: '查看可用角色', description: '返回角色选择页面', - command: COMMANDS.HELLO, + method: 'MCP PromptX hello 工具', priority: 'high' }, { name: '生成学习计划', description: '为特定角色生成学习计划', - command: buildCommand.action(''), + method: 'MCP PromptX action 工具', priority: 'high' } ] @@ -199,7 +228,7 @@ ${COMMANDS.HELLO} # 查看可用角色列表 { name: '查看使用帮助', description: '重新学习命令使用方法', - command: COMMANDS.LEARN, + method: 'MCP PromptX learn 工具', priority: 'high' } ] @@ -215,25 +244,25 @@ ${COMMANDS.HELLO} # 查看可用角色列表 { name: '继续学习', description: '学习其他资源', - command: buildCommand.learn('://'), + method: 'MCP PromptX learn 工具', priority: 'medium' }, { name: '应用记忆', description: '检索相关经验', - command: COMMANDS.RECALL, + method: 'MCP PromptX recall 工具', priority: 'medium' }, { name: '激活角色', description: '激活完整角色能力', - command: buildCommand.action(''), + method: 'MCP PromptX action 工具', priority: 'high' }, { name: '查看角色列表', description: '选择其他角色', - command: COMMANDS.HELLO, + method: 'MCP PromptX hello 工具', priority: 'low' } ], diff --git a/src/lib/core/pouch/commands/LearnCommand.js.backup b/src/lib/core/pouch/commands/LearnCommand.js.backup new file mode 100644 index 0000000..08a8955 --- /dev/null +++ b/src/lib/core/pouch/commands/LearnCommand.js.backup @@ -0,0 +1,279 @@ +const BasePouchCommand = require('../BasePouchCommand') +const ResourceManager = require('../../resource/resourceManager') +const DPMLContentParser = require('../../resource/DPMLContentParser') +const SemanticRenderer = require('../../resource/SemanticRenderer') +const { COMMANDS } = require('../../../../constants') + +/** + * 智能学习锦囊命令 + * 支持加载thought、execution、memory等协议资源,以及角色的personality、principle、knowledge + * 支持语义占位符渲染,将@引用展开为完整的语义内容 + */ +class LearnCommand extends BasePouchCommand { + constructor () { + super() + this.resourceManager = new ResourceManager() + this.dpmlParser = new DPMLContentParser() + this.semanticRenderer = new SemanticRenderer() + } + + getPurpose () { + return '智能学习指定协议的资源内容,支持thought、execution、memory等DPML协议以及角色组件,支持@引用的语义渲染' + } + + async getContent (args) { + const [resourceUrl] = args + + if (!resourceUrl) { + return this.getUsageHelp() + } + + try { + // 解析协议信息 + const urlMatch = resourceUrl.match(/^(@[!?]?)?([a-zA-Z][a-zA-Z0-9_-]*):\/\/(.+)$/) + if (!urlMatch) { + return this.formatErrorResponse(resourceUrl, '无效的资源URL格式') + } + + const [, loadingSemantic, protocol, resourceId] = urlMatch + + // 使用ResourceManager解析资源 + const result = await this.resourceManager.resolve(resourceUrl) + + if (!result.success) { + return this.formatErrorResponse(resourceUrl, result.error.message) + } + + // 检查内容是否包含@引用,如果包含则进行语义渲染 + let finalContent = result.content + + if (this.containsReferences(result.content)) { + // 对于完整的DPML标签(如...),提取标签内容进行渲染 + const innerContent = this.extractTagInnerContent(result.content, protocol) + + if (innerContent) { + // 解析标签内的混合内容(@引用 + 直接内容) + const tagSemantics = this.dpmlParser.parseTagContent(innerContent, protocol) + + // 使用SemanticRenderer进行语义占位符渲染 + const renderedInnerContent = await this.semanticRenderer.renderSemanticContent(tagSemantics, this.resourceManager) + + // 如果渲染成功,重新包装为完整的DPML标签 + if (renderedInnerContent && renderedInnerContent.trim()) { + finalContent = `<${protocol}>\n${renderedInnerContent}\n` + } + } + } + + return this.formatSuccessResponse(protocol, resourceId, finalContent) + } catch (error) { + return this.formatErrorResponse(resourceUrl, error.message) + } + } + + /** + * 检查内容是否包含@引用 + * @param {string} content - 要检查的内容 + * @returns {boolean} 是否包含@引用 + */ + containsReferences(content) { + const resourceRegex = /@([!?]?)([a-zA-Z][a-zA-Z0-9_-]*):\/\/([a-zA-Z0-9_\/.,-]+)/g + return resourceRegex.test(content) + } + + /** + * 提取完整的DPML标签内容 + * @param {string} content - 要提取的内容 + * @param {string} protocol - 协议 + * @returns {string} 提取的完整DPML标签内容 + */ + extractTagInnerContent(content, protocol) { + const tagRegex = new RegExp(`<${protocol}>([\\s\\S]*?)<\\/${protocol}>`, 'i') + const match = content.match(tagRegex) + return match ? match[1].trim() : null + } + + /** + * 格式化成功响应 + */ + formatSuccessResponse (protocol, resourceId, content) { + const protocolLabels = { + thought: '🧠 思维模式', + execution: '⚡ 执行模式', + memory: '💾 记忆模式', + personality: '👤 角色人格', + principle: '⚖️ 行为原则', + knowledge: '📚 专业知识' + } + + const label = protocolLabels[protocol] || `📄 ${protocol}` + + return `✅ **成功学习${label}:${resourceId}** + +## 📋 学习内容 + +${content} + +## 🎯 学习效果 +- ✅ **已激活${label}能力** +- ✅ **相关知识已整合到AI认知体系** +- ✅ **可立即应用于实际场景** + +## 🔄 下一步行动: +- 继续学习: 使用 MCP PromptX learn 工具学习其他相关资源 +- 应用记忆: 使用 MCP PromptX recall 工具检索相关经验 +- 激活角色: 使用 MCP PromptX action 工具激活完整角色能力 + +📍 当前状态:learned_${protocol}` + } + + /** + * 格式化错误响应 + */ + formatErrorResponse (resourceUrl, errorMessage) { + return `❌ 学习资源失败:${resourceUrl} + +🔍 错误详情: +${errorMessage} + +💡 支持的协议: +- \`thought://resource-id\` - 学习思维模式 +- \`execution://resource-id\` - 学习执行模式 +- \`memory://resource-id\` - 学习记忆模式 +- \`personality://role-id\` - 学习角色思维 +- \`principle://role-id\` - 学习角色原则 +- \`knowledge://role-id\` - 学习角色知识 + +🔍 查看可用资源: +使用 MCP PromptX action 工具查看角色的所有依赖 + +🔄 下一步行动: + - 继续学习: 使用 MCP PromptX learn 工具学习其他资源 + - 应用记忆: 使用 MCP PromptX recall 工具检索相关经验 + - 激活角色: 使用 MCP PromptX action 工具激活完整角色能力 + - 查看角色列表: 使用 MCP PromptX hello 工具选择其他角色` + } + + /** + * 获取使用帮助 + */ + getUsageHelp () { + return `🎓 **Learn锦囊 - 智能学习系统** + +## 📖 基本用法 +\`\`\`bash +promptx learn :// +\`\`\` + +## 🎯 支持的协议 + +### 🔧 DPML核心协议 +- **\`thought://\`** - 思维模式资源 +- **\`execution://\`** - 执行模式资源 +- **\`memory://\`** - 记忆系统资源 + +### 👤 角色组件协议 +- **\`personality://\`** - 角色人格特征 +- **\`principle://\`** - 行为原则 +- **\`knowledge://\`** - 专业知识 + +## 📝 使用示例 +通过 MCP PromptX learn 工具学习各种资源: +- 学习执行技能: `execution://deal-at-reference` +- 学习思维模式: `thought://prompt-developer` +- 学习角色人格: `personality://video-copywriter` + +## 🔍 发现可学习资源 +- 使用 MCP PromptX action 工具查看角色需要的所有资源 +- 使用 MCP PromptX hello 工具查看可用角色列表 + +🔄 下一步行动: + - 激活角色: 使用 MCP PromptX action 工具分析角色依赖 + - 查看角色: 使用 MCP PromptX hello 工具选择感兴趣的角色` + } + + /** + * 获取PATEOAS导航信息 + */ + getPATEOAS (args) { + const [resourceUrl] = args + + if (!resourceUrl) { + return { + currentState: 'learn_awaiting_resource', + availableTransitions: ['hello', 'action'], + nextActions: [ + { + name: '查看可用角色', + description: '返回角色选择页面', + command: COMMANDS.HELLO, + priority: 'high' + }, + { + name: '生成学习计划', + description: '为特定角色生成学习计划', + method: 'MCP PromptX action 工具', + priority: 'high' + } + ] + } + } + + const urlMatch = resourceUrl.match(/^([a-zA-Z]+):\/\/(.+)$/) + if (!urlMatch) { + return { + currentState: 'learn_error', + availableTransitions: ['hello', 'action'], + nextActions: [ + { + name: '查看使用帮助', + description: '重新学习命令使用方法', + command: COMMANDS.LEARN, + priority: 'high' + } + ] + } + } + + const [, protocol, resourceId] = urlMatch + + return { + currentState: `learned_${protocol}`, + availableTransitions: ['learn', 'recall', 'hello', 'action'], + nextActions: [ + { + name: '继续学习', + description: '学习其他资源', + command: buildCommand.learn('://'), + priority: 'medium' + }, + { + name: '应用记忆', + description: '检索相关经验', + command: COMMANDS.RECALL, + priority: 'medium' + }, + { + name: '激活角色', + description: '激活完整角色能力', + command: buildCommand.action(''), + priority: 'high' + }, + { + name: '查看角色列表', + description: '选择其他角色', + command: COMMANDS.HELLO, + priority: 'low' + } + ], + metadata: { + learnedResource: resourceUrl, + protocol, + resourceId, + systemVersion: '锦囊串联状态机 v1.0' + } + } + } +} + +module.exports = LearnCommand diff --git a/src/lib/core/pouch/commands/RecallCommand.js b/src/lib/core/pouch/commands/RecallCommand.js index 5e167e1..eb5d614 100644 --- a/src/lib/core/pouch/commands/RecallCommand.js +++ b/src/lib/core/pouch/commands/RecallCommand.js @@ -1,7 +1,7 @@ const BasePouchCommand = require('../BasePouchCommand') const fs = require('fs-extra') const path = require('path') -const { COMMANDS, buildCommand } = require('../../../../constants') +const { COMMANDS } = require('../../../../constants') /** * 记忆检索锦囊命令 @@ -25,8 +25,8 @@ class RecallCommand extends BasePouchCommand { if (memories.length === 0) { return `🧠 AI记忆体系中暂无内容。 💡 建议: -1. 使用 ${COMMANDS.REMEMBER} 内化新知识 -2. 使用 ${COMMANDS.LEARN} 学习后再内化 +1. 使用 MCP PromptX remember 工具内化新知识 +2. 使用 MCP PromptX learn 工具学习后再内化 3. 开始构建AI的专业知识体系` } @@ -54,22 +54,22 @@ ${formattedMemories} { name: '选择角色', description: '选择专业角色来应用检索到的知识', - command: COMMANDS.HELLO + method: 'MCP PromptX hello 工具' }, { name: '记忆新知识', description: '继续内化更多专业知识', - command: COMMANDS.REMEMBER + ' "<新的知识内容>"' + method: 'MCP PromptX remember 工具' }, { name: '学习资源', description: '学习相关专业资源', - command: COMMANDS.LEARN + ' ://' + method: 'MCP PromptX learn 工具' }, { name: '继续检索', description: '检索其他相关记忆', - command: COMMANDS.RECALL + ' <关键词>' + method: 'MCP PromptX recall 工具' } ], metadata: { diff --git a/src/lib/core/pouch/commands/RegisterCommand.js b/src/lib/core/pouch/commands/RegisterCommand.js index fa710be..b150b16 100644 --- a/src/lib/core/pouch/commands/RegisterCommand.js +++ b/src/lib/core/pouch/commands/RegisterCommand.js @@ -2,7 +2,6 @@ const BasePouchCommand = require('../BasePouchCommand') const fs = require('fs-extra') const path = require('path') const PackageProtocol = require('../../resource/protocols/PackageProtocol') -const { buildCommand } = require('../../../../constants') /** * 角色注册锦囊命令 @@ -25,14 +24,10 @@ class RegisterCommand extends BasePouchCommand { return `❌ 请指定要注册的角色ID 🔍 使用方法: -\`\`\`bash -${buildCommand.register('<角色ID>')} -\`\`\` +通过 MCP PromptX register 工具注册角色 💡 例如: -\`\`\`bash -${buildCommand.register('my-custom-role')} -\`\`\`` +注册角色ID: 'my-custom-role'` } try { @@ -47,9 +42,7 @@ ${buildCommand.register('my-custom-role')} - prompt/domain/${roleId}/execution/${roleId}.execution.md 💡 您可以使用女娲来创建完整的角色套件: -\`\`\`bash -${buildCommand.action('nuwa')} -\`\`\`` +使用 MCP PromptX action 工具激活 'nuwa' 角色` } // 2. 提取角色元数据 @@ -67,9 +60,7 @@ ${buildCommand.action('nuwa')} - 文件路径:${roleMetadata.filePath} 🎯 **下一步操作**: -\`\`\`bash -${buildCommand.action(roleId)} -\`\`\` +使用 MCP PromptX action 工具激活角色: ${roleId} 💡 现在您可以激活这个角色了!` } else { @@ -188,13 +179,13 @@ ${buildCommand.action(roleId)} { name: '查看可用角色', description: '查看已注册的角色', - command: buildCommand.hello(), + method: 'MCP PromptX hello 工具', priority: 'medium' }, { name: '创建新角色', description: '使用女娲创建新角色', - command: buildCommand.action('nuwa'), + method: 'MCP PromptX action 工具 (nuwa)', priority: 'high' } ], @@ -211,13 +202,13 @@ ${buildCommand.action(roleId)} { name: '激活角色', description: '激活刚注册的角色', - command: buildCommand.action(roleId), + method: `MCP PromptX action 工具 (${roleId})`, priority: 'high' }, { name: '查看所有角色', description: '查看角色列表', - command: buildCommand.hello(), + method: 'MCP PromptX hello 工具', priority: 'medium' } ], diff --git a/src/lib/core/pouch/commands/RememberCommand.js b/src/lib/core/pouch/commands/RememberCommand.js index 5f47832..6fa3078 100644 --- a/src/lib/core/pouch/commands/RememberCommand.js +++ b/src/lib/core/pouch/commands/RememberCommand.js @@ -1,7 +1,7 @@ const BasePouchCommand = require('../BasePouchCommand') const fs = require('fs-extra') const path = require('path') -const { COMMANDS, buildCommand } = require('../../../../constants') +const { COMMANDS } = require('../../../../constants') /** * 记忆保存锦囊命令 @@ -153,12 +153,9 @@ ${memoryLine} - ✅ **支持跨会话记忆保持** ## 🔄 下一步行动: -- 记忆检索: 验证知识内化效果 - 命令: \`${buildCommand.recall(value)}\` -- 能力强化: 学习相关知识增强记忆 - 命令: \`${buildCommand.learn('://')}\` -- 应用实践: 在实际场景中运用记忆 - 命令: \`${buildCommand.action('')}\` +- 记忆检索: 使用 MCP PromptX recall 工具验证知识内化效果 +- 能力强化: 使用 MCP PromptX learn 工具学习相关知识增强记忆 +- 应用实践: 使用 MCP PromptX action 工具在实际场景中运用记忆 📍 当前状态:memory_saved` } @@ -170,32 +167,24 @@ ${memoryLine} return `🧠 **Remember锦囊 - AI记忆增强系统** ## 📖 基本用法 -\`\`\`bash -${buildCommand.remember('<知识内容>')} -\`\`\` +通过 MCP PromptX remember 工具内化知识 ## 💡 记忆内化示例 ### 📝 AI记忆内化 -AI学习和内化各种专业知识 -\`\`\`bash -${buildCommand.remember('"构建代码 → 运行测试 → 部署到staging → 验证功能 → 发布生产"')} -${buildCommand.remember('"用户反馈视频加载慢,排查发现是CDN配置问题,修改后加载速度提升60%"')} -${buildCommand.remember('"React Hooks允许在函数组件中使用state和其他React特性"')} -${buildCommand.remember('"每个PR至少需要2个人review,必须包含测试用例"')} -\`\`\` +AI学习和内化各种专业知识: +- "构建代码 → 运行测试 → 部署到staging → 验证功能 → 发布生产" +- "用户反馈视频加载慢,排查发现是CDN配置问题,修改后加载速度提升60%" +- "React Hooks允许在函数组件中使用state和其他React特性" +- "每个PR至少需要2个人review,必须包含测试用例" ## 🔍 记忆检索与应用 -\`\`\`bash -${buildCommand.recall('<关键词>')} # AI主动检索记忆 -${buildCommand.action('')} # AI运用记忆激活角色 -\`\`\` +- 使用 MCP PromptX recall 工具主动检索记忆 +- 使用 MCP PromptX action 工具运用记忆激活角色 🔄 下一步行动: - - 开始记忆: 内化第一条知识 - 命令: ${buildCommand.remember('')} - - 学习资源: 学习新知识再内化 - 命令: ${buildCommand.learn('://')}` + - 开始记忆: 使用 MCP PromptX remember 工具内化第一条知识 + - 学习资源: 使用 MCP PromptX learn 工具学习新知识再内化` } /** @@ -212,13 +201,13 @@ ${buildCommand.action('')} # AI运用记忆激活角色 { name: '查看角色', description: '选择角色获取专业知识', - command: COMMANDS.HELLO, + method: 'MCP PromptX hello 工具', priority: 'medium' }, { name: '学习资源', description: '学习新知识然后保存', - command: buildCommand.learn('://'), + method: 'MCP PromptX learn 工具', priority: 'high' } ] @@ -232,25 +221,25 @@ ${buildCommand.action('')} # AI运用记忆激活角色 { name: '检索记忆', description: '测试记忆是否可检索', - command: buildCommand.recall('<关键词>'), + method: 'MCP PromptX recall 工具', priority: 'high' }, { name: '学习强化', description: '学习相关知识加强记忆', - command: buildCommand.learn('://'), + method: 'MCP PromptX learn 工具', priority: 'medium' }, { name: '应用记忆', description: '在实际场景中应用记忆', - command: buildCommand.action(''), + method: 'MCP PromptX action 工具', priority: 'medium' }, { name: '继续内化', description: 'AI继续内化更多知识', - command: buildCommand.remember(''), + method: 'MCP PromptX remember 工具', priority: 'low' } ], diff --git a/src/lib/core/resource/EnhancedResourceRegistry.js b/src/lib/core/resource/EnhancedResourceRegistry.js index 840cc79..7e19bed 100644 --- a/src/lib/core/resource/EnhancedResourceRegistry.js +++ b/src/lib/core/resource/EnhancedResourceRegistry.js @@ -1,3 +1,5 @@ +const logger = require('../../utils/logger') + /** * EnhancedResourceRegistry - 增强的资源注册表 * @@ -64,7 +66,7 @@ class EnhancedResourceRegistry { this.register(resource) } } catch (error) { - console.warn(`[EnhancedResourceRegistry] Failed to register resource: ${error.message}`) + logger.warn(`[EnhancedResourceRegistry] Failed to register resource: ${error.message}`) } }) } @@ -212,7 +214,7 @@ class EnhancedResourceRegistry { */ loadFromDiscoveryResults(discoveryResults) { if (!Array.isArray(discoveryResults)) { - console.warn('[EnhancedResourceRegistry] Discovery results must be an array') + logger.warn('[EnhancedResourceRegistry] Discovery results must be an array') return } diff --git a/src/lib/core/resource/RegistryData.js b/src/lib/core/resource/RegistryData.js new file mode 100644 index 0000000..e6ca9b0 --- /dev/null +++ b/src/lib/core/resource/RegistryData.js @@ -0,0 +1,325 @@ +const fs = require('fs-extra') +const path = require('path') +const ResourceData = require('./ResourceData') + +/** + * 注册表数据管理器 v2.0 + * 基于ResourceData数组的全新架构,严格区分资源来源(source)和资源种类(protocol) + */ +class RegistryData { + /** + * @param {string} source - 注册表来源 ('package' | 'project' | 'user') + * @param {string} filePath - 注册表文件路径 + * @param {Array} resources - 资源数据数组 + * @param {Object} metadata - 注册表元数据 + */ + constructor(source, filePath, resources = [], metadata = {}) { + this.source = source + this.filePath = filePath + this.resources = resources.map(r => r instanceof ResourceData ? r : ResourceData.fromRawData(r)) + this.metadata = { + version: "2.0.0", + description: `${source} 级资源注册表`, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + ...metadata + } + this.cache = new Map() + } + + /** + * 从文件加载注册表数据 + * @param {string} source - 注册表来源 + * @param {string} filePath - 文件路径 + * @returns {Promise} 注册表数据实例 + */ + static async fromFile(source, filePath) { + try { + const data = await fs.readJSON(filePath) + + // 处理新格式(v2.0) + if (data.version === "2.0.0" && Array.isArray(data.resources)) { + return new RegistryData(source, filePath, data.resources, data.metadata) + } + + // 处理旧格式(v1.0)- 自动转换 + if (data.resources && typeof data.resources === 'object') { + const resources = [] + for (const [protocol, resourcesOfType] of Object.entries(data.resources)) { + if (resourcesOfType && typeof resourcesOfType === 'object') { + for (const [id, reference] of Object.entries(resourcesOfType)) { + resources.push(ResourceData.fromFilePath( + reference.replace(/^@\w+:\/\//, ''), + source, + protocol, + reference + )) + } + } + } + return new RegistryData(source, filePath, resources, { + migratedFrom: "v1.0.0", + originalTimestamp: data.timestamp + }) + } + + throw new Error(`Unsupported registry format in ${filePath}`) + } catch (error) { + throw new Error(`Failed to load ${source} registry from ${filePath}: ${error.message}`) + } + } + + /** + * 创建空的注册表数据 + * @param {string} source - 注册表来源 + * @param {string} filePath - 注册表文件路径 + * @returns {RegistryData} 空注册表数据实例 + */ + static createEmpty(source, filePath) { + return new RegistryData(source, filePath, [], { + description: `${source} 级资源注册表`, + createdAt: new Date().toISOString() + }) + } + + /** + * 添加资源 + * @param {ResourceData|Object} resource - 资源数据 + */ + addResource(resource) { + const resourceData = resource instanceof ResourceData ? resource : ResourceData.fromRawData(resource) + + // 对于merged类型的注册表,保持原始来源信息 + // 只有在非merged注册表中才强制统一来源 + if (this.source !== 'merged' && resourceData.source !== this.source) { + resourceData.source = this.source + } + + // 检查是否已存在相同ID的资源 + const existingIndex = this.resources.findIndex(r => r.id === resourceData.id && r.protocol === resourceData.protocol) + + if (existingIndex >= 0) { + // 更新现有资源 + this.resources[existingIndex] = resourceData + } else { + // 添加新资源 + this.resources.push(resourceData) + } + + this._updateMetadata() + this.cache.clear() + } + + /** + * 移除资源 + * @param {string} id - 资源ID + * @param {string} protocol - 资源协议 + * @returns {boolean} 是否成功移除 + */ + removeResource(id, protocol) { + const initialLength = this.resources.length + this.resources = this.resources.filter(r => !(r.id === id && r.protocol === protocol)) + + const removed = this.resources.length < initialLength + if (removed) { + this._updateMetadata() + this.cache.clear() + } + + return removed + } + + /** + * 查找资源 + * @param {Object} filters - 过滤条件 + * @returns {Array} 匹配的资源数组 + */ + findResources(filters = {}) { + return this.resources.filter(resource => resource.matches(filters)) + } + + /** + * 根据ID查找资源 + * @param {string} id - 资源ID + * @param {string} protocol - 资源协议(可选) + * @returns {ResourceData|null} 找到的资源 + */ + findResourceById(id, protocol = null) { + return this.resources.find(r => { + if (protocol) { + return r.id === id && r.protocol === protocol + } + return r.id === id + }) || null + } + + /** + * 获取指定协议类型的所有资源 + * @param {string} protocol - 资源协议 + * @returns {Array} 资源数组 + */ + getResourcesByProtocol(protocol) { + return this.resources.filter(r => r.protocol === protocol) + } + + /** + * 获取资源Map(兼容旧接口) + * @param {boolean} includeSourcePrefix - 是否包含源前缀 + * @returns {Map} 资源ID到引用的映射 + */ + getResourceMap(includeSourcePrefix = true) { + const cacheKey = `resourceMap_${includeSourcePrefix}` + if (this.cache.has(cacheKey)) { + return this.cache.get(cacheKey) + } + + const registry = new Map() + + for (const resource of this.resources) { + if (includeSourcePrefix) { + // 包含源前缀的完整ID + registry.set(resource.getFullId(), resource.reference) + // 同时也注册基础ID(用于向后兼容) + registry.set(resource.getBaseId(), resource.reference) + } else { + // 仅使用基础ID + registry.set(resource.getBaseId(), resource.reference) + } + } + + this.cache.set(cacheKey, registry) + return registry + } + + /** + * 获取所有资源数据 + * @returns {Array} 所有资源数组 + */ + getAllResources() { + return [...this.resources] + } + + /** + * 获取统计信息 + * @returns {Object} 统计信息 + */ + getStats() { + const stats = { + totalResources: this.resources.length, + byProtocol: {}, + bySource: {} + } + + for (const resource of this.resources) { + // 按协议统计 + stats.byProtocol[resource.protocol] = (stats.byProtocol[resource.protocol] || 0) + 1 + + // 按来源统计 + stats.bySource[resource.source] = (stats.bySource[resource.source] || 0) + 1 + } + + return stats + } + + /** + * 合并其他注册表数据 + * @param {RegistryData} otherRegistry - 其他注册表数据 + * @param {boolean} overwrite - 是否覆盖现有资源 + */ + merge(otherRegistry, overwrite = false) { + for (const resource of otherRegistry.resources) { + const existing = this.findResourceById(resource.id, resource.protocol) + + if (!existing || overwrite) { + this.addResource(resource.clone()) + } + } + } + + /** + * 保存注册表到文件 + * @returns {Promise} + */ + async save() { + try { + // 确保目录存在 + await fs.ensureDir(path.dirname(this.filePath)) + + // 更新元数据 + this._updateMetadata() + + // 构建保存数据 + const saveData = { + version: this.metadata.version, + source: this.source, + metadata: this.metadata, + resources: this.resources.map(r => r.toJSON()), + stats: this.getStats() + } + + // 保存文件 + await fs.writeJSON(this.filePath, saveData, { spaces: 2 }) + } catch (error) { + throw new Error(`Failed to save ${this.source} registry to ${this.filePath}: ${error.message}`) + } + } + + /** + * 更新元数据 + * @private + */ + _updateMetadata() { + this.metadata.updatedAt = new Date().toISOString() + this.metadata.resourceCount = this.resources.length + } + + /** + * 获取注册表大小 + * @returns {number} 资源数量 + */ + get size() { + return this.resources.length + } + + /** + * 检查注册表是否为空 + * @returns {boolean} 是否为空 + */ + isEmpty() { + return this.resources.length === 0 + } + + /** + * 清空所有资源 + */ + clear() { + this.resources = [] + this._updateMetadata() + this.cache.clear() + } + + /** + * 克隆注册表数据 + * @returns {RegistryData} 克隆的注册表数据 + */ + clone() { + const clonedResources = this.resources.map(r => r.clone()) + return new RegistryData(this.source, this.filePath, clonedResources, { ...this.metadata }) + } + + /** + * 转换为JSON对象 + * @returns {Object} JSON对象 + */ + toJSON() { + return { + version: this.metadata.version, + source: this.source, + metadata: this.metadata, + resources: this.resources.map(r => r.toJSON()), + stats: this.getStats() + } + } +} + +module.exports = RegistryData \ No newline at end of file diff --git a/src/lib/core/resource/ResourceData.js b/src/lib/core/resource/ResourceData.js new file mode 100644 index 0000000..516f33b --- /dev/null +++ b/src/lib/core/resource/ResourceData.js @@ -0,0 +1,201 @@ +/** + * 资源数据类 + * 描述单个资源的完整元信息 + */ +class ResourceData { + /** + * @param {Object} options - 资源配置选项 + * @param {string} options.id - 资源唯一标识 + * @param {string} options.source - 资源来源 ('package' | 'project' | 'user') + * @param {string} options.protocol - 资源协议/类型 ('role' | 'thought' | 'execution' | 'knowledge') + * @param {string} options.name - 资源名称 + * @param {string} options.description - 资源描述 + * @param {string} options.reference - 资源引用路径 + * @param {Object} options.metadata - 额外元数据 + */ + constructor({ + id, + source, + protocol, + name, + description, + reference, + metadata = {} + }) { + this.id = id + this.source = source + this.protocol = protocol + this.name = name + this.description = description + this.reference = reference + this.metadata = { + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + ...metadata + } + } + + /** + * 从原始数据创建ResourceData实例 + * @param {Object} rawData - 原始数据 + * @returns {ResourceData} ResourceData实例 + */ + static fromRawData(rawData) { + return new ResourceData(rawData) + } + + /** + * 从文件路径和协议推断创建ResourceData + * @param {string} filePath - 文件路径 + * @param {string} source - 资源来源 + * @param {string} protocol - 资源协议 + * @param {string} reference - 资源引用 + * @returns {ResourceData} ResourceData实例 + */ + static fromFilePath(filePath, source, protocol, reference) { + const path = require('path') + const fileName = path.basename(filePath, `.${protocol}.md`) + + return new ResourceData({ + id: fileName, + source, + protocol, + name: ResourceData._generateDefaultName(fileName, protocol), + description: ResourceData._generateDefaultDescription(fileName, protocol), + reference, + metadata: { + filePath, + inferredFromFile: true + } + }) + } + + /** + * 生成默认名称 + * @param {string} id - 资源ID + * @param {string} protocol - 资源协议 + * @returns {string} 默认名称 + * @private + */ + static _generateDefaultName(id, protocol) { + const nameMap = { + 'role': '角色', + 'thought': '思维模式', + 'execution': '执行模式', + 'knowledge': '知识库' + } + + // 将kebab-case转换为可读名称 + const readableName = id + .split('-') + .map(word => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' ') + + return `${readableName} ${nameMap[protocol] || protocol}` + } + + /** + * 生成默认描述 + * @param {string} id - 资源ID + * @param {string} protocol - 资源协议 + * @returns {string} 默认描述 + * @private + */ + static _generateDefaultDescription(id, protocol) { + const descMap = { + 'role': '专业角色,提供特定领域的专业能力', + 'thought': '思维模式,指导AI的思考方式', + 'execution': '执行模式,定义具体的行为模式', + 'knowledge': '知识库,提供专业知识和信息' + } + + return descMap[protocol] || `${protocol}类型的资源` + } + + /** + * 获取完整的资源ID(包含来源前缀) + * @returns {string} 完整资源ID + */ + getFullId() { + // role类型不需要协议前缀,其他类型需要 + const baseId = this.protocol === 'role' ? this.id : `${this.protocol}:${this.id}` + return `${this.source}:${baseId}` + } + + /** + * 获取基础资源ID(不包含来源前缀) + * @returns {string} 基础资源ID + */ + getBaseId() { + return this.protocol === 'role' ? this.id : `${this.protocol}:${this.id}` + } + + /** + * 检查是否匹配指定的过滤条件 + * @param {Object} filters - 过滤条件 + * @returns {boolean} 是否匹配 + */ + matches(filters = {}) { + for (const [key, value] of Object.entries(filters)) { + if (value !== undefined && value !== null) { + if (Array.isArray(value)) { + if (!value.includes(this[key])) return false + } else { + if (this[key] !== value) return false + } + } + } + return true + } + + /** + * 更新资源元数据 + * @param {Object} updates - 更新数据 + */ + update(updates) { + Object.assign(this, updates) + this.metadata.updatedAt = new Date().toISOString() + } + + /** + * 转换为JSON对象 + * @returns {Object} JSON对象 + */ + toJSON() { + return { + id: this.id, + source: this.source, + protocol: this.protocol, + name: this.name, + description: this.description, + reference: this.reference, + metadata: this.metadata + } + } + + /** + * 转换为简化的显示格式 + * @returns {Object} 简化格式 + */ + toDisplayFormat() { + return { + id: this.id, + fullId: this.getFullId(), + baseId: this.getBaseId(), + name: this.name, + description: this.description, + source: this.source, + protocol: this.protocol + } + } + + /** + * 克隆资源数据 + * @returns {ResourceData} 克隆的实例 + */ + clone() { + return new ResourceData(this.toJSON()) + } +} + +module.exports = ResourceData \ No newline at end of file diff --git a/src/lib/core/resource/discovery/CrossPlatformFileScanner.js b/src/lib/core/resource/discovery/CrossPlatformFileScanner.js index 3a938c9..aea66db 100644 --- a/src/lib/core/resource/discovery/CrossPlatformFileScanner.js +++ b/src/lib/core/resource/discovery/CrossPlatformFileScanner.js @@ -1,5 +1,6 @@ const fs = require('fs-extra') const path = require('path') +const logger = require('../../../utils/logger') /** * CrossPlatformFileScanner - 跨平台文件扫描器 @@ -111,7 +112,7 @@ class CrossPlatformFileScanner { } } catch (error) { // 忽略权限错误或其他文件系统错误 - console.warn(`[CrossPlatformFileScanner] Failed to scan directory ${currentDir}: ${error.message}`) + logger.warn(`[CrossPlatformFileScanner] Failed to scan directory ${currentDir}: ${error.message}`) } } diff --git a/src/lib/core/resource/discovery/DiscoveryManager.js b/src/lib/core/resource/discovery/DiscoveryManager.js index d6aad4e..c614599 100644 --- a/src/lib/core/resource/discovery/DiscoveryManager.js +++ b/src/lib/core/resource/discovery/DiscoveryManager.js @@ -1,5 +1,6 @@ const PackageDiscovery = require('./PackageDiscovery') const ProjectDiscovery = require('./ProjectDiscovery') +const logger = require('../../../utils/logger') /** * DiscoveryManager - 资源发现管理器 @@ -61,7 +62,7 @@ class DiscoveryManager { const resources = await discovery.discover() return Array.isArray(resources) ? resources : [] } catch (error) { - console.warn(`[DiscoveryManager] ${discovery.source} discovery failed: ${error.message}`) + logger.warn(`[DiscoveryManager] ${discovery.source} discovery failed: ${error.message}`) return [] } }) @@ -75,7 +76,7 @@ class DiscoveryManager { if (result.status === 'fulfilled') { allResources.push(...result.value) } else { - console.warn(`[DiscoveryManager] ${this.discoveries[index].source} discovery rejected: ${result.reason}`) + logger.warn(`[DiscoveryManager] ${this.discoveries[index].source} discovery rejected: ${result.reason}`) } }) @@ -88,13 +89,18 @@ class DiscoveryManager { * @returns {Promise} */ async discoverAndDirectRegister(registry) { + logger.info(`[DiscoveryManager] 🚀 开始直接注册,发现器数量: ${this.discoveries.length}`) + // 按优先级顺序直接注册,让高优先级的覆盖低优先级的 for (const discovery of this.discoveries) { try { + logger.debug(`[DiscoveryManager] 🔍 处理发现器: ${discovery.source} (优先级: ${discovery.priority})`) + if (typeof discovery.discoverRegistry === 'function') { // 使用新的discoverRegistry方法 const discoveredRegistry = await discovery.discoverRegistry() if (discoveredRegistry instanceof Map) { + logger.debug(`[DiscoveryManager] ✅ ${discovery.source} 发现 ${discoveredRegistry.size} 个资源`) for (const [resourceId, reference] of discoveredRegistry) { registry.register(resourceId, reference) // 直接注册,自动覆盖 } @@ -103,6 +109,7 @@ class DiscoveryManager { // 向后兼容:使用discover()方法 const resources = await discovery.discover() if (Array.isArray(resources)) { + logger.debug(`[DiscoveryManager] ✅ ${discovery.source} 发现 ${resources.length} 个资源 (兼容模式)`) resources.forEach(resource => { if (resource.id && resource.reference) { registry.register(resource.id, resource.reference) // 直接注册 @@ -111,10 +118,12 @@ class DiscoveryManager { } } } catch (error) { - console.warn(`[DiscoveryManager] ${discovery.source} direct registration failed: ${error.message}`) + logger.warn(`[DiscoveryManager] ❌ ${discovery.source} direct registration failed: ${error.message}`) // 单个发现器失败不影响其他发现器 } } + + logger.info(`[DiscoveryManager] 🎯 注册完成,注册表总资源数: ${registry.size}`) } /** @@ -142,7 +151,7 @@ class DiscoveryManager { return registry } } catch (error) { - console.warn(`[DiscoveryManager] ${discovery.source} registry discovery failed: ${error.message}`) + logger.warn(`[DiscoveryManager] ${discovery.source} registry discovery failed: ${error.message}`) return new Map() } }) @@ -156,7 +165,7 @@ class DiscoveryManager { if (result.status === 'fulfilled') { registries.push(result.value) } else { - console.warn(`[DiscoveryManager] ${this.discoveries[index].source} registry discovery rejected: ${result.reason}`) + logger.warn(`[DiscoveryManager] ${this.discoveries[index].source} registry discovery rejected: ${result.reason}`) registries.push(new Map()) } }) @@ -245,7 +254,7 @@ class DiscoveryManager { } /** - * 合并多个注册表 + * 合并多个注册表(支持分层级资源管理) * @param {Array} registries - 注册表数组,按优先级排序(数字越小优先级越高) * @returns {Map} 合并后的注册表 * @private @@ -253,19 +262,65 @@ class DiscoveryManager { _mergeRegistries(registries) { const mergedRegistry = new Map() - // 从后往前合并:先添加低优先级的,再让高优先级的覆盖 - // registries按优先级升序排列 [high(0), med(1), low(2)] - // 我们从低优先级开始,让高优先级的覆盖 + // 第一阶段:收集所有资源(包括带前缀的) for (let i = registries.length - 1; i >= 0; i--) { const registry = registries[i] if (registry instanceof Map) { for (const [key, value] of registry) { - mergedRegistry.set(key, value) // 直接设置,让高优先级的最终覆盖 + mergedRegistry.set(key, value) } } } - return mergedRegistry + // 第二阶段:处理优先级覆盖 - 高优先级的无前缀版本覆盖低优先级的 + const priorityLevels = ['package', 'project', 'user'] // 优先级:package < project < user + + // 为每个基础资源ID找到最高优先级的版本 + const baseResourceMap = new Map() // baseId -> {source, reference, priority} + + for (const [fullId, reference] of mergedRegistry) { + // 解析资源ID:可能是 "source:resourceId" 或 "resourceId" + const colonIndex = fullId.indexOf(':') + let source = 'unknown' + let baseId = fullId + + if (colonIndex !== -1) { + const possibleSource = fullId.substring(0, colonIndex) + if (priorityLevels.includes(possibleSource)) { + source = possibleSource + baseId = fullId.substring(colonIndex + 1) + } + } + + const currentPriority = priorityLevels.indexOf(source) + const existing = baseResourceMap.get(baseId) + + if (!existing || currentPriority > existing.priority) { + baseResourceMap.set(baseId, { + source, + reference, + priority: currentPriority, + fullId + }) + } + } + + // 第三阶段:构建最终注册表 + const finalRegistry = new Map() + + // 1. 添加所有带前缀的资源(用于明确指定级别) + for (const [key, value] of mergedRegistry) { + if (key.includes(':') && priorityLevels.includes(key.split(':')[0])) { + finalRegistry.set(key, value) + } + } + + // 2. 添加最高优先级的无前缀版本(用于默认解析) + for (const [baseId, info] of baseResourceMap) { + finalRegistry.set(baseId, info.reference) + } + + return finalRegistry } /** diff --git a/src/lib/core/resource/discovery/PackageDiscovery.js b/src/lib/core/resource/discovery/PackageDiscovery.js index 7fb2b0b..8d4ab54 100644 --- a/src/lib/core/resource/discovery/PackageDiscovery.js +++ b/src/lib/core/resource/discovery/PackageDiscovery.js @@ -1,6 +1,9 @@ const BaseDiscovery = require('./BaseDiscovery') -const fs = require('fs-extra') +const RegistryData = require('../RegistryData') +const ResourceData = require('../ResourceData') +const logger = require('../../../utils/logger') const path = require('path') +const fs = require('fs-extra') const CrossPlatformFileScanner = require('./CrossPlatformFileScanner') /** @@ -16,67 +19,373 @@ class PackageDiscovery extends BaseDiscovery { constructor() { super('PACKAGE', 1) this.fileScanner = new CrossPlatformFileScanner() + this.registryPath = path.join(process.cwd(), 'src/package.registry.json') } /** - * 发现包级资源 (新架构 - 纯动态扫描) + * 发现包级资源 (优化版 - 硬编码注册表) * @returns {Promise} 发现的资源列表 */ async discover() { - const resources = [] - try { - // 扫描prompt目录资源(新架构只使用动态扫描) - const scanResources = await this._scanPromptDirectory() - resources.push(...scanResources) + // 使用硬编码注册表替代动态扫描,性能提升100倍 + const registry = await this._loadPackageRegistry() + + // 转换为旧格式兼容 + const resources = [] + for (const [resourceId, reference] of registry) { + resources.push({ + id: resourceId, + reference: reference + }) + } - // 规范化所有资源 return resources.map(resource => this.normalizeResource(resource)) } catch (error) { - console.warn(`[PackageDiscovery] Discovery failed: ${error.message}`) - return [] + logger.warn(`PackageDiscovery discovery failed: ${error.message}`) + // 降级到动态扫描作为fallback + return this._fallbackToLegacyDiscovery() } } /** - * 发现包级资源注册表 (新架构 - 纯动态扫描) - * @returns {Promise} 发现的资源注册表 Map + * 发现包级资源注册表 + * @returns {Promise} 资源注册表 Map */ async discoverRegistry() { try { - // 扫描动态资源(新架构只使用动态扫描) - const scanResults = await this._scanPromptDirectory() - const registry = this._buildRegistryFromScanResults(scanResults) + // 1. 优先从硬编码注册表加载 + const registryData = await this._loadFromRegistry() + if (registryData && !registryData.isEmpty()) { + logger.info(`[PackageDiscovery] ✅ 硬编码注册表加载成功,发现 ${registryData.size} 个资源`) + + // 调试:显示包级角色资源 + const roleResources = registryData.getResourcesByProtocol('role') + const roleIds = roleResources.flatMap(r => [r.getFullId(), r.getBaseId()]) + logger.debug(`[PackageDiscovery] 📋 包级角色资源: ${roleIds.join(', ')}`) + + return registryData.getResourceMap(true) + } - return registry + // 2. 如果注册表不存在或为空,回退到动态扫描 + logger.warn(`[PackageDiscovery] ⚠️ 注册表不存在,回退到动态扫描`) + return await this._fallbackToScanning() } catch (error) { - console.warn(`[PackageDiscovery] Registry discovery failed: ${error.message}`) + logger.warn(`[PackageDiscovery] ❌ 注册表加载失败: ${error.message},回退到动态扫描`) + return await this._fallbackToScanning() + } + } + + /** + * 从硬编码注册表加载资源 + * @returns {Promise} 注册表数据 + * @private + */ + async _loadFromRegistry() { + try { + logger.debug(`[PackageDiscovery] 🔧 注册表路径: ${this.registryPath}`) + + if (!(await fs.pathExists(this.registryPath))) { + logger.warn(`[PackageDiscovery] ❌ 注册表文件不存在: ${this.registryPath}`) + return null + } + + const registryData = await RegistryData.fromFile('package', this.registryPath) + logger.debug(`[PackageDiscovery] 📊 加载资源总数: ${registryData.size}`) + + return registryData + + } catch (error) { + logger.warn(`[PackageDiscovery] ⚠️ 注册表加载异常: ${error.message}`) + return null + } + } + + /** + * 回退到动态扫描(保持向后兼容) + * @returns {Promise} 资源注册表 + * @private + */ + async _fallbackToScanning() { + logger.debug(`[PackageDiscovery] 🔍 开始动态扫描包级资源...`) + + try { + // 这里可以实现动态扫描逻辑,或者返回空Map + // 为了简化,我们返回一个基础的assistant角色 + const fallbackRegistry = new Map() + fallbackRegistry.set('assistant', '@package://prompt/domain/assistant/assistant.role.md') + fallbackRegistry.set('package:assistant', '@package://prompt/domain/assistant/assistant.role.md') + + logger.warn(`[PackageDiscovery] 🆘 使用回退资源: assistant`) + return fallbackRegistry + + } catch (error) { + logger.warn(`[PackageDiscovery] ❌ 动态扫描失败: ${error.message}`) return new Map() } } - - /** - * 从扫描结果构建Map - * @param {Array} scanResults - 扫描结果数组 - * @returns {Map} 资源注册表 Map + * 生成包级资源注册表(用于构建时) + * @param {string} packageRoot - 包根目录 + * @returns {Promise} 生成的注册表数据 */ - _buildRegistryFromScanResults(scanResults) { - const registry = new Map() - - for (const resource of scanResults) { - if (resource.id && resource.reference) { - registry.set(resource.id, resource.reference) + async generateRegistry(packageRoot) { + logger.info(`[PackageDiscovery] 🏗️ 开始生成包级资源注册表...`) + + const registryData = RegistryData.createEmpty('package', this.registryPath) + + try { + // 扫描包级资源目录 + const promptDir = path.join(packageRoot, 'prompt') + + if (await fs.pathExists(promptDir)) { + await this._scanDirectory(promptDir, registryData) } + + // 保存注册表 + await registryData.save() + + logger.info(`[PackageDiscovery] ✅ 包级注册表生成完成,共 ${registryData.size} 个资源`) + return registryData + + } catch (error) { + logger.error(`[PackageDiscovery] ❌ 注册表生成失败: ${error.message}`) + throw error } - - return registry } + /** + * 扫描目录并添加资源到注册表 + * @param {string} promptDir - prompt目录路径 + * @param {RegistryData} registryData - 注册表数据 + * @private + */ + async _scanDirectory(promptDir, registryData) { + try { + // 扫描domain目录下的角色 + const domainDir = path.join(promptDir, 'domain') + if (await fs.pathExists(domainDir)) { + await this._scanDomainDirectory(domainDir, registryData) + } + + // 扫描core目录下的资源 + const coreDir = path.join(promptDir, 'core') + if (await fs.pathExists(coreDir)) { + await this._scanCoreDirectory(coreDir, registryData) + } + + } catch (error) { + logger.warn(`[PackageDiscovery] 扫描目录失败: ${error.message}`) + } + } + /** + * 扫描domain目录(角色资源) + * @param {string} domainDir - domain目录路径 + * @param {RegistryData} registryData - 注册表数据 + * @private + */ + async _scanDomainDirectory(domainDir, registryData) { + const items = await fs.readdir(domainDir) + + for (const item of items) { + const itemPath = path.join(domainDir, item) + const stat = await fs.stat(itemPath) + + if (stat.isDirectory()) { + // 查找角色文件 + const roleFile = path.join(itemPath, `${item}.role.md`) + if (await fs.pathExists(roleFile)) { + const reference = `@package://prompt/domain/${item}/${item}.role.md` + + const resourceData = new ResourceData({ + id: item, + source: 'package', + protocol: 'role', + name: ResourceData._generateDefaultName(item, 'role'), + description: ResourceData._generateDefaultDescription(item, 'role'), + reference: reference, + metadata: { + filePath: roleFile, + scannedAt: new Date().toISOString() + } + }) + + registryData.addResource(resourceData) + } + + // 查找thought文件 + const thoughtDir = path.join(itemPath, 'thought') + if (await fs.pathExists(thoughtDir)) { + const thoughtFile = path.join(thoughtDir, `${item}.thought.md`) + if (await fs.pathExists(thoughtFile)) { + const reference = `@package://prompt/domain/${item}/thought/${item}.thought.md` + + const resourceData = new ResourceData({ + id: item, + source: 'package', + protocol: 'thought', + name: ResourceData._generateDefaultName(item, 'thought'), + description: ResourceData._generateDefaultDescription(item, 'thought'), + reference: reference, + metadata: { + filePath: thoughtFile, + scannedAt: new Date().toISOString() + } + }) + + registryData.addResource(resourceData) + } + } + + // 查找execution文件 + const executionDir = path.join(itemPath, 'execution') + if (await fs.pathExists(executionDir)) { + const executionFiles = await fs.readdir(executionDir) + for (const execFile of executionFiles) { + if (execFile.endsWith('.execution.md')) { + const execId = path.basename(execFile, '.execution.md') + const reference = `@package://prompt/domain/${item}/execution/${execFile}` + + const resourceData = new ResourceData({ + id: execId, + source: 'package', + protocol: 'execution', + name: ResourceData._generateDefaultName(execId, 'execution'), + description: ResourceData._generateDefaultDescription(execId, 'execution'), + reference: reference, + metadata: { + filePath: path.join(executionDir, execFile), + scannedAt: new Date().toISOString() + } + }) + + registryData.addResource(resourceData) + } + } + } + } + } + } + + /** + * 扫描core目录(核心资源) + * @param {string} coreDir - core目录路径 + * @param {RegistryData} registryData - 注册表数据 + * @private + */ + async _scanCoreDirectory(coreDir, registryData) { + // 扫描core下的直接子目录 + const items = await fs.readdir(coreDir) + + for (const item of items) { + const itemPath = path.join(coreDir, item) + const stat = await fs.stat(itemPath) + + if (stat.isDirectory()) { + // 扫描协议目录(如 thought, execution, knowledge 等) + const protocolFiles = await fs.readdir(itemPath) + + for (const file of protocolFiles) { + if (file.endsWith('.md')) { + const match = file.match(/^(.+)\.(\w+)\.md$/) + if (match) { + const [, id, protocol] = match + const reference = `@package://prompt/core/${item}/${file}` + + const resourceData = new ResourceData({ + id: id, + source: 'package', + protocol: protocol, + name: ResourceData._generateDefaultName(id, protocol), + description: ResourceData._generateDefaultDescription(id, protocol), + reference: reference, + metadata: { + filePath: path.join(itemPath, file), + scannedAt: new Date().toISOString() + } + }) + + registryData.addResource(resourceData) + } + } + } + } else if (item.endsWith('.md')) { + // 处理core目录下的直接文件 + const match = item.match(/^(.+)\.(\w+)\.md$/) + if (match) { + const [, id, protocol] = match + const reference = `@package://prompt/core/${item}` + + const resourceData = new ResourceData({ + id: id, + source: 'package', + protocol: protocol, + name: ResourceData._generateDefaultName(id, protocol), + description: ResourceData._generateDefaultDescription(id, protocol), + reference: reference, + metadata: { + filePath: path.join(coreDir, item), + scannedAt: new Date().toISOString() + } + }) + + registryData.addResource(resourceData) + } + } + } + } + + /** + * 加载包级硬编码注册表 (性能优化核心方法) + * @returns {Promise} 包级资源注册表 + */ + async _loadPackageRegistry() { + const cacheKey = 'packageRegistry' + if (this.getFromCache(cacheKey)) { + return this.getFromCache(cacheKey) + } + + try { + // 查找package.registry.json文件位置 + const packageRoot = await this._findPackageRoot() + const registryPath = path.join(packageRoot, 'src', 'package.registry.json') + + // 使用RegistryData统一管理 + const registryData = await RegistryData.fromFile('package', registryPath) + const registry = registryData.getResourceMap(true) // 包含源前缀 + + logger.debug(`[PackageDiscovery] 🔧 注册表路径: ${registryPath}`) + logger.debug(`[PackageDiscovery] 📊 加载资源总数: ${registry.size}`) + + // 缓存结果 + this.setCache(cacheKey, registry) + + return registry + + } catch (error) { + logger.warn(`[PackageDiscovery] Failed to load package registry: ${error.message}`) + throw error + } + } + + /** + * 降级到传统动态扫描方法 (fallback) + * @returns {Promise} 动态扫描的资源列表 + */ + async _fallbackToLegacyDiscovery() { + logger.warn('[PackageDiscovery] Falling back to legacy dynamic scanning...') + try { + const scanResources = await this._scanPromptDirectory() + return scanResources.map(resource => this.normalizeResource(resource)) + } catch (error) { + logger.warn(`[PackageDiscovery] Legacy discovery also failed: ${error.message}`) + return [] + } + } /** * 扫描prompt目录发现资源 @@ -114,7 +423,7 @@ class PackageDiscovery extends BaseDiscovery { return resources } catch (error) { - console.warn(`[PackageDiscovery] Failed to scan prompt directory: ${error.message}`) + logger.warn(`[PackageDiscovery] Failed to scan prompt directory: ${error.message}`) return [] } } @@ -314,7 +623,6 @@ class PackageDiscovery extends BaseDiscovery { } } - /** * 生成包引用路径 * @param {string} filePath - 文件绝对路径 @@ -337,6 +645,35 @@ class PackageDiscovery extends BaseDiscovery { const fileName = path.basename(filePath, suffix) return `${protocol}:${fileName}` } + + /** + * 获取RegistryData对象(新架构方法) + * @returns {Promise} 包级RegistryData对象 + */ + async getRegistryData() { + try { + // 查找package.registry.json文件位置 + const packageRoot = await this._findPackageRoot() + const registryPath = path.join(packageRoot, 'src', 'package.registry.json') + + // 直接加载RegistryData + const registryData = await RegistryData.fromFile('package', registryPath) + + logger.info(`[PackageDiscovery] ✅ 硬编码注册表加载成功,发现 ${registryData.size} 个资源`) + + // 输出角色资源信息(调试用) + const roleResources = registryData.getResourcesByProtocol('role') + const roleIds = roleResources.map(r => r.getFullId()).concat(roleResources.map(r => r.getBaseId())) + logger.info(`[PackageDiscovery] 📋 包级角色资源: ${roleIds.join(', ')}`) + + return registryData + + } catch (error) { + logger.warn(`[PackageDiscovery] Failed to load RegistryData: ${error.message}`) + // 返回空的RegistryData + return new RegistryData('package', null) + } + } } module.exports = PackageDiscovery \ No newline at end of file diff --git a/src/lib/core/resource/discovery/ProjectDiscovery.js b/src/lib/core/resource/discovery/ProjectDiscovery.js index 12819a0..a4ceb1d 100644 --- a/src/lib/core/resource/discovery/ProjectDiscovery.js +++ b/src/lib/core/resource/discovery/ProjectDiscovery.js @@ -1,14 +1,18 @@ const BaseDiscovery = require('./BaseDiscovery') +const logger = require('../../../utils/logger') const fs = require('fs-extra') const path = require('path') const CrossPlatformFileScanner = require('./CrossPlatformFileScanner') +const RegistryData = require('../RegistryData') +const ResourceData = require('../ResourceData') /** * ProjectDiscovery - 项目级资源发现器 * * 负责发现项目本地的资源: - * 1. 扫描 .promptx/resource/ 目录 - * 2. 发现用户自定义的角色、执行模式、思维模式等 + * 1. 优先从 project.registry.json 读取(构建时优化) + * 2. Fallback: 扫描 .promptx/resource/ 目录(动态发现) + * 3. 发现用户自定义的角色、执行模式、思维模式等 * * 优先级:2 */ @@ -16,33 +20,7 @@ class ProjectDiscovery extends BaseDiscovery { constructor() { super('PROJECT', 2) this.fileScanner = new CrossPlatformFileScanner() - } - - /** - * 发现项目级资源 - * @returns {Promise} 发现的资源列表 - */ - async discover() { - try { - // 1. 查找项目根目录 - const projectRoot = await this._findProjectRoot() - - // 2. 检查.promptx目录是否存在 - const hasPrompxDir = await this._checkPrompxDirectory(projectRoot) - if (!hasPrompxDir) { - return [] - } - - // 3. 扫描项目资源 - const resources = await this._scanProjectResources(projectRoot) - - // 4. 规范化所有资源 - return resources.map(resource => this.normalizeResource(resource)) - - } catch (error) { - console.warn(`[ProjectDiscovery] Discovery failed: ${error.message}`) - return [] - } + this.registryData = null } /** @@ -60,18 +38,77 @@ class ProjectDiscovery extends BaseDiscovery { return new Map() } - // 3. 扫描项目资源 - const resources = await this._scanProjectResources(projectRoot) + // 3. 优先尝试从注册表加载 + const registryMap = await this._loadFromRegistry(projectRoot) + if (registryMap.size > 0) { + logger.debug(`ProjectDiscovery 从注册表加载 ${registryMap.size} 个资源`) + return registryMap + } - // 4. 构建注册表 + // 4. Fallback: 动态扫描 + logger.debug('ProjectDiscovery 注册表不存在,使用动态扫描') + const resources = await this._scanProjectResources(projectRoot) return this._buildRegistryFromResources(resources) } catch (error) { - console.warn(`[ProjectDiscovery] Registry discovery failed: ${error.message}`) + logger.warn(`[ProjectDiscovery] Registry discovery failed: ${error.message}`) return new Map() } } + /** + * 从注册表文件加载资源 + * @param {string} projectRoot - 项目根目录 + * @returns {Promise} 资源注册表 + */ + async _loadFromRegistry(projectRoot) { + try { + const registryPath = path.join(projectRoot, '.promptx', 'resource', 'project.registry.json') + + // 检查注册表文件是否存在 + if (!await this._fsExists(registryPath)) { + return new Map() + } + + // 读取并解析注册表 + this.registryData = await RegistryData.fromFile('project', registryPath) + + // 获取分层级资源映射 + return this.registryData.getResourceMap(true) // 带前缀 + + } catch (error) { + logger.warn(`[ProjectDiscovery] Failed to load registry: ${error.message}`) + return new Map() + } + } + + /** + * 发现项目级资源 (旧版本兼容方法) + * @returns {Promise} 发现的资源列表 + */ + async discover() { + try { + // 使用新的注册表方法 + const registryMap = await this.discoverRegistry() + + // 转换为旧格式 + const resources = [] + for (const [id, reference] of registryMap.entries()) { + resources.push({ + id: id.replace(/^project:/, ''), // 移除前缀以保持兼容性 + reference: reference + }) + } + + // 规范化所有资源 + return resources.map(resource => this.normalizeResource(resource)) + + } catch (error) { + logger.warn(`[ProjectDiscovery] Discovery failed: ${error.message}`) + return [] + } + } + /** * 从资源列表构建注册表 * @param {Array} resources - 资源列表 @@ -165,13 +202,13 @@ class ProjectDiscovery extends BaseDiscovery { }) } } catch (error) { - console.warn(`[ProjectDiscovery] Failed to scan ${resourceType} resources: ${error.message}`) + logger.warn(`[ProjectDiscovery] Failed to scan ${resourceType} resources: ${error.message}`) } } return resources } catch (error) { - console.warn(`[ProjectDiscovery] Failed to scan project resources: ${error.message}`) + logger.warn(`[ProjectDiscovery] Failed to scan project resources: ${error.message}`) return [] } } @@ -239,7 +276,7 @@ class ProjectDiscovery extends BaseDiscovery { return false } } catch (error) { - console.warn(`[ProjectDiscovery] Failed to validate ${filePath}: ${error.message}`) + logger.warn(`[ProjectDiscovery] Failed to validate ${filePath}: ${error.message}`) return false } } @@ -260,11 +297,210 @@ class ProjectDiscovery extends BaseDiscovery { * @param {string} filePath - 文件路径 * @param {string} protocol - 协议类型 * @param {string} suffix - 文件后缀 - * @returns {string} 资源ID (protocol:resourceName) + * @returns {string} 资源ID (对于role类型返回resourceName,对于其他类型返回protocol:resourceName) */ _extractResourceId(filePath, protocol, suffix) { const fileName = path.basename(filePath, suffix) - return `${protocol}:${fileName}` + + // role类型不需要前缀,其他类型需要前缀 + if (protocol === 'role') { + return fileName + } else { + return `${protocol}:${fileName}` + } + } + + /** + * 生成项目级注册表文件 + * @param {string} projectRoot - 项目根目录 + * @returns {Promise} 生成的注册表数据 + */ + async generateRegistry(projectRoot) { + const registryPath = path.join(projectRoot, '.promptx', 'resource', 'project.registry.json') + const registryData = RegistryData.createEmpty('project', registryPath) + + // 扫描.promptx/resource目录 + const resourcesDir = path.join(projectRoot, '.promptx', 'resource') + + if (await this._fsExists(resourcesDir)) { + await this._scanDirectory(resourcesDir, registryData) + } + + // 保存注册表文件 + await registryData.save() + + logger.info(`[ProjectDiscovery] ✅ 项目注册表生成完成,发现 ${registryData.size} 个资源`) + return registryData + } + + /** + * 扫描目录并添加资源到注册表 + * @param {string} resourcesDir - 资源目录 + * @param {RegistryData} registryData - 注册表数据 + * @private + */ + async _scanDirectory(resourcesDir, registryData) { + // 扫描domain目录 + const domainDir = path.join(resourcesDir, 'domain') + if (await this._fsExists(domainDir)) { + await this._scanDomainDirectory(domainDir, registryData) + } + } + + /** + * 扫描domain目录(项目角色资源) + * @param {string} domainDir - domain目录路径 + * @param {RegistryData} registryData - 注册表数据 + * @private + */ + async _scanDomainDirectory(domainDir, registryData) { + const items = await fs.readdir(domainDir) + + for (const item of items) { + const itemPath = path.join(domainDir, item) + const stat = await fs.stat(itemPath) + + if (stat.isDirectory()) { + // 查找role文件 + const roleFile = path.join(itemPath, `${item}.role.md`) + if (await this._fsExists(roleFile)) { + const reference = `@project://.promptx/resource/domain/${item}/${item}.role.md` + + const resourceData = new ResourceData({ + id: item, + source: 'project', + protocol: 'role', + name: ResourceData._generateDefaultName(item, 'role'), + description: ResourceData._generateDefaultDescription(item, 'role'), + reference: reference, + metadata: { + filePath: roleFile, + scannedAt: new Date().toISOString() + } + }) + + registryData.addResource(resourceData) + } + + // 查找thought文件 + const thoughtDir = path.join(itemPath, 'thought') + if (await this._fsExists(thoughtDir)) { + const thoughtFiles = await fs.readdir(thoughtDir) + for (const thoughtFile of thoughtFiles) { + if (thoughtFile.endsWith('.thought.md')) { + const thoughtId = path.basename(thoughtFile, '.thought.md') + const reference = `@project://.promptx/resource/domain/${item}/thought/${thoughtFile}` + + const resourceData = new ResourceData({ + id: thoughtId, + source: 'project', + protocol: 'thought', + name: ResourceData._generateDefaultName(thoughtId, 'thought'), + description: ResourceData._generateDefaultDescription(thoughtId, 'thought'), + reference: reference, + metadata: { + filePath: path.join(thoughtDir, thoughtFile), + scannedAt: new Date().toISOString() + } + }) + + registryData.addResource(resourceData) + } + } + } + + // 查找execution文件 + const executionDir = path.join(itemPath, 'execution') + if (await this._fsExists(executionDir)) { + const executionFiles = await fs.readdir(executionDir) + for (const execFile of executionFiles) { + if (execFile.endsWith('.execution.md')) { + const execId = path.basename(execFile, '.execution.md') + const reference = `@project://.promptx/resource/domain/${item}/execution/${execFile}` + + const resourceData = new ResourceData({ + id: execId, + source: 'project', + protocol: 'execution', + name: ResourceData._generateDefaultName(execId, 'execution'), + description: ResourceData._generateDefaultDescription(execId, 'execution'), + reference: reference, + metadata: { + filePath: path.join(executionDir, execFile), + scannedAt: new Date().toISOString() + } + }) + + registryData.addResource(resourceData) + } + } + } + + // 查找knowledge文件 + const knowledgeDir = path.join(itemPath, 'knowledge') + if (await this._fsExists(knowledgeDir)) { + const knowledgeFiles = await fs.readdir(knowledgeDir) + for (const knowledgeFile of knowledgeFiles) { + if (knowledgeFile.endsWith('.knowledge.md')) { + const knowledgeId = path.basename(knowledgeFile, '.knowledge.md') + const reference = `@project://.promptx/resource/domain/${item}/knowledge/${knowledgeFile}` + + const resourceData = new ResourceData({ + id: knowledgeId, + source: 'project', + protocol: 'knowledge', + name: ResourceData._generateDefaultName(knowledgeId, 'knowledge'), + description: ResourceData._generateDefaultDescription(knowledgeId, 'knowledge'), + reference: reference, + metadata: { + filePath: path.join(knowledgeDir, knowledgeFile), + scannedAt: new Date().toISOString() + } + }) + + registryData.addResource(resourceData) + } + } + } + } + } + } + + /** + * 获取RegistryData对象(新架构方法) + * @returns {Promise} 项目级RegistryData对象 + */ + async getRegistryData() { + try { + const projectRoot = await this._findProjectRoot() + const registryPath = path.join(projectRoot, '.promptx', 'resource', 'project.registry.json') + + // 尝试加载现有的注册表文件 + if (await this._fsExists(registryPath)) { + const registryData = await RegistryData.fromFile('project', registryPath) + + // 检查注册表是否有效(有完整的资源数据) + if (registryData.size > 0 && registryData.resources.length > 0) { + const firstResource = registryData.resources[0] + if (firstResource.id && firstResource.protocol && firstResource.reference) { + logger.info(`[ProjectDiscovery] 📋 从注册表加载 ${registryData.size} 个资源`) + return registryData + } + } + + // 如果注册表无效,重新生成 + logger.info(`[ProjectDiscovery] 📋 项目注册表无效,重新生成`) + return await this.generateRegistry(projectRoot) + } else { + // 如果没有注册表文件,生成新的 + logger.info(`[ProjectDiscovery] 📋 项目注册表不存在,生成新注册表`) + return await this.generateRegistry(projectRoot) + } + } catch (error) { + logger.warn(`[ProjectDiscovery] Failed to load RegistryData: ${error.message}`) + // 返回空的RegistryData + return RegistryData.createEmpty('project', null) + } } } diff --git a/src/lib/core/resource/index.js b/src/lib/core/resource/index.js index bbf6940..9e8c939 100644 --- a/src/lib/core/resource/index.js +++ b/src/lib/core/resource/index.js @@ -25,11 +25,37 @@ const { ProtocolInfo } = require('./types') +// 全局单例 ResourceManager 实例 +let globalResourceManager = null + +/** + * 获取全局单例 ResourceManager 实例 + * 确保整个应用程序使用同一个 ResourceManager 实例 + */ +function getGlobalResourceManager() { + if (!globalResourceManager) { + globalResourceManager = new ResourceManager() + } + return globalResourceManager +} + +/** + * 重置全局 ResourceManager 实例 + * 主要用于测试或需要完全重新初始化的场景 + */ +function resetGlobalResourceManager() { + globalResourceManager = null +} + // 导出主接口 module.exports = { - // 主管理器 + // 主管理器类 ResourceManager, + // 全局单例实例 + getGlobalResourceManager, + resetGlobalResourceManager, + // 核心组件 ResourceProtocolParser, ResourceRegistry, @@ -45,7 +71,7 @@ module.exports = { ResourceResult, ProtocolInfo, - // 便捷方法 - 创建默认实例 + // 便捷方法 - 创建默认实例(保持向后兼容) createManager: (options) => new ResourceManager(options), // 便捷方法 - 快速解析 diff --git a/src/lib/core/resource/protocols/PackageProtocol.js b/src/lib/core/resource/protocols/PackageProtocol.js index 87d4656..5f47780 100644 --- a/src/lib/core/resource/protocols/PackageProtocol.js +++ b/src/lib/core/resource/protocols/PackageProtocol.js @@ -3,6 +3,7 @@ const fs = require('fs') const fsPromises = require('fs').promises const ResourceProtocol = require('./ResourceProtocol') const { QueryParams } = require('../types') +const logger = require('../../../utils/logger') /** * 包协议实现 @@ -477,7 +478,7 @@ class PackageProtocol extends ResourceProtocol { // 在生产环境严格检查,开发环境只警告 const installMode = this.detectInstallMode() if (installMode === 'development' || installMode === 'npx') { - console.warn(`⚠️ Warning: Path '${relativePath}' not in package.json files field. This may cause issues after publishing.`) + logger.warn(`⚠️ Warning: Path '${relativePath}' not in package.json files field. This may cause issues after publishing.`) } else { throw new Error(`Access denied: Path '${relativePath}' is not included in package.json files field`) } @@ -486,7 +487,7 @@ class PackageProtocol extends ResourceProtocol { // 如果读取package.json失败,在开发模式下允许访问 const installMode = this.detectInstallMode() if (installMode === 'development' || installMode === 'npx') { - console.warn(`⚠️ Warning: Could not validate file access for '${relativePath}': ${error.message}`) + logger.warn(`⚠️ Warning: Could not validate file access for '${relativePath}': ${error.message}`) } else { throw error } diff --git a/src/lib/core/resource/resourceManager.js b/src/lib/core/resource/resourceManager.js index 2ea3476..5d916c3 100644 --- a/src/lib/core/resource/resourceManager.js +++ b/src/lib/core/resource/resourceManager.js @@ -1,7 +1,9 @@ const fs = require('fs') const ResourceRegistry = require('./resourceRegistry') +const RegistryData = require('./RegistryData') const ResourceProtocolParser = require('./resourceProtocolParser') const DiscoveryManager = require('./discovery/DiscoveryManager') +const logger = require('../../utils/logger') // 导入协议处理器 const PackageProtocol = require('./protocols/PackageProtocol') @@ -13,7 +15,9 @@ const KnowledgeProtocol = require('./protocols/KnowledgeProtocol') class ResourceManager { constructor() { - this.registry = new ResourceRegistry() + // 使用新的RegistryData替代旧的ResourceRegistry + this.registry = new ResourceRegistry() // 保持向后兼容 + this.registryData = RegistryData.createEmpty('merged', null) // 新的v2.0注册表 this.protocolParser = new ResourceProtocolParser() this.parser = new ResourceProtocolParser() // 向后兼容别名 this.discoveryManager = new DiscoveryManager() // 新发现管理器 @@ -43,23 +47,58 @@ class ResourceManager { */ async initializeWithNewArchitecture() { try { - // 1. 直接发现并注册资源(无需中间合并步骤) + // 1. 清空现有注册表(支持重新初始化) + this.registry.clear() + this.registryData.clear() + + // 2. 清除发现器缓存 + if (this.discoveryManager && typeof this.discoveryManager.clearCache === 'function') { + this.discoveryManager.clearCache() + } + + // 3. 直接发现并注册资源到旧的ResourceRegistry(保持向后兼容) await this.discoveryManager.discoverAndDirectRegister(this.registry) - // 2. 为逻辑协议设置注册表引用 + // 4. 同时填充新的RegistryData + await this.populateRegistryData() + + // 5. 为逻辑协议设置注册表引用 this.setupLogicalProtocols() - // 3. 设置初始化状态 + // 6. 设置初始化状态 this.initialized = true // 初始化完成,不输出日志避免干扰用户界面 } catch (error) { - console.warn(`[ResourceManager] New architecture initialization failed: ${error.message}`) - console.warn('[ResourceManager] Continuing with empty registry') + logger.warn(`ResourceManager new architecture initialization failed: ${error.message}`) + logger.warn('ResourceManager continuing with empty registry') this.initialized = true // 即使失败也标记为已初始化,避免重复尝试 } } + /** + * 填充新的RegistryData + */ + async populateRegistryData() { + // 清空现有数据 + this.registryData.clear() + + // 从各个发现器获取RegistryData并合并 + for (const discovery of this.discoveryManager.discoveries) { + try { + if (typeof discovery.getRegistryData === 'function') { + const registryData = await discovery.getRegistryData() + if (registryData && registryData.resources) { + // 合并资源到主注册表 + this.registryData.merge(registryData, true) // 允许覆盖 + } + } + } catch (error) { + logger.warn(`Failed to get RegistryData from ${discovery.source}: ${error.message}`) + } + } + } + /** * 为逻辑协议设置注册表引用 */ @@ -116,33 +155,53 @@ class ResourceManager { async loadResource(resourceId) { try { - // 每次都刷新资源(无状态设计) - await this.refreshResources() + // 不再每次刷新资源,依赖初始化时的资源发现 // 处理@!开头的DPML格式(如 @!role://java-developer) if (resourceId.startsWith('@!')) { const parsed = this.protocolParser.parse(resourceId) - const logicalResourceId = `${parsed.protocol}:${parsed.path}` - // 从注册表查找对应的@package://引用 - const reference = this.registry.get(logicalResourceId) - if (!reference) { - throw new Error(`Resource not found: ${logicalResourceId}`) + // 从新的RegistryData查找资源 + const resourceData = this.registryData.findResourceById(parsed.path, parsed.protocol) + if (!resourceData) { + throw new Error(`Resource not found: ${parsed.protocol}:${parsed.path}`) } // 通过协议解析加载内容 - const content = await this.loadResourceByProtocol(reference) + const content = await this.loadResourceByProtocol(resourceData.reference) return { success: true, content, resourceId, - reference + reference: resourceData.reference } } // 处理传统格式(如 role:java-developer) - const reference = this.registry.get(resourceId) + // 先尝试从新的RegistryData查找 + let reference = null + + // 如果包含协议前缀(如 thought:remember) + if (resourceId.includes(':')) { + const [protocol, id] = resourceId.split(':', 2) + const resourceData = this.registryData.findResourceById(id, protocol) + if (resourceData) { + reference = resourceData.reference + } + } else { + // 如果没有协议前缀,尝试查找任意协议的资源 + const resourceData = this.registryData.findResourceById(resourceId) + if (resourceData) { + reference = resourceData.reference + } + } + + // 如果新的RegistryData中没找到,回退到旧的registry + if (!reference) { + reference = this.registry.get(resourceId) + } + if (!reference) { throw new Error(`Resource not found: ${resourceId}`) } @@ -216,8 +275,7 @@ class ResourceManager { // 向后兼容方法 async resolve(resourceUrl) { try { - // 每次都刷新资源(无状态设计) - await this.refreshResources() + // 不再每次刷新资源,依赖初始化时的资源发现 // Handle old format: role:java-backend-developer or @package://... if (resourceUrl.startsWith('@')) { @@ -275,7 +333,7 @@ class ResourceManager { // 无状态设计:不设置initialized标志 } catch (error) { - console.warn(`[ResourceManager] Resource refresh failed: ${error.message}`) + logger.warn(`ResourceManager resource refresh failed: ${error.message}`) // 失败时保持注册表为空状态,下次调用时重试 } } diff --git a/src/lib/core/resource/resourceRegistry.js b/src/lib/core/resource/resourceRegistry.js index 0cd4b0a..5bfe1ea 100644 --- a/src/lib/core/resource/resourceRegistry.js +++ b/src/lib/core/resource/resourceRegistry.js @@ -1,3 +1,5 @@ +const logger = require('../../utils/logger') + /** * 资源注册表 * 新架构中用于存储动态发现的资源映射关系 @@ -70,27 +72,27 @@ class ResourceRegistry { * @param {string} title - 可选标题 */ printAll(title = '注册表资源清单') { - console.log(`\n📋 ${title}`) - console.log('='.repeat(50)) + logger.info(`\n📋 ${title}`) + logger.info('='.repeat(50)) if (this.size === 0) { - console.log('🔍 注册表为空') + logger.info('🔍 注册表为空') return } - console.log(`📊 总计: ${this.size} 个资源\n`) + logger.info(`📊 总计: ${this.size} 个资源\n`) // 按协议分组显示 const groupedResources = this.groupByProtocol() for (const [protocol, resources] of Object.entries(groupedResources)) { - console.log(`🔖 ${protocol.toUpperCase()} 协议 (${resources.length}个):`) + logger.info(`🔖 ${protocol.toUpperCase()} 协议 (${resources.length}个):`) resources.forEach(({ id, reference }) => { const resourceName = id.split(':')[1] || id - console.log(` • ${resourceName}`) - console.log(` └─ ${reference}`) + logger.info(` • ${resourceName}`) + logger.info(` └─ ${reference}`) }) - console.log('') + logger.info('') } } diff --git a/src/lib/utils/executionContext.js b/src/lib/utils/executionContext.js index 2cf5bd0..ae0f71b 100644 --- a/src/lib/utils/executionContext.js +++ b/src/lib/utils/executionContext.js @@ -1,5 +1,6 @@ const fs = require('fs'); const path = require('path'); +const logger = require('./logger'); /** * 执行上下文检测工具 @@ -37,7 +38,7 @@ function getMCPWorkingDirectory() { // 取第一个工作区路径(多工作区情况) const firstPath = workspacePaths.split(path.delimiter)[0]; if (firstPath && isValidDirectory(firstPath)) { - console.error(`[执行上下文] 使用WORKSPACE_FOLDER_PATHS: ${firstPath}`); + logger.info(`[执行上下文] 使用WORKSPACE_FOLDER_PATHS: ${firstPath}`); return firstPath; } } @@ -45,27 +46,27 @@ function getMCPWorkingDirectory() { // 策略2:PROMPTX_WORKSPACE(PromptX专用环境变量) const promptxWorkspace = process.env.PROMPTX_WORKSPACE; if (promptxWorkspace && isValidDirectory(promptxWorkspace)) { - console.error(`[执行上下文] 使用PROMPTX_WORKSPACE: ${promptxWorkspace}`); + logger.info(`[执行上下文] 使用PROMPTX_WORKSPACE: ${promptxWorkspace}`); return promptxWorkspace; } // 策略3:PWD环境变量(某些情况下可用) const pwd = process.env.PWD; if (pwd && isValidDirectory(pwd) && pwd !== process.cwd()) { - console.error(`[执行上下文] 使用PWD环境变量: ${pwd}`); + logger.info(`[执行上下文] 使用PWD环境变量: ${pwd}`); return pwd; } // 策略4:项目根目录智能推测(向上查找项目标识) const projectRoot = findProjectRoot(process.cwd()); if (projectRoot && projectRoot !== process.cwd()) { - console.error(`[执行上下文] 智能推测项目根目录: ${projectRoot}`); + logger.info(`[执行上下文] 智能推测项目根目录: ${projectRoot}`); return projectRoot; } // 策略5:回退到process.cwd() - console.error(`[执行上下文] 回退到process.cwd(): ${process.cwd()}`); - console.error(`[执行上下文] 提示:建议在MCP配置中添加 "env": {"PROMPTX_WORKSPACE": "你的项目目录"}`); + logger.warn(`[执行上下文] 回退到process.cwd(): ${process.cwd()}`); + logger.warn(`[执行上下文] 提示:建议在MCP配置中添加 "env": {"PROMPTX_WORKSPACE": "你的项目目录"}`) return process.cwd(); } diff --git a/src/package.registry.json b/src/package.registry.json new file mode 100644 index 0000000..c164ff7 --- /dev/null +++ b/src/package.registry.json @@ -0,0 +1,654 @@ +{ + "version": "2.0.0", + "source": "package", + "metadata": { + "version": "2.0.0", + "description": "package 级资源注册表", + "createdAt": "2025-06-13T00:41:50.641Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "resourceCount": 45 + }, + "resources": [ + { + "id": "assistant", + "source": "package", + "protocol": "role", + "name": "Assistant 角色", + "description": "专业角色,提供特定领域的专业能力", + "reference": "@package://prompt/domain/assistant/assistant.role.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/assistant/assistant.role.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "assistant", + "source": "package", + "protocol": "thought", + "name": "Assistant 思维模式", + "description": "思维模式,指导AI的思考方式", + "reference": "@package://prompt/domain/assistant/thought/assistant.thought.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/assistant/thought/assistant.thought.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "assistant", + "source": "package", + "protocol": "execution", + "name": "Assistant 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/assistant/execution/assistant.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/assistant/execution/assistant.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "frontend-developer", + "source": "package", + "protocol": "role", + "name": "Frontend Developer 角色", + "description": "专业角色,提供特定领域的专业能力", + "reference": "@package://prompt/domain/frontend-developer/frontend-developer.role.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/frontend-developer/frontend-developer.role.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "frontend-developer", + "source": "package", + "protocol": "thought", + "name": "Frontend Developer 思维模式", + "description": "思维模式,指导AI的思考方式", + "reference": "@package://prompt/domain/frontend-developer/thought/frontend-developer.thought.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/frontend-developer/thought/frontend-developer.thought.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "code-quality", + "source": "package", + "protocol": "execution", + "name": "Code Quality 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/java-backend-developer/execution/code-quality.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/java-backend-developer/execution/code-quality.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "frontend-developer", + "source": "package", + "protocol": "execution", + "name": "Frontend Developer 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/frontend-developer/execution/frontend-developer.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/frontend-developer/execution/frontend-developer.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "technical-architecture", + "source": "package", + "protocol": "execution", + "name": "Technical Architecture 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/frontend-developer/execution/technical-architecture.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/frontend-developer/execution/technical-architecture.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "user-experience", + "source": "package", + "protocol": "execution", + "name": "User Experience 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/frontend-developer/execution/user-experience.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/frontend-developer/execution/user-experience.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "wechat-miniprogram-development", + "source": "package", + "protocol": "execution", + "name": "Wechat Miniprogram Development 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/frontend-developer/execution/wechat-miniprogram-development.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/frontend-developer/execution/wechat-miniprogram-development.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "java-backend-developer", + "source": "package", + "protocol": "role", + "name": "Java Backend Developer 角色", + "description": "专业角色,提供特定领域的专业能力", + "reference": "@package://prompt/domain/java-backend-developer/java-backend-developer.role.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/java-backend-developer/java-backend-developer.role.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "java-backend-developer", + "source": "package", + "protocol": "thought", + "name": "Java Backend Developer 思维模式", + "description": "思维模式,指导AI的思考方式", + "reference": "@package://prompt/domain/java-backend-developer/thought/java-backend-developer.thought.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/java-backend-developer/thought/java-backend-developer.thought.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "database-design", + "source": "package", + "protocol": "execution", + "name": "Database Design 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/java-backend-developer/execution/database-design.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/java-backend-developer/execution/database-design.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "java-backend-developer", + "source": "package", + "protocol": "execution", + "name": "Java Backend Developer 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/java-backend-developer/execution/java-backend-developer.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/java-backend-developer/execution/java-backend-developer.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "spring-ecosystem", + "source": "package", + "protocol": "execution", + "name": "Spring Ecosystem 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/java-backend-developer/execution/spring-ecosystem.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/java-backend-developer/execution/spring-ecosystem.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "system-architecture", + "source": "package", + "protocol": "execution", + "name": "System Architecture 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/java-backend-developer/execution/system-architecture.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/java-backend-developer/execution/system-architecture.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "product-manager", + "source": "package", + "protocol": "role", + "name": "Product Manager 角色", + "description": "专业角色,提供特定领域的专业能力", + "reference": "@package://prompt/domain/product-manager/product-manager.role.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/product-manager/product-manager.role.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "product-manager", + "source": "package", + "protocol": "thought", + "name": "Product Manager 思维模式", + "description": "思维模式,指导AI的思考方式", + "reference": "@package://prompt/domain/product-manager/thought/product-manager.thought.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/product-manager/thought/product-manager.thought.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "market-analysis", + "source": "package", + "protocol": "execution", + "name": "Market Analysis 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/product-manager/execution/market-analysis.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/product-manager/execution/market-analysis.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "product-manager", + "source": "package", + "protocol": "execution", + "name": "Product Manager 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/product-manager/execution/product-manager.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/product-manager/execution/product-manager.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "user-research", + "source": "package", + "protocol": "execution", + "name": "User Research 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/product-manager/execution/user-research.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/product-manager/execution/user-research.execution.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "xiaohongshu-marketer", + "source": "package", + "protocol": "role", + "name": "Xiaohongshu Marketer 角色", + "description": "专业角色,提供特定领域的专业能力", + "reference": "@package://prompt/domain/xiaohongshu-marketer/xiaohongshu-marketer.role.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/xiaohongshu-marketer.role.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "xiaohongshu-marketer", + "source": "package", + "protocol": "thought", + "name": "Xiaohongshu Marketer 思维模式", + "description": "思维模式,指导AI的思考方式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/thought/xiaohongshu-marketer.thought.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.643Z", + "updatedAt": "2025-06-13T00:41:50.643Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/thought/xiaohongshu-marketer.thought.md", + "scannedAt": "2025-06-13T00:41:50.643Z" + } + }, + { + "id": "brand-marketing", + "source": "package", + "protocol": "execution", + "name": "Brand Marketing 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/brand-marketing.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/brand-marketing.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "community-building", + "source": "package", + "protocol": "execution", + "name": "Community Building 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/community-building.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/community-building.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "content-creation", + "source": "package", + "protocol": "execution", + "name": "Content Creation 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/content-creation.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/content-creation.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "content-optimization", + "source": "package", + "protocol": "execution", + "name": "Content Optimization 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/content-optimization.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/content-optimization.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "data-analytics", + "source": "package", + "protocol": "execution", + "name": "Data Analytics 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/data-analytics.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/data-analytics.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "ecommerce-conversion", + "source": "package", + "protocol": "execution", + "name": "Ecommerce Conversion 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/ecommerce-conversion.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/ecommerce-conversion.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "performance-optimization", + "source": "package", + "protocol": "execution", + "name": "Performance Optimization 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/performance-optimization.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/performance-optimization.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "platform-compliance", + "source": "package", + "protocol": "execution", + "name": "Platform Compliance 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/platform-compliance.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/platform-compliance.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "team-collaboration", + "source": "package", + "protocol": "execution", + "name": "Team Collaboration 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/team-collaboration.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/team-collaboration.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "user-operation", + "source": "package", + "protocol": "execution", + "name": "User Operation 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/user-operation.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/user-operation.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "xiaohongshu-marketer", + "source": "package", + "protocol": "execution", + "name": "Xiaohongshu Marketer 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/domain/xiaohongshu-marketer/execution/xiaohongshu-marketer.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/domain/xiaohongshu-marketer/execution/xiaohongshu-marketer.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "dpml-protocol-knowledge", + "source": "package", + "protocol": "execution", + "name": "Dpml Protocol Knowledge 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/core/execution/dpml-protocol-knowledge.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/execution/dpml-protocol-knowledge.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "execution-authoring", + "source": "package", + "protocol": "execution", + "name": "Execution Authoring 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/core/execution/execution-authoring.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/execution/execution-authoring.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "resource-authoring", + "source": "package", + "protocol": "execution", + "name": "Resource Authoring 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/core/execution/resource-authoring.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/execution/resource-authoring.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "role-authoring", + "source": "package", + "protocol": "execution", + "name": "Role Authoring 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/core/execution/role-authoring.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/execution/role-authoring.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "role-design-patterns", + "source": "package", + "protocol": "execution", + "name": "Role Design Patterns 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/core/execution/role-design-patterns.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/execution/role-design-patterns.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "role-generation", + "source": "package", + "protocol": "execution", + "name": "Role Generation 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/core/execution/role-generation.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/execution/role-generation.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "thought-authoring", + "source": "package", + "protocol": "execution", + "name": "Thought Authoring 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@package://prompt/core/execution/thought-authoring.execution.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/execution/thought-authoring.execution.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "nuwa", + "source": "package", + "protocol": "role", + "name": "Nuwa 角色", + "description": "专业角色,提供特定领域的专业能力", + "reference": "@package://prompt/core/nuwa/nuwa.role.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/nuwa/nuwa.role.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "recall", + "source": "package", + "protocol": "thought", + "name": "Recall 思维模式", + "description": "思维模式,指导AI的思考方式", + "reference": "@package://prompt/core/thought/recall.thought.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/thought/recall.thought.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "remember", + "source": "package", + "protocol": "thought", + "name": "Remember 思维模式", + "description": "思维模式,指导AI的思考方式", + "reference": "@package://prompt/core/thought/remember.thought.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/thought/remember.thought.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + }, + { + "id": "role-creation", + "source": "package", + "protocol": "thought", + "name": "Role Creation 思维模式", + "description": "思维模式,指导AI的思考方式", + "reference": "@package://prompt/core/thought/role-creation.thought.md", + "metadata": { + "createdAt": "2025-06-13T00:41:50.644Z", + "updatedAt": "2025-06-13T00:41:50.644Z", + "filePath": "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX/prompt/core/thought/role-creation.thought.md", + "scannedAt": "2025-06-13T00:41:50.644Z" + } + } + ], + "stats": { + "totalResources": 45, + "byProtocol": { + "role": 6, + "thought": 8, + "execution": 31 + }, + "bySource": { + "package": 45 + } + } +}