@garyr/pt-cli 0.40.0 → 0.40.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.
@@ -363,9 +363,11 @@ export async function update(sourcePath, templateName, options = {}) {
363
363
  let selectedStructure = [];
364
364
  if (!isFullMode) {
365
365
  // Additive mode for files and folders
366
- // Start with existing files and folders, preserving their substitute_variables settings
366
+ // Start with existing copy_files entries as the base (preserves all settings including substitute_variables)
367
367
  const existingCopyFiles = config.templates[templateName].copy_files || [];
368
- selectedFiles = existingCopyFiles.map(f => f.src);
368
+ // selectedFiles here is only used to track new file names to append
369
+ let newSelectedFiles = [];
370
+ let newSelectedFolderDirs = [];
369
371
  const fileDiff = getNewFiles(config.templates[templateName], resolvedPath);
370
372
  if (fileDiff.newFiles.length > 0) {
371
373
  console.log(chalk.cyan(`\nšŸ“Š New Files:`));
@@ -388,38 +390,38 @@ export async function update(sourcePath, templateName, options = {}) {
388
390
  checked: true // Auto-select by default
389
391
  }))
390
392
  });
391
- // Only add selected files
392
- selectedFiles.push(...fileDiff.newFiles.filter(f => selectedFileChoices.includes(f)));
393
+ newSelectedFiles = fileDiff.newFiles.filter(f => selectedFileChoices.includes(f));
393
394
  }
394
395
  else {
395
396
  // In --yes or --json mode, auto-add all
396
- selectedFiles.push(...fileDiff.newFiles);
397
+ newSelectedFiles = [...fileDiff.newFiles];
397
398
  }
398
399
  }
399
400
  else {
400
401
  console.log(chalk.cyan("No new files detected"));
401
402
  }
402
403
  // For folders, use additive mode logic
403
- // Always preserve existing folders first
404
+ // Preserve existing folder structure
404
405
  selectedStructure = config.templates[templateName].folders?.map(f => f.name) || [];
405
- selectedFolders = selectedStructure.filter(d => ['APP', 'scripts', 'bin'].some(p => d === p));
406
+ // Seed selectedFolders from existing copy_files directory entries (not a hardcoded list)
407
+ selectedFolders = existingCopyFiles
408
+ .filter(f => rootDirs.includes(f.src))
409
+ .map(f => f.src);
406
410
  if (rootDirs.length > 0) {
407
411
  const structureDiff = getNewFolders(config.templates[templateName].folders, resolvedPath, ignorePatterns);
408
412
  if (structureDiff.added.length > 0) {
409
413
  // Auto-select added folders for structure
410
414
  selectedStructure = [...new Set([...selectedStructure, ...structureDiff.added.map(f => f.name)])];
411
- // Auto-select for recursive copy if they're in the standard list
412
- selectedFolders = selectedStructure.filter(d => ['APP', 'scripts', 'bin'].some(p => d === p));
413
- }
414
- else {
415
- // Keep existing folders
416
- selectedFolders = selectedStructure.filter(d => ['APP', 'scripts', 'bin'].some(p => d === p));
415
+ // For new dirs, auto-select for recursive copy if they match the standard list
416
+ newSelectedFolderDirs = structureDiff.added
417
+ .filter(f => ['APP', 'scripts', 'bin'].some(p => f.name === p))
418
+ .map(f => f.name);
417
419
  }
418
420
  }
419
- else {
420
- // Keep existing folders
421
- selectedFolders = selectedStructure.filter(d => ['APP', 'scripts', 'bin'].some(p => d === p));
422
- }
421
+ // Merge: existing folder copy_files + newly selected dirs
422
+ selectedFolders = [...new Set([...selectedFolders, ...newSelectedFolderDirs])];
423
+ // Also carry forward file names for use in copy_files construction below
424
+ selectedFiles = [...existingCopyFiles.filter(f => !rootDirs.includes(f.src)).map(f => f.src), ...newSelectedFiles];
423
425
  }
424
426
  else {
425
427
  // Full mode: original behavior
@@ -502,34 +504,33 @@ export async function update(sourcePath, templateName, options = {}) {
502
504
  if (fileTemplateConfig.copy_files && Array.isArray(fileTemplateConfig.copy_files)) {
503
505
  copy_files.push(...fileTemplateConfig.copy_files);
504
506
  }
505
- else {
507
+ else if (!isFullMode) {
508
+ // Additive mode: start directly from the existing copy_files to preserve all settings,
509
+ // then append only brand-new entries (never rebuild from scratch).
506
510
  const existingCopyFiles = config.templates[templateName].copy_files || [];
507
- const existingMap = new Map();
508
- for (const entry of existingCopyFiles) {
509
- existingMap.set(entry.src, entry);
511
+ const existingSrcs = new Set(existingCopyFiles.map(e => e.src));
512
+ // Begin with all existing entries untouched
513
+ copy_files.push(...existingCopyFiles);
514
+ // Append new files that were selected by the user
515
+ for (const f of selectedFiles) {
516
+ if (existingSrcs.has(f))
517
+ continue; // already present, skip
518
+ copy_files.push({ src: f, dest: f, substitute_variables: true });
519
+ }
520
+ // Append new directory entries that were selected
521
+ for (const d of selectedFolders) {
522
+ if (existingSrcs.has(d))
523
+ continue; // already present, skip
524
+ copy_files.push({ src: d, dest: d, substitute_variables: true });
510
525
  }
511
- const addedSrcs = new Set();
526
+ }
527
+ else {
528
+ // Full mode: build from scratch using the selected files/folders
512
529
  for (const f of selectedFiles) {
513
- if (addedSrcs.has(f))
514
- continue;
515
- addedSrcs.add(f);
516
- if (existingMap.has(f)) {
517
- copy_files.push(existingMap.get(f));
518
- }
519
- else {
520
- copy_files.push({ src: f, dest: f, substitute_variables: true });
521
- }
530
+ copy_files.push({ src: f, dest: f, substitute_variables: true });
522
531
  }
523
532
  for (const d of selectedFolders) {
524
- if (addedSrcs.has(d))
525
- continue;
526
- addedSrcs.add(d);
527
- if (existingMap.has(d)) {
528
- copy_files.push(existingMap.get(d));
529
- }
530
- else {
531
- copy_files.push({ src: d, dest: d, substitute_variables: true });
532
- }
533
+ copy_files.push({ src: d, dest: d, substitute_variables: true });
533
534
  }
534
535
  }
535
536
  const templateConfig = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@garyr/pt-cli",
3
- "version": "0.40.0",
3
+ "version": "0.40.1",
4
4
  "description": "Project Template CLI - Learn structures and initialize projects",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -414,9 +414,11 @@ export async function update(sourcePath: string, templateName: string, options:
414
414
 
415
415
  if (!isFullMode) {
416
416
  // Additive mode for files and folders
417
- // Start with existing files and folders, preserving their substitute_variables settings
417
+ // Start with existing copy_files entries as the base (preserves all settings including substitute_variables)
418
418
  const existingCopyFiles = config.templates[templateName].copy_files || [];
419
- selectedFiles = existingCopyFiles.map(f => f.src);
419
+ // selectedFiles here is only used to track new file names to append
420
+ let newSelectedFiles: string[] = [];
421
+ let newSelectedFolderDirs: string[] = [];
420
422
 
421
423
  const fileDiff = getNewFiles(config.templates[templateName], resolvedPath);
422
424
 
@@ -442,37 +444,39 @@ export async function update(sourcePath: string, templateName: string, options:
442
444
  checked: true // Auto-select by default
443
445
  }))
444
446
  });
445
- // Only add selected files
446
- selectedFiles.push(...fileDiff.newFiles.filter(f => selectedFileChoices.includes(f)));
447
+ newSelectedFiles = fileDiff.newFiles.filter(f => selectedFileChoices.includes(f));
447
448
  } else {
448
449
  // In --yes or --json mode, auto-add all
449
- selectedFiles.push(...fileDiff.newFiles);
450
+ newSelectedFiles = [...fileDiff.newFiles];
450
451
  }
451
452
  } else {
452
453
  console.log(chalk.cyan("No new files detected"));
453
454
  }
454
455
 
455
- // For folders, use additive mode logic
456
- // Always preserve existing folders first
457
- selectedStructure = config.templates[templateName].folders?.map(f => f.name) || [];
458
- selectedFolders = selectedStructure.filter(d => ['APP', 'scripts', 'bin'].some(p => d === p));
459
-
460
- if (rootDirs.length > 0) {
461
- const structureDiff = getNewFolders(config.templates[templateName].folders, resolvedPath, ignorePatterns);
462
-
463
- if (structureDiff.added.length > 0) {
464
- // Auto-select added folders for structure
465
- selectedStructure = [...new Set([...selectedStructure, ...structureDiff.added.map(f => f.name)])];
466
- // Auto-select for recursive copy if they're in the standard list
467
- selectedFolders = selectedStructure.filter(d => ['APP', 'scripts', 'bin'].some(p => d === p));
468
- } else {
469
- // Keep existing folders
470
- selectedFolders = selectedStructure.filter(d => ['APP', 'scripts', 'bin'].some(p => d === p));
471
- }
472
- } else {
473
- // Keep existing folders
474
- selectedFolders = selectedStructure.filter(d => ['APP', 'scripts', 'bin'].some(p => d === p));
475
- }
456
+ // For folders, use additive mode logic
457
+ // Preserve existing folder structure
458
+ selectedStructure = config.templates[templateName].folders?.map(f => f.name) || [];
459
+ // Seed selectedFolders from existing copy_files directory entries (not a hardcoded list)
460
+ selectedFolders = existingCopyFiles
461
+ .filter(f => rootDirs.includes(f.src))
462
+ .map(f => f.src);
463
+
464
+ if (rootDirs.length > 0) {
465
+ const structureDiff = getNewFolders(config.templates[templateName].folders, resolvedPath, ignorePatterns);
466
+
467
+ if (structureDiff.added.length > 0) {
468
+ // Auto-select added folders for structure
469
+ selectedStructure = [...new Set([...selectedStructure, ...structureDiff.added.map(f => f.name)])];
470
+ // For new dirs, auto-select for recursive copy if they match the standard list
471
+ newSelectedFolderDirs = structureDiff.added
472
+ .filter(f => ['APP', 'scripts', 'bin'].some(p => f.name === p))
473
+ .map(f => f.name);
474
+ }
475
+ }
476
+ // Merge: existing folder copy_files + newly selected dirs
477
+ selectedFolders = [...new Set([...selectedFolders, ...newSelectedFolderDirs])];
478
+ // Also carry forward file names for use in copy_files construction below
479
+ selectedFiles = [...existingCopyFiles.filter(f => !rootDirs.includes(f.src)).map(f => f.src), ...newSelectedFiles];
476
480
  } else {
477
481
  // Full mode: original behavior
478
482
  if (options.yes || options.json) {
@@ -552,31 +556,32 @@ export async function update(sourcePath: string, templateName: string, options:
552
556
  const copy_files: CopyFileEntry[] = [];
553
557
  if (fileTemplateConfig.copy_files && Array.isArray(fileTemplateConfig.copy_files)) {
554
558
  copy_files.push(...fileTemplateConfig.copy_files);
555
- } else {
559
+ } else if (!isFullMode) {
560
+ // Additive mode: start directly from the existing copy_files to preserve all settings,
561
+ // then append only brand-new entries (never rebuild from scratch).
556
562
  const existingCopyFiles = config.templates[templateName].copy_files || [];
557
- const existingMap = new Map<string, CopyFileEntry>();
558
- for (const entry of existingCopyFiles) {
559
- existingMap.set(entry.src, entry);
560
- }
561
- const addedSrcs = new Set<string>();
563
+ const existingSrcs = new Set(existingCopyFiles.map(e => e.src));
562
564
 
565
+ // Begin with all existing entries untouched
566
+ copy_files.push(...existingCopyFiles);
567
+
568
+ // Append new files that were selected by the user
563
569
  for (const f of selectedFiles) {
564
- if (addedSrcs.has(f)) continue;
565
- addedSrcs.add(f);
566
- if (existingMap.has(f)) {
567
- copy_files.push(existingMap.get(f)!);
568
- } else {
569
- copy_files.push({ src: f, dest: f, substitute_variables: true });
570
- }
570
+ if (existingSrcs.has(f)) continue; // already present, skip
571
+ copy_files.push({ src: f, dest: f, substitute_variables: true });
571
572
  }
573
+ // Append new directory entries that were selected
572
574
  for (const d of selectedFolders) {
573
- if (addedSrcs.has(d)) continue;
574
- addedSrcs.add(d);
575
- if (existingMap.has(d)) {
576
- copy_files.push(existingMap.get(d)!);
577
- } else {
578
- copy_files.push({ src: d, dest: d, substitute_variables: true });
579
- }
575
+ if (existingSrcs.has(d)) continue; // already present, skip
576
+ copy_files.push({ src: d, dest: d, substitute_variables: true });
577
+ }
578
+ } else {
579
+ // Full mode: build from scratch using the selected files/folders
580
+ for (const f of selectedFiles) {
581
+ copy_files.push({ src: f, dest: f, substitute_variables: true });
582
+ }
583
+ for (const d of selectedFolders) {
584
+ copy_files.push({ src: d, dest: d, substitute_variables: true });
580
585
  }
581
586
  }
582
587