prompt-plus 1.1.1 → 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
@@ -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
@@ -69,7 +69,7 @@ pp ws init # 简写
69
69
  如果你想创建自己的技能包仓库,请按以下格式组织:
70
70
 
71
71
  ```
72
- your-repo/
72
+ prompt-plus-templates/
73
73
  └── skills/
74
74
  ├── backend_api/
75
75
  │ ├── manifest.md # 执行流程和规范(必需)
package/dist/cli.js CHANGED
@@ -91,9 +91,10 @@ program
91
91
  .action(commands_1.installedSkills))
92
92
  .addCommand(new commander_1.Command('upgrade')
93
93
  .alias('up')
94
- .description('升级技能包(保留 context.md、input/、output/)')
94
+ .description('升级技能包(智能合并 context.md')
95
95
  .argument('[skillName]', '技能包名称(不指定则交互式选择)')
96
96
  .option('-o, --output <path>', '工作区路径', '.ai-workspace')
97
+ .option('-m, --mode <mode>', 'context.md 处理策略: merge(智能合并) | keep(保留本地) | overwrite(使用仓库)')
97
98
  .action(commands_1.upgradeSkill));
98
99
  // 工作区管理
99
100
  program
@@ -19,4 +19,5 @@ export declare function installedSkills(options?: {
19
19
  }): Promise<void>;
20
20
  export declare function upgradeSkill(skillName?: string, options?: {
21
21
  output?: string;
22
+ mode?: string;
22
23
  }): Promise<void>;
package/dist/commands.js CHANGED
@@ -117,7 +117,7 @@ async function listRepos() {
117
117
  console.log(chalk.cyan('\n📦 技能包仓库列表:\n'));
118
118
  if (config.repos.length === 0) {
119
119
  console.log(chalk.gray(' 暂无仓库,请先添加:'));
120
- 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'));
121
121
  return;
122
122
  }
123
123
  for (const repo of config.repos) {
@@ -444,7 +444,31 @@ function restoreDirFromMemory(dir, files) {
444
444
  fs.writeFileSync(fullPath, content);
445
445
  }
446
446
  }
447
- // 升级技能包(保留 context.md、input/、output/)
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
+ // 升级技能包
448
472
  async function upgradeSkill(skillName, options) {
449
473
  const chalk = await getChalk();
450
474
  const inquirer = await getInquirer();
@@ -464,7 +488,6 @@ async function upgradeSkill(skillName, options) {
464
488
  const repoSkills = await getAllSkillsWithRepo();
465
489
  let skillsToUpgrade = [];
466
490
  if (skillName) {
467
- // 指定技能名
468
491
  if (!localSkills.find((s) => s.name === skillName)) {
469
492
  console.log(chalk.red(`\n❌ 未安装技能包: ${skillName}\n`));
470
493
  return;
@@ -472,7 +495,6 @@ async function upgradeSkill(skillName, options) {
472
495
  skillsToUpgrade = [skillName];
473
496
  }
474
497
  else {
475
- // 交互式选择
476
498
  const choices = localSkills.map((s) => ({
477
499
  name: s.name,
478
500
  value: s.name,
@@ -492,6 +514,24 @@ async function upgradeSkill(skillName, options) {
492
514
  console.log(chalk.yellow('\n⚠️ 未选择任何技能包\n'));
493
515
  return;
494
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
+ }
495
535
  console.log(chalk.cyan('\n🔄 开始升级技能包...\n'));
496
536
  for (const name of skillsToUpgrade) {
497
537
  const repoSkill = repoSkills.find((s) => s.name === name);
@@ -500,28 +540,52 @@ async function upgradeSkill(skillName, options) {
500
540
  continue;
501
541
  }
502
542
  const localDir = path.join(localSkillsDir, name);
503
- // 备份需要保留的文件
504
543
  const contextPath = path.join(localDir, 'context.md');
505
544
  const inputDir = path.join(localDir, 'input');
506
545
  const outputDir = path.join(localDir, 'output');
507
- const contextBackup = fs.existsSync(contextPath) ? fs.readFileSync(contextPath, 'utf-8') : null;
546
+ // 备份
547
+ const localContext = fs.existsSync(contextPath) ? fs.readFileSync(contextPath, 'utf-8') : null;
508
548
  const inputBackup = fs.existsSync(inputDir) ? copyDirToMemory(inputDir) : null;
509
549
  const outputBackup = fs.existsSync(outputDir) ? copyDirToMemory(outputDir) : null;
510
550
  // 删除旧技能包
511
551
  fs.rmSync(localDir, { recursive: true, force: true });
512
552
  // 复制新技能包
513
553
  (0, skills_1.copySkill)(repoSkill.path, localDir);
514
- // 恢复备份
515
- if (contextBackup) {
516
- fs.writeFileSync(contextPath, contextBackup, 'utf-8');
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');
517
575
  }
576
+ // 恢复 input 和 output
518
577
  if (inputBackup) {
519
578
  restoreDirFromMemory(inputDir, inputBackup);
520
579
  }
521
580
  if (outputBackup) {
522
581
  restoreDirFromMemory(outputDir, outputBackup);
523
582
  }
524
- console.log(chalk.green(` ✅ ${name}: 已升级(保留 context.md、input/、output/)`));
583
+ const modeLabel = contextMode === 'merge' ? '智能合并' : contextMode === 'keep' ? '保留本地' : '使用仓库';
584
+ console.log(chalk.green(` ✅ ${name}: 已升级(context.md: ${modeLabel})`));
525
585
  }
526
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
+ }
527
591
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prompt-plus",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "AI技能包管理工具 - 基于技能包驱动的 AI 开发工作流",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",