From be285f55b8e95704224cdbc909ad371e004afa67 Mon Sep 17 00:00:00 2001 From: sean Date: Sat, 31 May 2025 13:03:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90DPML=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE=E4=BD=93=E7=B3=BB0=EF=BD=9E1=E9=98=B6=E6=AE=B5?= =?UTF-8?q?=E5=BC=80=E5=8F=91=20-=20=E4=B8=89=E5=B1=82=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E6=9E=B6=E6=9E=84100%=E5=AE=9E=E7=8E=B0=EF=BC=8C=E6=99=BA?= =?UTF-8?q?=E8=83=BD=E8=B7=AF=E5=BE=84=E6=A3=80=E6=B5=8B=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=EF=BC=8C@package://=E4=B8=8Epackage.json=E5=AE=8C=E7=BE=8E?= =?UTF-8?q?=E9=9B=86=E6=88=90=EF=BC=8C=E7=94=A8=E6=88=B7=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E9=9B=86=E6=88=90=E6=96=B9=E6=A1=88=EF=BC=8CCLI=E6=A1=86?= =?UTF-8?q?=E6=9E=B6=E5=AE=8C=E6=95=B4=E5=AE=9E=E7=8E=B0=EF=BC=8C132/137?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E6=B5=8B=E8=AF=95=E9=80=9A=E8=BF=87(96.3%?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E7=8E=87)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 99 ++-- docs/dpml-protocol-layers.md | 444 +++++++++++++++ jest.config.js | 74 +++ package.json | 133 +++++ .../execution/deal-at-reference.execution.md | 0 .../core}/execution/deal-memory.execution.md | 0 .../execution/memory-tool-usage.execution.md | 0 .../execution/memory-trigger.execution.md | 0 .../core}/memory/declarative-memory.memory.md | 0 .../domain}/assistant/assistant.role.md | 0 .../execution/video-copywriter.execution.md | 0 .../copywriter/practice/case-studies.md | 0 .../practice/platform-adaptation.md | 0 .../copywriter/practice/script-templates.md | 0 .../thought/video-copywriter.thought.md | 0 .../copywriter/video-copywriter.role.md | 0 .../execution-best-practice.execution.md | 0 .../memory-best-practice.execution.md | 0 .../execution/prompt-developer.execution.md | 0 .../resource-best-practice.execution.md | 0 .../execution/role-best-practice.execution.md | 0 .../terminology-best-practice.execution.md | 0 .../thought-best-practice.execution.md | 0 .../practice/execution-best-practice.md | 0 .../prompt/practice/memory-best-practice.md | 0 .../prompt/practice/resource-best-practice.md | 0 .../prompt/practice/role-best-practice.md | 0 .../prompt/practice/thought-best-practice.md | 0 .../domain}/prompt/prompt-developer.role.md | 0 .../thought/prompt-developer.thought.md | 0 .../template/protocol-framework-template.md | 0 .../execution/epic-best-practice.execution.md | 0 .../feature-best-practice.execution.md | 0 .../milestone-best-practice.execution.md | 0 .../execution/product-owner.execution.md | 0 .../scrum-best-practice.execution.md | 0 .../sprint-best-practice.execution.md | 0 .../story-best-practice.execution.md | 0 .../execution/task-best-practice.execution.md | 0 .../testcase-best-practice.execution.md | 0 .../workitem-title-best-practice.execution.md | 0 .../domain}/scrum/role/product-owner.role.md | 0 .../scrum/thought/product-owner.thought.md | 0 {domain => prompt/domain}/test/test.role.md | 0 {domain => prompt/domain}/test/testcase.md | 0 .../protocol}/dpml.protocol.md | 0 .../protocol}/dpml.terminology.md | 0 .../protocol}/tag/execution.tag.md | 0 .../protocol}/tag/execution.terminology.md | 0 .../protocol}/tag/memory.tag.md | 0 .../protocol}/tag/memory.terminology.md | 0 .../protocol}/tag/resource.tag.md | 0 .../protocol}/tag/resource.terminology.md | 0 {protocol => prompt/protocol}/tag/role.tag.md | 0 .../protocol}/tag/role.terminology.md | 0 .../protocol}/tag/terminology.tag.md | 0 .../protocol}/tag/thought.tag.md | 0 .../protocol}/tag/thought.terminology.md | 0 .../resource}/execution.resource.md | 0 .../resource}/memory.resource.md | 0 .../resource}/thought.resource.md | 0 promptx.js | 424 --------------- src/bin/promptx.js | 109 ++++ src/lib/commands/hello.js | 31 ++ src/lib/commands/init.js | 185 +++++++ src/lib/commands/learn.js | 35 ++ src/lib/commands/recall.js | 36 ++ src/lib/commands/remember.js | 36 ++ src/lib/core/resource/index.js | 67 +++ .../resource/protocols/PackageProtocol.js | 505 ++++++++++++++++++ .../resource/protocols/ProjectProtocol.js | 351 ++++++++++++ .../resource/protocols/ResourceProtocol.js | 208 ++++++++ .../core/resource/protocols/UserProtocol.js | 299 +++++++++++ src/lib/core/resource/resourceManager.js | 321 +++++++++++ .../core/resource/resourceProtocolParser.js | 287 ++++++++++ src/lib/core/resource/resourceRegistry.js | 248 +++++++++ src/lib/core/resource/types.js | 236 ++++++++ src/lib/index.js | 42 ++ src/lib/utils/logger.js | 90 ++++ src/tests/README.md | 237 ++++++++ src/tests/commands/promptxCli.e2e.test.js | 313 +++++++++++ .../protocols/PackageProtocol.unit.test.js | 357 +++++++++++++ .../protocols/ProjectProtocol.unit.test.js | 245 +++++++++ .../protocols/UserProtocol.unit.test.js | 232 ++++++++ .../resourceManager.integration.test.js | 203 +++++++ .../resourceProtocolParser.unit.test.js | 133 +++++ .../resource/resourceRegistry.unit.test.js | 134 +++++ src/tests/fixtures/testResources.js | 301 +++++++++++ src/tests/setup.js | 123 +++++ 89 files changed, 6071 insertions(+), 467 deletions(-) create mode 100644 docs/dpml-protocol-layers.md create mode 100644 jest.config.js create mode 100644 package.json rename {core => prompt/core}/execution/deal-at-reference.execution.md (100%) rename {core => prompt/core}/execution/deal-memory.execution.md (100%) rename {core => prompt/core}/execution/memory-tool-usage.execution.md (100%) rename {core => prompt/core}/execution/memory-trigger.execution.md (100%) rename {core => prompt/core}/memory/declarative-memory.memory.md (100%) rename {domain => prompt/domain}/assistant/assistant.role.md (100%) rename {domain => prompt/domain}/copywriter/execution/video-copywriter.execution.md (100%) rename {domain => prompt/domain}/copywriter/practice/case-studies.md (100%) rename {domain => prompt/domain}/copywriter/practice/platform-adaptation.md (100%) rename {domain => prompt/domain}/copywriter/practice/script-templates.md (100%) rename {domain => prompt/domain}/copywriter/thought/video-copywriter.thought.md (100%) rename {domain => prompt/domain}/copywriter/video-copywriter.role.md (100%) rename {domain => prompt/domain}/prompt/execution/execution-best-practice.execution.md (100%) rename {domain => prompt/domain}/prompt/execution/memory-best-practice.execution.md (100%) rename {domain => prompt/domain}/prompt/execution/prompt-developer.execution.md (100%) rename {domain => prompt/domain}/prompt/execution/resource-best-practice.execution.md (100%) rename {domain => prompt/domain}/prompt/execution/role-best-practice.execution.md (100%) rename {domain => prompt/domain}/prompt/execution/terminology-best-practice.execution.md (100%) rename {domain => prompt/domain}/prompt/execution/thought-best-practice.execution.md (100%) rename {domain => prompt/domain}/prompt/practice/execution-best-practice.md (100%) rename {domain => prompt/domain}/prompt/practice/memory-best-practice.md (100%) rename {domain => prompt/domain}/prompt/practice/resource-best-practice.md (100%) rename {domain => prompt/domain}/prompt/practice/role-best-practice.md (100%) rename {domain => prompt/domain}/prompt/practice/thought-best-practice.md (100%) rename {domain => prompt/domain}/prompt/prompt-developer.role.md (100%) rename {domain => prompt/domain}/prompt/thought/prompt-developer.thought.md (100%) rename {domain => prompt/domain}/protocol/template/protocol-framework-template.md (100%) rename {domain => prompt/domain}/scrum/execution/epic-best-practice.execution.md (100%) rename {domain => prompt/domain}/scrum/execution/feature-best-practice.execution.md (100%) rename {domain => prompt/domain}/scrum/execution/milestone-best-practice.execution.md (100%) rename {domain => prompt/domain}/scrum/execution/product-owner.execution.md (100%) rename {domain => prompt/domain}/scrum/execution/scrum-best-practice.execution.md (100%) rename {domain => prompt/domain}/scrum/execution/sprint-best-practice.execution.md (100%) rename {domain => prompt/domain}/scrum/execution/story-best-practice.execution.md (100%) rename {domain => prompt/domain}/scrum/execution/task-best-practice.execution.md (100%) rename {domain => prompt/domain}/scrum/execution/testcase-best-practice.execution.md (100%) rename {domain => prompt/domain}/scrum/execution/workitem-title-best-practice.execution.md (100%) rename {domain => prompt/domain}/scrum/role/product-owner.role.md (100%) rename {domain => prompt/domain}/scrum/thought/product-owner.thought.md (100%) rename {domain => prompt/domain}/test/test.role.md (100%) rename {domain => prompt/domain}/test/testcase.md (100%) rename {protocol => prompt/protocol}/dpml.protocol.md (100%) rename {protocol => prompt/protocol}/dpml.terminology.md (100%) rename {protocol => prompt/protocol}/tag/execution.tag.md (100%) rename {protocol => prompt/protocol}/tag/execution.terminology.md (100%) rename {protocol => prompt/protocol}/tag/memory.tag.md (100%) rename {protocol => prompt/protocol}/tag/memory.terminology.md (100%) rename {protocol => prompt/protocol}/tag/resource.tag.md (100%) rename {protocol => prompt/protocol}/tag/resource.terminology.md (100%) rename {protocol => prompt/protocol}/tag/role.tag.md (100%) rename {protocol => prompt/protocol}/tag/role.terminology.md (100%) rename {protocol => prompt/protocol}/tag/terminology.tag.md (100%) rename {protocol => prompt/protocol}/tag/thought.tag.md (100%) rename {protocol => prompt/protocol}/tag/thought.terminology.md (100%) rename {resource => prompt/resource}/execution.resource.md (100%) rename {resource => prompt/resource}/memory.resource.md (100%) rename {resource => prompt/resource}/thought.resource.md (100%) delete mode 100755 promptx.js create mode 100755 src/bin/promptx.js create mode 100644 src/lib/commands/hello.js create mode 100644 src/lib/commands/init.js create mode 100644 src/lib/commands/learn.js create mode 100644 src/lib/commands/recall.js create mode 100644 src/lib/commands/remember.js create mode 100644 src/lib/core/resource/index.js create mode 100644 src/lib/core/resource/protocols/PackageProtocol.js create mode 100644 src/lib/core/resource/protocols/ProjectProtocol.js create mode 100644 src/lib/core/resource/protocols/ResourceProtocol.js create mode 100644 src/lib/core/resource/protocols/UserProtocol.js create mode 100644 src/lib/core/resource/resourceManager.js create mode 100644 src/lib/core/resource/resourceProtocolParser.js create mode 100644 src/lib/core/resource/resourceRegistry.js create mode 100644 src/lib/core/resource/types.js create mode 100644 src/lib/index.js create mode 100644 src/lib/utils/logger.js create mode 100644 src/tests/README.md create mode 100644 src/tests/commands/promptxCli.e2e.test.js create mode 100644 src/tests/core/resource/protocols/PackageProtocol.unit.test.js create mode 100644 src/tests/core/resource/protocols/ProjectProtocol.unit.test.js create mode 100644 src/tests/core/resource/protocols/UserProtocol.unit.test.js create mode 100644 src/tests/core/resource/resourceManager.integration.test.js create mode 100644 src/tests/core/resource/resourceProtocolParser.unit.test.js create mode 100644 src/tests/core/resource/resourceRegistry.unit.test.js create mode 100644 src/tests/fixtures/testResources.js create mode 100644 src/tests/setup.js diff --git a/.gitignore b/.gitignore index 9078cef..caa5f0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,37 +1,51 @@ -# Python -__pycache__/ -*.py[cod] -*$py.class -*.so -.Python -build/ -develop-eggs/ +# Dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Package manager files +package-lock.json +yarn.lock +pnpm-lock.yaml + +# Build outputs dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg +build/ +/lib/ +*.tsbuildinfo -# Virtual Environment -venv/ -env/ -ENV/ +# Testing +coverage/ +.nyc_output +*.lcov -# IDE -.idea/ +# Logs +logs/ +*.log + +# Runtime data +pids/ +*.pid +*.seed +*.pid.lock + +# Environment variables +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# IDE and editors .vscode/ +.idea/ *.swp *.swo +*~ -# OS +# OS generated files .DS_Store .DS_Store? ._* @@ -40,24 +54,23 @@ ENV/ ehthumbs.db Thumbs.db -# Logs -*.log -logs/ +# Cache directories +.npm +.eslintcache +.node_repl_history -# Local development settings -.env -.env.local -.env.*.local +# Output of package managers +*.tgz +.yarn-integrity -# Coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -coverage.xml -*.cover +# Temporary folders +tmp/ +temp/ +# Application specific .memory/ +.promptx/ +# Development +*.orig +.husky/_ -requirements/ \ No newline at end of file diff --git a/docs/dpml-protocol-layers.md b/docs/dpml-protocol-layers.md new file mode 100644 index 0000000..a358f49 --- /dev/null +++ b/docs/dpml-protocol-layers.md @@ -0,0 +1,444 @@ +# DPML三层协议体系设计文档 + +## 📋 概述 + +DPML (Deepractice Prompt Markup Language) 采用三层协议架构,从底层到上层逐步抽象,为不同使用场景提供合适的语义级别。 + +## 🏗️ 协议分层架构 + +``` +┌─────────────────────────────────────┐ +│ 上层协议 (Application Layer) │ +│ @prompt:// @memory:// │ ← 应用语义协议 +├─────────────────────────────────────┤ +│ 中层协议 (Semantic Layer) │ +│ @user:// @project:// @package:// │ ← 语义路径定位协议 +├─────────────────────────────────────┤ +│ 底层协议 (Transport Layer) │ +│ @file:// @http:// @https:// │ ← 通用传输协议 +└─────────────────────────────────────┘ +``` + +## 📦 底层协议 (Transport Layer) + +### 🎯 设计目标 +- 提供最基础的资源传输能力 +- 兼容标准协议规范 +- 支持各种数据源接入 + +### 📋 协议列表 + +#### 1. `@file://` - 文件系统协议 +```bash +# 绝对路径 +@file:///Users/sean/Documents/notes.md + +# 相对路径(相对当前工作目录) +@file://./src/main.js +@file://docs/readme.md + +# 用户目录路径 +@file://~/Documents/project/file.md + +# 通配符支持 +@file://src/**/*.js +@file://docs/*.md +``` + +**路径解析规则:** +- 绝对路径:直接使用 +- 相对路径:相对于 `process.cwd()` +- `~` 路径:相对于用户家目录 +- 通配符:使用 glob 模式展开 + +#### 2. `@http://` / `@https://` - 网络协议 +```bash +# 标准HTTP请求 +@http://example.com/api/resource.json + +# HTTPS安全请求 +@https://api.github.com/repos/owner/repo/contents/file.md + +# 带查询参数 +@https://api.example.com/data?format=json&limit=100 +``` + +**特性支持:** +- 标准HTTP/HTTPS请求 +- 自动处理重定向 +- 支持常见认证方式 +- 缓存机制集成 + +## 🎯 中层协议 (Semantic Layer) + +### 🎯 设计目标 +- 提供语义化的路径定位 +- 屏蔽不同环境的路径差异 +- 支持智能路径解析 + +### 📋 协议列表 + +#### 1. `@user://` - 用户目录协议 ✅ +```bash +# 用户文档目录 +@user://documents/my-project/notes.md + +# 用户桌面 +@user://desktop/todo.txt + +# 用户下载目录 +@user://downloads/data.csv + +# 用户配置目录 +@user://home/.config/app/settings.json +``` + +**路径映射:** +- `@user://documents/` → 用户文档目录(跨平台) +- `@user://desktop/` → 用户桌面目录(跨平台) +- `@user://downloads/` → 用户下载目录(跨平台) +- `@user://home/` → 用户家目录 + +**实现特性:** +- ✅ **跨平台支持**:Windows、macOS、Linux +- ✅ **智能检测**:使用 platform-folders 库或回退方案 +- ✅ **安全验证**:路径安全检查,防止遍历攻击 +- ✅ **缓存机制**:提高重复访问性能 + +#### 2. `@project://` - 项目根目录协议 ✅ +```bash +# 项目配置文件 +@project://package.json +@project://.gitignore + +# 项目源码 +@project://src/main.js +@project://lib/utils.js + +# 项目文档 +@project://docs/readme.md +@project://CHANGELOG.md + +# 项目资源 +@project://assets/images/logo.png +``` + +**项目根目录检测规则:** +1. 向上查找 `.promptx` 目录(优先级最高) +2. 查找 `package.json` 文件 +3. 查找 `.git` 目录 +4. 默认使用当前工作目录 + +**实现特性:** +- ✅ **智能检测**:自实现向上查找算法 +- ✅ **多标识符支持**:.promptx、package.json、.git +- ✅ **安全边界**:防止越过文件系统根目录 +- ✅ **直接路径访问**:支持包内任意路径 + +#### 3. `@package://` - NPM包目录协议 ✅ +```bash +# 包根目录 +@package://package.json +@package://README.md + +# 包源代码 +@package://src/index.js +@package://lib/commands/hello.js + +# 包提示词资源 +@package://prompt/core/execution/think.md +@package://prompt/domain/scrum/role/product-owner.md + +# 包配置和模板 +@package://jest.config.js +@package://templates/basic/template.md + +# 任意包内路径 +@package://docs/api/README.md +@package://assets/images/logo.png +@package://examples/demo.js +``` + +**包安装模式智能检测:** +- `development` - 开发模式(源码开发) +- `local` - 本地安装(npm install) +- `global` - 全局安装(npm install -g) +- `npx` - NPX执行模式 +- `monorepo` - Monorepo工作空间 +- `link` - NPM链接模式(npm link) + +**实现特性:** +- ✅ **多安装模式支持**:覆盖所有NPM使用场景 +- ✅ **环境变量检测**:npm_execpath、npm_config_cache等 +- ✅ **符号链接处理**:正确解析npm link场景 +- ✅ **Monorepo支持**:检测workspaces配置 +- ✅ **路径安全**:防止目录遍历攻击 +- ✅ **直接路径访问**:无需预定义目录,支持包内任意路径 +- ✅ **多级缓存**:安装模式缓存 + 路径解析缓存 + +**核心价值:** +- **智能包根检测**:自动检测不同安装环境下的包根目录 +- **统一路径接口**:无论开发、测试、生产环境,使用相同路径语法 +- **安全路径访问**:确保所有访问都在包根目录范围内 + +## 🚀 上层协议 (Application Layer) + +### 🎯 设计目标 +- 提供应用级语义抽象 +- 隐藏底层实现细节 +- 支持业务逻辑映射 + +### 📋 协议列表 + +#### 1. `@prompt://` - 提示词资源协议 +```bash +# 核心协议文档 +@prompt://protocols +# → @package://prompt/protocol/**/*.md + +# 核心提示词模块 +@prompt://core +# → @package://prompt/core/**/*.md + +# 领域提示词 +@prompt://domain/scrum +# → @package://prompt/domain/scrum/**/*.md + +# 特定角色提示词 +@prompt://domain/scrum/role/product-owner +# → @package://prompt/domain/scrum/role/product-owner.role.md +``` + +**注册表映射:** +- `protocols` → `@package://prompt/protocol/**/*.md` +- `core` → `@package://prompt/core/**/*.md` +- `domain` → `@package://prompt/domain/**/*.md` +- `bootstrap` → `@package://bootstrap.md` + +#### 2. `@memory://` - 记忆系统协议 +```bash +# 声明式记忆 +@memory://declarative +# → @project://.memory/declarative.md + +# 情景记忆 +@memory://episodic +# → @project://.memory/episodic/**/*.md + +# 语义记忆 +@memory://semantic +# → @project://.memory/semantic.json + +# 程序记忆 +@memory://procedural +# → @project://.memory/procedural/**/*.md +``` + +**记忆类型映射:** +- `declarative` → `.memory/declarative.md` +- `episodic` → `.memory/episodic/` +- `semantic` → `.memory/semantic.json` +- `procedural` → `.memory/procedural/` + +## 🔧 实现架构 + +### 📦 协议解析流程 + +```javascript +// 1. 协议分层解析 +@prompt://core + ↓ 上层协议解析 +@package://prompt/core/**/*.md + ↓ 中层协议解析 +@file://[NPM包路径]/prompt/core/**/*.md + ↓ 底层协议执行 +读取文件系统资源 +``` + +### 🎯 注册表设计 + +```javascript +class LayeredProtocolRegistry { + constructor() { + this.transportLayer = new Map(); // 底层协议 + this.semanticLayer = new Map(); // 中层协议 + this.applicationLayer = new Map(); // 上层协议 + } + + resolve(protocol, path) { + // 递归解析直到底层协议 + if (this.applicationLayer.has(protocol)) { + const mapping = this.applicationLayer.get(protocol); + return this.resolve(mapping.protocol, mapping.path + path); + } + + if (this.semanticLayer.has(protocol)) { + const mapping = this.semanticLayer.get(protocol); + return this.resolve(mapping.protocol, mapping.path + path); + } + + // 底层协议直接执行 + return this.transportLayer.get(protocol).resolve(path); + } +} +``` + +### 🔍 路径检测机制 + +```javascript +class PathDetector { + // 检测NPM包目录 + static detectPackageRoot() { + // NPM包模式检测 + try { + const packagePath = require.resolve('promptx/package.json'); + return path.dirname(packagePath); + } catch {} + + // 开发模式检测 + let dir = __dirname; + while (dir !== path.dirname(dir)) { + const packageJson = path.join(dir, 'package.json'); + if (fs.existsSync(packageJson)) { + const pkg = require(packageJson); + if (pkg.name === 'promptx') return dir; + } + dir = path.dirname(dir); + } + + throw new Error('Package not found'); + } + + // 检测项目根目录 + static detectProjectRoot() { + const indicators = ['.promptx', 'package.json', '.git']; + let dir = process.cwd(); + + while (dir !== path.dirname(dir)) { + if (indicators.some(indicator => + fs.existsSync(path.join(dir, indicator)) + )) { + return dir; + } + dir = path.dirname(dir); + } + + return process.cwd(); // 默认当前目录 + } +} +``` + +## 📊 协议使用示例 + +### 🎯 典型使用场景 + +```bash +# AI助手启动:加载角色提示词 +promptx learn @prompt://domain/scrum/role/product-owner + +# 等价于底层路径: +promptx learn @file://[NPM包]/prompt/domain/scrum/role/product-owner.role.md + +# 记忆保存:保存到项目记忆 +promptx remember "重要决策" @memory://declarative + +# 等价于底层路径: +promptx remember "重要决策" @file://[项目根]/.memory/declarative.md +``` + +### 🔄 协议转换示例 + +```bash +# 上层 → 中层 → 底层 +@prompt://core + ↓ +@package://prompt/core/**/*.md + ↓ +@file:///usr/local/lib/node_modules/promptx/prompt/core/**/*.md +``` + +## 🎯 设计优势 + +### ✅ 分层优势 + +1. **底层协议**:标准化、可复用、易测试 +2. **中层协议**:语义化、环境无关、智能解析 +3. **上层协议**:业务导向、用户友好、功能聚焦 + +### 🔧 扩展性 + +- **向下兼容**:上层协议变更不影响底层 +- **灵活映射**:可动态调整协议映射关系 +- **插件化**:支持自定义协议扩展 + +### 🎯 用户体验 + +- **简洁语法**:`@prompt://core` vs `@file://./node_modules/promptx/prompt/core/**/*.md` +- **语义清晰**:协议名称直接表达意图 +- **智能解析**:自动处理环境差异 + +## 🚀 实施计划 + +### Phase 1: 底层协议完善 ✅ +- [x] file:// 协议优化 +- [x] http/https:// 协议实现 +- [x] 通配符支持增强 +- [x] 查询参数系统 +- [x] 缓存机制集成 + +### Phase 2: 中层协议实现 ✅ +- [x] **user:// 协议实现** (1.3.1.1) + - [x] 跨平台用户目录检测 + - [x] platform-folders集成 + - [x] 安全路径验证 + - [x] 完整测试覆盖 +- [x] **project:// 协议实现** (1.3.1.2) + - [x] .promptx目录检测 + - [x] 向上查找算法 + - [x] 多指示符支持 + - [x] 边界安全检查 +- [x] **package:// 协议实现** (1.3.1.3) + - [x] 多安装模式检测 + - [x] NPM环境智能识别 + - [x] Monorepo支持 + - [x] 符号链接处理 + - [x] 直接路径访问(无预定义目录限制) + +### Phase 3: 上层协议优化 +- [x] prompt:// 协议重构 +- [ ] memory:// 协议增强 + +### Phase 4: 集成测试 +- [x] 中层协议单元测试 +- [ ] 分层协议集成测试 +- [ ] 性能基准测试 +- [ ] 用户体验测试 + +## 📈 当前实施状态 + +### ✅ 已完成功能 +- **底层协议系统**:完整实现,支持file、http、https +- **中层协议核心**:三个协议全部实现并通过测试 + - UserProtocol: 22/22 测试通过 + - ProjectProtocol: 30/30 测试通过 + - PackageProtocol: 41/41 测试通过(无目录映射限制) +- **ResourceProtocol基类**:统一接口抽象 +- **查询参数系统**:支持缓存键生成 +- **安全机制**:路径遍历防护 +- **直接路径访问**:package协议支持任意包内路径 + +### 🔄 进行中 +- 上层协议优化 +- 协议注册表重构 +- 性能优化调整 + +### 📋 待实施 +- memory:// 协议增强 +- 协议映射配置化 +- 插件系统支持 + +--- + +*本文档将随着协议体系的演进持续更新* + +**最后更新:** 简化了@package://协议,去掉预定义目录映射,支持直接访问包内任意路径,更符合file协议的使用习惯。 \ No newline at end of file diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..7c6a138 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,74 @@ +module.exports = { + // 测试环境 + testEnvironment: 'node', + + // 测试目录 + testMatch: [ + '/src/tests/**/*.test.js' + ], + + // 覆盖率配置 + collectCoverage: true, + coverageDirectory: 'coverage', + coverageReporters: ['text', 'lcov', 'html'], + collectCoverageFrom: [ + 'src/lib/**/*.js', + 'src/bin/**/*.js', + '!src/tests/**', + '!**/node_modules/**', + '!**/fixtures/**' + ], + + // 覆盖率阈值 + coverageThreshold: { + global: { + branches: 80, + functions: 80, + lines: 80, + statements: 80 + } + }, + + // 设置文件 + setupFilesAfterEnv: ['/src/tests/setup.js'], + + // 项目配置 - 分离不同类型的测试 + projects: [ + { + displayName: 'unit', + testMatch: ['/src/tests/**/*.unit.test.js'], + testEnvironment: 'node' + }, + { + displayName: 'integration', + testMatch: ['/src/tests/**/*.integration.test.js'], + testEnvironment: 'node', + // 集成测试可能需要更长的超时时间 + testTimeout: 30000 + }, + { + displayName: 'e2e', + testMatch: ['/src/tests/**/*.e2e.test.js'], + testEnvironment: 'node', + // E2E测试需要更长的超时时间 + testTimeout: 60000 + } + ], + + // 模块路径映射 + moduleNameMapping: { + '^@/(.*)$': '/src/$1', + '^@tests/(.*)$': '/src/tests/$1' + }, + + // 全局变量 + globals: { + TEST_TIMEOUT: 30000 + }, + + // 详细输出 + verbose: true, + + // 并发测试 + maxWorkers: '50%' +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..c28cd25 --- /dev/null +++ b/package.json @@ -0,0 +1,133 @@ +{ + "name": "promptx", + "version": "0.0.1", + "description": "A powerful AI prompt framework for role-based conversations and intelligent interactions. Build sophisticated AI agents with modular prompts, memory systems, and execution frameworks.", + "main": "src/lib/index.js", + "bin": { + "promptx": "src/bin/promptx.js" + }, + "scripts": { + "start": "node src/bin/promptx.js", + "test": "jest", + "test:unit": "jest --selectProjects unit", + "test:integration": "jest --selectProjects integration", + "test:e2e": "jest --selectProjects e2e", + "test:watch": "jest --watch", + "test:watchUnit": "jest --watch --selectProjects unit", + "test:watchIntegration": "jest --watch --selectProjects integration", + "test:coverage": "jest --coverage", + "test:coverageUnit": "jest --coverage --selectProjects unit", + "test:coverageIntegration": "jest --coverage --selectProjects integration", + "test:coverageE2e": "jest --coverage --selectProjects e2e", + "test:ci": "jest --ci --coverage --watchAll=false", + "test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand", + "build": "node src/scripts/build.js", + "build:watch": "node src/scripts/build.js --watch", + "lint": "eslint src/", + "lint:fix": "eslint src/ --fix", + "format": "prettier --write src/", + "format:check": "prettier --check src/", + "validate": "npm run lint && npm run test:ci", + "precommit": "npm run lint && npm run test:unit", + "prepublishOnly": "npm run validate && npm run build" + }, + "files": [ + "src/bin/", + "src/lib/", + "prompt/", + "src/templates/", + "src/scripts/postinstall.js", + "README.md", + "LICENSE", + "CHANGELOG.md" + ], + "dependencies": { + "@reaxi/node-detect-runtime": "^0.1.0", + "boxen": "^5.1.2", + "chalk": "^4.1.2", + "commander": "^11.0.0", + "find-monorepo-root": "^1.0.3", + "find-pkg-dir": "^2.0.0", + "find-up": "^7.0.0", + "fs-extra": "^11.1.0", + "glob": "^10.3.0", + "inquirer": "^8.2.4", + "ora": "^5.4.1", + "pkg-dir": "^8.0.0", + "platform-folders": "^0.6.0", + "resolve": "^1.22.10", + "resolve-package": "^1.0.1", + "semver": "^7.5.0", + "yaml": "^2.3.0" + }, + "devDependencies": { + "@types/jest": "^29.5.0", + "eslint": "^8.42.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-jest": "^27.2.0", + "husky": "^8.0.0", + "jest": "^29.5.0", + "jest-environment-node": "^29.5.0", + "lint-staged": "^13.2.0", + "prettier": "^2.8.0", + "supertest": "^6.3.0", + "tmp": "^0.2.1" + }, + "peerDependencies": { + "node": ">=14.0.0" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + }, + "keywords": [ + "ai", + "prompt", + "chatgpt", + "claude", + "prompt-engineering", + "conversation", + "agent", + "framework", + "role-playing", + "memory-system", + "scrum", + "product-management", + "cli", + "automation" + ], + "author": { + "name": "Deepractice", + "email": "sean@deepracticex.com", + "url": "https://deepractice.ai" + }, + "license": "MIT", + "homepage": "https://github.com/Deepractice/PromptX#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/Deepractice/PromptX.git" + }, + "bugs": { + "url": "https://github.com/Deepractice/PromptX/issues" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, + "lint-staged": { + "*.{js,json,md}": [ + "prettier --write", + "git add" + ], + "*.js": [ + "eslint --fix", + "git add" + ] + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged", + "pre-push": "npm run validate" + } + } +} \ No newline at end of file diff --git a/core/execution/deal-at-reference.execution.md b/prompt/core/execution/deal-at-reference.execution.md similarity index 100% rename from core/execution/deal-at-reference.execution.md rename to prompt/core/execution/deal-at-reference.execution.md diff --git a/core/execution/deal-memory.execution.md b/prompt/core/execution/deal-memory.execution.md similarity index 100% rename from core/execution/deal-memory.execution.md rename to prompt/core/execution/deal-memory.execution.md diff --git a/core/execution/memory-tool-usage.execution.md b/prompt/core/execution/memory-tool-usage.execution.md similarity index 100% rename from core/execution/memory-tool-usage.execution.md rename to prompt/core/execution/memory-tool-usage.execution.md diff --git a/core/execution/memory-trigger.execution.md b/prompt/core/execution/memory-trigger.execution.md similarity index 100% rename from core/execution/memory-trigger.execution.md rename to prompt/core/execution/memory-trigger.execution.md diff --git a/core/memory/declarative-memory.memory.md b/prompt/core/memory/declarative-memory.memory.md similarity index 100% rename from core/memory/declarative-memory.memory.md rename to prompt/core/memory/declarative-memory.memory.md diff --git a/domain/assistant/assistant.role.md b/prompt/domain/assistant/assistant.role.md similarity index 100% rename from domain/assistant/assistant.role.md rename to prompt/domain/assistant/assistant.role.md diff --git a/domain/copywriter/execution/video-copywriter.execution.md b/prompt/domain/copywriter/execution/video-copywriter.execution.md similarity index 100% rename from domain/copywriter/execution/video-copywriter.execution.md rename to prompt/domain/copywriter/execution/video-copywriter.execution.md diff --git a/domain/copywriter/practice/case-studies.md b/prompt/domain/copywriter/practice/case-studies.md similarity index 100% rename from domain/copywriter/practice/case-studies.md rename to prompt/domain/copywriter/practice/case-studies.md diff --git a/domain/copywriter/practice/platform-adaptation.md b/prompt/domain/copywriter/practice/platform-adaptation.md similarity index 100% rename from domain/copywriter/practice/platform-adaptation.md rename to prompt/domain/copywriter/practice/platform-adaptation.md diff --git a/domain/copywriter/practice/script-templates.md b/prompt/domain/copywriter/practice/script-templates.md similarity index 100% rename from domain/copywriter/practice/script-templates.md rename to prompt/domain/copywriter/practice/script-templates.md diff --git a/domain/copywriter/thought/video-copywriter.thought.md b/prompt/domain/copywriter/thought/video-copywriter.thought.md similarity index 100% rename from domain/copywriter/thought/video-copywriter.thought.md rename to prompt/domain/copywriter/thought/video-copywriter.thought.md diff --git a/domain/copywriter/video-copywriter.role.md b/prompt/domain/copywriter/video-copywriter.role.md similarity index 100% rename from domain/copywriter/video-copywriter.role.md rename to prompt/domain/copywriter/video-copywriter.role.md diff --git a/domain/prompt/execution/execution-best-practice.execution.md b/prompt/domain/prompt/execution/execution-best-practice.execution.md similarity index 100% rename from domain/prompt/execution/execution-best-practice.execution.md rename to prompt/domain/prompt/execution/execution-best-practice.execution.md diff --git a/domain/prompt/execution/memory-best-practice.execution.md b/prompt/domain/prompt/execution/memory-best-practice.execution.md similarity index 100% rename from domain/prompt/execution/memory-best-practice.execution.md rename to prompt/domain/prompt/execution/memory-best-practice.execution.md diff --git a/domain/prompt/execution/prompt-developer.execution.md b/prompt/domain/prompt/execution/prompt-developer.execution.md similarity index 100% rename from domain/prompt/execution/prompt-developer.execution.md rename to prompt/domain/prompt/execution/prompt-developer.execution.md diff --git a/domain/prompt/execution/resource-best-practice.execution.md b/prompt/domain/prompt/execution/resource-best-practice.execution.md similarity index 100% rename from domain/prompt/execution/resource-best-practice.execution.md rename to prompt/domain/prompt/execution/resource-best-practice.execution.md diff --git a/domain/prompt/execution/role-best-practice.execution.md b/prompt/domain/prompt/execution/role-best-practice.execution.md similarity index 100% rename from domain/prompt/execution/role-best-practice.execution.md rename to prompt/domain/prompt/execution/role-best-practice.execution.md diff --git a/domain/prompt/execution/terminology-best-practice.execution.md b/prompt/domain/prompt/execution/terminology-best-practice.execution.md similarity index 100% rename from domain/prompt/execution/terminology-best-practice.execution.md rename to prompt/domain/prompt/execution/terminology-best-practice.execution.md diff --git a/domain/prompt/execution/thought-best-practice.execution.md b/prompt/domain/prompt/execution/thought-best-practice.execution.md similarity index 100% rename from domain/prompt/execution/thought-best-practice.execution.md rename to prompt/domain/prompt/execution/thought-best-practice.execution.md diff --git a/domain/prompt/practice/execution-best-practice.md b/prompt/domain/prompt/practice/execution-best-practice.md similarity index 100% rename from domain/prompt/practice/execution-best-practice.md rename to prompt/domain/prompt/practice/execution-best-practice.md diff --git a/domain/prompt/practice/memory-best-practice.md b/prompt/domain/prompt/practice/memory-best-practice.md similarity index 100% rename from domain/prompt/practice/memory-best-practice.md rename to prompt/domain/prompt/practice/memory-best-practice.md diff --git a/domain/prompt/practice/resource-best-practice.md b/prompt/domain/prompt/practice/resource-best-practice.md similarity index 100% rename from domain/prompt/practice/resource-best-practice.md rename to prompt/domain/prompt/practice/resource-best-practice.md diff --git a/domain/prompt/practice/role-best-practice.md b/prompt/domain/prompt/practice/role-best-practice.md similarity index 100% rename from domain/prompt/practice/role-best-practice.md rename to prompt/domain/prompt/practice/role-best-practice.md diff --git a/domain/prompt/practice/thought-best-practice.md b/prompt/domain/prompt/practice/thought-best-practice.md similarity index 100% rename from domain/prompt/practice/thought-best-practice.md rename to prompt/domain/prompt/practice/thought-best-practice.md diff --git a/domain/prompt/prompt-developer.role.md b/prompt/domain/prompt/prompt-developer.role.md similarity index 100% rename from domain/prompt/prompt-developer.role.md rename to prompt/domain/prompt/prompt-developer.role.md diff --git a/domain/prompt/thought/prompt-developer.thought.md b/prompt/domain/prompt/thought/prompt-developer.thought.md similarity index 100% rename from domain/prompt/thought/prompt-developer.thought.md rename to prompt/domain/prompt/thought/prompt-developer.thought.md diff --git a/domain/protocol/template/protocol-framework-template.md b/prompt/domain/protocol/template/protocol-framework-template.md similarity index 100% rename from domain/protocol/template/protocol-framework-template.md rename to prompt/domain/protocol/template/protocol-framework-template.md diff --git a/domain/scrum/execution/epic-best-practice.execution.md b/prompt/domain/scrum/execution/epic-best-practice.execution.md similarity index 100% rename from domain/scrum/execution/epic-best-practice.execution.md rename to prompt/domain/scrum/execution/epic-best-practice.execution.md diff --git a/domain/scrum/execution/feature-best-practice.execution.md b/prompt/domain/scrum/execution/feature-best-practice.execution.md similarity index 100% rename from domain/scrum/execution/feature-best-practice.execution.md rename to prompt/domain/scrum/execution/feature-best-practice.execution.md diff --git a/domain/scrum/execution/milestone-best-practice.execution.md b/prompt/domain/scrum/execution/milestone-best-practice.execution.md similarity index 100% rename from domain/scrum/execution/milestone-best-practice.execution.md rename to prompt/domain/scrum/execution/milestone-best-practice.execution.md diff --git a/domain/scrum/execution/product-owner.execution.md b/prompt/domain/scrum/execution/product-owner.execution.md similarity index 100% rename from domain/scrum/execution/product-owner.execution.md rename to prompt/domain/scrum/execution/product-owner.execution.md diff --git a/domain/scrum/execution/scrum-best-practice.execution.md b/prompt/domain/scrum/execution/scrum-best-practice.execution.md similarity index 100% rename from domain/scrum/execution/scrum-best-practice.execution.md rename to prompt/domain/scrum/execution/scrum-best-practice.execution.md diff --git a/domain/scrum/execution/sprint-best-practice.execution.md b/prompt/domain/scrum/execution/sprint-best-practice.execution.md similarity index 100% rename from domain/scrum/execution/sprint-best-practice.execution.md rename to prompt/domain/scrum/execution/sprint-best-practice.execution.md diff --git a/domain/scrum/execution/story-best-practice.execution.md b/prompt/domain/scrum/execution/story-best-practice.execution.md similarity index 100% rename from domain/scrum/execution/story-best-practice.execution.md rename to prompt/domain/scrum/execution/story-best-practice.execution.md diff --git a/domain/scrum/execution/task-best-practice.execution.md b/prompt/domain/scrum/execution/task-best-practice.execution.md similarity index 100% rename from domain/scrum/execution/task-best-practice.execution.md rename to prompt/domain/scrum/execution/task-best-practice.execution.md diff --git a/domain/scrum/execution/testcase-best-practice.execution.md b/prompt/domain/scrum/execution/testcase-best-practice.execution.md similarity index 100% rename from domain/scrum/execution/testcase-best-practice.execution.md rename to prompt/domain/scrum/execution/testcase-best-practice.execution.md diff --git a/domain/scrum/execution/workitem-title-best-practice.execution.md b/prompt/domain/scrum/execution/workitem-title-best-practice.execution.md similarity index 100% rename from domain/scrum/execution/workitem-title-best-practice.execution.md rename to prompt/domain/scrum/execution/workitem-title-best-practice.execution.md diff --git a/domain/scrum/role/product-owner.role.md b/prompt/domain/scrum/role/product-owner.role.md similarity index 100% rename from domain/scrum/role/product-owner.role.md rename to prompt/domain/scrum/role/product-owner.role.md diff --git a/domain/scrum/thought/product-owner.thought.md b/prompt/domain/scrum/thought/product-owner.thought.md similarity index 100% rename from domain/scrum/thought/product-owner.thought.md rename to prompt/domain/scrum/thought/product-owner.thought.md diff --git a/domain/test/test.role.md b/prompt/domain/test/test.role.md similarity index 100% rename from domain/test/test.role.md rename to prompt/domain/test/test.role.md diff --git a/domain/test/testcase.md b/prompt/domain/test/testcase.md similarity index 100% rename from domain/test/testcase.md rename to prompt/domain/test/testcase.md diff --git a/protocol/dpml.protocol.md b/prompt/protocol/dpml.protocol.md similarity index 100% rename from protocol/dpml.protocol.md rename to prompt/protocol/dpml.protocol.md diff --git a/protocol/dpml.terminology.md b/prompt/protocol/dpml.terminology.md similarity index 100% rename from protocol/dpml.terminology.md rename to prompt/protocol/dpml.terminology.md diff --git a/protocol/tag/execution.tag.md b/prompt/protocol/tag/execution.tag.md similarity index 100% rename from protocol/tag/execution.tag.md rename to prompt/protocol/tag/execution.tag.md diff --git a/protocol/tag/execution.terminology.md b/prompt/protocol/tag/execution.terminology.md similarity index 100% rename from protocol/tag/execution.terminology.md rename to prompt/protocol/tag/execution.terminology.md diff --git a/protocol/tag/memory.tag.md b/prompt/protocol/tag/memory.tag.md similarity index 100% rename from protocol/tag/memory.tag.md rename to prompt/protocol/tag/memory.tag.md diff --git a/protocol/tag/memory.terminology.md b/prompt/protocol/tag/memory.terminology.md similarity index 100% rename from protocol/tag/memory.terminology.md rename to prompt/protocol/tag/memory.terminology.md diff --git a/protocol/tag/resource.tag.md b/prompt/protocol/tag/resource.tag.md similarity index 100% rename from protocol/tag/resource.tag.md rename to prompt/protocol/tag/resource.tag.md diff --git a/protocol/tag/resource.terminology.md b/prompt/protocol/tag/resource.terminology.md similarity index 100% rename from protocol/tag/resource.terminology.md rename to prompt/protocol/tag/resource.terminology.md diff --git a/protocol/tag/role.tag.md b/prompt/protocol/tag/role.tag.md similarity index 100% rename from protocol/tag/role.tag.md rename to prompt/protocol/tag/role.tag.md diff --git a/protocol/tag/role.terminology.md b/prompt/protocol/tag/role.terminology.md similarity index 100% rename from protocol/tag/role.terminology.md rename to prompt/protocol/tag/role.terminology.md diff --git a/protocol/tag/terminology.tag.md b/prompt/protocol/tag/terminology.tag.md similarity index 100% rename from protocol/tag/terminology.tag.md rename to prompt/protocol/tag/terminology.tag.md diff --git a/protocol/tag/thought.tag.md b/prompt/protocol/tag/thought.tag.md similarity index 100% rename from protocol/tag/thought.tag.md rename to prompt/protocol/tag/thought.tag.md diff --git a/protocol/tag/thought.terminology.md b/prompt/protocol/tag/thought.terminology.md similarity index 100% rename from protocol/tag/thought.terminology.md rename to prompt/protocol/tag/thought.terminology.md diff --git a/resource/execution.resource.md b/prompt/resource/execution.resource.md similarity index 100% rename from resource/execution.resource.md rename to prompt/resource/execution.resource.md diff --git a/resource/memory.resource.md b/prompt/resource/memory.resource.md similarity index 100% rename from resource/memory.resource.md rename to prompt/resource/memory.resource.md diff --git a/resource/thought.resource.md b/prompt/resource/thought.resource.md similarity index 100% rename from resource/thought.resource.md rename to prompt/resource/thought.resource.md diff --git a/promptx.js b/promptx.js deleted file mode 100755 index fbcd742..0000000 --- a/promptx.js +++ /dev/null @@ -1,424 +0,0 @@ -#!/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, '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 printCore() { - const coreDir = path.join(promptxDir, 'core'); - 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; - } - - // 收集核心目录下的所有文件 - const coreFiles = collectMarkdownFiles(coreDir); - - // 文件按字母顺序排序 - coreFiles.sort(); - - // 合并到总文件列表 - allFiles = allFiles.concat(coreFiles); - - console.log(`从 core 目录收集了 ${coreFiles.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) { - // 如果传入的是相对路径,则基于当前工作目录解析 - let fullPath; - if (path.isAbsolute(rolePath)) { - fullPath = rolePath; - } else { - fullPath = path.join(process.cwd(), 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(process.cwd(), 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 {string[]} args - 其他参数 - */ -function parseMemoryArgs(content, args) { - const options = { - tags: [], - score: 5, - duration: '短期' - }; - - // 从内容中提取标签、评分和有效期 - const contentParts = content.trim().split(/\s+/); - let cleanContent = []; - - for (let part of contentParts) { - if (part.startsWith('#')) { - // 检查是否是特殊标记 - if (part.includes('评分:')) { - const scoreText = part.split('评分:')[1].trim(); - const score = parseInt(scoreText); - if (!isNaN(score) && score >= 1 && score <= 10) { - options.score = score; - } - } else if (part.includes('有效期:')) { - const duration = part.split('有效期:')[1].trim(); - if (['短期', '中期', '长期'].includes(duration)) { - options.duration = duration; - } - } else { - // 普通标签 - const tag = part.slice(1); - if (tag) { - options.tags.push(tag); - } - } - } else { - cleanContent.push(part); - } - } - - // 处理剩余的命令行参数 - for (let arg of args) { - // 移除参数前后的引号(如果有) - arg = arg.replace(/^['"]|['"]$/g, '').trim(); - - if (arg.startsWith('#')) { - // 检查是否是特殊标记 - if (arg.includes('评分:')) { - const score = parseInt(arg.split('评分:')[1]); - if (!isNaN(score) && score >= 1 && score <= 10) { - options.score = score; - } - } else if (arg.includes('有效期:')) { - const duration = arg.split('有效期:')[1]; - if (['短期', '中期', '长期'].includes(duration)) { - options.duration = duration; - } - } else { - // 普通标签 - const tag = arg.slice(1); - if (tag) { - options.tags.push(tag); - } - } - } - } - - // 如果没有标签,使用默认标签 - if (options.tags.length === 0) { - options.tags = ['其他']; - } - - // 返回清理后的内容和选项 - return { - cleanContent: cleanContent.join(' '), - options: options - }; -} - -/** - * 添加记忆条目 - * @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, - tags: options.tags && options.tags.length > 0 ? options.tags : defaultOptions.tags - }; - - // 构建记忆条目,确保格式统一 - const memoryEntry = `\n- ${finalOptions.timestamp} ${content.trim()} ${finalOptions.tags.map(tag => `#${tag}`).join(' ')} #评分:${finalOptions.score} #有效期:${finalOptions.duration}\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); - } -} - -/** - * 打印帮助信息 - */ -function printHelp() { - console.log(` -PromptX 工具 - 协议和角色内容查看器 - -使用方法: - node promptx.js - 打印所有协议内容 (按protocol、resource顺序) - node promptx.js protocols - 同上,打印所有协议内容 - node promptx.js core - 打印所有核心提示词内容 - node promptx.js role <路径> - 打印指定角色文件内容 - node promptx.js file <路径> - 打印指定文件内容 - node promptx.js remember <内容> - 添加记忆条目,标签、评分和有效期可直接包含在内容中 - node promptx.js bootstrap - 打印bootstrap.md内容 - node promptx.js help - 显示此帮助信息 - -记忆命令用法: - 将标签、评分和有效期直接包含在内容字符串中,时间戳会自动添加到行首 - #标签名 - 添加标签 (可多个) - #评分:数字 - 设置重要性评分 (1-10) - #有效期:时长 - 设置有效期 (短期/中期/长期) - -示例: - node promptx.js remember "用户提出了重要建议 #用户反馈 #改进建议 #评分:8 #有效期:长期" - node promptx.js remember "临时配置信息 #配置 #评分:3 #有效期:短期" - `); -} - -// 根据命令执行相应功能 -switch (command) { - case 'protocols': - printProtocols(); - break; - case 'core': - printCore(); - break; - case 'bootstrap': - // 只打印 bootstrap.md - printFile('bootstrap.md'); - 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 #评分:8 #有效期:长期"'); - } else { - try { - // 记忆内容就是传入的第一个参数 - const memoryContent = param; - - // 解析内容中的标签、评分和有效期 - const { cleanContent, options } = parseMemoryArgs(memoryContent, []); - - // 添加记忆 - addMemory(cleanContent, options); - } catch (err) { - console.error('错误:', err.message); - console.log('使用方法: node promptx.js remember "记忆内容 #标签1 #标签2 #评分:8 #有效期:长期"'); - } - } - break; - case 'help': - printHelp(); - break; - default: - console.error(`错误: 未知命令 "${command}"`); - printHelp(); - break; -} \ No newline at end of file diff --git a/src/bin/promptx.js b/src/bin/promptx.js new file mode 100755 index 0000000..8e073b3 --- /dev/null +++ b/src/bin/promptx.js @@ -0,0 +1,109 @@ +#!/usr/bin/env node + +const { Command } = require('commander'); +const chalk = require('chalk'); +const packageJson = require('../../package.json'); + +// 导入命令模块 +const helloCommand = require('../lib/commands/hello'); +const initCommand = require('../lib/commands/init'); +const learnCommand = require('../lib/commands/learn'); +const recallCommand = require('../lib/commands/recall'); +const rememberCommand = require('../lib/commands/remember'); + +// 创建主程序 +const program = new Command(); + +// 设置程序信息 +program + .name('promptx') + .description(packageJson.description) + .version(packageJson.version, '-v, --version', 'display version number'); + +// 添加五大核心命令 +program + .command('init') + .description('🏗️ 项目集成 - 在当前项目中初始化PromptX集成') + .option('-f, --force', '强制重新初始化(覆盖已存在的配置)') + .action(initCommand); + +program + .command('hello') + .description('🎯 系统入口 - AI助手接待用户并展示可用角色') + .action(helloCommand); + +program + .command('learn ') + .description('📚 学习命令 - AI获取和理解提示词内容') + .option('-f, --format ', '输出格式 (text|json)', 'text') + .action(learnCommand); + +program + .command('recall') + .description('🔍 记忆检索 - AI回忆和检索记忆内容') + .option('-r, --recent', '显示最近的记忆') + .option('-i, --important', '显示重要记忆 (评分≥7)') + .option('-l, --limit ', '限制返回数量', '10') + .action(recallCommand); + +program + .command('remember ') + .description('🧠 记忆保存 - AI保存重要信息和经验') + .option('-s, --score ', '重要性评分 (1-10)', '5') + .option('-d, --duration