prizmkit 1.1.19 → 1.1.20

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "frameworkVersion": "1.1.19",
3
- "bundledAt": "2026-04-11T01:16:59.208Z",
4
- "bundledFrom": "fff3866"
2
+ "frameworkVersion": "1.1.20",
3
+ "bundledAt": "2026-04-11T05:49:50.851Z",
4
+ "bundledFrom": "13e5e58"
5
5
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.19",
2
+ "version": "1.1.20",
3
3
  "skills": {
4
4
  "prizm-kit": {
5
5
  "description": "Full-lifecycle dev toolkit. Covers spec-driven development, Prizm context docs, code quality, debugging, deployment, and knowledge management.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.1.19",
3
+ "version": "1.1.20",
4
4
  "description": "Create a new PrizmKit-powered project with clean initialization — no framework dev files, just what you need.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/config.js CHANGED
@@ -79,6 +79,65 @@ function expandPlatforms(platform) {
79
79
  return platform === 'both' ? ['codebuddy', 'claude'] : [platform];
80
80
  }
81
81
 
82
+ function getProjectMemoryFile(platform) {
83
+ if (platform === 'claude') return 'CLAUDE.md';
84
+ if (platform === 'codebuddy') return 'CODEBUDDY.md';
85
+ return null;
86
+ }
87
+
88
+ function getCounterpartPlatform(platform) {
89
+ return platform === 'claude' ? 'codebuddy' : platform === 'codebuddy' ? 'claude' : null;
90
+ }
91
+
92
+ async function migrateProjectMemoryOnPlatformDrop(droppedPlatform, newPlatforms, projectRoot, dryRun) {
93
+ const sourceFile = getProjectMemoryFile(droppedPlatform);
94
+ if (!sourceFile) return;
95
+
96
+ const sourcePath = path.join(projectRoot, sourceFile);
97
+ if (!await fs.pathExists(sourcePath)) return;
98
+
99
+ const counterpart = getCounterpartPlatform(droppedPlatform);
100
+ const targetPlatform = (counterpart && newPlatforms.includes(counterpart))
101
+ ? counterpart
102
+ : newPlatforms.find(p => p !== droppedPlatform);
103
+
104
+ if (!targetPlatform || targetPlatform === droppedPlatform) return;
105
+
106
+ const targetFile = getProjectMemoryFile(targetPlatform);
107
+ if (!targetFile || targetFile === sourceFile) return;
108
+
109
+ const targetPath = path.join(projectRoot, targetFile);
110
+
111
+ if (dryRun) {
112
+ console.log(chalk.gray(` [dry-run] migrate ${sourceFile} -> ${targetFile}`));
113
+ return;
114
+ }
115
+
116
+ const sourceContent = await fs.readFile(sourcePath, 'utf-8');
117
+ if (!sourceContent.trim()) return;
118
+
119
+ if (!await fs.pathExists(targetPath)) {
120
+ const normalized = sourceContent.endsWith('\n') ? sourceContent : `${sourceContent}\n`;
121
+ await fs.writeFile(targetPath, normalized, 'utf-8');
122
+ console.log(chalk.green(` ✓ migrated ${sourceFile} -> ${targetFile}`));
123
+ return;
124
+ }
125
+
126
+ const targetContent = await fs.readFile(targetPath, 'utf-8');
127
+ const normalizedSource = sourceContent.replace(/\r\n/g, '\n').trim();
128
+ const normalizedTarget = targetContent.replace(/\r\n/g, '\n').trim();
129
+
130
+ if (!normalizedSource || normalizedTarget.includes(normalizedSource)) {
131
+ console.log(chalk.gray(` • ${targetFile} already contains ${sourceFile} content, skip merge`));
132
+ return;
133
+ }
134
+
135
+ const separator = targetContent.endsWith('\n') ? '\n' : '\n\n';
136
+ const merged = `${targetContent}${separator}<!-- MIGRATED FROM ${sourceFile} via prizmkit config -->\n\n${sourceContent.trimEnd()}\n`;
137
+ await fs.writeFile(targetPath, merged, 'utf-8');
138
+ console.log(chalk.green(` ✓ merged ${sourceFile} content into ${targetFile}`));
139
+ }
140
+
82
141
  const platformLabel = (p) => p === 'both' ? 'CodeBuddy + Claude Code'
83
142
  : p === 'codebuddy' ? 'CodeBuddy' : 'Claude Code';
84
143
 
@@ -364,13 +423,18 @@ export async function runConfig(directory, options = {}) {
364
423
  const newRuleFiles = (rulesPresetDef?.rules || []).map(name => `${name}.md`);
365
424
  const newPipelineFiles = newConfig.pipeline ? resolvePipelineFileList() : [];
366
425
 
367
- // 5a. Remove files for platforms being dropped
426
+ // 5a. Migrate project memory before removing dropped platforms
427
+ for (const p of platformsToRemove) {
428
+ await migrateProjectMemoryOnPlatformDrop(p, newPlatforms, projectRoot, false);
429
+ }
430
+
431
+ // 5b. Remove files for platforms being dropped
368
432
  for (const p of platformsToRemove) {
369
433
  console.log(chalk.bold(` 移除 ${platformLabel(p)} 平台文件...`));
370
434
  await removePlatformFiles(p, projectRoot, oldManifest, false);
371
435
  }
372
436
 
373
- // 5b. Handle skill/rule diff for existing platforms (suite or rules changed)
437
+ // 5c. Handle skill/rule diff for existing platforms (suite or rules changed)
374
438
  if (newConfig.suite !== currentConfig.suite || newConfig.rules !== currentConfig.rules) {
375
439
  const newTempManifest = buildManifest({
376
440
  version: pkg.version, platform: newConfig.platform, suite: newConfig.suite,
@@ -393,7 +457,7 @@ export async function runConfig(directory, options = {}) {
393
457
  }
394
458
  }
395
459
 
396
- // 5c. Install/update files for new + existing platforms
460
+ // 5d. Install/update files for new + existing platforms
397
461
  const allTargetPlatforms = [...platformsToAdd, ...platformsToUpdate];
398
462
  const needsReinstall = newConfig.platform !== currentConfig.platform
399
463
  || newConfig.suite !== currentConfig.suite
@@ -427,7 +491,7 @@ export async function runConfig(directory, options = {}) {
427
491
  }
428
492
  }
429
493
 
430
- // 5d. Pipeline changes
494
+ // 5e. Pipeline changes
431
495
  if (newConfig.pipeline !== currentConfig.pipeline) {
432
496
  if (newConfig.pipeline) {
433
497
  console.log(chalk.blue('\n 安装 Pipeline:'));
@@ -441,11 +505,11 @@ export async function runConfig(directory, options = {}) {
441
505
  }
442
506
  }
443
507
 
444
- // 5e. Update .gitignore
508
+ // 5f. Update .gitignore
445
509
  console.log(chalk.blue('\n Gitignore:'));
446
510
  await installGitignore(projectRoot, { pipeline: newConfig.pipeline }, false);
447
511
 
448
- // 5f. Update .prizmkit/config.json (ai_cli)
512
+ // 5g. Update .prizmkit/config.json (ai_cli)
449
513
  if (newConfig.aiCli !== currentConfig.aiCli) {
450
514
  const prizmkitDir = path.join(projectRoot, '.prizmkit');
451
515
  await fs.ensureDir(prizmkitDir);
@@ -462,7 +526,7 @@ export async function runConfig(directory, options = {}) {
462
526
  console.log(chalk.green(`\n ✓ .prizmkit/config.json (ai_cli: ${newConfig.aiCli || '(cleared)'})`));
463
527
  }
464
528
 
465
- // 5g. Write new manifest
529
+ // 5h. Write new manifest
466
530
  const newManifest = buildManifest({
467
531
  version: pkg.version,
468
532
  platform: newConfig.platform,