🎯 PromptX v0.0.1 完整实现 - 五大锦囊命令、AI记忆系统、角色系统、PATEOAS状态机、DPML协议全部完成

This commit is contained in:
sean
2025-05-31 16:48:21 +08:00
parent be285f55b8
commit 323c4e569c
50 changed files with 4308 additions and 1947 deletions

View File

@ -1,31 +0,0 @@
const chalk = require('chalk');
const logger = require('../utils/logger');
/**
* promptx hello 命令
* 系统入口 - AI助手接待用户并展示可用角色
*/
async function helloCommand(options) {
try {
logger.step('PromptX Hello - 系统初始化中...');
// TODO: 实现在任务 2.1 中
console.log(chalk.cyan(`
🎯 PromptX 系统入口
${chalk.yellow('功能:')} AI助手接待用户并展示可用角色
${chalk.yellow('状态:')} 待实现 (任务 2.1)
${chalk.green('下一步:')}
请执行任务 2.1 来实现完整的 hello 命令功能
`));
logger.info('Hello命令框架已就绪等待具体实现');
} catch (error) {
logger.error('Hello命令执行失败:', error.message);
process.exit(1);
}
}
module.exports = helloCommand;

View File

@ -1,185 +0,0 @@
const fs = require('fs').promises;
const path = require('path');
const chalk = require('chalk');
/**
* promptx init 命令
* 在用户项目中初始化PromptX集成
*/
async function init(options = {}) {
console.log(chalk.blue.bold('🚀 初始化 PromptX 项目集成...\n'));
try {
const projectRoot = process.cwd();
const promptxDir = path.join(projectRoot, '.promptx');
const memoryDir = path.join(promptxDir, 'memory');
// 检查是否已经初始化
try {
await fs.access(promptxDir);
console.log(chalk.yellow('⚠️ 项目已经初始化过 PromptX 集成'));
console.log(chalk.gray(` .promptx 目录已存在: ${promptxDir}`));
if (!options.force) {
console.log(chalk.gray(' 使用 --force 参数强制重新初始化'));
return;
}
console.log(chalk.blue('🔄 强制重新初始化...'));
} catch (error) {
// 目录不存在,继续初始化
}
// 创建 .promptx 目录
await fs.mkdir(promptxDir, { recursive: true });
console.log(chalk.green('✅ 创建 .promptx 目录'));
// 创建 .promptx/memory 目录
await fs.mkdir(memoryDir, { recursive: true });
console.log(chalk.green('✅ 创建 memory 目录'));
// 创建基础记忆文件
const memoryFiles = [
{
name: 'declarative.md',
content: `# 声明式记忆
## 项目重要信息
- 项目初始化时间: ${new Date().toISOString()}
- PromptX 集成状态: ✅ 已完成
## 使用说明
在这里记录项目的重要决策、配置信息和关键知识点。
### 示例条目
**时间**: 2024-01-01T00:00:00.000Z
**重要性**: 8/10
**内容**: 项目使用 PromptX 进行 AI 助手集成
**有效期**: 长期
`
},
{
name: 'episodic.md',
content: `# 情景记忆
## 项目历程记录
记录项目开发过程中的重要事件和里程碑。
### 项目初始化
- **时间**: ${new Date().toISOString()}
- **事件**: PromptX 集成初始化完成
- **详情**: 使用 \`promptx init\` 命令完成项目集成设置
`
},
{
name: 'procedural.md',
content: `# 程序记忆
## 项目工作流程
### PromptX 使用流程
1. **学习阶段**: \`promptx learn <resource>\`
2. **记忆保存**: \`promptx remember <content>\`
3. **记忆检索**: \`promptx recall\`
4. **助手切换**: \`promptx hello\`
### 项目开发流程
在这里记录项目特有的开发流程和最佳实践。
`
},
{
name: 'semantic.md',
content: `# 语义记忆
## 项目知识图谱
### PromptX 协议体系
- **@project://**: 指向当前项目根目录
- **@memory://**: 指向项目记忆系统
- **@package://**: 指向 PromptX 包资源
- **@prompt://**: 指向提示词资源
### 项目特定概念
在这里定义项目中的重要概念和术语。
`
}
];
for (const file of memoryFiles) {
const filePath = path.join(memoryDir, file.name);
await fs.writeFile(filePath, file.content, 'utf8');
console.log(chalk.green(`✅ 创建记忆文件: ${file.name}`));
}
// 创建 .promptx/config.json 配置文件
const config = {
version: "0.0.1",
initialized: new Date().toISOString(),
settings: {
memoryPath: "memory",
defaultRole: null,
autoRemember: false
},
protocols: {
project: {
root: ".",
identifiers: [".promptx", "package.json", ".git"]
},
memory: {
types: ["declarative", "episodic", "procedural", "semantic"]
}
}
};
const configPath = path.join(promptxDir, 'config.json');
await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf8');
console.log(chalk.green('✅ 创建配置文件: config.json'));
// 创建 .gitignore (如果需要)
const gitignorePath = path.join(projectRoot, '.gitignore');
try {
let gitignoreContent = '';
try {
gitignoreContent = await fs.readFile(gitignorePath, 'utf8');
} catch (error) {
// .gitignore 不存在
}
if (!gitignoreContent.includes('.promptx')) {
const appendContent = gitignoreContent.length > 0 ? '\n# PromptX\n.promptx/config.json\n' : '# PromptX\n.promptx/config.json\n';
await fs.appendFile(gitignorePath, appendContent, 'utf8');
console.log(chalk.green('✅ 更新 .gitignore 文件'));
}
} catch (error) {
console.log(chalk.yellow('⚠️ 无法更新 .gitignore 文件'));
}
// 完成提示
console.log(chalk.green.bold('\n🎉 PromptX 项目集成初始化完成!\n'));
console.log(chalk.blue('📁 创建的文件结构:'));
console.log(chalk.gray(' .promptx/'));
console.log(chalk.gray(' ├── config.json'));
console.log(chalk.gray(' └── memory/'));
console.log(chalk.gray(' ├── declarative.md'));
console.log(chalk.gray(' ├── episodic.md'));
console.log(chalk.gray(' ├── procedural.md'));
console.log(chalk.gray(' └── semantic.md'));
console.log(chalk.blue('\n🚀 可用的协议:'));
console.log(chalk.gray(' @project:// - 访问项目文件'));
console.log(chalk.gray(' @memory:// - 访问项目记忆'));
console.log(chalk.gray(' @prompt:// - 访问提示词资源'));
console.log(chalk.blue('\n🎯 下一步:'));
console.log(chalk.gray(' 1. 使用 promptx hello 选择 AI 角色'));
console.log(chalk.gray(' 2. 使用 promptx learn 学习项目知识'));
console.log(chalk.gray(' 3. 使用 promptx remember 保存重要信息'));
console.log(chalk.gray(' 4. 使用 promptx recall 检索记忆内容'));
} catch (error) {
console.error(chalk.red('❌ 初始化失败:'), error.message);
process.exit(1);
}
}
module.exports = init;

View File

@ -1,35 +0,0 @@
const chalk = require('chalk');
const logger = require('../utils/logger');
/**
* promptx learn 命令
* 学习命令 - AI获取和理解提示词内容
*/
async function learnCommand(resource, options) {
try {
logger.step(`学习资源: ${resource}`);
// TODO: 实现在任务 2.2 中
console.log(chalk.blue(`
📚 PromptX Learn 命令
${chalk.yellow('资源:')} ${resource}
${chalk.yellow('格式:')} ${options.format}
${chalk.yellow('状态:')} 待实现 (任务 2.2)
${chalk.green('计划功能:')}
- 支持打包参数 (protocols, core, domain)
- 支持具体文件路径
- 替代现有 node promptx.js 功能
- 向后兼容现有AI bootstrap流程
`));
logger.info('Learn命令框架已就绪等待具体实现');
} catch (error) {
logger.error('Learn命令执行失败:', error.message);
process.exit(1);
}
}
module.exports = learnCommand;

View File

@ -1,36 +0,0 @@
const chalk = require('chalk');
const logger = require('../utils/logger');
/**
* promptx recall 命令
* 记忆检索 - AI回忆和检索记忆内容
*/
async function recallCommand(options) {
try {
logger.step('检索记忆内容...');
// TODO: 实现在任务 2.3 中
console.log(chalk.green(`
🔍 PromptX Recall 命令
${chalk.yellow('选项:')}
- 最近记忆: ${options.recent || false}
- 重要记忆: ${options.important || false}
- 限制数量: ${options.limit}
${chalk.yellow('状态:')} 待实现 (任务 2.3)
${chalk.green('计划功能:')}
- 读取 .memory/declarative.md 文件
- 基础筛选功能 (--recent, --important)
- 为未来高级记忆体系打基础
`));
logger.info('Recall命令框架已就绪等待具体实现');
} catch (error) {
logger.error('Recall命令执行失败:', error.message);
process.exit(1);
}
}
module.exports = recallCommand;

View File

@ -1,36 +0,0 @@
const chalk = require('chalk');
const logger = require('../utils/logger');
/**
* promptx remember 命令
* 记忆保存 - AI保存重要信息和经验
*/
async function rememberCommand(content, options) {
try {
logger.step('保存记忆中...');
// TODO: 实现在任务 2.4 中
console.log(chalk.magenta(`
🧠 PromptX Remember 命令
${chalk.yellow('内容:')} ${content}
${chalk.yellow('评分:')} ${options.score}
${chalk.yellow('有效期:')} ${options.duration}
${chalk.yellow('状态:')} 待实现 (任务 2.4)
${chalk.green('计划功能:')}
- 写入 .memory/declarative.md 文件
- 结构化参数设计 (--score, --duration)
- 替代复杂标签系统
- 支持智能默认值
`));
logger.info('Remember命令框架已就绪等待具体实现');
} catch (error) {
logger.error('Remember命令执行失败:', error.message);
process.exit(1);
}
}
module.exports = rememberCommand;

View File

@ -0,0 +1,57 @@
{
"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"
}

View File

@ -0,0 +1,120 @@
/**
* 基础锦囊命令抽象类
* 所有锦囊命令都需要继承此类
*/
class BasePouchCommand {
constructor() {
this.context = {
currentPouch: '',
history: [],
userProfile: {},
sessionData: {},
domainContext: {}
};
this.outputFormat = 'human';
}
/**
* 执行锦囊命令
* @param {Array} args - 命令参数
* @returns {Promise<PouchOutput>} 锦囊输出
*/
async execute(args = []) {
const purpose = this.getPurpose();
const content = await this.getContent(args);
const pateoas = this.getPATEOAS(args);
return this.formatOutput(purpose, content, pateoas);
}
/**
* 设置状态上下文
* @param {StateContext} context - 状态上下文
*/
setContext(context) {
this.context = { ...this.context, ...context };
}
/**
* 设置输出格式
* @param {'human'|'json'} format - 输出格式
*/
setOutputFormat(format) {
this.outputFormat = format;
}
/**
* 获取锦囊目的说明(子类必须实现)
* @returns {string} 目的说明
*/
getPurpose() {
throw new Error('子类必须实现 getPurpose 方法');
}
/**
* 获取锦囊内容(子类必须实现)
* @param {Array} args - 命令参数
* @returns {Promise<string>} 锦囊内容
*/
async getContent(args) {
throw new Error('子类必须实现 getContent 方法');
}
/**
* 获取PATEOAS导航信息子类必须实现
* @param {Array} args - 命令参数
* @returns {PATEOASNavigation} PATEOAS导航
*/
getPATEOAS(args) {
throw new Error('子类必须实现 getPATEOAS 方法');
}
/**
* 格式化输出
* @param {string} purpose - 目的说明
* @param {string} content - 内容
* @param {PATEOASNavigation} pateoas - PATEOAS导航
* @returns {PouchOutput} 格式化的输出
*/
formatOutput(purpose, content, pateoas) {
const output = {
purpose,
content,
pateoas,
context: this.context,
format: this.outputFormat
};
if (this.outputFormat === 'json') {
return output;
}
// 人类可读格式
return {
...output,
toString() {
const divider = '='.repeat(60);
const nextSteps = pateoas.nextActions
.map(action => ` - ${action.name}: ${action.description}\n 命令: ${action.command}`)
.join('\n');
return `
${divider}
🎯 锦囊目的:${purpose}
${divider}
📜 锦囊内容:
${content}
🔄 下一步行动:
${nextSteps}
📍 当前状态:${pateoas.currentState}
${divider}
`;
}
};
}
}
module.exports = BasePouchCommand;

View File

@ -0,0 +1,200 @@
const PouchStateMachine = require('./state/PouchStateMachine');
const PouchRegistry = require('./PouchRegistry');
const commands = require('./commands');
/**
* 锦囊CLI主入口
* 提供命令行接口和统一的执行入口
*/
class PouchCLI {
constructor() {
this.stateMachine = new PouchStateMachine();
this.registry = new PouchRegistry();
this.initialized = false;
}
/**
* 初始化CLI
*/
async initialize() {
if (this.initialized) {
return;
}
// 批量注册所有命令
this.registry.registerBatch({
init: commands.InitCommand,
hello: commands.HelloCommand,
action: commands.ActionCommand,
learn: commands.LearnCommand,
recall: commands.RecallCommand,
remember: commands.RememberCommand
});
// 将命令注册到状态机
for (const name of this.registry.list()) {
const command = this.registry.get(name);
this.stateMachine.registerCommand(name, command);
}
// 加载历史状态
await this.stateMachine.loadState();
this.initialized = true;
}
/**
* 执行命令
* @param {string} commandName - 命令名称
* @param {Array} args - 命令参数
* @returns {Promise<PouchOutput>} 执行结果
*/
async execute(commandName, args = []) {
// 确保已初始化
if (!this.initialized) {
await this.initialize();
}
// 验证命令是否存在
if (!this.registry.validate(commandName)) {
throw new Error(`未知命令: ${commandName}\n使用 'promptx help' 查看可用命令`);
}
try {
// 通过状态机执行命令
const result = await this.stateMachine.transition(commandName, args);
// 如果结果有 toString 方法,打印人类可读格式
if (result && result.toString && typeof result.toString === 'function') {
console.log(result.toString());
} else {
console.log(JSON.stringify(result, null, 2));
}
return result;
} catch (error) {
console.error(`执行命令出错: ${error.message}`);
throw error;
}
}
/**
* 获取帮助信息
* @returns {string} 帮助文本
*/
getHelp() {
const commands = this.registry.getCommandDetails();
const currentState = this.stateMachine.getCurrentState();
const availableTransitions = this.stateMachine.getAvailableTransitions();
let help = `
🎯 PromptX 锦囊系统帮助
========================
当前状态: ${currentState}
可用转换: ${availableTransitions.join(', ')}
📋 可用命令:
`;
for (const cmd of commands) {
help += `\n ${cmd.name.padEnd(12)} - ${cmd.purpose}`;
}
help += `
💡 使用示例:
promptx init # 初始化工作环境
promptx hello # 发现可用角色
promptx action copywriter # 激活文案专家
promptx learn scrum # 学习敏捷知识
promptx recall frontend # 检索前端记忆
🔄 PATEOAS 导航:
每个命令执行后都会提供下一步的建议操作,
按照提示即可完成完整的工作流程。
📚 更多信息请访问: https://github.com/yourusername/promptx
`;
return help;
}
/**
* 获取当前状态信息
* @returns {StateContext} 状态上下文
*/
getStatus() {
return {
currentState: this.stateMachine.getCurrentState(),
availableCommands: this.registry.list(),
availableTransitions: this.stateMachine.getAvailableTransitions(),
context: this.stateMachine.context,
initialized: this.initialized
};
}
/**
* 解析命令行输入
* @param {string} input - 用户输入
* @returns {Object} 解析结果
*/
parseCommand(input) {
const parts = input.trim().split(/\s+/);
const command = parts[0];
const args = parts.slice(1);
return {
command: command,
args: args
};
}
/**
* 运行交互式CLI
*/
async runInteractive() {
console.log('🎯 欢迎使用 PromptX 锦囊系统!');
console.log('输入 "help" 查看帮助,"exit" 退出\n');
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'promptx> '
});
rl.prompt();
rl.on('line', async (line) => {
const input = line.trim();
if (input === 'exit' || input === 'quit') {
console.log('再见!');
rl.close();
return;
}
if (input === 'help') {
console.log(this.getHelp());
} else if (input === 'status') {
console.log(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);
}
}
rl.prompt();
});
rl.on('close', () => {
process.exit(0);
});
}
}
module.exports = PouchCLI;

View File

@ -0,0 +1,91 @@
/**
* 锦囊命令注册器
* 负责管理和注册所有锦囊命令
*/
class PouchRegistry {
constructor() {
this.commands = new Map();
}
/**
* 注册锦囊命令
* @param {string} name - 命令名称
* @param {BasePouchCommand} command - 命令实例
*/
register(name, command) {
if (!name || typeof name !== 'string') {
throw new Error('命令名称必须是非空字符串');
}
if (!command || typeof command.execute !== 'function') {
throw new Error('命令必须实现 execute 方法');
}
this.commands.set(name.toLowerCase(), command);
}
/**
* 获取锦囊命令
* @param {string} name - 命令名称
* @returns {BasePouchCommand} 命令实例
*/
get(name) {
return this.commands.get(name.toLowerCase());
}
/**
* 列出所有已注册的命令
* @returns {string[]} 命令名称列表
*/
list() {
return Array.from(this.commands.keys());
}
/**
* 验证命令是否存在
* @param {string} name - 命令名称
* @returns {boolean} 是否存在
*/
validate(name) {
return this.commands.has(name.toLowerCase());
}
/**
* 获取命令详情
* @returns {Object[]} 命令详情列表
*/
getCommandDetails() {
const details = [];
for (const [name, command] of this.commands) {
details.push({
name: name,
purpose: command.getPurpose ? command.getPurpose() : '未定义',
className: command.constructor.name
});
}
return details;
}
/**
* 清空注册器
*/
clear() {
this.commands.clear();
}
/**
* 批量注册命令
* @param {Object} commandMap - 命令映射对象
*/
registerBatch(commandMap) {
for (const [name, CommandClass] of Object.entries(commandMap)) {
if (typeof CommandClass === 'function') {
this.register(name.toLowerCase(), new CommandClass());
}
}
}
}
module.exports = PouchRegistry;

View File

@ -0,0 +1,179 @@
# 锦囊框架 (Pouch Framework)
基于 PATEOAS (Prompt as the Engine of Application State) 理念的 AI-First CLI 框架。
## 🎯 核心理念
锦囊框架实现了"诸葛锦囊"的设计模式,每个锦囊都是:
- **自包含的专家知识单元**:独立执行,不依赖上下文
- **状态驱动的导航系统**:通过 PATEOAS 引导下一步操作
- **AI 友好的接口设计**:专为 AI 使用而优化
## 🏗️ 架构设计
```
锦囊框架
├── BasePouchCommand # 基础命令抽象类
├── PouchCLI # CLI 主入口
├── PouchRegistry # 命令注册器
├── PouchStateMachine # 状态机管理器
└── Commands/ # 五个核心锦囊
├── InitCommand # 初始化锦囊
├── HelloCommand # 角色发现锦囊
├── ActionCommand # 角色激活锦囊
├── LearnCommand # 领域学习锦囊
└── RecallCommand # 记忆检索锦囊
```
## 📦 快速开始
### 1. 引入框架
```javascript
const { cli } = require('./lib/core/pouch');
// 或者引入完整框架
const { PouchCLI, BasePouchCommand } = require('./lib/core/pouch');
```
### 2. 执行命令
```javascript
// 初始化环境
await cli.execute('init');
// 发现可用角色
await cli.execute('hello');
// 激活特定角色
await cli.execute('action', ['copywriter']);
// 学习领域知识
await cli.execute('learn', ['scrum']);
// 检索记忆
await cli.execute('recall', ['frontend']);
```
### 3. 获取状态
```javascript
// 获取当前状态
const status = cli.getStatus();
// 获取帮助信息
const help = cli.getHelp();
```
## 🔧 创建自定义锦囊
### 1. 继承 BasePouchCommand
```javascript
const BasePouchCommand = require('./lib/core/pouch/BasePouchCommand');
class CustomCommand extends BasePouchCommand {
getPurpose() {
return '自定义锦囊的目的说明';
}
async getContent(args) {
// 返回锦囊的核心内容(提示词)
return `这是自定义锦囊的内容...`;
}
getPATEOAS(args) {
// 返回 PATEOAS 导航信息
return {
currentState: 'custom-state',
availableTransitions: ['next-command'],
nextActions: [
{
name: '下一步操作',
description: '操作描述',
command: 'promptx next-command'
}
]
};
}
}
```
### 2. 注册命令
```javascript
const registry = new PouchRegistry();
registry.register('custom', new CustomCommand());
```
## 🌟 核心特性
### 三层输出结构
每个锦囊都输出三层信息:
1. **Purpose目的**:说明锦囊的作用
2. **Content内容**:核心提示词或知识
3. **PATEOAS导航**:下一步操作指引
### 状态机管理
- 自动记录状态历史
- 持久化状态到 `.promptx.json`
- 支持状态回溯和恢复
### 灵活的输出格式
```javascript
// 设置为 JSON 格式
command.setOutputFormat('json');
// 设置为人类可读格式(默认)
command.setOutputFormat('human');
```
## 📋 命令列表
| 命令 | 说明 | 示例 |
|------|------|------|
| init | 初始化工作环境 | `promptx init` |
| hello | 发现可用角色 | `promptx hello` |
| action | 激活特定角色 | `promptx action copywriter` |
| learn | 学习领域知识 | `promptx learn scrum` |
| recall | 检索相关记忆 | `promptx recall test` |
## 🚀 进阶用法
### 交互式模式
```javascript
const cli = new PouchCLI();
await cli.runInteractive();
```
### 批量执行
```javascript
const commands = [
{ name: 'init', args: [] },
{ name: 'hello', args: [] },
{ name: 'action', args: ['frontend'] }
];
for (const cmd of commands) {
await cli.execute(cmd.name, cmd.args);
}
```
## 🤝 贡献指南
欢迎贡献新的锦囊命令!请确保:
1. 继承 `BasePouchCommand`
2. 实现三个核心方法
3. 提供清晰的 PATEOAS 导航
4. 编写测试用例
## <20><> 许可证
MIT License

View File

@ -0,0 +1,325 @@
const BasePouchCommand = require('../BasePouchCommand');
const fs = require('fs-extra');
const path = require('path');
/**
* 角色激活锦囊命令
* 负责分析角色文件提取需要学习的thought、execution和knowledge
*/
class ActionCommand extends BasePouchCommand {
constructor() {
super();
// 获取HelloCommand的角色注册表
this.helloCommand = null;
}
getPurpose() {
return '激活特定AI角色分析并生成具体的思维模式、行为模式和知识学习计划';
}
async getContent(args) {
const [roleId] = args;
if (!roleId) {
return `❌ 请指定要激活的角色ID
🔍 使用方法:
\`\`\`bash
promptx action <角色ID>
\`\`\`
💡 查看可用角色:
\`\`\`bash
promptx hello
\`\`\``;
}
try {
// 1. 获取角色信息
const roleInfo = await this.getRoleInfo(roleId);
if (!roleInfo) {
return `❌ 角色 "${roleId}" 不存在!
🔍 请使用以下命令查看可用角色:
\`\`\`bash
promptx hello
\`\`\``;
}
// 2. 分析角色文件,提取依赖
const dependencies = await this.analyzeRoleDependencies(roleInfo);
// 3. 生成学习计划 (新版本以role://开头)
return this.generateLearningPlan(roleInfo.id, dependencies);
} catch (error) {
console.error('Action command error:', error);
return `❌ 激活角色 "${roleId}" 时发生错误。
🔍 可能的原因:
- 角色文件不存在或格式错误
- 权限不足
- 系统资源问题
💡 请使用 \`promptx hello\` 查看可用角色列表。`;
}
}
/**
* 获取角色信息从HelloCommand
*/
async getRoleInfo(roleId) {
// 懒加载HelloCommand实例
if (!this.helloCommand) {
const HelloCommand = require('./HelloCommand');
this.helloCommand = new HelloCommand();
}
return this.helloCommand.getRoleInfo(roleId);
}
/**
* 分析角色文件提取thought和execution依赖
*/
async analyzeRoleDependencies(roleInfo) {
try {
// 处理文件路径,将@package://前缀替换为实际路径
let filePath = roleInfo.file;
if (filePath.startsWith('@package://')) {
filePath = filePath.replace('@package://', '');
}
// 读取角色文件内容
const roleContent = await fs.readFile(filePath, 'utf-8');
// 提取所有资源引用
const resourceRegex = /@([!?]?)([a-zA-Z][a-zA-Z0-9_-]*):\/\/([a-zA-Z0-9_\/.,-]+?)(?=[\s\)\],]|$)/g;
const matches = Array.from(roleContent.matchAll(resourceRegex));
const dependencies = {
thoughts: new Set(),
executions: new Set(),
knowledge: [roleInfo.id] // 角色自身的knowledge
};
// 分类依赖
matches.forEach(match => {
const [fullMatch, priority, protocol, resource] = match;
if (protocol === 'thought') {
dependencies.thoughts.add(resource);
} else if (protocol === 'execution') {
dependencies.executions.add(resource);
}
});
return {
thoughts: dependencies.thoughts,
executions: dependencies.executions,
knowledge: dependencies.knowledge
};
} catch (error) {
console.error('Error analyzing role dependencies:', error);
// 如果分析失败,返回基础结构
return {
thoughts: [],
executions: [],
knowledge: [roleInfo.id]
};
}
}
/**
* 生成学习指引(基于分析出的依赖)
*/
generateLearningGuide(roleInfo, dependencies) {
let guide = `🎬 **角色激活计划:${roleInfo.name}**
📋 **角色概述**
${roleInfo.description}
`;
// 思维模式部分
if (dependencies.thoughts.length > 0) {
guide += `## 🧠 第一步:学习思维模式
掌握角色所需的核心思考技能
`;
dependencies.thoughts.forEach((thought, index) => {
guide += `### ${index + 1}. ${thought}
\`\`\`bash
promptx learn thought://${thought}
\`\`\`
`;
});
}
// 行为模式部分
if (dependencies.executions.length > 0) {
guide += `## ⚖️ 第二步:学习行为模式
掌握角色所需的核心执行技能
`;
dependencies.executions.forEach((execution, index) => {
guide += `### ${index + 1}. ${execution}
\`\`\`bash
promptx learn execution://${execution}
\`\`\`
`;
});
}
// 知识部分
guide += `## 📚 第三步:学习专业知识
获取角色的领域知识体系
`;
dependencies.knowledge.forEach((knowledge, index) => {
guide += `### ${index + 1}. ${knowledge} 领域知识
\`\`\`bash
promptx learn knowledge://${knowledge}
\`\`\`
`;
});
// 编排学习
guide += `## 🎪 第四步:学习编排方式
理解如何组合使用已学的技能
\`\`\`bash
promptx learn personality://${roleInfo.id}
\`\`\`
\`\`\`bash
promptx learn principle://${roleInfo.id}
\`\`\`
## ✅ 角色激活确认
完成学习后,请确认角色激活:
1. **思维确认**:🧠 "我已掌握所需的思考技能!"
2. **行为确认**:⚖️ "我已掌握所需的执行技能!"
3. **知识确认**:📚 "我已具备领域专业知识!"
4. **编排确认**:🎪 "我已理解技能的组合使用方式!"
## 🎯 下一步操作
角色激活完成后,可以:
- 📝 **开始专业工作** - 运用角色能力解决实际问题
- 🔍 **调用记忆** - 使用 \`promptx recall\` 检索相关经验
- 🔄 **切换角色** - 使用 \`promptx hello\` 选择其他专业角色
💡 **设计理念**:基于 DPML 基础协议组合通过thought和execution的灵活编排实现角色能力。`;
return guide;
}
/**
* 生成学习计划
*/
generateLearningPlan(roleId, dependencies) {
const { thoughts, executions } = dependencies;
let plan = `🎭 **准备激活角色:${roleId}**\n\n`;
// 第一步:学习完整角色
plan += `## 🎯 第一步:掌握角色全貌\n`;
plan += `理解角色的完整定义和核心特征\n\n`;
plan += `\`\`\`bash\n`;
plan += `promptx learn role://${roleId}\n`;
plan += `\`\`\`\n\n`;
// 第二步:学习思维模式
if (thoughts.size > 0) {
plan += `## 🧠 第二步:掌握思维模式\n`;
plan += `学习角色特定的思考方式和认知框架\n\n`;
Array.from(thoughts).forEach((thought, index) => {
plan += `\`\`\`bash\n`;
plan += `promptx learn thought://${thought}\n`;
plan += `\`\`\`\n\n`;
});
}
// 第三步:掌握执行技能
if (executions.size > 0) {
plan += `## ⚡ 第${thoughts.size > 0 ? '三' : '二'}步:掌握执行技能\n`;
plan += `学习角色的行为模式和操作技能\n\n`;
Array.from(executions).forEach((execution, index) => {
plan += `\`\`\`bash\n`;
plan += `promptx learn execution://${execution}\n`;
plan += `\`\`\`\n\n`;
});
}
// 激活确认
const stepCount = thoughts.size > 0 ? (executions.size > 0 ? '四' : '三') : (executions.size > 0 ? '三' : '二');
plan += `## 🎪 第${stepCount}步:完成角色激活\n`;
plan += `确认角色能力已完全激活\n\n`;
plan += `✅ **角色激活检查清单**\n`;
plan += `- [x] 已学习完整角色定义\n`;
if (thoughts.size > 0) plan += `- [x] 已掌握 ${thoughts.size} 个思维模式\n`;
if (executions.size > 0) plan += `- [x] 已掌握 ${executions.size} 个执行技能\n`;
plan += `- [x] 可以开始以${roleId}身份工作\n\n`;
return plan;
}
getPATEOAS(args) {
const [roleId] = args;
if (!roleId) {
return {
currentState: 'action_awaiting_role',
availableTransitions: ['hello'],
nextActions: [
{
name: '查看可用角色',
description: '返回角色发现页面',
command: 'promptx hello',
priority: 'high'
}
],
metadata: {
message: '需要指定角色ID'
}
};
}
return {
currentState: 'action_plan_generated',
availableTransitions: ['learn', 'recall', 'hello'],
nextActions: [
{
name: '开始学习',
description: '按计划开始学习技能',
command: `promptx learn`,
priority: 'high'
},
{
name: '返回角色选择',
description: '选择其他角色',
command: 'promptx hello',
priority: 'low'
}
],
metadata: {
targetRole: roleId,
planGenerated: true,
architecture: 'DPML协议组合',
approach: '分析-提取-编排',
systemVersion: '锦囊串联状态机 v1.0',
designPhilosophy: 'AI use CLI get prompt for AI'
}
};
}
}
module.exports = ActionCommand;

View File

@ -0,0 +1,225 @@
const BasePouchCommand = require('../BasePouchCommand');
const fs = require('fs-extra');
const path = require('path');
/**
* 角色发现锦囊命令
* 负责展示可用的AI角色和领域专家
*/
class HelloCommand extends BasePouchCommand {
constructor() {
super();
// 角色注册表 - 硬编码版本,未来可扩展为动态发现
this.ROLES_REGISTRY = [
{
id: 'video-copywriter',
name: '🎬 视频文案专家',
description: '专业视频内容创作与营销文案,具备创意性、故事性和营销性思维',
category: '内容创作',
domain: 'video-copywriting',
file: '@package://prompt/domain/copywriter/video-copywriter.role.md'
},
{
id: 'product-owner',
name: '🎯 产品负责人',
description: '敏捷开发核心决策者,具备全栈产品管理能力和技术理解',
category: '项目管理',
domain: 'scrum-product-ownership',
file: '@package://prompt/domain/scrum/role/product-owner.role.md'
},
{
id: 'prompt-developer',
name: '🔧 提示词开发者',
description: '探索性、系统性和批判性思维的提示词设计专家',
category: '技术开发',
domain: 'prompt-engineering',
file: '@package://prompt/domain/prompt/prompt-developer.role.md'
},
{
id: 'test-assistant',
name: '🧪 测试助手',
description: '基础测试角色,具备思考和记忆处理能力',
category: '质量保证',
domain: 'testing',
file: '@package://prompt/domain/test/test.role.md'
},
{
id: 'assistant',
name: '🙋 智能助手',
description: '通用助理角色,提供基础的助理服务和记忆支持',
category: '通用服务',
domain: 'general-assistance',
file: '@package://prompt/domain/assistant/assistant.role.md'
}
];
}
getPurpose() {
return '发现并展示所有可用的AI角色和领域专家帮助选择合适的专业身份开始工作';
}
async getContent(args) {
const rolesByCategory = this.groupRolesByCategory();
const totalRoles = this.ROLES_REGISTRY.length;
let content = `👋 欢迎来到 PromptX 锦囊系统!
🎭 **可用的AI角色与领域专家** (共 ${totalRoles} 个角色)
`;
// 按分类展示角色
for (const [category, roles] of Object.entries(rolesByCategory)) {
content += `## ${this.getCategoryIcon(category)} ${category}\n\n`;
roles.forEach(role => {
content += `### ${role.name}\n`;
content += `- **角色ID**: \`${role.id}\`\n`;
content += `- **专业领域**: ${role.domain}\n`;
content += `- **能力描述**: ${role.description}\n\n`;
});
}
content += `
🎯 **下一步操作指南**
选择一个角色,使用以下命令激活专业能力:
\`\`\`bash
# 1. 激活角色 (推荐)
promptx action <角色ID>
# 2. 或直接学习角色知识
promptx learn <角色ID>
\`\`\`
💡 **使用示例**
\`\`\`bash
promptx action video-copywriter # 激活视频文案专家
promptx action product-owner # 激活产品负责人
promptx action prompt-developer # 激活提示词开发者
\`\`\`
🔄 **锦囊串联流程**
👋 **hello**(发现角色) → ⚡ **action**(激活角色) → 📚 **learn**(学习知识) → 🔍 **recall**(应用经验)
`;
return content;
}
getPATEOAS(args) {
const availableRoles = this.ROLES_REGISTRY.map(role => ({
roleId: role.id,
name: role.name,
category: role.category,
actionCommand: `promptx action ${role.id}`
}));
return {
currentState: 'role_discovery',
availableTransitions: ['action', 'learn', 'init', 'recall'],
nextActions: [
{
name: '激活视频文案专家',
description: '成为专业的视频内容创作者',
command: 'promptx action video-copywriter',
priority: 'high'
},
{
name: '激活产品负责人',
description: '成为敏捷开发的决策者',
command: 'promptx action product-owner',
priority: 'high'
},
{
name: '激活提示词开发者',
description: '成为提示词设计专家',
command: 'promptx action prompt-developer',
priority: 'medium'
},
{
name: '激活智能助手',
description: '成为通用助理',
command: 'promptx action assistant',
priority: 'low'
},
{
name: '学习特定领域',
description: '深入学习某个专业领域',
command: 'promptx learn <domain>',
parameters: {
domain: '可选值copywriter, scrum, prompt, test, assistant'
}
}
],
metadata: {
totalRoles: this.ROLES_REGISTRY.length,
categories: [...new Set(this.ROLES_REGISTRY.map(r => r.category))],
availableRoles: availableRoles,
systemVersion: '锦囊串联状态机 v1.0',
designPhilosophy: 'AI use CLI get prompt for AI'
}
};
}
/**
* 按分类分组角色
*/
groupRolesByCategory() {
const grouped = {};
this.ROLES_REGISTRY.forEach(role => {
if (!grouped[role.category]) {
grouped[role.category] = [];
}
grouped[role.category].push(role);
});
return grouped;
}
/**
* 获取分类图标
*/
getCategoryIcon(category) {
const icons = {
'内容创作': '✍️',
'项目管理': '📊',
'技术开发': '💻',
'质量保证': '🔍',
'通用服务': '🤖'
};
return icons[category] || '🎯';
}
/**
* 获取角色信息(提供给其他命令使用)
*/
getRoleInfo(roleId) {
return this.ROLES_REGISTRY.find(role => role.id === roleId);
}
/**
* 获取所有角色列表
*/
getAllRoles() {
return this.ROLES_REGISTRY;
}
/**
* 未来扩展:动态角色发现
* TODO: 实现真正的文件扫描和解析
*/
async discoverAvailableDomains() {
// 预留接口,未来实现动态角色发现
// 1. 扫描 prompt/domain/ 目录
// 2. 解析 .role.md 文件
// 3. 提取元数据和描述
// 4. 构建动态注册表
return this.ROLES_REGISTRY.map(role => role.domain);
}
}
module.exports = HelloCommand;

View File

@ -0,0 +1,146 @@
const BasePouchCommand = require('../BasePouchCommand');
const fs = require('fs-extra');
const path = require('path');
const { ResourceManager } = require('../../resource');
/**
* 初始化锦囊命令
* 负责准备工作环境和传达系统协议
*/
class InitCommand extends BasePouchCommand {
constructor() {
super();
this.resourceManager = new ResourceManager();
}
getPurpose() {
return '初始化PromptX工作环境传达系统基本诺记协议体系';
}
async getContent(args) {
const [workspacePath = '.'] = args;
// 1. 技术初始化
await this.initializeWorkspace(workspacePath);
// 2. 加载协议体系
const protocolContent = await this.loadProtocolSystem();
return `🎯 PromptX 系统初始化完成!
## 🏗️ 技术环境准备
✅ 创建了项目目录结构
✅ 配置了 .promptx/pouch.json 锦囊状态文件
✅ 准备了锦囊状态机框架
## 📋 系统基本诺记 (协议体系)
${protocolContent}
## 🚀 开始使用
现在你已经获得了 PromptX 的完整理念和协议体系。
每个锦囊都是独立的智慧单元即使AI忘记了上下文锦囊依然能够独立执行。
### 🎒 核心锦囊流程
\`\`\`
🏗init(已完成) → 👋hello → ⚡action → 📚learn → 🔍recall → 循环
\`\`\`
你现在可以开始探索锦囊世界了!`;
}
/**
* 加载协议体系内容
*/
async loadProtocolSystem() {
try {
// 加载完整协议体系PATEOAS + DPML + 所有标签协议
const result = await this.resourceManager.resolve('@prompt://protocols');
if (result.success) {
return result.content;
} else {
console.warn('⚠️ 协议加载失败:', result.error?.message);
return this.getCoreProtocolSummary();
}
} catch (error) {
console.warn('⚠️ 无法加载完整协议体系,使用核心摘要:', error.message);
return this.getCoreProtocolSummary();
}
}
/**
* 获取核心协议摘要fallback
*/
getCoreProtocolSummary() {
return `### 🎯 核心理念AI use CLI get prompt for AI
**PATEOAS协议** - Prompt as the Engine of Application State
- 🎒 锦囊自包含:每个命令包含完整执行信息
- 🔗 串联无依赖即使AI忘记上文也能继续执行
- 🎯 分阶段专注:每个锦囊只关注当前任务
- 🔄 Prompt驱动每个输出引导AI发现下一步操作
**DPML协议** - Deepractice Prompt Markup Language
- 📋 标准化标记:使用 \`<thinking>\`\`<executing>\` 等标签
- 🏷️ 语义清晰:通过标签明确表达提示词结构
- 🔗 协议绑定:支持 \`A:B\` 语法表达实现关系
**三大解决方案**
- **上下文遗忘** → 锦囊自包含,每个命令独立执行
- **注意力分散** → 分阶段专注,每锦囊专注单一任务
- **能力局限** → 即时专家化,通过提示词获得专业能力`;
}
getPATEOAS(args) {
return {
currentState: 'initialized',
availableTransitions: ['hello', 'action', 'learn'],
nextActions: [
{
name: '发现角色',
description: '探索可用的AI角色和领域专家',
command: 'promptx hello'
},
{
name: '查看帮助',
description: '了解更多锦囊使用方法',
command: 'promptx help'
}
],
metadata: {
timestamp: new Date().toISOString(),
version: '0.0.1'
}
};
}
async initializeWorkspace(workspacePath) {
// 创建基础目录结构
const dirs = [
'prompt/core',
'prompt/domain',
'prompt/protocol',
'prompt/resource',
'.promptx'
];
for (const dir of dirs) {
await fs.ensureDir(path.join(workspacePath, dir));
}
// 创建锦囊状态配置文件
const configPath = path.join(workspacePath, '.promptx', 'pouch.json');
if (!await fs.pathExists(configPath)) {
await fs.writeJson(configPath, {
version: '0.0.1',
initialized: new Date().toISOString(),
defaultFormat: 'human',
stateHistory: []
}, { spaces: 2 });
}
}
}
module.exports = InitCommand;

View File

@ -0,0 +1,242 @@
const BasePouchCommand = require('../BasePouchCommand');
const ResourceManager = require('../../resource/resourceManager');
/**
* 智能学习锦囊命令
* 支持加载thought、execution、memory等协议资源以及角色的personality、principle、knowledge
*/
class LearnCommand extends BasePouchCommand {
constructor() {
super();
this.resourceManager = new ResourceManager();
}
getPurpose() {
return '智能学习指定协议的资源内容支持thought、execution、memory等DPML协议以及角色组件';
}
async getContent(args) {
const [resourceUrl] = args;
if (!resourceUrl) {
return this.getUsageHelp();
}
try {
// 直接使用ResourceManager解析资源
const content = await this.resourceManager.resolve(resourceUrl);
// 解析协议信息
const urlMatch = resourceUrl.match(/^([a-zA-Z]+):\/\/(.+)$/);
const [, protocol, resourceId] = urlMatch;
return this.formatSuccessResponse(protocol, resourceId, content);
} catch (error) {
return this.formatErrorResponse(resourceUrl, error.message);
}
}
/**
* 格式化成功响应
*/
formatSuccessResponse(protocol, resourceId, content) {
const protocolLabels = {
thought: '🧠 思维模式',
execution: '⚡ 执行模式',
memory: '💾 记忆模式',
personality: '👤 角色人格',
principle: '⚖️ 行为原则',
knowledge: '📚 专业知识'
};
const label = protocolLabels[protocol] || `📄 ${protocol}`;
return `✅ **成功学习${label}${resourceId}**
## 📋 学习内容
${content}
## 🎯 学习效果
- ✅ **已激活${label}能力**
- ✅ **相关知识已整合到AI认知体系**
- ✅ **可立即应用于实际场景**
## 🔄 下一步行动:
- 继续学习: 学习其他相关资源
命令: \`promptx learn <protocol>://<resource-id>\`
- 应用记忆: 检索相关经验
命令: \`promptx recall\`
- 激活角色: 激活完整角色能力
命令: \`promptx action <role-id>\`
📍 当前状态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\` - 学习角色知识
🔍 查看可用资源:
\`\`\`bash
promptx action <role-id> # 查看角色的所有依赖
\`\`\`
🔄 下一步行动:
- 继续学习: 学习其他资源
命令: promptx learn <protocol>://<resource-id>
- 应用记忆: 检索相关经验
命令: promptx recall
- 激活角色: 激活完整角色能力
命令: promptx action <role-id>
- 查看角色列表: 选择其他角色
命令: promptx hello`;
}
/**
* 获取使用帮助
*/
getUsageHelp() {
return `🎓 **Learn锦囊 - 智能学习系统**
## 📖 基本用法
\`\`\`bash
promptx learn <protocol>://<resource-id>
\`\`\`
## 🎯 支持的协议
### 🔧 DPML核心协议
- **\`thought://\`** - 思维模式资源
- **\`execution://\`** - 执行模式资源
- **\`memory://\`** - 记忆系统资源
### 👤 角色组件协议
- **\`personality://\`** - 角色人格特征
- **\`principle://\`** - 行为原则
- **\`knowledge://\`** - 专业知识
## 📝 使用示例
\`\`\`bash
# 学习执行技能
promptx learn execution://deal-at-reference
# 学习思维模式
promptx learn thought://prompt-developer
# 学习角色人格
promptx learn personality://video-copywriter
\`\`\`
## 🔍 发现可学习资源
\`\`\`bash
promptx action <role-id> # 查看角色需要的所有资源
promptx hello # 查看可用角色列表
\`\`\`
🔄 下一步行动:
- 激活角色: 分析角色依赖
命令: promptx action <role-id>
- 查看角色: 选择感兴趣的角色
命令: promptx hello`;
}
/**
* 获取PATEOAS导航信息
*/
getPATEOAS(args) {
const [resourceUrl] = args;
if (!resourceUrl) {
return {
currentState: 'learn_awaiting_resource',
availableTransitions: ['hello', 'action'],
nextActions: [
{
name: '查看可用角色',
description: '返回角色选择页面',
command: 'promptx hello',
priority: 'high'
},
{
name: '生成学习计划',
description: '为特定角色生成学习计划',
command: 'promptx action <role-id>',
priority: 'high'
}
]
};
}
const urlMatch = resourceUrl.match(/^([a-zA-Z]+):\/\/(.+)$/);
if (!urlMatch) {
return {
currentState: 'learn_error',
availableTransitions: ['hello', 'action'],
nextActions: [
{
name: '查看使用帮助',
description: '重新学习命令使用方法',
command: 'promptx learn',
priority: 'high'
}
]
};
}
const [, protocol, resourceId] = urlMatch;
return {
currentState: `learned_${protocol}`,
availableTransitions: ['learn', 'recall', 'hello', 'action'],
nextActions: [
{
name: '继续学习',
description: '学习其他资源',
command: 'promptx learn <protocol>://<resource-id>',
priority: 'medium'
},
{
name: '应用记忆',
description: '检索相关经验',
command: 'promptx recall',
priority: 'medium'
},
{
name: '激活角色',
description: '激活完整角色能力',
command: 'promptx action <role-id>',
priority: 'high'
},
{
name: '查看角色列表',
description: '选择其他角色',
command: 'promptx hello',
priority: 'low'
}
],
metadata: {
learnedResource: resourceUrl,
protocol: protocol,
resourceId: resourceId,
systemVersion: '锦囊串联状态机 v1.0'
}
};
}
}
module.exports = LearnCommand;

View File

@ -0,0 +1,217 @@
const BasePouchCommand = require('../BasePouchCommand');
const fs = require('fs-extra');
const path = require('path');
/**
* 记忆检索锦囊命令
* 负责从记忆库中检索相关知识和经验
*/
class RecallCommand extends BasePouchCommand {
constructor() {
super();
}
getPurpose() {
return 'AI主动检索记忆中的专业知识、最佳实践和历史经验';
}
async getContent(args) {
const [query] = args;
try {
const memories = await this.getAllMemories(query);
if (memories.length === 0) {
return `🧠 AI记忆体系中暂无内容。
💡 建议:
1. 使用 promptx remember 内化新知识
2. 使用 promptx learn 学习后再内化
3. 开始构建AI的专业知识体系`;
}
const formattedMemories = this.formatRetrievedKnowledge(memories, query);
return `🧠 AI记忆体系 ${query ? `检索"${query}"` : '全部记忆'} (${memories.length}条)
${formattedMemories}
💡 记忆运用建议:
1. 结合当前任务场景灵活运用
2. 根据实际情况调整和变通
3. 持续学习和增强记忆能力`;
} catch (error) {
return `❌ 检索记忆时出错:${error.message}`;
}
}
getPATEOAS(args) {
const [query] = args;
if (!query) {
return {
currentState: 'recall-waiting',
availableTransitions: ['hello', 'learn'],
nextActions: [
{
name: '查看领域',
description: '查看可检索的领域',
command: 'promptx hello'
}
]
};
}
const domain = this.extractDomain(query);
return {
currentState: `recalled-${query}`,
availableTransitions: ['action', 'learn', 'remember'],
nextActions: [
{
name: '应用记忆',
description: `使用检索到的${query}知识`,
command: `promptx action ${query}`
},
{
name: '深入学习',
description: `学习更多${domain}知识`,
command: `promptx learn ${domain}`
},
{
name: '增强记忆',
description: 'AI内化新的知识增强记忆',
command: `promptx remember ${query}-update`
},
{
name: '相关检索',
description: '检索相关领域知识',
command: `promptx recall ${this.getRelatedQuery(query)}`
}
],
metadata: {
query: query,
resultCount: this.lastSearchCount || 0,
searchTime: new Date().toISOString()
}
};
}
/**
* 获取所有记忆(紧凑格式)
*/
async getAllMemories(query) {
this.lastSearchCount = 0;
const memories = [];
// 读取单一记忆文件
const memoryFile = path.join(process.cwd(), '.promptx/memory/declarative.md');
try {
if (await fs.pathExists(memoryFile)) {
const content = await fs.readFile(memoryFile, 'utf-8');
const lines = content.split('\n');
for (const line of lines) {
if (line.startsWith('- ')) {
// 解析记忆行
const memory = this.parseMemoryLine(line);
if (memory && (!query || this.matchesMemory(memory, query))) {
memories.push(memory);
}
}
}
}
} catch (error) {
console.error('Error reading memories:', error);
}
this.lastSearchCount = memories.length;
return memories;
}
/**
* 解析记忆行(紧凑格式)
*/
parseMemoryLine(line) {
// 格式:- 2025/05/31 14:30 内容 #key #tag1 #tag2 #评分:8 #有效期:长期
const match = line.match(/^- (\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}) (.*?) (#\w+.*?)$/);
if (!match) return null;
const [, timestamp, content, tagsStr] = match;
const tags = tagsStr.split(' ').filter(t => t.startsWith('#'));
const keyTag = tags.find(t => !t.includes(':') && !['#敏捷开发', '#测试', '#部署', '#前端开发', '#后端开发', '#AI', '#最佳实践', '#流程管理', '#工具使用', '#其他'].includes(t));
return {
timestamp,
content,
key: keyTag ? keyTag.substring(1) : 'unknown',
tags,
source: keyTag ? keyTag.substring(1) : 'unknown'
};
}
/**
* 检查记忆是否匹配查询
*/
matchesMemory(memory, query) {
const lowerQuery = query.toLowerCase();
return memory.content.toLowerCase().includes(lowerQuery) ||
memory.key.toLowerCase().includes(lowerQuery) ||
memory.tags.some(tag => tag.toLowerCase().includes(lowerQuery));
}
matchesQuery(content, query) {
const lowerContent = content.toLowerCase();
const lowerQuery = query.toLowerCase();
const keywords = lowerQuery.split(/\s+/);
return keywords.some(keyword => lowerContent.includes(keyword));
}
/**
* 格式化检索到的记忆(紧凑格式)
*/
formatRetrievedKnowledge(memories, query) {
return memories.map((memory, index) => {
const content = memory.content.length > 120 ?
memory.content.substring(0, 120) + '...' :
memory.content;
return `📝 ${index + 1}. **${memory.key}** (${memory.timestamp})
${content}
${memory.tags.slice(0, 5).join(' ')}
---`;
}).join('\n\n');
}
extractDomain(query) {
const domains = ['copywriter', 'scrum', 'developer', 'test', 'prompt'];
const lowerQuery = query.toLowerCase();
return domains.find(domain => lowerQuery.includes(domain)) || null;
}
getRelatedQuery(query) {
const relatedMap = {
'copywriter': 'marketing',
'scrum': 'agile',
'frontend': 'ui',
'backend': 'api',
'test': 'qa'
};
for (const [key, value] of Object.entries(relatedMap)) {
if (query.toLowerCase().includes(key)) {
return value;
}
}
return query + '-advanced';
}
}
module.exports = RecallCommand;

View File

@ -0,0 +1,328 @@
const BasePouchCommand = require('../BasePouchCommand');
const fs = require('fs-extra');
const path = require('path');
/**
* 记忆保存锦囊命令
* 负责将知识、经验和最佳实践保存到记忆库中
*/
class RememberCommand extends BasePouchCommand {
constructor() {
super();
}
getPurpose() {
return '增强AI长期记忆能力主动内化专业知识、最佳实践和项目经验';
}
async getContent(args) {
const [key, ...valueParts] = args;
const value = valueParts.join(' ');
if (!key) {
return this.getUsageHelp();
}
if (!value) {
return `❌ 请提供要内化的知识内容
🔍 使用方法:
\`\`\`bash
promptx remember <记忆标识> <知识内容>
\`\`\`
📝 示例:
\`\`\`bash
promptx remember copywriter-tips "视频文案要有强烈的画面感和节奏感"
promptx remember scrum-daily "每日站会应该控制在15分钟内关注昨天、今天、阻碍"
\`\`\``;
}
try {
const memoryEntry = await this.saveMemory(key, value);
return this.formatSaveResponse(key, value, memoryEntry);
} catch (error) {
return `❌ 记忆内化失败:${error.message}
💡 可能的原因:
- AI记忆体系目录权限不足
- 磁盘空间不够
- 记忆标识格式不正确
🔧 解决方案:
1. 检查 .promptx 目录权限
2. 确保磁盘空间充足
3. 使用简洁的记忆标识(字母、数字、连字符)`;
}
}
/**
* 将知识内化到AI记忆体系紧凑格式
*/
async saveMemory(key, value) {
// 1. 确保AI记忆体系目录存在
const memoryDir = await this.ensureMemoryDirectory();
// 2. 使用单一记忆文件
const memoryFile = path.join(memoryDir, 'declarative.md');
// 3. 格式化为一行记忆
const memoryLine = this.formatMemoryLine(key, value);
// 4. 追加到记忆文件
const action = await this.appendToMemoryFile(memoryFile, key, memoryLine);
return {
key,
value,
filePath: memoryFile,
action,
timestamp: new Date().toISOString()
};
}
/**
* 确保AI记忆体系目录存在
*/
async ensureMemoryDirectory() {
const promptxDir = path.join(process.cwd(), '.promptx');
const memoryDir = path.join(promptxDir, 'memory');
await fs.ensureDir(memoryDir);
return memoryDir;
}
/**
* 格式化为一行记忆(紧凑格式)
*/
formatMemoryLine(key, value) {
const now = new Date();
const timestamp = `${now.getFullYear()}/${String(now.getMonth() + 1).padStart(2, '0')}/${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
// 自动生成标签
const tags = this.generateTags(key, value);
return `- ${timestamp} ${value} #${key} ${tags} #评分:8 #有效期:长期`;
}
/**
* 自动生成标签
*/
generateTags(key, value) {
const tags = [];
const lowerKey = key.toLowerCase();
const lowerValue = value.toLowerCase();
// 基于key生成标签
if (lowerKey.includes('scrum') || lowerKey.includes('agile')) tags.push('#敏捷开发');
if (lowerKey.includes('test') || lowerKey.includes('qa')) tags.push('#测试');
if (lowerKey.includes('deploy') || lowerKey.includes('发布')) tags.push('#部署');
if (lowerKey.includes('react') || lowerKey.includes('前端')) tags.push('#前端开发');
if (lowerKey.includes('api') || lowerKey.includes('后端')) tags.push('#后端开发');
if (lowerKey.includes('prompt') || lowerKey.includes('ai')) tags.push('#AI');
// 基于value生成标签
if (lowerValue.includes('最佳实践') || lowerValue.includes('规则')) tags.push('#最佳实践');
if (lowerValue.includes('流程') || lowerValue.includes('步骤')) tags.push('#流程管理');
if (lowerValue.includes('命令') || lowerValue.includes('工具')) tags.push('#工具使用');
return tags.join(' ') || '#其他';
}
/**
* 追加到记忆文件
*/
async appendToMemoryFile(memoryFile, key, memoryLine) {
// 初始化文件(如果不存在)
if (!await fs.pathExists(memoryFile)) {
await fs.writeFile(memoryFile, `# 陈述性记忆
## 高价值记忆(评分 ≥ 7
${memoryLine}
`);
return 'created';
}
// 读取现有内容
const content = await fs.readFile(memoryFile, 'utf-8');
// 检查是否已存在相同key的记忆
const keyPattern = new RegExp(`^- .*#${key}\\b`, 'm');
if (keyPattern.test(content)) {
// 替换现有记忆
const updatedContent = content.replace(keyPattern, memoryLine);
await fs.writeFile(memoryFile, updatedContent);
return 'updated';
} else {
// 追加新记忆(在高价值记忆部分)
const insertPosition = content.indexOf('\n\n') + 2;
const updatedContent = content.slice(0, insertPosition) + memoryLine + '\n\n' + content.slice(insertPosition);
await fs.writeFile(memoryFile, updatedContent);
return 'created';
}
}
/**
* 格式化保存响应(简化版本)
*/
formatSaveResponse(key, value, memoryEntry) {
const { action, timestamp } = memoryEntry;
const actionLabels = {
created: '✅ AI已内化新记忆',
updated: '🔄 AI已更新记忆'
};
return `${actionLabels[action]}${key}
## 📋 记忆详情
- **记忆标识**: \`${key}\`
- **内化时间**: ${timestamp.split('T')[0]}
- **知识内容**: ${value.length > 100 ? value.substring(0, 100) + '...' : value}
## 🎯 能力增强效果
- ✅ **知识已内化到AI长期记忆**
- ✅ **可通过recall命令主动检索**
- ✅ **支持跨会话记忆保持**
## 🔄 下一步行动:
- 记忆检索: 验证知识内化效果
命令: \`promptx recall ${key}\`
- 能力强化: 学习相关知识增强记忆
命令: \`promptx learn <protocol>://<resource-id>\`
- 应用实践: 在实际场景中运用记忆
命令: \`promptx action <role-id>\`
📍 当前状态memory_saved`;
}
/**
* 获取使用帮助
*/
getUsageHelp() {
return `🧠 **Remember锦囊 - AI记忆增强系统**
## 📖 基本用法
\`\`\`bash
promptx remember <记忆标识> <知识内容>
\`\`\`
## 💡 记忆内化示例
### 📝 AI记忆内化
AI学习和内化各种专业知识
\`\`\`bash
promptx remember "deploy-process" "1.构建代码 2.运行测试 3.部署到staging 4.验证功能 5.发布生产"
promptx remember "debug-case-001" "用户反馈视频加载慢排查发现是CDN配置问题修改后加载速度提升60%"
promptx remember "react-hooks" "React Hooks允许在函数组件中使用state和其他React特性"
promptx remember "code-review-rules" "每个PR至少需要2个人review必须包含测试用例"
\`\`\`
## 💡 记忆标识规范
- 使用简洁的英文标识
- 支持连字符分隔
- 例如:\`copywriter-tips\`\`scrum-daily\`\`react-best-practice\`
## 🔍 记忆检索与应用
\`\`\`bash
promptx recall <关键词> # AI主动检索记忆
promptx action <role-id> # AI运用记忆激活角色
\`\`\`
🔄 下一步行动:
- 开始记忆: 内化第一条知识
命令: promptx remember <key> <content>
- 学习资源: 学习新知识再内化
命令: promptx learn <protocol>://<resource>`;
}
/**
* 获取PATEOAS导航信息
*/
getPATEOAS(args) {
const [key, ...valueParts] = args;
const value = valueParts.join(' ');
if (!key) {
return {
currentState: 'remember_awaiting_input',
availableTransitions: ['hello', 'learn', 'recall'],
nextActions: [
{
name: '查看角色',
description: '选择角色获取专业知识',
command: 'promptx hello',
priority: 'medium'
},
{
name: '学习资源',
description: '学习新知识然后保存',
command: 'promptx learn <protocol>://<resource>',
priority: 'high'
}
]
};
}
if (!value) {
return {
currentState: 'remember_awaiting_content',
availableTransitions: ['remember', 'recall'],
nextActions: [
{
name: '重新输入',
description: '提供完整的记忆内容',
command: `promptx remember ${key} <content>`,
priority: 'high'
}
]
};
}
return {
currentState: 'memory_saved',
availableTransitions: ['recall', 'learn', 'action', 'remember'],
nextActions: [
{
name: '检索记忆',
description: '测试记忆是否可检索',
command: `promptx recall ${key}`,
priority: 'high'
},
{
name: '学习强化',
description: '学习相关知识加强记忆',
command: 'promptx learn <protocol>://<resource>',
priority: 'medium'
},
{
name: '应用记忆',
description: '在实际场景中应用记忆',
command: 'promptx action <role-id>',
priority: 'medium'
},
{
name: '继续内化',
description: 'AI继续内化更多知识',
command: 'promptx remember <key> <content>',
priority: 'low'
}
],
metadata: {
savedMemory: key,
memoryLength: value.length,
timestamp: new Date().toISOString(),
systemVersion: '锦囊串联状态机 v1.0'
}
};
}
}
module.exports = RememberCommand;

View File

@ -0,0 +1,19 @@
/**
* 锦囊命令导出
*/
const InitCommand = require('./InitCommand');
const HelloCommand = require('./HelloCommand');
const ActionCommand = require('./ActionCommand');
const LearnCommand = require('./LearnCommand');
const RecallCommand = require('./RecallCommand');
const RememberCommand = require('./RememberCommand');
module.exports = {
InitCommand,
HelloCommand,
ActionCommand,
LearnCommand,
RecallCommand,
RememberCommand
};

View File

@ -0,0 +1,43 @@
/**
* 锦囊框架 (PATEOAS Framework)
* Prompt as the Engine of Application State
*
* 这是一个革命性的AI-First CLI框架通过锦囊串联实现AI的状态管理。
* 每个锦囊都是独立的专家知识单元通过PATEOAS导航实现状态转换。
*/
const PouchCLI = require('./PouchCLI');
const PouchRegistry = require('./PouchRegistry');
const PouchStateMachine = require('./state/PouchStateMachine');
const BasePouchCommand = require('./BasePouchCommand');
const commands = require('./commands');
// 创建全局CLI实例
const cli = new PouchCLI();
module.exports = {
// 主要导出
PouchCLI,
cli,
// 框架组件
PouchRegistry,
PouchStateMachine,
BasePouchCommand,
// 内置命令
commands,
// 便捷方法
execute: async (commandName, args) => {
return await cli.execute(commandName, args);
},
help: () => {
return cli.getHelp();
},
status: () => {
return cli.getStatus();
}
};

View File

@ -0,0 +1,47 @@
/**
* 锦囊框架核心接口定义
* PATEOAS (Prompt as the Engine of Application State)
*/
/**
* 动作定义
* @typedef {Object} Action
* @property {string} name - 动作名称
* @property {string} description - 动作描述
* @property {string} command - 执行命令
* @property {Object} [parameters] - 命令参数
* @property {string} [condition] - 执行条件
*/
/**
* PATEOAS导航信息
* @typedef {Object} PATEOASNavigation
* @property {Action[]} nextActions - 下一步可执行的动作列表
* @property {string} currentState - 当前状态
* @property {string[]} availableTransitions - 可用的状态转换
* @property {Object} [metadata] - 额外的元数据
*/
/**
* 状态上下文
* @typedef {Object} StateContext
* @property {string} currentPouch - 当前锦囊
* @property {string[]} history - 历史记录
* @property {Object} [userProfile] - 用户配置
* @property {Object} [sessionData] - 会话数据
* @property {Object} [domainContext] - 领域上下文
*/
/**
* 锦囊输出格式
* @typedef {Object} PouchOutput
* @property {string} purpose - 锦囊目的说明
* @property {string} content - 锦囊内容(提示词)
* @property {PATEOASNavigation} pateoas - PATEOAS导航信息
* @property {StateContext} [context] - 状态上下文
* @property {'human'|'json'} [format='human'] - 输出格式
*/
module.exports = {
// 这些是类型定义JavaScript中不需要导出
};

View File

@ -0,0 +1,173 @@
const fs = require('fs-extra');
const path = require('path');
/**
* 锦囊状态机管理器
* 负责管理锦囊之间的状态转换
*/
class PouchStateMachine {
constructor() {
this.currentState = 'initial';
this.stateHistory = [];
this.context = {
currentPouch: '',
history: [],
userProfile: {},
sessionData: {},
domainContext: {}
};
this.commands = new Map();
}
/**
* 注册锦囊命令
* @param {string} name - 命令名称
* @param {BasePouchCommand} command - 命令实例
*/
registerCommand(name, command) {
this.commands.set(name, command);
}
/**
* 执行状态转换
* @param {string} commandName - 命令名称
* @param {Array} args - 命令参数
* @returns {Promise<PouchOutput>} 执行结果
*/
async transition(commandName, args = []) {
// 获取命令对应的锦囊
const command = this.commands.get(commandName);
if (!command) {
throw new Error(`未找到命令: ${commandName}`);
}
// 记录历史
this.stateHistory.push({
from: this.currentState,
command: commandName,
timestamp: new Date().toISOString(),
args: args
});
// 更新上下文
this.context.currentPouch = commandName;
this.context.history = this.stateHistory.map(h => h.command || h.to);
// 设置命令上下文
command.setContext(this.context);
// 执行命令
const result = await command.execute(args);
// 根据PATEOAS导航更新状态
if (result && result.pateoas && result.pateoas.currentState) {
this.currentState = result.pateoas.currentState;
}
// 保存状态
await this.saveState();
return result;
}
/**
* 获取当前状态
* @returns {string} 当前状态
*/
getCurrentState() {
return this.currentState;
}
/**
* 获取可用的状态转换
* @returns {string[]} 可转换的状态列表
*/
getAvailableTransitions() {
const transitions = {
'initial': ['init', 'hello'],
'initialized': ['hello', 'action', 'learn'],
'discovering': ['action', 'learn', 'init'],
'activated': ['learn', 'recall', 'hello'],
'learned': ['action', 'recall', 'hello'],
'recalled': ['action', 'learn', 'remember']
};
// 根据当前状态的前缀匹配
for (const [statePrefix, availableStates] of Object.entries(transitions)) {
if (this.currentState.startsWith(statePrefix)) {
return availableStates;
}
}
// 默认可转换状态
return ['hello', 'init'];
}
/**
* 保存状态到文件
*/
async saveState() {
const promptxDir = path.join(process.cwd(), '.promptx');
const configPath = path.join(promptxDir, 'pouch.json');
try {
// 确保 .promptx 目录存在
await fs.ensureDir(promptxDir);
let config = {};
if (await fs.pathExists(configPath)) {
config = await fs.readJson(configPath);
}
config.currentState = this.currentState;
config.stateHistory = this.stateHistory.slice(-50); // 只保留最近50条记录
config.lastUpdated = new Date().toISOString();
await fs.writeJson(configPath, config, { spaces: 2 });
} catch (error) {
console.error('保存状态失败:', error);
}
}
/**
* 从文件加载状态
*/
async loadState() {
const configPath = path.join(process.cwd(), '.promptx', 'pouch.json');
try {
if (await fs.pathExists(configPath)) {
const config = await fs.readJson(configPath);
if (config.currentState) {
this.currentState = config.currentState;
}
if (config.stateHistory) {
this.stateHistory = config.stateHistory;
}
}
} catch (error) {
console.error('加载状态失败:', error);
}
}
/**
* 重置状态机
*/
reset() {
this.currentState = 'initial';
this.stateHistory = [];
this.context = {
currentPouch: '',
history: [],
userProfile: {},
sessionData: {},
domainContext: {}
};
}
}
module.exports = PouchStateMachine;

View File

@ -0,0 +1,78 @@
const ResourceProtocol = require('./ResourceProtocol');
const fs = require('fs-extra');
const path = require('path');
/**
* 执行模式协议处理器
* 处理 execution:// 协议的资源解析
*/
class ExecutionProtocol extends ResourceProtocol {
constructor() {
super('execution');
this.registry = {};
}
/**
* 设置注册表
*/
setRegistry(registry) {
this.registry = registry || {};
}
/**
* 获取协议信息
*/
getProtocolInfo() {
return {
name: 'execution',
description: '执行模式资源协议',
location: 'execution://{execution_id}',
examples: [
'execution://deal-at-reference',
'execution://prompt-developer',
'execution://memory-trigger'
]
};
}
/**
* 解析资源路径
*/
async resolvePath(resourcePath, queryParams) {
const executionId = resourcePath.trim();
if (!this.registry[executionId]) {
throw new Error(`执行模式 "${executionId}" 未在注册表中找到`);
}
let resolvedPath = this.registry[executionId];
// 处理 @package:// 前缀
if (resolvedPath.startsWith('@package://')) {
resolvedPath = resolvedPath.replace('@package://', '');
}
return resolvedPath;
}
/**
* 加载资源内容
*/
async loadContent(resolvedPath, queryParams) {
try {
const content = await fs.readFile(resolvedPath, 'utf-8');
return content;
} catch (error) {
throw new Error(`无法加载执行模式文件 ${resolvedPath}: ${error.message}`);
}
}
/**
* 验证资源路径
*/
validatePath(resourcePath) {
return /^[a-zA-Z0-9_-]+$/.test(resourcePath);
}
}
module.exports = ExecutionProtocol;

View File

@ -17,6 +17,14 @@ class PackageProtocol extends ResourceProtocol {
this.installModeCache = new Map();
}
/**
* 设置注册表(保持与其他协议的一致性)
*/
setRegistry(registry) {
// Package协议不使用注册表但为了一致性提供此方法
this.registry = registry || {};
}
/**
* 获取协议信息
*/

View File

@ -35,6 +35,14 @@ class ProjectProtocol extends ResourceProtocol {
this.projectRootCache = new Map();
}
/**
* 设置注册表(保持与其他协议的一致性)
*/
setRegistry(registry) {
// Project协议不使用注册表但为了一致性提供此方法
this.registry = registry || {};
}
/**
* 获取协议信息
* @returns {object} 协议信息

View File

@ -0,0 +1,255 @@
const ResourceProtocol = require('./ResourceProtocol');
const path = require('path');
const fs = require('fs').promises;
const { glob } = require('glob');
const { promisify } = require('util');
/**
* PromptX内置提示词资源协议实现
* 实现@prompt://协议用于访问PromptX内置的提示词资源
*/
class PromptProtocol extends ResourceProtocol {
constructor(options = {}) {
super('prompt', options);
// PromptX 内置资源注册表
this.registry = new Map([
['protocols', '@package://prompt/protocol/**/*.md'],
['core', '@package://prompt/core/**/*.md'],
['domain', '@package://prompt/domain/**/*.md'],
['resource', '@package://prompt/resource/**/*.md'],
['bootstrap', '@package://bootstrap.md']
]);
// 依赖的其他协议
this.packageProtocol = null;
}
/**
* 设置依赖的协议
* @param {PackageProtocol} packageProtocol - 包协议实例
*/
setPackageProtocol(packageProtocol) {
this.packageProtocol = packageProtocol;
}
/**
* 设置注册表
*/
setRegistry(registry) {
this.registry = registry || {};
}
/**
* 获取协议信息
*/
getProtocolInfo() {
return {
name: 'prompt',
description: 'PromptX内置提示词资源协议',
location: 'prompt://{resource_id}',
examples: [
'prompt://protocols',
'prompt://core',
'prompt://domain',
'prompt://bootstrap'
],
availableResources: Array.from(this.registry.keys()),
params: this.getSupportedParams()
};
}
/**
* 支持的查询参数
*/
getSupportedParams() {
return {
...super.getSupportedParams(),
merge: 'boolean - 是否合并多个文件内容',
separator: 'string - 文件间分隔符',
include_filename: 'boolean - 是否包含文件名标题'
};
}
/**
* 验证资源路径
*/
validatePath(resourcePath) {
if (!super.validatePath(resourcePath)) {
return false;
}
// 检查是否在注册表中
return this.registry.has(resourcePath);
}
/**
* 解析资源路径
*/
async resolvePath(resourcePath, queryParams) {
// 验证资源是否存在
if (!this.registry.has(resourcePath)) {
throw new Error(`未找到 prompt 资源: ${resourcePath}。可用资源: ${Array.from(this.registry.keys()).join(', ')}`);
}
// 获取对应的包路径
const packagePath = this.registry.get(resourcePath);
return packagePath;
}
/**
* 加载资源内容
*/
async loadContent(packagePath, queryParams) {
// 确保有包协议依赖
if (!this.packageProtocol) {
throw new Error('PromptProtocol 需要 PackageProtocol 依赖');
}
// 检查是否是通配符路径
if (packagePath.includes('**') || packagePath.includes('*')) {
return await this.loadMultipleFiles(packagePath, queryParams);
} else {
return await this.loadSingleFile(packagePath, queryParams);
}
}
/**
* 加载单个文件
*/
async loadSingleFile(packagePath, queryParams) {
try {
// 移除协议前缀
const cleanPath = packagePath.replace('@package://', '');
const result = await this.packageProtocol.loadContent(cleanPath, queryParams);
return result.content || result;
} catch (error) {
throw new Error(`加载单个文件失败 ${packagePath}: ${error.message}`);
}
}
/**
* 加载多个文件(通配符支持)
*/
async loadMultipleFiles(packagePath, queryParams) {
try {
// 获取包根目录
const packageRoot = await this.packageProtocol.getPackageRoot();
// 移除协议前缀并构建搜索路径
const cleanPath = packagePath.replace('@package://', '');
const searchPattern = path.join(packageRoot, cleanPath);
// 使用 glob 查找匹配的文件
const files = await glob(searchPattern, {
ignore: ['**/node_modules/**', '**/.git/**']
});
if (files.length === 0) {
throw new Error(`没有找到匹配的文件: ${packagePath}`);
}
// 读取所有文件内容
const contents = [];
for (const filePath of files.sort()) {
try {
const content = await fs.readFile(filePath, 'utf8');
const relativePath = path.relative(packageRoot, filePath);
contents.push({
path: relativePath,
content: content
});
} catch (error) {
console.warn(`警告: 无法读取文件 ${filePath}: ${error.message}`);
}
}
// 合并内容
return this.mergeContents(contents, queryParams);
} catch (error) {
throw new Error(`加载多个文件失败 ${packagePath}: ${error.message}`);
}
}
/**
* 合并多个文件内容
*/
mergeContents(contents, queryParams) {
const merge = queryParams?.get('merge') !== 'false'; // 默认合并
const separator = queryParams?.get('separator') || '\n\n---\n\n';
const includeFilename = queryParams?.get('include_filename') !== 'false'; // 默认包含文件名
if (!merge) {
// 不合并,返回 JSON 格式
return JSON.stringify(contents, null, 2);
}
// 合并所有内容
const mergedParts = contents.map(({ path, content }) => {
let part = '';
if (includeFilename) {
part += `# ${path}\n\n`;
}
part += content;
return part;
});
return mergedParts.join(separator);
}
/**
* 检查资源是否存在
*/
async exists(resourcePath, queryParams) {
try {
const packagePath = await this.resolvePath(resourcePath, queryParams);
if (packagePath.includes('**') || packagePath.includes('*')) {
// 通配符路径:检查是否有匹配的文件
const packageRoot = await this.packageProtocol.getPackageRoot();
const cleanPath = packagePath.replace('@package://', '');
const searchPattern = path.join(packageRoot, cleanPath);
const files = await glob(searchPattern);
return files.length > 0;
} else {
// 单个文件:检查文件是否存在
const cleanPath = packagePath.replace('@package://', '');
return await this.packageProtocol.exists(cleanPath, queryParams);
}
} catch (error) {
return false;
}
}
/**
* 列出所有可用资源
*/
listResources() {
return Array.from(this.registry.entries()).map(([key, value]) => ({
id: key,
path: value,
description: this.getResourceDescription(key)
}));
}
/**
* 获取资源描述
*/
getResourceDescription(resourceId) {
const descriptions = {
'protocols': 'DPML协议规范文档',
'core': '核心思维和执行模式',
'domain': '领域专家角色定义',
'resource': '资源管理和路径解析',
'bootstrap': 'PromptX启动引导文件'
};
return descriptions[resourceId] || '未知资源';
}
}
module.exports = PromptProtocol;

View File

@ -0,0 +1,79 @@
const ResourceProtocol = require('./ResourceProtocol');
const fs = require('fs-extra');
const path = require('path');
/**
* AI角色协议处理器
* 处理 role:// 协议的资源解析直接加载完整role文件
*/
class RoleProtocol extends ResourceProtocol {
constructor() {
super('role');
this.registry = {};
}
/**
* 设置注册表
*/
setRegistry(registry) {
this.registry = registry || {};
}
/**
* 获取协议信息
*/
getProtocolInfo() {
return {
name: 'role',
description: 'AI角色资源协议',
location: 'role://{role_id}',
examples: [
'role://video-copywriter',
'role://product-owner',
'role://assistant',
'role://prompt-developer'
]
};
}
/**
* 解析资源路径
*/
async resolvePath(resourcePath, queryParams) {
const roleId = resourcePath.trim();
if (!this.registry[roleId]) {
throw new Error(`角色 "${roleId}" 未在注册表中找到。可用角色:${Object.keys(this.registry).join(', ')}`);
}
let resolvedPath = this.registry[roleId];
// 处理 @package:// 前缀
if (resolvedPath.startsWith('@package://')) {
resolvedPath = resolvedPath.replace('@package://', '');
}
return resolvedPath;
}
/**
* 加载资源内容
*/
async loadContent(resolvedPath, queryParams) {
try {
const content = await fs.readFile(resolvedPath, 'utf-8');
return content;
} catch (error) {
throw new Error(`无法加载角色文件 ${resolvedPath}: ${error.message}`);
}
}
/**
* 验证资源路径
*/
validatePath(resourcePath) {
return /^[a-zA-Z0-9_-]+$/.test(resourcePath);
}
}
module.exports = RoleProtocol;

View File

@ -0,0 +1,77 @@
const ResourceProtocol = require('./ResourceProtocol');
const fs = require('fs-extra');
const path = require('path');
/**
* 思维模式协议处理器
* 处理 thought:// 协议的资源解析
*/
class ThoughtProtocol extends ResourceProtocol {
constructor() {
super('thought');
this.registry = {};
}
/**
* 设置注册表
*/
setRegistry(registry) {
this.registry = registry || {};
}
/**
* 获取协议信息
*/
getProtocolInfo() {
return {
name: 'thought',
description: '思维模式资源协议',
location: 'thought://{thought_id}',
examples: [
'thought://prompt-developer',
'thought://product-owner'
]
};
}
/**
* 解析资源路径
*/
async resolvePath(resourcePath, queryParams) {
const thoughtId = resourcePath.trim();
if (!this.registry[thoughtId]) {
throw new Error(`思维模式 "${thoughtId}" 未在注册表中找到`);
}
let resolvedPath = this.registry[thoughtId];
// 处理 @package:// 前缀
if (resolvedPath.startsWith('@package://')) {
resolvedPath = resolvedPath.replace('@package://', '');
}
return resolvedPath;
}
/**
* 加载资源内容
*/
async loadContent(resolvedPath, queryParams) {
try {
const content = await fs.readFile(resolvedPath, 'utf-8');
return content;
} catch (error) {
throw new Error(`无法加载思维模式文件 ${resolvedPath}: ${error.message}`);
}
}
/**
* 验证资源路径
*/
validatePath(resourcePath) {
return /^[a-zA-Z0-9_-]+$/.test(resourcePath);
}
}
module.exports = ThoughtProtocol;

View File

@ -49,6 +49,14 @@ class UserProtocol extends ResourceProtocol {
this.dirCache = new Map();
}
/**
* 设置注册表(保持与其他协议的一致性)
*/
setRegistry(registry) {
// User协议不使用注册表但为了一致性提供此方法
this.registry = registry || {};
}
/**
* 获取协议信息
* @returns {object} 协议信息

View File

@ -2,319 +2,140 @@ const ResourceProtocolParser = require('./resourceProtocolParser');
const ResourceRegistry = require('./resourceRegistry');
const { ResourceResult } = require('./types');
const logger = require('../../utils/logger');
const fs = require('fs-extra');
const path = require('path');
// 导入协议实现
const PackageProtocol = require('./protocols/PackageProtocol');
const ProjectProtocol = require('./protocols/ProjectProtocol');
const UserProtocol = require('./protocols/UserProtocol');
const PromptProtocol = require('./protocols/PromptProtocol');
/**
* 资源管理器
* 基于DPML资源协议的统一资源管理入口
* 资源管理器 - 统一管理各种协议的资源加载
*/
class ResourceManager {
constructor(options = {}) {
this.parser = new ResourceProtocolParser();
this.registry = new ResourceRegistry();
this.workingDirectory = options.workingDirectory || process.cwd();
// 暂时直接实现简单的加载功能,后续可扩展为独立组件
this.cache = new Map();
this.enableCache = options.enableCache !== false;
constructor() {
this.protocolHandlers = new Map();
this.registry = null;
this.initialized = false;
}
/**
* 解析并获取资源
* @param {string} resourceRef - DPML资源引用
* @param {object} options - 选项
* @returns {Promise<ResourceResult>} 资源结果
* 初始化资源管理器
*/
async resolve(resourceRef, options = {}) {
async initialize() {
if (this.initialized) return;
try {
logger.debug(`Resolving resource: ${resourceRef}`);
// 从统一注册表加载所有协议信息
await this.loadUnifiedRegistry();
// 1. 解析资源引用
const parsed = this.parser.parse(resourceRef);
logger.debug(`Parsed reference:`, parsed);
// 2. 通过注册表解析路径
const resolvedPath = this.registry.resolve(parsed.protocol, parsed.path);
logger.debug(`Resolved path: ${resolvedPath}`);
// 3. 处理可能的嵌套引用
if (resolvedPath.startsWith('@')) {
logger.debug(`Detected nested reference: ${resolvedPath}`);
return await this.resolve(resolvedPath, options);
}
// 4. 加载资源内容
let content = await this.loadResource(resolvedPath, parsed, options);
// 注册协议处理器
await this.registerProtocolHandlers();
// 5. 检查内容是否是另一个资源引用(用于嵌套引用)
if (content.trim().startsWith('@')) {
logger.debug(`Content is a nested reference: ${content.trim()}`);
return await this.resolve(content.trim(), options);
}
// 6. 创建结果
const result = ResourceResult.success(content, {
originalRef: resourceRef,
resolvedPath: resolvedPath,
protocol: parsed.protocol,
loadingSemantics: parsed.loadingSemantics,
queryParams: parsed.queryParams.getAll()
});
result.sources = [resolvedPath];
result.format = options.format || 'text';
logger.debug(`Resource resolved successfully`);
return result;
this.initialized = true;
} catch (error) {
logger.error(`Failed to resolve resource ${resourceRef}:`, error.message);
return ResourceResult.error(error, { originalRef: resourceRef });
throw new Error(`ResourceManager初始化失败: ${error.message}`);
}
}
/**
* 批量解析多个资源
* @param {string[]} resourceRefs - 资源引用列表
* @param {object} options - 选项
* @returns {Promise<ResourceResult[]>} 资源结果列表
* 加载统一资源注册表
*/
async resolveMultiple(resourceRefs, options = {}) {
const results = [];
async loadUnifiedRegistry() {
const registryPath = path.resolve(__dirname, '../../../resource.registry.json');
for (const ref of resourceRefs) {
const result = await this.resolve(ref, options);
results.push(result);
if (!await fs.pathExists(registryPath)) {
throw new Error(`统一资源注册表文件不存在: ${registryPath}`);
}
const registryContent = await fs.readJSON(registryPath);
this.registry = registryContent;
}
/**
* 注册协议处理器
*/
async registerProtocolHandlers() {
// 动态导入协议处理器
const protocolsDir = path.join(__dirname, 'protocols');
const protocolFiles = await fs.readdir(protocolsDir);
return results;
}
/**
* 加载单个资源
* @param {string} resourcePath - 资源路径
* @param {ParsedReference} parsed - 解析后的引用
* @param {object} options - 选项
* @returns {Promise<string>} 资源内容
*/
async loadResource(resourcePath, parsed, options = {}) {
// 检查缓存
const cacheKey = `${resourcePath}:${JSON.stringify(parsed.queryParams.getAll())}`;
if (this.enableCache && this.cache.has(cacheKey)) {
logger.debug(`Cache hit for: ${cacheKey}`);
return this.cache.get(cacheKey);
}
let content = '';
// 根据协议类型加载资源
if (parsed.protocol === 'file' || resourcePath.startsWith('/') || resourcePath.includes('./')) {
content = await this.loadFileResource(resourcePath, parsed.queryParams);
} else if (parsed.protocol === 'http' || parsed.protocol === 'https') {
content = await this.loadHttpResource(resourcePath, parsed.queryParams);
} else if (parsed.protocol === 'prompt') {
// prompt协议通过注册表已经解析为文件路径
content = await this.loadFileResource(resourcePath, parsed.queryParams);
} else {
throw new Error(`Unsupported protocol: ${parsed.protocol}`);
}
// 应用查询参数过滤
content = this.applyQueryParams(content, parsed.queryParams);
// 缓存结果
if (this.enableCache) {
this.cache.set(cacheKey, content);
}
return content;
}
/**
* 加载文件资源
* @param {string} filePath - 文件路径
* @param {QueryParams} queryParams - 查询参数
* @returns {Promise<string>} 文件内容
*/
async loadFileResource(filePath, queryParams) {
const fs = require('fs').promises;
const path = require('path');
// 处理相对路径
let fullPath = filePath;
if (!path.isAbsolute(filePath)) {
fullPath = path.resolve(this.workingDirectory, filePath);
}
// 处理通配符
if (fullPath.includes('*')) {
return await this.loadGlobPattern(fullPath, queryParams);
}
// 读取单个文件
try {
const content = await fs.readFile(fullPath, 'utf8');
return content;
} catch (error) {
throw new Error(`Failed to read file ${fullPath}: ${error.message}`);
}
}
/**
* 加载通配符模式的文件
* @param {string} pattern - 通配符模式
* @param {QueryParams} queryParams - 查询参数
* @returns {Promise<string>} 合并后的内容
*/
async loadGlobPattern(pattern, queryParams) {
const fs = require('fs').promises;
const path = require('path');
const { glob } = require('glob');
try {
const files = await glob(pattern, { nodir: true });
if (files.length === 0) {
return '';
}
// 排序文件
files.sort();
const contents = [];
for (const file of files) {
try {
const content = await fs.readFile(file, 'utf8');
const relativePath = path.relative(this.workingDirectory, file);
// 添加文件分隔符
const separator = '='.repeat(80);
const header = `### 文件: ${relativePath}`;
contents.push(`${separator}\n${header}\n${separator}\n\n${content}`);
} catch (error) {
logger.warn(`Failed to read file ${file}: ${error.message}`);
for (const file of protocolFiles) {
if (file.endsWith('.js') && file !== 'ResourceProtocol.js') {
// 将文件名映射到协议名ExecutionProtocol.js -> execution
const protocolName = file.replace('Protocol.js', '').toLowerCase();
const ProtocolClass = require(path.join(protocolsDir, file));
const protocolHandler = new ProtocolClass();
// 从统一注册表获取协议配置
const protocolConfig = this.registry.protocols[protocolName];
if (protocolConfig && protocolConfig.registry) {
protocolHandler.setRegistry(protocolConfig.registry);
}
}
return contents.join('\n\n');
} catch (error) {
throw new Error(`Glob pattern error: ${error.message}`);
}
}
/**
* 加载HTTP资源
* @param {string} url - URL地址
* @param {QueryParams} queryParams - 查询参数
* @returns {Promise<string>} 响应内容
*/
async loadHttpResource(url, queryParams) {
// 简单实现实际项目中可以使用axios等库
const https = require('https');
const http = require('http');
return new Promise((resolve, reject) => {
const client = url.startsWith('https://') ? https : http;
client.get(url, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(data);
});
}).on('error', (err) => {
reject(new Error(`HTTP request failed: ${err.message}`));
});
});
}
/**
* 应用查询参数过滤
* @param {string} content - 原始内容
* @param {QueryParams} queryParams - 查询参数
* @returns {string} 处理后的内容
*/
applyQueryParams(content, queryParams) {
let result = content;
// 处理行范围过滤
if (queryParams.line) {
result = this.applyLineFilter(result, queryParams.line);
}
return result;
}
/**
* 应用行范围过滤
* @param {string} content - 内容
* @param {string} lineRange - 行范围 "5-10"
* @returns {string} 过滤后的内容
*/
applyLineFilter(content, lineRange) {
const lines = content.split('\n');
if (lineRange.includes('-')) {
const [start, end] = lineRange.split('-').map(n => parseInt(n.trim()));
if (!isNaN(start) && !isNaN(end)) {
// 转换为0基索引并确保范围有效
const startIdx = Math.max(0, start - 1);
const endIdx = Math.min(lines.length, end);
return lines.slice(startIdx, endIdx).join('\n');
}
} else {
const lineNum = parseInt(lineRange);
if (!isNaN(lineNum) && lineNum > 0 && lineNum <= lines.length) {
return lines[lineNum - 1];
this.protocolHandlers.set(protocolName, protocolHandler);
}
}
}
/**
* 解析资源路径并获取内容
*/
async resolveResource(resourceUrl) {
await this.initialize();
const urlMatch = resourceUrl.match(/^([a-zA-Z]+):\/\/(.+)$/);
if (!urlMatch) {
throw new Error(`无效的资源URL格式: ${resourceUrl}`);
}
const [, protocol, path] = urlMatch;
const handler = this.protocolHandlers.get(protocol);
return content;
}
/**
* 验证资源引用
* @param {string} resourceRef - 资源引用
* @returns {boolean} 是否有效
*/
isValidReference(resourceRef) {
try {
const parsed = this.parser.parse(resourceRef);
return this.registry.validateReference(parsed.protocol, parsed.path);
} catch (error) {
return false;
if (!handler) {
throw new Error(`未注册的协议: ${protocol}`);
}
return await handler.resolve(path);
}
/**
* 获取注册表信息
* @param {string} protocol - 协议名(可选)
* @returns {object} 注册表信息
* resolve方法的别名保持向后兼容
*/
getRegistryInfo(protocol) {
if (protocol) {
return this.registry.getProtocolInfo(protocol);
async resolve(resourceUrl) {
return await this.resolveResource(resourceUrl);
}
/**
* 获取协议的注册表信息
*/
getProtocolRegistry(protocol) {
if (!this.registry) {
throw new Error('ResourceManager未初始化');
}
return this.registry.getRegistryInfo();
const protocolConfig = this.registry.protocols[protocol];
return protocolConfig ? protocolConfig.registry : null;
}
/**
* 列出可用协议
* @returns {string[]} 协议列表
* 获取所有已注册的协议
*/
listProtocols() {
return this.registry.listProtocols();
getAvailableProtocols() {
return this.registry ? Object.keys(this.registry.protocols) : [];
}
/**
* 清除缓存
* 获取协议的描述信息
*/
clearCache() {
this.cache.clear();
logger.debug('Resource cache cleared');
getProtocolInfo(protocol) {
if (!this.registry) {
throw new Error('ResourceManager未初始化');
}
return this.registry.protocols[protocol];
}
}