refactor: Migrate project to monorepo structure with pnpm workspaces

- Convert project to monorepo with separate web and extension packages
- Update package.json scripts to support pnpm workspace commands
- Remove individual configuration files from root directory
- Adjust Vercel configuration for monorepo deployment
- Prepare for Chrome extension development
- Remove existing web application source files in preparation for restructuring
This commit is contained in:
linshen committed 2025-02-13 22:51:28 +08:00
1 parent fcc61fd626
commit 9be9f6b3ae
68 files changed
+3917 -5165

No files matched your search

+44 -21
View File
@@ -26,30 +26,36 @@
- 📋 一键复制优化结果
- 🔄 历史记录管理
- 📝 提示词模板管理
- 🧩 Chrome浏览器插件支持(开发中)
## 项目结构
```
prompt-optimizer-v3/
├── src/ # 源代码目录
│ ├── api/ # API 接口封装
│ ├── assets/ # 静态资源
│ ├── components/ # Vue 组件
│ ├── services/ # 业务逻辑服务
│ │ ├── llm/ # LLM 服务封装
│ │ ├── prompt/ # 提示词处理服务
│ │ └── template/ # 模板管理服务
│ ├── App.vue # 根组件
│ ├── main.js # 入口文件
│ └── style.css # 全局样式
├── public/ # 公共资源目录
├── tools/ # 工具脚本
├── tests/ # 测试文件
├── .env.example # 环境变量示例
├── .env.local # 本地环境变量(需自行创建)
├── package.json # 项目配置
├── vite.config.js # Vite 配置
└── tailwind.config.js # TailwindCSS 配置
prompt-optimizer/
├── packages/ # 项目包
│ ├── web/ # Web版本
│ ├── extension/ # Chrome插件版本
│ └── core/ # 共享核心代码
├── src/ # 源代码目录
│ ├── api/ # API 接口封装
│ ├── assets/ # 静态资源
│ ├── components/ # Vue 组件
│ ├── services/ # 业务逻辑服务
│ │ ├── llm/ # LLM 服务封装
│ │ ├── prompt/ # 提示词处理服务
│ │ └── template/# 模板管理服务
│ ├── App.vue # 根组件
│ ├── main.js # 入口文件
│ └── style.css # 全局样式
├── public/ # 公共资源目录
├── tools/ # 工具脚本
├── tests/ # 测试文件
├── docs/ # 项目文档
├── .env.example # 环境变量示例
├── .env.local # 本地环境变量(需自行创建)
├── package.json # 项目配置
├── vite.config.js # Vite 配置
└── tailwind.config.js # TailwindCSS 配置
```
## 功能清单
@@ -61,7 +67,12 @@ prompt-optimizer-v3/
- [x] 一键清空输入
- [x] 优化结果预览
- [x] 提示词模板管理
- [ ] Chrome插件支持
- [ ] 选中文本快捷优化
- [ ] 右键菜单集成
- [ ] 快捷键支持
- [ ] 历史记录同步
### 设置与配置
- [x] API 密钥管理
- [x] 加密存储
@@ -132,6 +143,7 @@ vercel --prod
## 使用说明
### Web版本
1. 首次使用需要配置 API 密钥:
- 点击右上角的 ⚙️ 设置按钮
- 输入相应的 API 密钥
@@ -147,6 +159,17 @@ vercel --prod
- 可以查看之前的优化记录
- 点击"重新使用"可以快速恢复历史提示词
### Chrome插件版本(开发中)
1. 从Chrome商店安装插件(即将上线)
2. 配置API密钥:
- 点击插件图标
- 进入设置页面
- 配置相应API密钥
3. 使用方式:
- 选中文本右键优化
- 点击插件图标使用完整功能
- 使用快捷键触发(可自定义)
## 技术栈
- Vue 3 - 渐进式 JavaScript 框架
+139
View File
@@ -0,0 +1,139 @@
# Chrome插件版本开发计划
## 项目概述
将提示词优化器开发为Chrome浏览器插件,实现更便捷的使用体验。采用monorepo结构,在现有项目中创建子目录进行开发。
## 项目结构
```bash
prompt-optimizer/
├── packages/
│ ├── web/ # 现有的Web版本
│ ├── extension/ # Chrome插件版本
│ │ ├── src/
│ │ │ ├── popup/ # 弹窗界面
│ │ │ ├── background/# 后台脚本
│ │ │ ├── content/ # 内容脚本
│ │ │ └── manifest.json
│ │ └── package.json
│ └── core/ # 共享的核心代码
├── pnpm-workspace.yaml
└── package.json
```
## 开发计划
### 阶段1:项目结构调整(预计1周)
1. 创建monorepo结构
- 设置pnpm工作空间
- 迁移现有代码到web子目录
- 创建extension和core目录
2. 核心代码抽取
- 识别可复用的核心逻辑
- 将核心代码迁移到core包
- 更新依赖关系
### 阶段2:插件基础框架(预计1周)
1. 创建插件基础结构
- 配置manifest.json
- 设置构建流程
- 创建基础UI组件
2. 实现基础功能
- 弹出窗口界面
- 后台服务
- 内容脚本
### 阶段3:功能开发(预计2周)
1. 核心功能迁移
- 提示词优化
- API集成
- 历史记录
- 模板管理
2. 插件特定功能
- 右键菜单集成
- 选中文本处理
- 快捷键支持
- 上下文感知
### 阶段4:优化与测试(预计1周)
1. 性能优化
- 资源加载优化
- 响应速度优化
- 内存使用优化
2. 安全加固
- 权限管理
- 数据安全
- 通信安全
3. 测试与文档
- 单元测试
- 集成测试
- 文档更新
## 技术要点
### 核心功能
- 文本选择优化
- 快捷操作支持
- 历史记录同步
- 设置同步
- 模板管理
### 性能考虑
- 按需加载
- 资源缓存
- 后台优化
- 内存管理
### 安全考虑
- API密钥保护
- 数据加密存储
- 通信安全
- 权限控制
## 发布计划
### 测试版(v0.1.0)
- 基础功能可用
- 核心特性完整
- 初步性能优化
- 基本安全措施
### 正式版(v1.0.0)
- 完整功能集
- 性能优化完成
- 安全措施完善
- 文档完整
## 风险评估
### 技术风险
- Chrome API兼容性
- 性能瓶颈
- 安全隐患
- 跨域通信
### 缓解措施
- 充分测试
- 渐进式开发
- 安全审查
- 性能监控
## 维护计划
### 日常维护
- 问题修复
- 性能监控
- 安全更新
- 用户反馈
### 版本更新
- 功能迭代
- 性能优化
- 安全加固
- 文档更新
-5020
View File
File diff suppressed because it is too large. Load diff
+6 -36
View File
@@ -1,41 +1,11 @@
{
"name": "prompt-optimizer-v3",
"name": "prompt-optimizer-monorepo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest run --coverage",
"test:unit": "vitest run tests/unit"
},
"dependencies": {
"@langchain/anthropic": "^0.3.12",
"@langchain/core": "^0.3.33",
"@langchain/google-genai": "^0.1.6",
"@langchain/openai": "^0.3.17",
"dotenv": "^16.4.7",
"element-plus": "^2.9.3",
"js-yaml": "^4.1.0",
"langchain": "^0.3.12",
"uuid": "^11.0.5",
"vue": "^3.5.13"
},
"devDependencies": {
"@pinia/testing": "^0.1.7",
"@tailwindcss/forms": "^0.5.10",
"@tailwindcss/typography": "^0.5.16",
"@vitejs/plugin-basic-ssl": "^1.2.0",
"@vitejs/plugin-vue": "^5.2.1",
"@vue/test-utils": "^2.4.6",
"autoprefixer": "^10.4.20",
"jsdom": "^26.0.0",
"postcss": "^8.5.1",
"tailwindcss": "^3.4.17",
"vite": "^6.0.7",
"vitest": "^3.0.2"
"dev:web": "pnpm --filter web dev",
"dev:extension": "pnpm --filter extension dev",
"build:web": "pnpm --filter web build",
"build:extension": "pnpm --filter extension build",
"test": "pnpm -r test"
}
}
+21
View File
@@ -0,0 +1,21 @@
{
"name": "@prompt-optimizer/core",
"version": "0.0.0",
"private": true,
"type": "module",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage"
},
"devDependencies": {
"tsup": "^8.0.2",
"typescript": "^5.3.3",
"vitest": "^3.0.2"
}
}
+3
View File
@@ -0,0 +1,3 @@
// Core package entry point
export * from './types'
export * from './services'
+4
View File
@@ -0,0 +1,4 @@
// Core services
export * from './template'
export * from './history'
export * from './llm'
+24
View File
@@ -0,0 +1,24 @@
// Core types
export interface PromptTemplate {
id: string
name: string
description: string
content: string
metadata?: Record<string, any>
}
export interface LLMConfig {
name: string
baseURL: string
apiKey: string
models: string[]
}
export interface HistoryRecord {
id: string
timestamp: number
input: string
output: string
model: string
metadata?: Record<string, any>
}
+22
View File
@@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"declaration": true,
"outDir": "dist"
},
"include": ["src"],
"exclude": ["node_modules", "dist", "tests"]
}
File renamed without changes.
File renamed without changes.
+42
View File
@@ -0,0 +1,42 @@
{
"name": "@prompt-optimizer/web",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest run --coverage",
"test:unit": "vitest run tests/unit"
},
"dependencies": {
"@langchain/anthropic": "^0.3.12",
"@langchain/core": "^0.3.33",
"@langchain/google-genai": "^0.1.6",
"@langchain/openai": "^0.3.17",
"@prompt-optimizer/core": "workspace:*",
"dotenv": "^16.4.7",
"element-plus": "^2.9.3",
"js-yaml": "^4.1.0",
"langchain": "^0.3.12",
"uuid": "^11.0.5",
"vue": "^3.5.13"
},
"devDependencies": {
"@pinia/testing": "^0.1.7",
"@tailwindcss/forms": "^0.5.10",
"@tailwindcss/typography": "^0.5.16",
"@vitejs/plugin-basic-ssl": "^1.2.0",
"@vitejs/plugin-vue": "^5.2.1",
"@vue/test-utils": "^2.4.6",
"autoprefixer": "^10.4.20",
"jsdom": "^26.0.0",
"postcss": "^8.5.1",
"tailwindcss": "^3.4.17",
"vite": "^6.0.7",
"vitest": "^3.0.2"
}
}
File renamed without changes.
File renamed without changes.

Before

Width:  |  Height:  |  Size: 872 B

After

Width:  |  Height:  |  Size: 872 B

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -33,15 +33,20 @@ describe('自定义模型测试', () => {
it('应该能正确处理自定义模型的配置更新', () => {
const updatedConfig = {
name: 'Updated Custom Model',
baseURL: import.meta.env.VITE_CUSTOM_API_BASE_URL || 'https://api.custom.test',
models: [import.meta.env.VITE_CUSTOM_API_MODEL || 'test-model'],
defaultModel: import.meta.env.VITE_CUSTOM_API_MODEL || 'test-model',
enabled: true,
provider: 'custom'
};
modelManager.updateModel('custom', updatedConfig);
const model = modelManager.getModel('custom');
expect(model.name).toBe(updatedConfig.name);
expect(model.baseURL).toBe(import.meta.env.VITE_CUSTOM_API_BASE_URL);
expect(model.models).toEqual([import.meta.env.VITE_CUSTOM_API_MODEL]);
expect(model.defaultModel).toBe(import.meta.env.VITE_CUSTOM_API_MODEL);
expect(model.baseURL).toBe(updatedConfig.baseURL);
expect(model.models).toEqual(updatedConfig.models);
expect(model.defaultModel).toBe(updatedConfig.defaultModel);
});
it('应该能正确调用自定义模型的 API', async () => {
+80
View File
@@ -0,0 +1,80 @@
import { vi } from 'vitest'
import { config } from '@vue/test-utils'
// 模拟 window 对象
const windowMock = {
localStorage: {
store: new Map(),
getItem: vi.fn((key) => {
return windowMock.localStorage.store.get(key) || null;
}),
setItem: vi.fn((key, value) => {
windowMock.localStorage.store.set(key, value);
}),
removeItem: vi.fn((key) => {
windowMock.localStorage.store.delete(key);
}),
clear: vi.fn(() => {
windowMock.localStorage.store.clear();
})
},
navigator: {
clipboard: {
writeText: vi.fn()
}
},
// 添加事件监听相关功能
eventListeners: new Map(),
addEventListener: vi.fn((event, handler) => {
if (!windowMock.eventListeners.has(event)) {
windowMock.eventListeners.set(event, new Set());
}
windowMock.eventListeners.get(event).add(handler);
}),
removeEventListener: vi.fn((event, handler) => {
if (windowMock.eventListeners.has(event)) {
windowMock.eventListeners.get(event).delete(handler);
}
}),
dispatchEvent: vi.fn((event) => {
if (windowMock.eventListeners.has(event.type)) {
windowMock.eventListeners.get(event.type).forEach(handler => handler(event));
}
return true;
})
};
// 全局注入 window mock
Object.defineProperty(global, 'window', {
value: windowMock,
writable: true,
configurable: true
});
// 全局注入 localStorage
Object.defineProperty(global, 'localStorage', {
value: windowMock.localStorage,
writable: true,
configurable: true
});
// 全局注入 navigator
Object.defineProperty(global, 'navigator', {
value: windowMock.navigator,
writable: true,
configurable: true
});
// 模拟 Teleport 组件
config.global.stubs = {
Teleport: {
template: '<div><slot /></div>'
}
}
// 在每个测试之前重置 mock 状态
beforeEach(() => {
windowMock.localStorage.store.clear();
windowMock.eventListeners.clear();
vi.clearAllMocks();
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
+19
View File
@@ -0,0 +1,19 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
export default defineConfig({
plugins: [vue()],
test: {
environment: 'jsdom',
setupFiles: ['./tests/setup.js'],
include: ['tests/**/*.{test,spec}.{js,ts,jsx,tsx}'],
globals: true
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
});
+3472
View File
File diff suppressed because it is too large. Load diff
+2
View File
@@ -0,0 +1,2 @@
packages:
- 'packages/*'
+28 -8
View File
@@ -119,17 +119,23 @@
- 🔄 增强API调用安全
### 📅 待开发任务
1. 提示词功能增强
1. Chrome插件版本开发
- 基础框架搭建
- 核心功能迁移
- 插件特定功能
- UI适配优化
2. 提示词功能增强
- 提示词模板库
- 提示词版本管理
- 提示词测试用例
2. 主题系统
3. 主题系统
- 深色/浅色主题切换
- 自定义主题配置
- 主题持久化存储
3. 国际化支持
4. 国际化支持
- 多语言框架集成
- 翻译资源管理
- 语言切换功能
@@ -147,9 +153,14 @@
- API响应时间 < 3秒
- 首次内容渲染 < 1秒
### 📈 风险评估
### �� 风险评估
1. 技术风险
- Chrome插件开发风险(新增)
- ⚠️ 插件特定API适配
- ⚠️ 性能优化需求
- ⚠️ 跨域通信安全
- ⚠️ 插件权限管理
- API依赖风险(已降低)
- 实现了错误重试机制
- 优化了响应处理
@@ -170,6 +181,7 @@
- 技术债务处理中
### 🔄 更新记录
- 2024-03-21: 规划Chrome插件版本开发,采用monorepo结构
- 2024-03-20: 增强模板管理器,支持多类型模板和本地存储选择
- 2024-03-19: 重构模板管理器,实现本地存储和用户模板支持
- 2024-03-17: 增加自定义API集成和流式输出支持
@@ -182,25 +194,31 @@
### 📝 近期计划 (未来2周)
1. 提示词服务增强
1. Chrome插件版本启动
- 项目结构调整
- 创建插件基础框架
- 开始核心功能迁移
- 目标:完成基础框架搭建
2. 提示词服务增强
- 优化响应处理机制
- 完善错误重试
- 提升性能表现
- 目标:提升服务稳定性
2. 历史记录功能完善
3. 历史记录功能完善
- 实现高级搜索
- 优化数据结构
- 添加批量操作
- 改进用户体验
3. 安全性增强
4. 安全性增强
- 完善数据加密
- 增强访问控制
- 添加安全日志
- 优化异常处理
4. 性能优化
5. 性能优化
- 实现数据缓存
- 优化加载速度
- 改进资源利用
@@ -227,12 +245,14 @@
- ⏳ 版本管理功能
- ⏳ 测试用例管理
- 🔄 搜索和过滤功能
- 🆕 Chrome插件基础框架
#### 里程碑3:质量提升(4月下旬)
- 🔄 测试覆盖率达到80%
- 🔄 完成安全性增强
- ⏳ 实现性能优化
- 🔄 文档持续完善
- 🆕 完成插件版本1.0
### 🔍 经验总结
-45
View File
@@ -1,45 +0,0 @@
import { vi } from 'vitest'
import { config } from '@vue/test-utils'
// 模拟 Teleport 组件
config.global.stubs = {
Teleport: {
template: '<div><slot /></div>'
}
}
// 模拟 localStorage
const localStorageMock = {
store: new Map(),
getItem: vi.fn((key) => {
return localStorageMock.store.get(key) || null;
}),
setItem: vi.fn((key, value) => {
localStorageMock.store.set(key, value);
}),
removeItem: vi.fn((key) => {
localStorageMock.store.delete(key);
}),
clear: vi.fn(() => {
localStorageMock.store.clear();
})
};
Object.defineProperty(window, 'localStorage', {
value: localStorageMock,
writable: true,
configurable: true
});
// 在每个测试之前重置 localStorage
beforeEach(() => {
localStorageMock.store.clear();
vi.clearAllMocks();
});
// 模拟 clipboard API
Object.defineProperty(navigator, 'clipboard', {
value: {
writeText: vi.fn()
}
})
+3 -2
View File
@@ -1,6 +1,7 @@
{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"buildCommand": "pnpm build:web",
"outputDirectory": "packages/web/dist",
"installCommand": "pnpm install",
"framework": "vite",
"rewrites": [
{
-30
View File
@@ -1,30 +0,0 @@
import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['./tests/setup.js'],
include: ['./tests/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
exclude: [
'node_modules/',
'tests/setup.js',
],
},
typecheck: {
tsconfig: './tsconfig.json',
include: ['./tests/**/*.{ts,tsx}'],
exclude: ['node_modules']
},
reporters: ['verbose'],
outputFile: 'test-results.json',
logHeapUsage: true,
watch: false,
silent: false
},
})