@lumy-pack/syncpoint 0.0.2 → 0.0.3

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
@@ -313,12 +313,12 @@ npx @lumy-pack/syncpoint restore --dry-run
313
313
 
314
314
  ---
315
315
 
316
- ### `syncpoint provision <template> [options]`
316
+ ### `syncpoint provision [template] [options]`
317
317
 
318
318
  Run template-based machine provisioning to install software and configure your system.
319
319
 
320
320
  **What it does:**
321
- 1. Loads template YAML from `~/.syncpoint/templates/`
321
+ 1. Loads template YAML from `~/.syncpoint/templates/` (by name) or from a custom path (with `--file`)
322
322
  2. Validates template structure and security
323
323
  3. Checks for sudo requirement (prompts if needed)
324
324
  4. Executes steps sequentially with real-time progress
@@ -330,22 +330,38 @@ Run template-based machine provisioning to install software and configure your s
330
330
 
331
331
  | Option | Description |
332
332
  |--------|-------------|
333
+ | `-f, --file <path>` | Path to template file (alternative to template name) |
333
334
  | `--dry-run` | Show execution plan without running commands |
334
335
  | `--skip-restore` | Skip automatic config restore after provisioning |
335
336
 
336
337
  **Usage:**
337
338
 
338
339
  ```bash
339
- # Run provisioning template
340
+ # Run provisioning template by name
340
341
  npx @lumy-pack/syncpoint provision my-setup
341
342
 
343
+ # Run template from custom path
344
+ npx @lumy-pack/syncpoint provision --file ./my-template.yml
345
+
346
+ # Use short flag with relative path
347
+ npx @lumy-pack/syncpoint provision -f ~/templates/custom.yaml
348
+
342
349
  # Preview template execution
343
350
  npx @lumy-pack/syncpoint provision my-setup --dry-run
344
351
 
345
352
  # Provision without restoring configs
346
353
  npx @lumy-pack/syncpoint provision my-setup --skip-restore
354
+
355
+ # Combine --file with other options
356
+ npx @lumy-pack/syncpoint provision -f ./template.yml --dry-run --skip-restore
347
357
  ```
348
358
 
359
+ **Path Resolution:**
360
+ - Supports absolute paths: `/path/to/template.yml`
361
+ - Supports relative paths: `./template.yml`, `../templates/setup.yaml`
362
+ - Supports tilde expansion: `~/templates/custom.yml`
363
+ - Must have `.yml` or `.yaml` extension
364
+
349
365
  **Security:**
350
366
  - Blocks dangerous remote script patterns (`curl | bash`, `wget | sh`)
351
367
  - Sanitizes error output to mask sensitive paths and credentials
@@ -616,14 +632,20 @@ steps:
616
632
  ### Running Templates
617
633
 
618
634
  ```bash
635
+ # Run template by name (from ~/.syncpoint/templates/)
636
+ npx @lumy-pack/syncpoint provision dev-setup
637
+
638
+ # Run template from custom path
639
+ npx @lumy-pack/syncpoint provision --file ./my-template.yml
640
+
619
641
  # Preview template execution
620
642
  npx @lumy-pack/syncpoint provision dev-setup --dry-run
621
643
 
622
- # Run template
623
- npx @lumy-pack/syncpoint provision dev-setup
624
-
625
644
  # Run and skip config restore
626
645
  npx @lumy-pack/syncpoint provision dev-setup --skip-restore
646
+
647
+ # Combine custom path with options
648
+ npx @lumy-pack/syncpoint provision -f ~/templates/setup.yaml --dry-run
627
649
  ```
628
650
 
629
651
  ---
@@ -25,6 +25,10 @@ backup:
25
25
  exclude:
26
26
  - "**/*.swp"
27
27
  - "**/.DS_Store"
28
+ - "**/.Trash/**"
29
+ - "**/Library/**"
30
+ - "**/.cache/**"
31
+ - "**/node_modules/**"
28
32
  # Example regex: "/\\.bak$/" (excludes all .bak files)
29
33
 
30
34
  # (Required) Backup archive filename pattern.
package/dist/cli.mjs CHANGED
@@ -426,7 +426,7 @@ function validateMetadata(data) {
426
426
  }
427
427
 
428
428
  // src/version.ts
429
- var VERSION = "0.0.2";
429
+ var VERSION = "0.0.3";
430
430
 
431
431
  // src/core/metadata.ts
432
432
  var METADATA_VERSION = "1.0.0";
@@ -594,8 +594,18 @@ async function scanTargets(config) {
594
594
  dot: true,
595
595
  absolute: true,
596
596
  onlyFiles: true,
597
- deep: 5
597
+ deep: 5,
598
598
  // Limit depth for performance
599
+ suppressErrors: true,
600
+ ignore: [
601
+ "**/.Trash/**",
602
+ "**/Library/**",
603
+ "**/.cache/**",
604
+ "**/node_modules/**",
605
+ ...config.backup.exclude.filter(
606
+ (p) => detectPatternType(p) === "glob"
607
+ )
608
+ ]
599
609
  });
600
610
  for (const match of allFiles) {
601
611
  if (regex.test(match) && !isExcluded(match)) {
@@ -615,8 +625,15 @@ async function scanTargets(config) {
615
625
  const matches = await fg(expanded, {
616
626
  dot: true,
617
627
  absolute: true,
618
- ignore: globExcludes,
619
- onlyFiles: true
628
+ ignore: [
629
+ "**/.Trash/**",
630
+ "**/Library/**",
631
+ "**/.cache/**",
632
+ "**/node_modules/**",
633
+ ...globExcludes
634
+ ],
635
+ onlyFiles: true,
636
+ suppressErrors: true
620
637
  });
621
638
  for (const match of matches) {
622
639
  if (!isExcluded(match)) {
@@ -640,9 +657,16 @@ async function scanTargets(config) {
640
657
  const matches = await fg(dirGlob, {
641
658
  dot: true,
642
659
  absolute: true,
643
- ignore: globExcludes,
644
- onlyFiles: true
660
+ ignore: [
661
+ "**/.Trash/**",
662
+ "**/Library/**",
663
+ "**/.cache/**",
664
+ "**/node_modules/**",
665
+ ...globExcludes
666
+ ],
667
+ onlyFiles: true,
645
668
  // Only include files, not subdirectories
669
+ suppressErrors: true
646
670
  });
647
671
  for (const match of matches) {
648
672
  if (!isExcluded(match)) {
@@ -947,10 +971,14 @@ var COMMANDS = {
947
971
  {
948
972
  name: "template",
949
973
  description: "Template name to execute",
950
- required: true
974
+ required: false
951
975
  }
952
976
  ],
953
977
  options: [
978
+ {
979
+ flag: "-f, --file <path>",
980
+ description: "Path to template file (alternative to template name)"
981
+ },
954
982
  {
955
983
  flag: "--dry-run",
956
984
  description: "Show execution plan without running commands"
@@ -963,7 +991,9 @@ var COMMANDS = {
963
991
  examples: [
964
992
  "npx @lumy-pack/syncpoint provision dev-setup",
965
993
  "npx @lumy-pack/syncpoint provision dev-setup --dry-run",
966
- "npx @lumy-pack/syncpoint provision dev-setup --skip-restore"
994
+ "npx @lumy-pack/syncpoint provision dev-setup --skip-restore",
995
+ "npx @lumy-pack/syncpoint provision --file ./my-template.yml",
996
+ "npx @lumy-pack/syncpoint provision -f ~/templates/custom.yaml --dry-run"
967
997
  ]
968
998
  },
969
999
  "create-template": {
@@ -1623,7 +1653,7 @@ var GeneralHelpView = () => {
1623
1653
  "Restore configuration files"
1624
1654
  ] }),
1625
1655
  /* @__PURE__ */ jsxs4(Text4, { children: [
1626
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", children: "provision <template>" }),
1656
+ /* @__PURE__ */ jsx4(Text4, { color: "cyan", children: "provision [template]" }),
1627
1657
  " ",
1628
1658
  "Run machine provisioning template"
1629
1659
  ] }),
@@ -2852,17 +2882,36 @@ var ProvisionView = ({
2852
2882
  ] });
2853
2883
  };
2854
2884
  function registerProvisionCommand(program2) {
2855
- program2.command("provision <template>").description("Run template-based machine provisioning").option("--dry-run", "Show plan without execution", false).option("--skip-restore", "Skip automatic restore after template completion", false).action(
2885
+ program2.command("provision [template]").description("Run template-based machine provisioning").option("--dry-run", "Show plan without execution", false).option("--skip-restore", "Skip automatic restore after template completion", false).option("-f, --file <path>", "Path to template file").action(
2856
2886
  async (templateName, opts) => {
2857
- const templates = await listTemplates();
2858
- const match = templates.find(
2859
- (t) => t.name === templateName || t.name === `${templateName}.yml` || t.config.name === templateName
2860
- );
2861
- if (!match) {
2862
- console.error(`Template not found: ${templateName}`);
2887
+ let templatePath;
2888
+ if (opts.file) {
2889
+ templatePath = resolveTargetPath(opts.file);
2890
+ if (!await fileExists(templatePath)) {
2891
+ console.error(`Template file not found: ${opts.file}`);
2892
+ process.exit(1);
2893
+ }
2894
+ if (!templatePath.endsWith(".yml") && !templatePath.endsWith(".yaml")) {
2895
+ console.error(`Template file must have .yml or .yaml extension: ${opts.file}`);
2896
+ process.exit(1);
2897
+ }
2898
+ } else if (templateName) {
2899
+ const templates = await listTemplates();
2900
+ const match = templates.find(
2901
+ (t) => t.name === templateName || t.name === `${templateName}.yml` || t.config.name === templateName
2902
+ );
2903
+ if (!match) {
2904
+ console.error(`Template not found: ${templateName}`);
2905
+ process.exit(1);
2906
+ }
2907
+ templatePath = match.path;
2908
+ } else {
2909
+ console.error("Error: Either <template> name or --file option must be provided");
2910
+ console.error("Usage: syncpoint provision <template> [options]");
2911
+ console.error(" syncpoint provision --file <path> [options]");
2863
2912
  process.exit(1);
2864
2913
  }
2865
- const tmpl = await loadTemplate(match.path);
2914
+ const tmpl = await loadTemplate(templatePath);
2866
2915
  if (tmpl.sudo && !opts.dryRun) {
2867
2916
  ensureSudo(tmpl.name);
2868
2917
  }
@@ -2871,7 +2920,7 @@ function registerProvisionCommand(program2) {
2871
2920
  ProvisionView,
2872
2921
  {
2873
2922
  template: tmpl,
2874
- templatePath: match.path,
2923
+ templatePath,
2875
2924
  options: {
2876
2925
  dryRun: opts.dryRun,
2877
2926
  skipRestore: opts.skipRestore
@@ -3629,7 +3678,8 @@ async function scanHomeDirectory(options) {
3629
3678
  onlyFiles: true,
3630
3679
  deep: maxDepth,
3631
3680
  absolute: false,
3632
- cwd: homeDir
3681
+ cwd: homeDir,
3682
+ suppressErrors: true
3633
3683
  });
3634
3684
  const validFiles = [];
3635
3685
  for (const file of files) {
@@ -3661,7 +3711,8 @@ async function scanHomeDirectory(options) {
3661
3711
  onlyFiles: true,
3662
3712
  deep: maxDepth,
3663
3713
  absolute: false,
3664
- cwd: homeDir
3714
+ cwd: homeDir,
3715
+ suppressErrors: true
3665
3716
  });
3666
3717
  const uncategorizedFiles = [];
3667
3718
  for (const file of allFiles) {
package/dist/index.cjs CHANGED
@@ -560,7 +560,7 @@ function validateMetadata(data) {
560
560
  }
561
561
 
562
562
  // src/version.ts
563
- var VERSION = "0.0.2";
563
+ var VERSION = "0.0.3";
564
564
 
565
565
  // src/core/metadata.ts
566
566
  var METADATA_VERSION = "1.0.0";
@@ -728,8 +728,18 @@ async function scanTargets(config) {
728
728
  dot: true,
729
729
  absolute: true,
730
730
  onlyFiles: true,
731
- deep: 5
731
+ deep: 5,
732
732
  // Limit depth for performance
733
+ suppressErrors: true,
734
+ ignore: [
735
+ "**/.Trash/**",
736
+ "**/Library/**",
737
+ "**/.cache/**",
738
+ "**/node_modules/**",
739
+ ...config.backup.exclude.filter(
740
+ (p) => detectPatternType(p) === "glob"
741
+ )
742
+ ]
733
743
  });
734
744
  for (const match of allFiles) {
735
745
  if (regex.test(match) && !isExcluded(match)) {
@@ -749,8 +759,15 @@ async function scanTargets(config) {
749
759
  const matches = await (0, import_fast_glob.default)(expanded, {
750
760
  dot: true,
751
761
  absolute: true,
752
- ignore: globExcludes,
753
- onlyFiles: true
762
+ ignore: [
763
+ "**/.Trash/**",
764
+ "**/Library/**",
765
+ "**/.cache/**",
766
+ "**/node_modules/**",
767
+ ...globExcludes
768
+ ],
769
+ onlyFiles: true,
770
+ suppressErrors: true
754
771
  });
755
772
  for (const match of matches) {
756
773
  if (!isExcluded(match)) {
@@ -774,9 +791,16 @@ async function scanTargets(config) {
774
791
  const matches = await (0, import_fast_glob.default)(dirGlob, {
775
792
  dot: true,
776
793
  absolute: true,
777
- ignore: globExcludes,
778
- onlyFiles: true
794
+ ignore: [
795
+ "**/.Trash/**",
796
+ "**/Library/**",
797
+ "**/.cache/**",
798
+ "**/node_modules/**",
799
+ ...globExcludes
800
+ ],
801
+ onlyFiles: true,
779
802
  // Only include files, not subdirectories
803
+ suppressErrors: true
780
804
  });
781
805
  for (const match of matches) {
782
806
  if (!isExcluded(match)) {
package/dist/index.mjs CHANGED
@@ -510,7 +510,7 @@ function validateMetadata(data) {
510
510
  }
511
511
 
512
512
  // src/version.ts
513
- var VERSION = "0.0.2";
513
+ var VERSION = "0.0.3";
514
514
 
515
515
  // src/core/metadata.ts
516
516
  var METADATA_VERSION = "1.0.0";
@@ -678,8 +678,18 @@ async function scanTargets(config) {
678
678
  dot: true,
679
679
  absolute: true,
680
680
  onlyFiles: true,
681
- deep: 5
681
+ deep: 5,
682
682
  // Limit depth for performance
683
+ suppressErrors: true,
684
+ ignore: [
685
+ "**/.Trash/**",
686
+ "**/Library/**",
687
+ "**/.cache/**",
688
+ "**/node_modules/**",
689
+ ...config.backup.exclude.filter(
690
+ (p) => detectPatternType(p) === "glob"
691
+ )
692
+ ]
683
693
  });
684
694
  for (const match of allFiles) {
685
695
  if (regex.test(match) && !isExcluded(match)) {
@@ -699,8 +709,15 @@ async function scanTargets(config) {
699
709
  const matches = await fg(expanded, {
700
710
  dot: true,
701
711
  absolute: true,
702
- ignore: globExcludes,
703
- onlyFiles: true
712
+ ignore: [
713
+ "**/.Trash/**",
714
+ "**/Library/**",
715
+ "**/.cache/**",
716
+ "**/node_modules/**",
717
+ ...globExcludes
718
+ ],
719
+ onlyFiles: true,
720
+ suppressErrors: true
704
721
  });
705
722
  for (const match of matches) {
706
723
  if (!isExcluded(match)) {
@@ -724,9 +741,16 @@ async function scanTargets(config) {
724
741
  const matches = await fg(dirGlob, {
725
742
  dot: true,
726
743
  absolute: true,
727
- ignore: globExcludes,
728
- onlyFiles: true
744
+ ignore: [
745
+ "**/.Trash/**",
746
+ "**/Library/**",
747
+ "**/.cache/**",
748
+ "**/node_modules/**",
749
+ ...globExcludes
750
+ ],
751
+ onlyFiles: true,
729
752
  // Only include files, not subdirectories
753
+ suppressErrors: true
730
754
  });
731
755
  for (const match of matches) {
732
756
  if (!isExcluded(match)) {
@@ -92,6 +92,7 @@ export interface RestoreOptions {
92
92
  export interface ProvisionOptions {
93
93
  dryRun?: boolean;
94
94
  skipRestore?: boolean;
95
+ file?: string;
95
96
  }
96
97
  export interface BackupInfo {
97
98
  filename: string;
package/dist/version.d.ts CHANGED
@@ -2,4 +2,4 @@
2
2
  * Current package version from package.json
3
3
  * Automatically synchronized during build process
4
4
  */
5
- export declare const VERSION = "0.0.2";
5
+ export declare const VERSION = "0.0.3";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumy-pack/syncpoint",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "CLI tool for project synchronization and scaffolding",
5
5
  "keywords": [
6
6
  "cli",