@svton/cli 1.2.3 → 1.2.4

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/dist/index.js CHANGED
@@ -746,52 +746,62 @@ async function generateEnvExample(features, config, targetPath) {
746
746
  await import_fs_extra4.default.writeFile(import_path3.default.join(targetPath, ".env.example"), content);
747
747
  logger.info("Generated .env.example");
748
748
  }
749
- async function copyConfigFiles(features, config, templatePath, targetPath) {
749
+ async function copyConfigFiles(features, config, templateDir, targetPath) {
750
750
  for (const featureKey of features) {
751
751
  const feature = config.features[featureKey];
752
752
  if (feature && feature.configFiles) {
753
753
  for (const configFile of feature.configFiles) {
754
- const sourcePath = import_path3.default.join(templatePath, configFile.template);
754
+ const sourcePath = import_path3.default.join(templateDir, configFile.template);
755
755
  const destPath = import_path3.default.join(targetPath, configFile.path);
756
- await import_fs_extra4.default.ensureDir(import_path3.default.dirname(destPath));
757
- await import_fs_extra4.default.copy(sourcePath, destPath);
758
- logger.info(`Copied config: ${configFile.path}`);
756
+ if (await import_fs_extra4.default.pathExists(sourcePath)) {
757
+ await import_fs_extra4.default.ensureDir(import_path3.default.dirname(destPath));
758
+ await import_fs_extra4.default.copy(sourcePath, destPath);
759
+ logger.info(`Copied config: ${configFile.path}`);
760
+ } else {
761
+ logger.warn(`Config template not found: ${sourcePath}`);
762
+ }
759
763
  }
760
764
  }
761
765
  }
762
766
  }
763
- async function copyExampleFiles(features, config, templatePath, targetPath) {
767
+ async function copyExampleFiles(features, config, templateDir, targetPath) {
764
768
  for (const featureKey of features) {
765
769
  const feature = config.features[featureKey];
766
770
  if (feature && feature.exampleFiles) {
767
- const sourcePath = import_path3.default.join(templatePath, feature.exampleFiles.source);
771
+ const sourcePath = import_path3.default.join(templateDir, feature.exampleFiles.source);
768
772
  const destPath = import_path3.default.join(targetPath, feature.exampleFiles.target);
769
773
  if (await import_fs_extra4.default.pathExists(sourcePath)) {
770
774
  await import_fs_extra4.default.ensureDir(import_path3.default.dirname(destPath));
771
775
  await import_fs_extra4.default.copy(sourcePath, destPath);
772
776
  logger.info(`Copied examples: ${feature.exampleFiles.target}`);
777
+ } else {
778
+ logger.warn(`Example template not found: ${sourcePath}`);
773
779
  }
774
780
  }
775
781
  }
776
782
  }
777
- async function copySkillFiles(features, config, templatePath, targetPath) {
783
+ async function copySkillFiles(features, config, templateDir, targetPath) {
778
784
  const skillsDir = import_path3.default.join(targetPath, ".kiro/skills");
779
785
  await import_fs_extra4.default.ensureDir(skillsDir);
780
- const baseSkillSource = import_path3.default.join(templatePath, "skills/base.skill.md");
786
+ const baseSkillSource = import_path3.default.join(templateDir, "skills/base.skill.md");
781
787
  const baseSkillDest = import_path3.default.join(skillsDir, "project-capabilities.md");
782
788
  if (await import_fs_extra4.default.pathExists(baseSkillSource)) {
783
789
  await import_fs_extra4.default.copy(baseSkillSource, baseSkillDest);
784
790
  logger.info("Copied base skill file");
791
+ } else {
792
+ logger.warn(`Base skill template not found: ${baseSkillSource}`);
785
793
  }
786
794
  for (const featureKey of features) {
787
795
  const feature = config.features[featureKey];
788
796
  if (feature && feature.skillFile) {
789
- const sourcePath = import_path3.default.join(templatePath, feature.skillFile.template);
797
+ const sourcePath = import_path3.default.join(templateDir, feature.skillFile.template);
790
798
  const destPath = import_path3.default.join(targetPath, feature.skillFile.target);
791
799
  if (await import_fs_extra4.default.pathExists(sourcePath)) {
792
800
  await import_fs_extra4.default.ensureDir(import_path3.default.dirname(destPath));
793
801
  await import_fs_extra4.default.copy(sourcePath, destPath);
794
802
  logger.info(`Copied skill: ${feature.skillFile.target}`);
803
+ } else {
804
+ logger.warn(`Skill template not found: ${sourcePath}`);
795
805
  }
796
806
  }
797
807
  }
@@ -1041,8 +1051,26 @@ async function createProject(projectName, options = {}) {
1041
1051
  process.exit(1);
1042
1052
  }
1043
1053
  }
1054
+ async function getTemplateDirectory() {
1055
+ const cliPackageRoot = import_path4.default.dirname(__dirname);
1056
+ const frameworkRoot = import_path4.default.dirname(import_path4.default.dirname(cliPackageRoot));
1057
+ const localTemplateDir = import_path4.default.join(frameworkRoot, "templates");
1058
+ if (await import_fs_extra5.default.pathExists(localTemplateDir)) {
1059
+ logger.debug(`Using local template directory: ${localTemplateDir}`);
1060
+ return localTemplateDir;
1061
+ }
1062
+ logger.debug("Downloading templates from GitHub for feature integration...");
1063
+ try {
1064
+ const templateDir = await downloadTemplateFromGitHub();
1065
+ logger.debug("Templates downloaded successfully");
1066
+ return templateDir;
1067
+ } catch (error) {
1068
+ throw new Error(`Failed to download templates from GitHub: ${error}`);
1069
+ }
1070
+ }
1044
1071
  async function createProjectFromTemplate(config) {
1045
1072
  const spinner = (0, import_ora.default)("Creating project...").start();
1073
+ let templateDirToCleanup = null;
1046
1074
  try {
1047
1075
  await import_fs_extra5.default.ensureDir(config.projectPath);
1048
1076
  process.chdir(config.projectPath);
@@ -1051,11 +1079,17 @@ async function createProjectFromTemplate(config) {
1051
1079
  if (config.features.length > 0) {
1052
1080
  spinner.text = "Integrating selected features...";
1053
1081
  const featuresConfig = await loadFeaturesConfig();
1054
- const templatePath = import_path4.default.join(__dirname, "../../../templates");
1082
+ const templateDir = await getTemplateDirectory();
1083
+ const cliPackageRoot = import_path4.default.dirname(__dirname);
1084
+ const frameworkRoot = import_path4.default.dirname(import_path4.default.dirname(cliPackageRoot));
1085
+ const localTemplateDir = import_path4.default.join(frameworkRoot, "templates");
1086
+ if (templateDir !== localTemplateDir) {
1087
+ templateDirToCleanup = templateDir;
1088
+ }
1055
1089
  await updatePackageJson(config.features, featuresConfig, config.projectPath);
1056
- await copyConfigFiles(config.features, featuresConfig, templatePath, config.projectPath);
1057
- await copyExampleFiles(config.features, featuresConfig, templatePath, config.projectPath);
1058
- await copySkillFiles(config.features, featuresConfig, templatePath, config.projectPath);
1090
+ await copyConfigFiles(config.features, featuresConfig, templateDir, config.projectPath);
1091
+ await copyExampleFiles(config.features, featuresConfig, templateDir, config.projectPath);
1092
+ await copySkillFiles(config.features, featuresConfig, templateDir, config.projectPath);
1059
1093
  await generateEnvExample(config.features, featuresConfig, config.projectPath);
1060
1094
  if (config.template === "backend-only" || config.template === "full-stack") {
1061
1095
  await updateAppModule(config.features, featuresConfig, config.projectPath);
@@ -1073,11 +1107,15 @@ async function createProjectFromTemplate(config) {
1073
1107
  } catch (error) {
1074
1108
  spinner.fail("Failed to create project");
1075
1109
  throw error;
1110
+ } finally {
1111
+ if (templateDirToCleanup) {
1112
+ await cleanupTemplateDir(templateDirToCleanup);
1113
+ }
1076
1114
  }
1077
1115
  }
1078
1116
 
1079
1117
  // package.json
1080
- var version = "1.2.3";
1118
+ var version = "1.2.4";
1081
1119
 
1082
1120
  // src/index.ts
1083
1121
  async function cli() {
package/dist/index.mjs CHANGED
@@ -719,52 +719,62 @@ async function generateEnvExample(features, config, targetPath) {
719
719
  await fs4.writeFile(path3.join(targetPath, ".env.example"), content);
720
720
  logger.info("Generated .env.example");
721
721
  }
722
- async function copyConfigFiles(features, config, templatePath, targetPath) {
722
+ async function copyConfigFiles(features, config, templateDir, targetPath) {
723
723
  for (const featureKey of features) {
724
724
  const feature = config.features[featureKey];
725
725
  if (feature && feature.configFiles) {
726
726
  for (const configFile of feature.configFiles) {
727
- const sourcePath = path3.join(templatePath, configFile.template);
727
+ const sourcePath = path3.join(templateDir, configFile.template);
728
728
  const destPath = path3.join(targetPath, configFile.path);
729
- await fs4.ensureDir(path3.dirname(destPath));
730
- await fs4.copy(sourcePath, destPath);
731
- logger.info(`Copied config: ${configFile.path}`);
729
+ if (await fs4.pathExists(sourcePath)) {
730
+ await fs4.ensureDir(path3.dirname(destPath));
731
+ await fs4.copy(sourcePath, destPath);
732
+ logger.info(`Copied config: ${configFile.path}`);
733
+ } else {
734
+ logger.warn(`Config template not found: ${sourcePath}`);
735
+ }
732
736
  }
733
737
  }
734
738
  }
735
739
  }
736
- async function copyExampleFiles(features, config, templatePath, targetPath) {
740
+ async function copyExampleFiles(features, config, templateDir, targetPath) {
737
741
  for (const featureKey of features) {
738
742
  const feature = config.features[featureKey];
739
743
  if (feature && feature.exampleFiles) {
740
- const sourcePath = path3.join(templatePath, feature.exampleFiles.source);
744
+ const sourcePath = path3.join(templateDir, feature.exampleFiles.source);
741
745
  const destPath = path3.join(targetPath, feature.exampleFiles.target);
742
746
  if (await fs4.pathExists(sourcePath)) {
743
747
  await fs4.ensureDir(path3.dirname(destPath));
744
748
  await fs4.copy(sourcePath, destPath);
745
749
  logger.info(`Copied examples: ${feature.exampleFiles.target}`);
750
+ } else {
751
+ logger.warn(`Example template not found: ${sourcePath}`);
746
752
  }
747
753
  }
748
754
  }
749
755
  }
750
- async function copySkillFiles(features, config, templatePath, targetPath) {
756
+ async function copySkillFiles(features, config, templateDir, targetPath) {
751
757
  const skillsDir = path3.join(targetPath, ".kiro/skills");
752
758
  await fs4.ensureDir(skillsDir);
753
- const baseSkillSource = path3.join(templatePath, "skills/base.skill.md");
759
+ const baseSkillSource = path3.join(templateDir, "skills/base.skill.md");
754
760
  const baseSkillDest = path3.join(skillsDir, "project-capabilities.md");
755
761
  if (await fs4.pathExists(baseSkillSource)) {
756
762
  await fs4.copy(baseSkillSource, baseSkillDest);
757
763
  logger.info("Copied base skill file");
764
+ } else {
765
+ logger.warn(`Base skill template not found: ${baseSkillSource}`);
758
766
  }
759
767
  for (const featureKey of features) {
760
768
  const feature = config.features[featureKey];
761
769
  if (feature && feature.skillFile) {
762
- const sourcePath = path3.join(templatePath, feature.skillFile.template);
770
+ const sourcePath = path3.join(templateDir, feature.skillFile.template);
763
771
  const destPath = path3.join(targetPath, feature.skillFile.target);
764
772
  if (await fs4.pathExists(sourcePath)) {
765
773
  await fs4.ensureDir(path3.dirname(destPath));
766
774
  await fs4.copy(sourcePath, destPath);
767
775
  logger.info(`Copied skill: ${feature.skillFile.target}`);
776
+ } else {
777
+ logger.warn(`Skill template not found: ${sourcePath}`);
768
778
  }
769
779
  }
770
780
  }
@@ -1014,8 +1024,26 @@ async function createProject(projectName, options = {}) {
1014
1024
  process.exit(1);
1015
1025
  }
1016
1026
  }
1027
+ async function getTemplateDirectory() {
1028
+ const cliPackageRoot = path4.dirname(__dirname);
1029
+ const frameworkRoot = path4.dirname(path4.dirname(cliPackageRoot));
1030
+ const localTemplateDir = path4.join(frameworkRoot, "templates");
1031
+ if (await fs5.pathExists(localTemplateDir)) {
1032
+ logger.debug(`Using local template directory: ${localTemplateDir}`);
1033
+ return localTemplateDir;
1034
+ }
1035
+ logger.debug("Downloading templates from GitHub for feature integration...");
1036
+ try {
1037
+ const templateDir = await downloadTemplateFromGitHub();
1038
+ logger.debug("Templates downloaded successfully");
1039
+ return templateDir;
1040
+ } catch (error) {
1041
+ throw new Error(`Failed to download templates from GitHub: ${error}`);
1042
+ }
1043
+ }
1017
1044
  async function createProjectFromTemplate(config) {
1018
1045
  const spinner = ora("Creating project...").start();
1046
+ let templateDirToCleanup = null;
1019
1047
  try {
1020
1048
  await fs5.ensureDir(config.projectPath);
1021
1049
  process.chdir(config.projectPath);
@@ -1024,11 +1052,17 @@ async function createProjectFromTemplate(config) {
1024
1052
  if (config.features.length > 0) {
1025
1053
  spinner.text = "Integrating selected features...";
1026
1054
  const featuresConfig = await loadFeaturesConfig();
1027
- const templatePath = path4.join(__dirname, "../../../templates");
1055
+ const templateDir = await getTemplateDirectory();
1056
+ const cliPackageRoot = path4.dirname(__dirname);
1057
+ const frameworkRoot = path4.dirname(path4.dirname(cliPackageRoot));
1058
+ const localTemplateDir = path4.join(frameworkRoot, "templates");
1059
+ if (templateDir !== localTemplateDir) {
1060
+ templateDirToCleanup = templateDir;
1061
+ }
1028
1062
  await updatePackageJson(config.features, featuresConfig, config.projectPath);
1029
- await copyConfigFiles(config.features, featuresConfig, templatePath, config.projectPath);
1030
- await copyExampleFiles(config.features, featuresConfig, templatePath, config.projectPath);
1031
- await copySkillFiles(config.features, featuresConfig, templatePath, config.projectPath);
1063
+ await copyConfigFiles(config.features, featuresConfig, templateDir, config.projectPath);
1064
+ await copyExampleFiles(config.features, featuresConfig, templateDir, config.projectPath);
1065
+ await copySkillFiles(config.features, featuresConfig, templateDir, config.projectPath);
1032
1066
  await generateEnvExample(config.features, featuresConfig, config.projectPath);
1033
1067
  if (config.template === "backend-only" || config.template === "full-stack") {
1034
1068
  await updateAppModule(config.features, featuresConfig, config.projectPath);
@@ -1046,11 +1080,15 @@ async function createProjectFromTemplate(config) {
1046
1080
  } catch (error) {
1047
1081
  spinner.fail("Failed to create project");
1048
1082
  throw error;
1083
+ } finally {
1084
+ if (templateDirToCleanup) {
1085
+ await cleanupTemplateDir(templateDirToCleanup);
1086
+ }
1049
1087
  }
1050
1088
  }
1051
1089
 
1052
1090
  // package.json
1053
- var version = "1.2.3";
1091
+ var version = "1.2.4";
1054
1092
 
1055
1093
  // src/index.ts
1056
1094
  async function cli() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svton/cli",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "Svton CLI - Create full-stack applications with NestJS, Next.js, and Taro",
5
5
  "keywords": [
6
6
  "cli",