Files
PromptX/promptx.js

294 lines
8.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
// 简单的命令行参数处理
const args = process.argv.slice(2);
const command = args[0] || 'protocols'; // 默认执行protocols命令而不是help
const param = args[1]; // role命令时的角色文件路径
// 获取脚本所在目录和PromptX根目录
const scriptDir = __dirname;
const promptxDir = scriptDir; // 脚本现在就在PromptX目录内
/**
* 打印所有协议内容
*/
function printProtocols() {
// 定义目录优先级顺序
const directories = [
{ path: path.join(promptxDir, 'protocol'), name: 'protocol' },
{ path: path.join(promptxDir, 'core'), name: 'core' },
{ path: path.join(promptxDir, 'resource'), name: 'resource' }
];
let allFiles = [];
// 递归查找文件函数
function collectMarkdownFiles(dir) {
if (!fs.existsSync(dir)) {
console.warn(`警告: 目录不存在 ${dir}`);
return [];
}
let files = [];
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
files = files.concat(collectMarkdownFiles(fullPath));
} else if (entry.isFile() && entry.name.endsWith('.md')) {
files.push(fullPath);
}
}
return files;
}
// 按目录优先级收集文件
for (const dir of directories) {
const dirFiles = collectMarkdownFiles(dir.path);
// 每个目录内的文件按字母顺序排序
dirFiles.sort();
// 合并到总文件列表
allFiles = allFiles.concat(dirFiles);
console.log(`${dir.name} 目录收集了 ${dirFiles.length} 个文件`);
}
// 没有文件时的提示
if (allFiles.length === 0) {
console.log("未找到任何协议文件。请确认PromptX目录结构是否正确。");
return;
}
// 打印每个文件
for (const file of allFiles) {
const relativePath = path.relative(promptxDir, file);
const separator = "=".repeat(80);
console.log(`\n${separator}\n### 文件: ${relativePath}\n${separator}\n`);
try {
const content = fs.readFileSync(file, 'utf8');
console.log(content);
} catch (err) {
console.error(`读取文件错误: ${file}`, err);
}
}
console.log(`\n总计读取了 ${allFiles.length} 个协议文件。`);
}
/**
* 打印指定角色内容
*/
function printRole(rolePath) {
// 如果传入的是相对路径则基于PromptX目录解析
let fullPath;
if (path.isAbsolute(rolePath)) {
fullPath = rolePath;
} else {
fullPath = path.join(promptxDir, rolePath);
}
if (!fs.existsSync(fullPath)) {
console.error(`错误: 角色文件不存在: ${fullPath}`);
return;
}
try {
const content = fs.readFileSync(fullPath, 'utf8');
const separator = "=".repeat(80);
console.log(`\n${separator}\n### 角色文件: ${path.relative(promptxDir, fullPath)}\n${separator}\n`);
console.log(content);
} catch (err) {
console.error(`读取角色文件错误: ${fullPath}`, err);
}
}
/**
* 打印指定路径的文件内容
*/
function printFile(filePath) {
// 如果传入的是相对路径则基于PromptX目录解析
let fullPath;
if (path.isAbsolute(filePath)) {
fullPath = filePath;
} else {
fullPath = path.join(promptxDir, filePath);
}
if (!fs.existsSync(fullPath)) {
console.error(`错误: 文件不存在: ${fullPath}`);
return;
}
try {
const content = fs.readFileSync(fullPath, 'utf8');
const separator = "=".repeat(80);
console.log(`\n${separator}\n### 文件: ${path.relative(promptxDir, fullPath)}\n${separator}\n`);
console.log(content);
} catch (err) {
console.error(`读取文件错误: ${fullPath}`, err);
}
}
/**
* 添加记忆条目
* @param {string} content - 记忆内容
* @param {object} options - 配置选项
*/
function addMemory(content, options = {}) {
const defaultOptions = {
tags: ['其他'],
score: 5,
duration: '短期',
timestamp: new Date().toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
})
};
const finalOptions = { ...defaultOptions, ...options };
// 构建记忆条目,确保格式统一
const memoryEntry = `\n- ${content.trim()} ${finalOptions.tags.map(tag => `#${tag}`).join(' ')} #评分:${finalOptions.score} #有效期:${finalOptions.duration} #时间:${finalOptions.timestamp}\n`;
// 确保.memory目录存在
const memoryDir = path.join(process.cwd(), '.memory');
if (!fs.existsSync(memoryDir)) {
fs.mkdirSync(memoryDir, { recursive: true });
}
// 追加到记忆文件
const memoryFile = path.join(memoryDir, 'declarative.md');
try {
// 如果文件不存在,创建文件并添加标题
if (!fs.existsSync(memoryFile)) {
fs.writeFileSync(memoryFile, '# 陈述性记忆库\n\n## 高价值记忆(评分 ≥ 7\n');
}
fs.appendFileSync(memoryFile, memoryEntry);
console.log('✅ 记忆已成功保存');
// 如果评分大于等于7,输出高价值提醒
if (finalOptions.score >= 7) {
console.log('🌟 这是一条高价值记忆');
}
} catch (err) {
console.error('❌ 记忆保存失败:', err);
}
}
/**
* 解析记忆命令参数
* @param {string} content - 记忆内容
* @param {string[]} args - 其他参数
*/
function parseMemoryArgs(content, args) {
const options = {
tags: [],
score: 5,
duration: '短期'
};
// 解析标签和其他选项
args.forEach(arg => {
if (arg.startsWith('#')) {
// 去掉#号并添加到标签数组
options.tags.push(arg.slice(1).trim());
} else if (arg.startsWith('score:')) {
const score = parseInt(arg.split(':')[1]);
if (!isNaN(score) && score >= 1 && score <= 10) {
options.score = score;
}
} else if (arg.startsWith('duration:')) {
const duration = arg.split(':')[1].trim();
if (['短期', '长期'].includes(duration)) {
options.duration = duration;
}
}
});
// 如果没有标签,使用默认标签
if (options.tags.length === 0) {
options.tags = ['其他'];
}
return options;
}
/**
* 打印帮助信息
*/
function printHelp() {
console.log(`
PromptX 工具 - 协议和角色内容查看器
使用方法:
node promptx.js - 打印所有协议内容 (按protocol、core、resource顺序)
node promptx.js protocols - 同上,打印所有协议内容
node promptx.js role <路径> - 打印指定角色文件内容
node promptx.js file <路径> - 打印指定文件内容
node promptx.js remember <内容> [选项] - 添加记忆条目
node promptx.js help - 显示此帮助信息
记忆命令选项:
#标签名 - 添加标签 (可多个)
score:数字 - 设置重要性评分 (1-10)
duration:时长 - 设置有效期 (短期/长期)
示例:
node promptx.js remember "用户提出了重要建议" #用户反馈 #改进建议 score:7 duration:长期
node promptx.js remember "临时配置信息" #配置 score:3
`);
}
// 根据命令执行相应功能
switch (command) {
case 'protocols':
printProtocols();
break;
case 'role':
if (!param) {
console.error('错误: 缺少角色文件路径');
printHelp();
} else {
printRole(param);
}
break;
case 'file':
if (!param) {
console.error('错误: 缺少文件路径');
printHelp();
} else {
printFile(param);
}
break;
case 'remember':
if (!param) {
console.error('错误: 缺少记忆内容');
console.log('使用方法: node promptx.js remember "记忆内容" [#标签1 #标签2] [score:7] [duration:长期]');
} else {
const memoryContent = param;
const memoryArgs = args.slice(2); // 获取其他参数
const options = parseMemoryArgs(memoryContent, memoryArgs);
addMemory(memoryContent, options);
}
break;
case 'help':
printHelp();
break;
default:
console.error(`错误: 未知命令 "${command}"`);
printHelp();
break;
}