prizmkit 1.0.112 → 1.0.114

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.0.112",
3
- "bundledAt": "2026-03-26T06:44:08.682Z",
4
- "bundledFrom": "a59fa27"
2
+ "frameworkVersion": "1.0.114",
3
+ "bundledAt": "2026-03-26T08:00:15.434Z",
4
+ "bundledFrom": "896bf87"
5
5
  }
@@ -341,17 +341,9 @@ def action_get_next(feature_list_data, state_dir, feature_filter=None):
341
341
  print("PIPELINE_COMPLETE")
342
342
  return
343
343
 
344
- # Apply feature filter: only consider features in the whitelist
345
- if feature_filter is not None:
346
- features = [
347
- f for f in features
348
- if isinstance(f, dict) and f.get("id") in feature_filter
349
- ]
350
- if not features:
351
- print("PIPELINE_COMPLETE")
352
- return
353
-
354
- # Build a map of feature statuses from state dir
344
+ # Build status map from ALL features (for dependency checking).
345
+ # This must happen BEFORE the feature filter is applied, because
346
+ # filtered features may depend on features outside the filter.
355
347
  status_map = {} # feature_id -> status string
356
348
  status_data_map = {} # feature_id -> full status data
357
349
  for feature in features:
@@ -364,6 +356,17 @@ def action_get_next(feature_list_data, state_dir, feature_filter=None):
364
356
  status_map[fid] = fs.get("status", "pending")
365
357
  status_data_map[fid] = fs
366
358
 
359
+ # Apply feature filter: only consider these features as candidates
360
+ # for execution, but dependency checking still uses the full status_map
361
+ if feature_filter is not None:
362
+ features = [
363
+ f for f in features
364
+ if isinstance(f, dict) and f.get("id") in feature_filter
365
+ ]
366
+ if not features:
367
+ print("PIPELINE_COMPLETE")
368
+ return
369
+
367
370
  # Check if all features are in terminal state
368
371
  non_terminal = [
369
372
  f for f in features
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.112",
2
+ "version": "1.0.114",
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.",
@@ -1,3 +1,4 @@
1
+ <!-- PRIZMKIT:START — managed by PrizmKit, do not edit manually -->
1
2
  ## PrizmKit Documentation Framework
2
3
 
3
4
  This project uses PrizmKit with the Prizm documentation system for AI-optimized progressive context loading.
@@ -36,3 +37,4 @@ Not every change needs the full spec -> plan workflow. Use fast path for:
36
37
 
37
38
  Use the full workflow (/prizmkit-specify -> /prizmkit-plan -> /prizmkit-analyze -> /prizmkit-implement) for:
38
39
  - New features, multi-file coordinated changes, architectural decisions, data model or API changes
40
+ <!-- PRIZMKIT:END -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.0.112",
3
+ "version": "1.0.114",
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/scaffold.js CHANGED
@@ -502,10 +502,16 @@ export async function installPrizmkitScripts(projectRoot, dryRun) {
502
502
  }
503
503
  }
504
504
 
505
+ const PRIZMKIT_MARKER_START = '<!-- PRIZMKIT:START';
506
+ const PRIZMKIT_MARKER_END = '<!-- PRIZMKIT:END -->';
507
+
505
508
  /**
506
- * 安装项目记忆文件(CODEBUDDY.md / CLAUDE.md
509
+ * Merge PrizmKit template content into a project memory file (CLAUDE.md / CODEBUDDY.md).
510
+ * - File missing → create with template content
511
+ * - File exists with markers → replace content between markers
512
+ * - File exists without markers → append template content
507
513
  */
508
- async function installProjectMemory(platform, projectRoot, dryRun) {
514
+ export async function installProjectMemory(platform, projectRoot, dryRun) {
509
515
  const templatesDir = getTemplatesDir();
510
516
  const skillsDir = getSkillsDir();
511
517
  const templateName = 'project-memory-template.md';
@@ -520,21 +526,42 @@ async function installProjectMemory(platform, projectRoot, dryRun) {
520
526
  ];
521
527
  const templatePath = templateCandidates.find(candidate => fs.pathExistsSync(candidate));
522
528
 
523
- if (await fs.pathExists(targetPath)) {
524
- console.log(chalk.yellow(` ⚠ ${targetName} 已存在,跳过`));
529
+ if (!templatePath || !await fs.pathExists(templatePath)) {
530
+ console.log(chalk.yellow(` ⚠ 模板文件不存在: ${templateName},跳过`));
525
531
  return;
526
532
  }
527
533
 
534
+ const templateContent = (await fs.readFile(templatePath, 'utf-8')).trimEnd();
535
+
528
536
  if (dryRun) {
529
537
  console.log(chalk.gray(` [dry-run] ${targetName}`));
530
538
  return;
531
539
  }
532
540
 
533
- if (templatePath && await fs.pathExists(templatePath)) {
534
- await fs.copy(templatePath, targetPath);
535
- console.log(chalk.green(` ✓ ${targetName}`));
541
+ if (!await fs.pathExists(targetPath)) {
542
+ // File doesn't exist — create with template content
543
+ await fs.writeFile(targetPath, templateContent + '\n', 'utf-8');
544
+ console.log(chalk.green(` ✓ ${targetName} (created)`));
545
+ return;
546
+ }
547
+
548
+ // File exists — merge via markers
549
+ const existing = await fs.readFile(targetPath, 'utf-8');
550
+ const startIdx = existing.indexOf(PRIZMKIT_MARKER_START);
551
+ const endIdx = existing.indexOf(PRIZMKIT_MARKER_END);
552
+
553
+ if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
554
+ // Replace content between markers (inclusive)
555
+ const before = existing.substring(0, startIdx);
556
+ const after = existing.substring(endIdx + PRIZMKIT_MARKER_END.length);
557
+ const merged = before + templateContent + after;
558
+ await fs.writeFile(targetPath, merged, 'utf-8');
559
+ console.log(chalk.green(` ✓ ${targetName} (updated PrizmKit section)`));
536
560
  } else {
537
- console.log(chalk.yellow(` ⚠ 模板文件不存在: ${templateName},跳过`));
561
+ // No markers found — append template content
562
+ const separator = existing.endsWith('\n') ? '\n' : '\n\n';
563
+ await fs.writeFile(targetPath, existing + separator + templateContent + '\n', 'utf-8');
564
+ console.log(chalk.green(` ✓ ${targetName} (appended PrizmKit section)`));
538
565
  }
539
566
  }
540
567
 
package/src/upgrade.js CHANGED
@@ -28,6 +28,7 @@ import {
28
28
  installPrizmkitScripts,
29
29
  installGitHook,
30
30
  installGitignore,
31
+ installProjectMemory,
31
32
  resolvePipelineFileList,
32
33
  } from './scaffold.js';
33
34
 
@@ -371,20 +372,9 @@ export async function runUpgrade(directory, options = {}) {
371
372
  console.log(chalk.blue(' PrizmKit Scripts:'));
372
373
  await installPrizmkitScripts(projectRoot, dryRun);
373
374
 
374
- // 7c. Project memory — skip unless --force
375
- if (force) {
376
- console.log(chalk.blue('\n Project Memory (forced):'));
377
- const memoryFile = platform === 'claude' ? 'CLAUDE.md' : 'CODEBUDDY.md';
378
- console.log(chalk.yellow(` ⚠ --force: ${memoryFile} will be overwritten if template exists`));
379
- // Force overwrite by removing first, then let scaffold write fresh
380
- const memoryPath = path.join(projectRoot, memoryFile);
381
- if (!dryRun && await fs.pathExists(memoryPath)) {
382
- await fs.remove(memoryPath);
383
- }
384
- // installProjectMemory is not exported, but the template logic is in scaffold
385
- // For force mode, we just warn; the file was already there from initial install
386
- console.log(chalk.gray(` (project memory files are user-customizable, skipped by default)`));
387
- }
375
+ // 7c. Project memory — smart merge via markers
376
+ console.log(chalk.blue('\n Project Memory:'));
377
+ await installProjectMemory(platform, projectRoot, dryRun);
388
378
 
389
379
  // 8. Write new manifest
390
380
  if (!dryRun) {