prompt-plus 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -53
- package/dist/cli.js +7 -1
- package/dist/commands.d.ts +3 -0
- package/dist/commands.js +112 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
AI 技能包管理工具 - 基于技能包驱动的开发工作流
|
|
4
4
|
|
|
5
|
-
> ⚠️ **v1.1.0
|
|
5
|
+
> ⚠️ **v1.1.0+ 断档式更新**:不兼容 v1.0.x,请重新安装
|
|
6
6
|
|
|
7
7
|
## 安装
|
|
8
8
|
|
|
@@ -34,29 +34,32 @@ pp skill installed
|
|
|
34
34
|
### 仓库管理
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
pp repo add <name> <url>
|
|
37
|
+
pp repo add <name> <url> # 添加技能包仓库
|
|
38
38
|
pp repo add <name> <url> -b <branch> # 指定分支
|
|
39
|
-
pp repo remove <name>
|
|
40
|
-
pp repo list
|
|
41
|
-
pp repo sync
|
|
42
|
-
pp repo sync <name>
|
|
39
|
+
pp repo remove <name> # 移除仓库
|
|
40
|
+
pp repo list # 列出所有仓库
|
|
41
|
+
pp repo sync # 同步所有仓库
|
|
42
|
+
pp repo sync <name> # 同步指定仓库
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
### 技能包管理
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
pp skill list
|
|
49
|
-
pp skill list -r <repo>
|
|
50
|
-
pp skill install
|
|
51
|
-
pp skill install <name>
|
|
52
|
-
pp skill installed
|
|
48
|
+
pp skill list # 列出所有可用技能包
|
|
49
|
+
pp skill list -r <repo> # 列出指定仓库的技能包
|
|
50
|
+
pp skill install # 交互式安装技能包
|
|
51
|
+
pp skill install <name> # 安装指定技能包
|
|
52
|
+
pp skill installed # 查看已安装的技能包
|
|
53
|
+
pp skill upgrade # 升级技能包(保留 context.md)
|
|
54
|
+
pp skill upgrade <name> # 升级指定技能包
|
|
55
|
+
pp skill up # upgrade 简写
|
|
53
56
|
```
|
|
54
57
|
|
|
55
58
|
### 工作区管理
|
|
56
59
|
|
|
57
60
|
```bash
|
|
58
|
-
pp workspace init
|
|
59
|
-
pp ws init
|
|
61
|
+
pp workspace init # 初始化 AI 工作区
|
|
62
|
+
pp ws init # 简写
|
|
60
63
|
```
|
|
61
64
|
|
|
62
65
|
---
|
|
@@ -79,8 +82,6 @@ your-repo/
|
|
|
79
82
|
│ ├── init.md # 初始化提示词
|
|
80
83
|
│ └── dev.md # 开发提示词
|
|
81
84
|
├── frontend_api/
|
|
82
|
-
│ ├── manifest.md
|
|
83
|
-
│ ├── context.md
|
|
84
85
|
│ └── ...
|
|
85
86
|
└── another_skill/
|
|
86
87
|
└── ...
|
|
@@ -114,43 +115,6 @@ your-repo/
|
|
|
114
115
|
- 约束 2
|
|
115
116
|
```
|
|
116
117
|
|
|
117
|
-
### context.md 格式
|
|
118
|
-
|
|
119
|
-
```markdown
|
|
120
|
-
# Project Context Configuration
|
|
121
|
-
|
|
122
|
-
> ⚠️ 此文件需要初始化
|
|
123
|
-
|
|
124
|
-
## Tech Stack
|
|
125
|
-
- **Framework**: <!-- 待填充 -->
|
|
126
|
-
- **ORM**: <!-- 待填充 -->
|
|
127
|
-
|
|
128
|
-
## Directory Mapping
|
|
129
|
-
- **Controller Path**: <!-- 待填充 -->
|
|
130
|
-
- **Service Path**: <!-- 待填充 -->
|
|
131
|
-
|
|
132
|
-
## Code Style
|
|
133
|
-
- **Naming Convention**: <!-- 待填充 -->
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### tools/init.md 格式
|
|
137
|
-
|
|
138
|
-
```markdown
|
|
139
|
-
# 技能名 - 初始化提示词
|
|
140
|
-
|
|
141
|
-
## 使用方法
|
|
142
|
-
复制以下内容发送给 AI
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
\`\`\`
|
|
147
|
-
请执行 xxx 技能初始化:
|
|
148
|
-
1. 扫描项目结构
|
|
149
|
-
2. 识别技术栈
|
|
150
|
-
3. 将结果写入 context.md
|
|
151
|
-
\`\`\`
|
|
152
|
-
```
|
|
153
|
-
|
|
154
118
|
---
|
|
155
119
|
|
|
156
120
|
## 安装后的项目结构
|
|
@@ -158,7 +122,7 @@ your-repo/
|
|
|
158
122
|
```
|
|
159
123
|
your-project/
|
|
160
124
|
├── .ai-workspace/
|
|
161
|
-
│ ├── RULES.md # AI
|
|
125
|
+
│ ├── RULES.md # AI 工作流规则(自动生成)
|
|
162
126
|
│ └── skills/
|
|
163
127
|
│ ├── backend_api/
|
|
164
128
|
│ │ ├── manifest.md
|
|
@@ -178,6 +142,29 @@ your-project/
|
|
|
178
142
|
3. **AI 扫描项目**:AI 会分析项目并填充 `context.md`
|
|
179
143
|
4. **开始开发**:将需求文档放入 `input/`,使用 `tools/dev.md` 的提示词
|
|
180
144
|
|
|
145
|
+
## 技能包升级
|
|
146
|
+
|
|
147
|
+
当仓库有更新时:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pp repo sync # 同步仓库(不影响已安装的技能包)
|
|
151
|
+
pp skill upgrade # 升级技能包(保留 context.md、input/、output/)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## 工作流闭环
|
|
155
|
+
|
|
156
|
+
backend_api 会输出前端对接文档,可直接用于 frontend_api:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
backend_api 开发完成
|
|
160
|
+
↓
|
|
161
|
+
输出 output/api-spec-[模块].md
|
|
162
|
+
↓
|
|
163
|
+
复制到 frontend_api/input/
|
|
164
|
+
↓
|
|
165
|
+
frontend_api 生成前端代码
|
|
166
|
+
```
|
|
167
|
+
|
|
181
168
|
## License
|
|
182
169
|
|
|
183
170
|
MIT
|
package/dist/cli.js
CHANGED
|
@@ -88,7 +88,13 @@ program
|
|
|
88
88
|
.addCommand(new commander_1.Command('installed')
|
|
89
89
|
.description('查看已安装的技能包')
|
|
90
90
|
.option('-o, --output <path>', '工作区路径', '.ai-workspace')
|
|
91
|
-
.action(commands_1.installedSkills))
|
|
91
|
+
.action(commands_1.installedSkills))
|
|
92
|
+
.addCommand(new commander_1.Command('upgrade')
|
|
93
|
+
.alias('up')
|
|
94
|
+
.description('升级技能包(保留 context.md、input/、output/)')
|
|
95
|
+
.argument('[skillName]', '技能包名称(不指定则交互式选择)')
|
|
96
|
+
.option('-o, --output <path>', '工作区路径', '.ai-workspace')
|
|
97
|
+
.action(commands_1.upgradeSkill));
|
|
92
98
|
// 工作区管理
|
|
93
99
|
program
|
|
94
100
|
.command('workspace')
|
package/dist/commands.d.ts
CHANGED
package/dist/commands.js
CHANGED
|
@@ -41,6 +41,7 @@ exports.listSkills = listSkills;
|
|
|
41
41
|
exports.installSkill = installSkill;
|
|
42
42
|
exports.initWorkspace = initWorkspace;
|
|
43
43
|
exports.installedSkills = installedSkills;
|
|
44
|
+
exports.upgradeSkill = upgradeSkill;
|
|
44
45
|
const fs = __importStar(require("fs"));
|
|
45
46
|
const path = __importStar(require("path"));
|
|
46
47
|
const child_process_1 = require("child_process");
|
|
@@ -413,3 +414,114 @@ async function installedSkills(options) {
|
|
|
413
414
|
}
|
|
414
415
|
console.log(chalk.gray(`\n📁 位置: ${skillsDir}\n`));
|
|
415
416
|
}
|
|
417
|
+
// 辅助函数:将目录内容复制到内存
|
|
418
|
+
function copyDirToMemory(dir) {
|
|
419
|
+
const files = new Map();
|
|
420
|
+
function readDir(currentDir, prefix = '') {
|
|
421
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
422
|
+
for (const entry of entries) {
|
|
423
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
424
|
+
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
425
|
+
if (entry.isDirectory()) {
|
|
426
|
+
readDir(fullPath, relativePath);
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
files.set(relativePath, fs.readFileSync(fullPath));
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
readDir(dir);
|
|
434
|
+
return files;
|
|
435
|
+
}
|
|
436
|
+
// 辅助函数:从内存恢复目录
|
|
437
|
+
function restoreDirFromMemory(dir, files) {
|
|
438
|
+
for (const [relativePath, content] of files) {
|
|
439
|
+
const fullPath = path.join(dir, relativePath);
|
|
440
|
+
const dirPath = path.dirname(fullPath);
|
|
441
|
+
if (!fs.existsSync(dirPath)) {
|
|
442
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
443
|
+
}
|
|
444
|
+
fs.writeFileSync(fullPath, content);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
// 升级技能包(保留 context.md、input/、output/)
|
|
448
|
+
async function upgradeSkill(skillName, options) {
|
|
449
|
+
const chalk = await getChalk();
|
|
450
|
+
const inquirer = await getInquirer();
|
|
451
|
+
const baseDir = options?.output || '.ai-workspace';
|
|
452
|
+
const localSkillsDir = path.join(process.cwd(), baseDir, 'skills');
|
|
453
|
+
if (!fs.existsSync(localSkillsDir)) {
|
|
454
|
+
console.log(chalk.yellow('\n⚠️ 未找到 AI 工作区'));
|
|
455
|
+
console.log(chalk.gray('使用 "pp workspace init" 初始化工作区\n'));
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
const localSkills = (0, skills_1.loadSkillsFromDir)(localSkillsDir);
|
|
459
|
+
if (localSkills.length === 0) {
|
|
460
|
+
console.log(chalk.yellow('\n⚠️ 未安装任何技能包\n'));
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
// 获取仓库中的技能包
|
|
464
|
+
const repoSkills = await getAllSkillsWithRepo();
|
|
465
|
+
let skillsToUpgrade = [];
|
|
466
|
+
if (skillName) {
|
|
467
|
+
// 指定技能名
|
|
468
|
+
if (!localSkills.find((s) => s.name === skillName)) {
|
|
469
|
+
console.log(chalk.red(`\n❌ 未安装技能包: ${skillName}\n`));
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
skillsToUpgrade = [skillName];
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
// 交互式选择
|
|
476
|
+
const choices = localSkills.map((s) => ({
|
|
477
|
+
name: s.name,
|
|
478
|
+
value: s.name,
|
|
479
|
+
checked: true,
|
|
480
|
+
}));
|
|
481
|
+
const answer = await inquirer.prompt([
|
|
482
|
+
{
|
|
483
|
+
type: 'checkbox',
|
|
484
|
+
name: 'skills',
|
|
485
|
+
message: '选择要升级的技能包:',
|
|
486
|
+
choices,
|
|
487
|
+
},
|
|
488
|
+
]);
|
|
489
|
+
skillsToUpgrade = answer.skills;
|
|
490
|
+
}
|
|
491
|
+
if (skillsToUpgrade.length === 0) {
|
|
492
|
+
console.log(chalk.yellow('\n⚠️ 未选择任何技能包\n'));
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
console.log(chalk.cyan('\n🔄 开始升级技能包...\n'));
|
|
496
|
+
for (const name of skillsToUpgrade) {
|
|
497
|
+
const repoSkill = repoSkills.find((s) => s.name === name);
|
|
498
|
+
if (!repoSkill) {
|
|
499
|
+
console.log(chalk.yellow(` ⚠️ ${name}: 仓库中未找到,跳过`));
|
|
500
|
+
continue;
|
|
501
|
+
}
|
|
502
|
+
const localDir = path.join(localSkillsDir, name);
|
|
503
|
+
// 备份需要保留的文件
|
|
504
|
+
const contextPath = path.join(localDir, 'context.md');
|
|
505
|
+
const inputDir = path.join(localDir, 'input');
|
|
506
|
+
const outputDir = path.join(localDir, 'output');
|
|
507
|
+
const contextBackup = fs.existsSync(contextPath) ? fs.readFileSync(contextPath, 'utf-8') : null;
|
|
508
|
+
const inputBackup = fs.existsSync(inputDir) ? copyDirToMemory(inputDir) : null;
|
|
509
|
+
const outputBackup = fs.existsSync(outputDir) ? copyDirToMemory(outputDir) : null;
|
|
510
|
+
// 删除旧技能包
|
|
511
|
+
fs.rmSync(localDir, { recursive: true, force: true });
|
|
512
|
+
// 复制新技能包
|
|
513
|
+
(0, skills_1.copySkill)(repoSkill.path, localDir);
|
|
514
|
+
// 恢复备份
|
|
515
|
+
if (contextBackup) {
|
|
516
|
+
fs.writeFileSync(contextPath, contextBackup, 'utf-8');
|
|
517
|
+
}
|
|
518
|
+
if (inputBackup) {
|
|
519
|
+
restoreDirFromMemory(inputDir, inputBackup);
|
|
520
|
+
}
|
|
521
|
+
if (outputBackup) {
|
|
522
|
+
restoreDirFromMemory(outputDir, outputBackup);
|
|
523
|
+
}
|
|
524
|
+
console.log(chalk.green(` ✅ ${name}: 已升级(保留 context.md、input/、output/)`));
|
|
525
|
+
}
|
|
526
|
+
console.log(chalk.gray('\n升级完成!\n'));
|
|
527
|
+
}
|