prompt-plus 1.1.0 → 1.1.2

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 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
 
@@ -14,7 +14,7 @@ npm install -g prompt-plus
14
14
 
15
15
  ```bash
16
16
  # 1. 添加技能包仓库
17
- pp repo add official https://github.com/your-repo/skills.git
17
+ pp repo add official https://github.com/LeeSeaside/prompt-plus-templates.git
18
18
 
19
19
  # 2. 同步仓库
20
20
  pp repo sync
@@ -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 # 初始化 AI 工作区
59
- pp ws init # 简写
61
+ pp workspace init # 初始化 AI 工作区
62
+ pp ws init # 简写
60
63
  ```
61
64
 
62
65
  ---
@@ -66,7 +69,7 @@ pp ws init # 简写
66
69
  如果你想创建自己的技能包仓库,请按以下格式组织:
67
70
 
68
71
  ```
69
- your-repo/
72
+ prompt-plus-templates/
70
73
  └── skills/
71
74
  ├── backend_api/
72
75
  │ ├── manifest.md # 执行流程和规范(必需)
@@ -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,14 @@ 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)')
95
+ .argument('[skillName]', '技能包名称(不指定则交互式选择)')
96
+ .option('-o, --output <path>', '工作区路径', '.ai-workspace')
97
+ .option('-m, --mode <mode>', 'context.md 处理策略: merge(智能合并) | keep(保留本地) | overwrite(使用仓库)')
98
+ .action(commands_1.upgradeSkill));
92
99
  // 工作区管理
93
100
  program
94
101
  .command('workspace')
@@ -17,3 +17,7 @@ export declare function initWorkspace(options?: {
17
17
  export declare function installedSkills(options?: {
18
18
  output?: string;
19
19
  }): Promise<void>;
20
+ export declare function upgradeSkill(skillName?: string, options?: {
21
+ output?: string;
22
+ mode?: string;
23
+ }): Promise<void>;
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");
@@ -116,7 +117,7 @@ async function listRepos() {
116
117
  console.log(chalk.cyan('\n📦 技能包仓库列表:\n'));
117
118
  if (config.repos.length === 0) {
118
119
  console.log(chalk.gray(' 暂无仓库,请先添加:'));
119
- console.log(chalk.gray(' pp repo add official https://github.com/your-repo/skills.git\n'));
120
+ console.log(chalk.gray(' pp repo add official https://github.com/LeeSeaside/prompt-plus-templates.git\n'));
120
121
  return;
121
122
  }
122
123
  for (const repo of config.repos) {
@@ -413,3 +414,178 @@ 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:保留用户填充的值,更新模板结构
448
+ function mergeContextMd(localContent, repoContent) {
449
+ // 提取本地已填充的值(非注释、非占位符的内容)
450
+ const userValues = new Map();
451
+ // 匹配 "- **Key**: Value" 或 "- Key: Value" 格式
452
+ const valuePattern = /^[-*]\s*\*?\*?([^:*]+)\*?\*?:\s*(.+)$/gm;
453
+ let match;
454
+ while ((match = valuePattern.exec(localContent)) !== null) {
455
+ const key = match[1].trim();
456
+ const value = match[2].trim();
457
+ // 跳过占位符和注释
458
+ if (value && !value.startsWith('<!--') && !value.includes('待填充') && !value.includes('⚠️')) {
459
+ userValues.set(key.toLowerCase(), value);
460
+ }
461
+ }
462
+ // 在新模板中填充用户值
463
+ let merged = repoContent;
464
+ for (const [key, value] of userValues) {
465
+ // 替换占位符
466
+ const placeholderPattern = new RegExp(`([-*]\\s*\\*?\\*?${key}\\*?\\*?:\\s*)<!--[^>]*-->`, 'gi');
467
+ merged = merged.replace(placeholderPattern, `$1${value}`);
468
+ }
469
+ return merged;
470
+ }
471
+ // 升级技能包
472
+ async function upgradeSkill(skillName, options) {
473
+ const chalk = await getChalk();
474
+ const inquirer = await getInquirer();
475
+ const baseDir = options?.output || '.ai-workspace';
476
+ const localSkillsDir = path.join(process.cwd(), baseDir, 'skills');
477
+ if (!fs.existsSync(localSkillsDir)) {
478
+ console.log(chalk.yellow('\n⚠️ 未找到 AI 工作区'));
479
+ console.log(chalk.gray('使用 "pp workspace init" 初始化工作区\n'));
480
+ return;
481
+ }
482
+ const localSkills = (0, skills_1.loadSkillsFromDir)(localSkillsDir);
483
+ if (localSkills.length === 0) {
484
+ console.log(chalk.yellow('\n⚠️ 未安装任何技能包\n'));
485
+ return;
486
+ }
487
+ // 获取仓库中的技能包
488
+ const repoSkills = await getAllSkillsWithRepo();
489
+ let skillsToUpgrade = [];
490
+ if (skillName) {
491
+ if (!localSkills.find((s) => s.name === skillName)) {
492
+ console.log(chalk.red(`\n❌ 未安装技能包: ${skillName}\n`));
493
+ return;
494
+ }
495
+ skillsToUpgrade = [skillName];
496
+ }
497
+ else {
498
+ const choices = localSkills.map((s) => ({
499
+ name: s.name,
500
+ value: s.name,
501
+ checked: true,
502
+ }));
503
+ const answer = await inquirer.prompt([
504
+ {
505
+ type: 'checkbox',
506
+ name: 'skills',
507
+ message: '选择要升级的技能包:',
508
+ choices,
509
+ },
510
+ ]);
511
+ skillsToUpgrade = answer.skills;
512
+ }
513
+ if (skillsToUpgrade.length === 0) {
514
+ console.log(chalk.yellow('\n⚠️ 未选择任何技能包\n'));
515
+ return;
516
+ }
517
+ // 选择 context.md 处理策略
518
+ let contextMode = options?.mode;
519
+ if (!contextMode) {
520
+ const modeAnswer = await inquirer.prompt([
521
+ {
522
+ type: 'list',
523
+ name: 'mode',
524
+ message: 'context.md 处理策略:',
525
+ choices: [
526
+ { name: '智能合并 - 保留用户数据,更新模板结构(推荐)', value: 'merge' },
527
+ { name: '保留本地 - 完全保留本地 context.md', value: 'keep' },
528
+ { name: '使用仓库 - 使用仓库最新版本(会丢失已填充数据)', value: 'overwrite' },
529
+ ],
530
+ default: 'merge',
531
+ },
532
+ ]);
533
+ contextMode = modeAnswer.mode;
534
+ }
535
+ console.log(chalk.cyan('\n🔄 开始升级技能包...\n'));
536
+ for (const name of skillsToUpgrade) {
537
+ const repoSkill = repoSkills.find((s) => s.name === name);
538
+ if (!repoSkill) {
539
+ console.log(chalk.yellow(` ⚠️ ${name}: 仓库中未找到,跳过`));
540
+ continue;
541
+ }
542
+ const localDir = path.join(localSkillsDir, name);
543
+ const contextPath = path.join(localDir, 'context.md');
544
+ const inputDir = path.join(localDir, 'input');
545
+ const outputDir = path.join(localDir, 'output');
546
+ // 备份
547
+ const localContext = fs.existsSync(contextPath) ? fs.readFileSync(contextPath, 'utf-8') : null;
548
+ const inputBackup = fs.existsSync(inputDir) ? copyDirToMemory(inputDir) : null;
549
+ const outputBackup = fs.existsSync(outputDir) ? copyDirToMemory(outputDir) : null;
550
+ // 删除旧技能包
551
+ fs.rmSync(localDir, { recursive: true, force: true });
552
+ // 复制新技能包
553
+ (0, skills_1.copySkill)(repoSkill.path, localDir);
554
+ // 处理 context.md
555
+ const repoContextPath = path.join(repoSkill.path, 'context.md');
556
+ const repoContext = fs.existsSync(repoContextPath) ? fs.readFileSync(repoContextPath, 'utf-8') : null;
557
+ if (localContext && repoContext) {
558
+ let finalContext;
559
+ switch (contextMode) {
560
+ case 'keep':
561
+ finalContext = localContext;
562
+ break;
563
+ case 'overwrite':
564
+ finalContext = repoContext;
565
+ break;
566
+ case 'merge':
567
+ default:
568
+ finalContext = mergeContextMd(localContext, repoContext);
569
+ break;
570
+ }
571
+ fs.writeFileSync(contextPath, finalContext, 'utf-8');
572
+ }
573
+ else if (localContext) {
574
+ fs.writeFileSync(contextPath, localContext, 'utf-8');
575
+ }
576
+ // 恢复 input 和 output
577
+ if (inputBackup) {
578
+ restoreDirFromMemory(inputDir, inputBackup);
579
+ }
580
+ if (outputBackup) {
581
+ restoreDirFromMemory(outputDir, outputBackup);
582
+ }
583
+ const modeLabel = contextMode === 'merge' ? '智能合并' : contextMode === 'keep' ? '保留本地' : '使用仓库';
584
+ console.log(chalk.green(` ✅ ${name}: 已升级(context.md: ${modeLabel})`));
585
+ }
586
+ console.log(chalk.gray('\n升级完成!\n'));
587
+ if (contextMode === 'merge') {
588
+ console.log(chalk.cyan('💡 提示: 智能合并已尝试保留您的配置数据。'));
589
+ console.log(chalk.gray(' 如果仓库新增了配置项,请检查 context.md 并补充填写。\n'));
590
+ }
591
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prompt-plus",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "AI技能包管理工具 - 基于技能包驱动的 AI 开发工作流",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",