@editframe/create 0.36.2-beta → 0.37.0-beta

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
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { getDevCommand, getUserPkgManager, installAgentSkills, installDependencies } from "./utils.js";
2
3
  import { access, cp, readdir } from "node:fs/promises";
3
4
  import path from "node:path";
4
5
  import { fileURLToPath } from "node:url";
@@ -10,28 +11,31 @@ import prompts from "prompts";
10
11
  function showHelp(templates) {
11
12
  const usage = `
12
13
  ${chalk.bold("Usage:")}
13
- npm create @editframe/elements -- [template] [options]
14
+ npm create @editframe -- [template] [options]
14
15
 
15
16
  ${chalk.bold("Options:")}
16
- -d, --directory <name> Project directory name (default: prompts for input)
17
+ -d, --directory <name> Project directory name
18
+ --skip-install Skip dependency installation
19
+ --skip-skills Skip agent skills installation
20
+ --agent <name> Specify AI agent (cursor, claude, vscode, etc.)
21
+ -y, --yes Skip all prompts, use defaults
17
22
  -h, --help Show this help message
18
23
 
19
24
  ${chalk.bold("Available Templates:")}
20
25
  ${templates.map((t) => ` - ${t}`).join("\n")}
21
26
 
22
27
  ${chalk.bold("Examples:")}
23
- ${chalk.dim("# Interactive mode (prompts for all inputs)")}
24
- npm create @editframe/elements
28
+ ${chalk.dim("# Interactive mode (recommended)")}
29
+ npm create @editframe
25
30
 
26
- ${chalk.dim("# Specify template, prompt for directory")}
27
- npm create @editframe/elements -- react-demo
31
+ ${chalk.dim("# Specify template")}
32
+ npm create @editframe -- react
28
33
 
29
- ${chalk.dim("# Specify both template and directory")}
30
- npm create @editframe/elements -- react-demo --directory my-app
31
- npm create @editframe/elements -- react-demo -d my-app
34
+ ${chalk.dim("# Full non-interactive")}
35
+ npm create @editframe -- react -d my-app --agent cursor -y
32
36
 
33
- ${chalk.dim("# Show help")}
34
- npm create @editframe/elements -- --help
37
+ ${chalk.dim("# Skip auto-installation")}
38
+ npm create @editframe -- react --skip-install --skip-skills
35
39
  `;
36
40
  process.stdout.write(usage);
37
41
  }
@@ -57,6 +61,20 @@ async function main() {
57
61
  directory: {
58
62
  type: "string",
59
63
  short: "d"
64
+ },
65
+ skipInstall: {
66
+ type: "boolean",
67
+ default: false
68
+ },
69
+ skipSkills: {
70
+ type: "boolean",
71
+ default: false
72
+ },
73
+ agent: { type: "string" },
74
+ yes: {
75
+ type: "boolean",
76
+ short: "y",
77
+ default: false
60
78
  }
61
79
  },
62
80
  allowPositionals: true
@@ -67,6 +85,10 @@ async function main() {
67
85
  }
68
86
  const cliTemplate = positionals[0];
69
87
  const cliDirectory = values.directory;
88
+ const skipInstall = values.skipInstall;
89
+ const skipSkills = values.skipSkills;
90
+ const cliAgent = values.agent;
91
+ const nonInteractive = values.yes;
70
92
  if (cliTemplate && !templates.includes(cliTemplate)) {
71
93
  process.stderr.write(chalk.red(`Error: Template "${cliTemplate}" does not exist.\n\n`));
72
94
  process.stderr.write(chalk.bold("Available templates:\n"));
@@ -75,13 +97,13 @@ async function main() {
75
97
  process.exit(1);
76
98
  }
77
99
  const promptQuestions = [];
78
- if (!cliDirectory) promptQuestions.push({
100
+ if (!cliDirectory && !nonInteractive) promptQuestions.push({
79
101
  type: "text",
80
102
  name: "directoryName",
81
103
  message: "Enter the name of the directory to generate into:",
82
104
  initial: "my-project"
83
105
  });
84
- if (!cliTemplate) promptQuestions.push({
106
+ if (!cliTemplate && !nonInteractive) promptQuestions.push({
85
107
  type: "select",
86
108
  name: "templateName",
87
109
  message: "Choose a starter template:",
@@ -91,8 +113,12 @@ async function main() {
91
113
  }))
92
114
  });
93
115
  const answers = promptQuestions.length > 0 ? await prompts(promptQuestions) : {};
94
- const directoryName = cliDirectory || answers.directoryName;
95
- const templateName = cliTemplate || answers.templateName;
116
+ if (!cliDirectory && !nonInteractive && !answers.directoryName || !cliTemplate && !nonInteractive && !answers.templateName) {
117
+ process.stderr.write(chalk.red("\nCancelled\n"));
118
+ process.exit(1);
119
+ }
120
+ const directoryName = cliDirectory || answers.directoryName || "my-project";
121
+ const templateName = cliTemplate || answers.templateName || templates[0];
96
122
  const targetDir = path.join(process.cwd(), directoryName);
97
123
  const templateDir = path.join(__dirname, "templates", templateName);
98
124
  if (await checkDirectoryExists(targetDir)) {
@@ -108,15 +134,76 @@ async function main() {
108
134
  process.exit(1);
109
135
  }
110
136
  }
111
- process.stderr.write(`Creating project in directory: ${targetDir}\n`);
112
- process.stderr.write(`Using template: ${templateName}\n`);
137
+ process.stderr.write(`\nCreating project in directory: ${targetDir}\n`);
138
+ process.stderr.write(`Using template: ${templateName}\n\n`);
113
139
  await cp(templateDir, targetDir, { recursive: true });
114
- process.stderr.write(chalk.green("\nProject created successfully.\n\n"));
115
- process.stderr.write(chalk.green("Next steps:\n"));
116
- process.stderr.write(` cd ${directoryName}\n`);
117
- process.stderr.write(" npm install\n");
118
- process.stderr.write(" npm start\n\n");
119
- process.stderr.write("Happy hacking!\n");
140
+ const pkgManager = getUserPkgManager();
141
+ let depsInstalled = false;
142
+ let skillsInstalled = false;
143
+ let selectedAgent = cliAgent;
144
+ if (!skipInstall) depsInstalled = await installDependencies(targetDir);
145
+ if (!skipSkills) {
146
+ if (!selectedAgent && !nonInteractive) selectedAgent = (await prompts([{
147
+ type: "confirm",
148
+ name: "installSkills",
149
+ message: "Install AI agent skills for better coding assistance?",
150
+ initial: true
151
+ }, {
152
+ type: (prev) => prev ? "select" : null,
153
+ name: "agent",
154
+ message: "Which AI coding agent are you using?",
155
+ choices: [
156
+ {
157
+ title: "Cursor",
158
+ value: "cursor",
159
+ description: "Most popular"
160
+ },
161
+ {
162
+ title: "VS Code Copilot",
163
+ value: "vscode"
164
+ },
165
+ {
166
+ title: "Claude Code",
167
+ value: "claude"
168
+ },
169
+ {
170
+ title: "Windsurf",
171
+ value: "windsurf"
172
+ },
173
+ {
174
+ title: "All agents",
175
+ value: "all"
176
+ },
177
+ {
178
+ title: "Skip",
179
+ value: "skip"
180
+ }
181
+ ],
182
+ initial: 0
183
+ }])).agent;
184
+ if (!selectedAgent && nonInteractive) selectedAgent = "cursor";
185
+ if (selectedAgent && selectedAgent !== "skip") skillsInstalled = await installAgentSkills(targetDir, selectedAgent);
186
+ }
187
+ process.stderr.write(chalk.green.bold("\n✓ Project created successfully!\n"));
188
+ if (depsInstalled) process.stderr.write(chalk.green("✓ Dependencies installed\n"));
189
+ if (skillsInstalled) process.stderr.write(chalk.green(`✓ Agent skills installed (${selectedAgent})\n`));
190
+ process.stderr.write(chalk.bold("\nYour project is ready! 🎉\n\n"));
191
+ process.stderr.write(chalk.bold("Next steps:\n"));
192
+ process.stderr.write(chalk.cyan(` cd ${directoryName}\n`));
193
+ if (!depsInstalled) process.stderr.write(chalk.cyan(` ${pkgManager} install\n`));
194
+ process.stderr.write(chalk.cyan(` ${getDevCommand(pkgManager)}\n`));
195
+ if (skillsInstalled) {
196
+ process.stderr.write(chalk.bold("\nAI Agent Skills installed:\n"));
197
+ process.stderr.write(chalk.dim(" • elements-composition - HTML/Web Components\n"));
198
+ process.stderr.write(chalk.dim(" • react-composition - React components\n"));
199
+ process.stderr.write(chalk.dim(" • motion-design - Animation principles\n"));
200
+ process.stderr.write(chalk.bold("\nTry asking your AI agent:\n"));
201
+ process.stderr.write(chalk.dim(" \"Create a 5-second video with fade-in text\"\n"));
202
+ process.stderr.write(chalk.dim(" \"Add a waveform visualization\"\n"));
203
+ process.stderr.write(chalk.dim(" \"Animate this element with spring physics\"\n"));
204
+ }
205
+ process.stderr.write(chalk.dim("\nDocumentation: https://editframe.com/docs\n"));
206
+ process.stderr.write(chalk.dim("Happy coding! 🎬\n\n"));
120
207
  }
121
208
  main();
122
209
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["path","promptQuestions: prompts.PromptObject[]"],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { access, cp, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport chalk from \"chalk\";\nimport prompts from \"prompts\";\n\nfunction showHelp(templates: string[]) {\n const usage = `\n${chalk.bold(\"Usage:\")}\n npm create @editframe/elements -- [template] [options]\n\n${chalk.bold(\"Options:\")}\n -d, --directory <name> Project directory name (default: prompts for input)\n -h, --help Show this help message\n\n${chalk.bold(\"Available Templates:\")}\n${templates.map((t) => ` - ${t}`).join(\"\\n\")}\n\n${chalk.bold(\"Examples:\")}\n ${chalk.dim(\"# Interactive mode (prompts for all inputs)\")}\n npm create @editframe/elements\n\n ${chalk.dim(\"# Specify template, prompt for directory\")}\n npm create @editframe/elements -- react-demo\n\n ${chalk.dim(\"# Specify both template and directory\")}\n npm create @editframe/elements -- react-demo --directory my-app\n npm create @editframe/elements -- react-demo -d my-app\n\n ${chalk.dim(\"# Show help\")}\n npm create @editframe/elements -- --help\n`;\n\n process.stdout.write(usage);\n}\n\nasync function checkDirectoryExists(path: string) {\n try {\n await access(path);\n return true;\n } catch (_error) {\n return false;\n }\n}\n\nasync function main() {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n // List of available starter templates\n const templates = await readdir(path.join(__dirname, \"templates\"));\n\n // Parse command line arguments\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n help: {\n type: \"boolean\",\n short: \"h\",\n default: false,\n },\n directory: {\n type: \"string\",\n short: \"d\",\n },\n },\n allowPositionals: true,\n });\n\n // Show help if requested\n if (values.help) {\n showHelp(templates);\n process.exit(0);\n }\n\n // Extract CLI arguments\n const cliTemplate = positionals[0];\n const cliDirectory = values.directory;\n\n // Validate template if provided\n if (cliTemplate && !templates.includes(cliTemplate)) {\n process.stderr.write(\n chalk.red(`Error: Template \"${cliTemplate}\" does not exist.\\n\\n`),\n );\n process.stderr.write(chalk.bold(\"Available templates:\\n\"));\n for (const t of templates) {\n process.stderr.write(` - ${t}\\n`);\n }\n process.stderr.write(\n chalk.dim(\"\\nRun with --help for more information.\\n\"),\n );\n process.exit(1);\n }\n\n // Build prompts array based on what CLI args were provided\n const promptQuestions: prompts.PromptObject[] = [];\n\n if (!cliDirectory) {\n promptQuestions.push({\n type: \"text\",\n name: \"directoryName\",\n message: \"Enter the name of the directory to generate into:\",\n initial: \"my-project\",\n });\n }\n\n if (!cliTemplate) {\n promptQuestions.push({\n type: \"select\",\n name: \"templateName\",\n message: \"Choose a starter template:\",\n choices: templates.map((template) => ({\n title: template,\n value: template,\n })),\n });\n }\n\n // Prompt for missing information\n const answers =\n promptQuestions.length > 0 ? await prompts(promptQuestions) : {};\n\n // Use CLI args or prompted values\n const directoryName = cliDirectory || answers.directoryName;\n const templateName = cliTemplate || answers.templateName;\n\n const targetDir = path.join(process.cwd(), directoryName);\n const templateDir = path.join(__dirname, \"templates\", templateName);\n\n const exists = await checkDirectoryExists(targetDir);\n\n if (exists) {\n process.stderr.write(\n chalk.yellow(`Directory ${targetDir} already exists.\\n`),\n );\n const { overwrite } = await prompts({\n type: \"confirm\",\n name: \"overwrite\",\n message: \"Directory already exists. Do you want to overwrite it?\",\n initial: false,\n });\n\n if (!overwrite) {\n process.stderr.write(chalk.red(\"Aborting...\\n\"));\n process.exit(1);\n }\n }\n\n process.stderr.write(`Creating project in directory: ${targetDir}\\n`);\n process.stderr.write(`Using template: ${templateName}\\n`);\n\n // Copy the selected template to the target directory\n await cp(templateDir, targetDir, { recursive: true });\n\n process.stderr.write(chalk.green(\"\\nProject created successfully.\\n\\n\"));\n\n process.stderr.write(chalk.green(\"Next steps:\\n\"));\n\n process.stderr.write(` cd ${directoryName}\\n`);\n process.stderr.write(\" npm install\\n\");\n process.stderr.write(\" npm start\\n\\n\");\n\n process.stderr.write(\"Happy hacking!\\n\");\n}\n\nmain();\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["path","promptQuestions: prompts.PromptObject[]"],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { access, cp, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport chalk from \"chalk\";\nimport prompts from \"prompts\";\nimport {\n getUserPkgManager,\n installDependencies,\n installAgentSkills,\n getDevCommand,\n} from \"./utils.js\";\n\nfunction showHelp(templates: string[]) {\n const usage = `\n${chalk.bold(\"Usage:\")}\n npm create @editframe -- [template] [options]\n\n${chalk.bold(\"Options:\")}\n -d, --directory <name> Project directory name\n --skip-install Skip dependency installation\n --skip-skills Skip agent skills installation\n --agent <name> Specify AI agent (cursor, claude, vscode, etc.)\n -y, --yes Skip all prompts, use defaults\n -h, --help Show this help message\n\n${chalk.bold(\"Available Templates:\")}\n${templates.map((t) => ` - ${t}`).join(\"\\n\")}\n\n${chalk.bold(\"Examples:\")}\n ${chalk.dim(\"# Interactive mode (recommended)\")}\n npm create @editframe\n\n ${chalk.dim(\"# Specify template\")}\n npm create @editframe -- react\n\n ${chalk.dim(\"# Full non-interactive\")}\n npm create @editframe -- react -d my-app --agent cursor -y\n\n ${chalk.dim(\"# Skip auto-installation\")}\n npm create @editframe -- react --skip-install --skip-skills\n`;\n\n process.stdout.write(usage);\n}\n\nasync function checkDirectoryExists(path: string) {\n try {\n await access(path);\n return true;\n } catch (_error) {\n return false;\n }\n}\n\nasync function main() {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n // List of available starter templates\n const templates = await readdir(path.join(__dirname, \"templates\"));\n\n // Parse command line arguments\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n help: {\n type: \"boolean\",\n short: \"h\",\n default: false,\n },\n directory: {\n type: \"string\",\n short: \"d\",\n },\n skipInstall: {\n type: \"boolean\",\n default: false,\n },\n skipSkills: {\n type: \"boolean\",\n default: false,\n },\n agent: {\n type: \"string\",\n },\n yes: {\n type: \"boolean\",\n short: \"y\",\n default: false,\n },\n },\n allowPositionals: true,\n });\n\n // Show help if requested\n if (values.help) {\n showHelp(templates);\n process.exit(0);\n }\n\n // Extract CLI arguments\n const cliTemplate = positionals[0];\n const cliDirectory = values.directory;\n const skipInstall = values.skipInstall;\n const skipSkills = values.skipSkills;\n const cliAgent = values.agent;\n const nonInteractive = values.yes;\n\n // Validate template if provided\n if (cliTemplate && !templates.includes(cliTemplate)) {\n process.stderr.write(\n chalk.red(`Error: Template \"${cliTemplate}\" does not exist.\\n\\n`),\n );\n process.stderr.write(chalk.bold(\"Available templates:\\n\"));\n for (const t of templates) {\n process.stderr.write(` - ${t}\\n`);\n }\n process.stderr.write(\n chalk.dim(\"\\nRun with --help for more information.\\n\"),\n );\n process.exit(1);\n }\n\n // Build prompts array based on what CLI args were provided\n const promptQuestions: prompts.PromptObject[] = [];\n\n if (!cliDirectory && !nonInteractive) {\n promptQuestions.push({\n type: \"text\",\n name: \"directoryName\",\n message: \"Enter the name of the directory to generate into:\",\n initial: \"my-project\",\n });\n }\n\n if (!cliTemplate && !nonInteractive) {\n promptQuestions.push({\n type: \"select\",\n name: \"templateName\",\n message: \"Choose a starter template:\",\n choices: templates.map((template) => ({\n title: template,\n value: template,\n })),\n });\n }\n\n // Prompt for missing information\n const answers =\n promptQuestions.length > 0 ? await prompts(promptQuestions) : {};\n\n // Handle user cancellation\n if (\n (!cliDirectory && !nonInteractive && !answers.directoryName) ||\n (!cliTemplate && !nonInteractive && !answers.templateName)\n ) {\n process.stderr.write(chalk.red(\"\\nCancelled\\n\"));\n process.exit(1);\n }\n\n // Use CLI args or prompted values (with defaults for non-interactive mode)\n const directoryName =\n cliDirectory || answers.directoryName || \"my-project\";\n const templateName = cliTemplate || answers.templateName || templates[0];\n\n const targetDir = path.join(process.cwd(), directoryName);\n const templateDir = path.join(__dirname, \"templates\", templateName);\n\n const exists = await checkDirectoryExists(targetDir);\n\n if (exists) {\n process.stderr.write(\n chalk.yellow(`Directory ${targetDir} already exists.\\n`),\n );\n const { overwrite } = await prompts({\n type: \"confirm\",\n name: \"overwrite\",\n message: \"Directory already exists. Do you want to overwrite it?\",\n initial: false,\n });\n\n if (!overwrite) {\n process.stderr.write(chalk.red(\"Aborting...\\n\"));\n process.exit(1);\n }\n }\n\n process.stderr.write(`\\nCreating project in directory: ${targetDir}\\n`);\n process.stderr.write(`Using template: ${templateName}\\n\\n`);\n\n // Copy the selected template to the target directory\n await cp(templateDir, targetDir, { recursive: true });\n\n const pkgManager = getUserPkgManager();\n let depsInstalled = false;\n let skillsInstalled = false;\n let selectedAgent = cliAgent;\n\n // Install dependencies unless skipped\n if (!skipInstall) {\n depsInstalled = await installDependencies(targetDir);\n }\n\n // Prompt for and install agent skills unless skipped\n if (!skipSkills) {\n // If agent not specified via CLI, prompt for it (unless non-interactive)\n if (!selectedAgent && !nonInteractive) {\n const skillsPrompt = await prompts([\n {\n type: \"confirm\",\n name: \"installSkills\",\n message: \"Install AI agent skills for better coding assistance?\",\n initial: true,\n },\n {\n type: (prev) => (prev ? \"select\" : null),\n name: \"agent\",\n message: \"Which AI coding agent are you using?\",\n choices: [\n {\n title: \"Cursor\",\n value: \"cursor\",\n description: \"Most popular\",\n },\n { title: \"VS Code Copilot\", value: \"vscode\" },\n { title: \"Claude Code\", value: \"claude\" },\n { title: \"Windsurf\", value: \"windsurf\" },\n { title: \"All agents\", value: \"all\" },\n { title: \"Skip\", value: \"skip\" },\n ],\n initial: 0,\n },\n ]);\n\n selectedAgent = skillsPrompt.agent;\n }\n\n // Install skills if agent was selected (default to cursor in non-interactive mode)\n if (!selectedAgent && nonInteractive) {\n selectedAgent = \"cursor\";\n }\n\n if (selectedAgent && selectedAgent !== \"skip\") {\n skillsInstalled = await installAgentSkills(targetDir, selectedAgent);\n }\n }\n\n // Success message\n process.stderr.write(chalk.green.bold(\"\\n✓ Project created successfully!\\n\"));\n\n if (depsInstalled) {\n process.stderr.write(chalk.green(\"✓ Dependencies installed\\n\"));\n }\n\n if (skillsInstalled) {\n process.stderr.write(\n chalk.green(`✓ Agent skills installed (${selectedAgent})\\n`)\n );\n }\n\n process.stderr.write(chalk.bold(\"\\nYour project is ready! 🎉\\n\\n\"));\n\n // Next steps\n process.stderr.write(chalk.bold(\"Next steps:\\n\"));\n process.stderr.write(chalk.cyan(` cd ${directoryName}\\n`));\n\n if (!depsInstalled) {\n process.stderr.write(chalk.cyan(` ${pkgManager} install\\n`));\n }\n\n process.stderr.write(chalk.cyan(` ${getDevCommand(pkgManager)}\\n`));\n\n // Skills info\n if (skillsInstalled) {\n process.stderr.write(chalk.bold(\"\\nAI Agent Skills installed:\\n\"));\n process.stderr.write(\n chalk.dim(\" • elements-composition - HTML/Web Components\\n\")\n );\n process.stderr.write(\n chalk.dim(\" • react-composition - React components\\n\")\n );\n process.stderr.write(\n chalk.dim(\" • motion-design - Animation principles\\n\")\n );\n\n process.stderr.write(chalk.bold(\"\\nTry asking your AI agent:\\n\"));\n process.stderr.write(\n chalk.dim(' \"Create a 5-second video with fade-in text\"\\n')\n );\n process.stderr.write(chalk.dim(' \"Add a waveform visualization\"\\n'));\n process.stderr.write(\n chalk.dim(' \"Animate this element with spring physics\"\\n')\n );\n }\n\n process.stderr.write(\n chalk.dim(\"\\nDocumentation: https://editframe.com/docs\\n\")\n );\n process.stderr.write(chalk.dim(\"Happy coding! 🎬\\n\\n\"));\n}\n\nmain();\n"],"mappings":"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"}
@@ -11,9 +11,9 @@
11
11
  "author": "",
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
- "@editframe/cli": "0.36.2-beta",
15
- "@editframe/elements": "0.36.2-beta",
16
- "@editframe/vite-plugin": "0.36.2-beta",
14
+ "@editframe/cli": "0.37.0-beta",
15
+ "@editframe/elements": "0.37.0-beta",
16
+ "@editframe/vite-plugin": "0.37.0-beta",
17
17
  "animejs": "^4.2.2",
18
18
  "prismjs": "^1.30.0",
19
19
  "tailwindcss": "^3.4.3",
@@ -11,9 +11,9 @@
11
11
  "author": "",
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
- "@editframe/cli": "0.36.2-beta",
15
- "@editframe/elements": "0.36.2-beta",
16
- "@editframe/vite-plugin": "0.36.2-beta",
14
+ "@editframe/cli": "0.37.0-beta",
15
+ "@editframe/elements": "0.37.0-beta",
16
+ "@editframe/vite-plugin": "0.37.0-beta",
17
17
  "tailwindcss": "^3.4.3",
18
18
  "vite": "^6.3.5",
19
19
  "vite-plugin-singlefile": "^2.0.1"
@@ -7,9 +7,9 @@
7
7
  "start": "editframe preview"
8
8
  },
9
9
  "dependencies": {
10
- "@editframe/cli": "0.36.2-beta",
11
- "@editframe/elements": "0.36.2-beta",
12
- "@editframe/vite-plugin": "0.36.2-beta",
10
+ "@editframe/cli": "0.37.0-beta",
11
+ "@editframe/elements": "0.37.0-beta",
12
+ "@editframe/vite-plugin": "0.37.0-beta",
13
13
  "tailwindcss": "^3.4.3",
14
14
  "vite": "^6.3.5",
15
15
  "vite-plugin-singlefile": "^2.0.1"
@@ -7,9 +7,9 @@
7
7
  "start": "editframe preview"
8
8
  },
9
9
  "dependencies": {
10
- "@editframe/cli": "0.36.2-beta",
11
- "@editframe/react": "0.36.2-beta",
12
- "@editframe/vite-plugin": "0.36.2-beta",
10
+ "@editframe/cli": "0.37.0-beta",
11
+ "@editframe/react": "0.37.0-beta",
12
+ "@editframe/vite-plugin": "0.37.0-beta",
13
13
  "@vitejs/plugin-react": "^4.3.1",
14
14
  "tailwindcss": "^3.4.3",
15
15
  "vite": "^6.3.5",
@@ -11,9 +11,9 @@
11
11
  "author": "",
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
- "@editframe/cli": "0.36.2-beta",
15
- "@editframe/react": "0.36.2-beta",
16
- "@editframe/vite-plugin": "0.36.2-beta",
14
+ "@editframe/cli": "0.37.0-beta",
15
+ "@editframe/react": "0.37.0-beta",
16
+ "@editframe/vite-plugin": "0.37.0-beta",
17
17
  "@vitejs/plugin-react": "^4.3.1",
18
18
  "tailwindcss": "^3.4.3",
19
19
  "vite": "^6.3.5",
@@ -11,9 +11,9 @@
11
11
  "author": "",
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
- "@editframe/cli": "0.36.2-beta",
15
- "@editframe/elements": "0.36.2-beta",
16
- "@editframe/vite-plugin": "0.36.2-beta",
14
+ "@editframe/cli": "0.37.0-beta",
15
+ "@editframe/elements": "0.37.0-beta",
16
+ "@editframe/vite-plugin": "0.37.0-beta",
17
17
  "tailwindcss": "^3.4.3",
18
18
  "vite": "^6.3.5",
19
19
  "vite-plugin-singlefile": "^2.0.1"
package/dist/utils.js ADDED
@@ -0,0 +1,103 @@
1
+ import chalk from "chalk";
2
+ import { execa } from "execa";
3
+ import ora from "ora";
4
+
5
+ //#region src/utils.ts
6
+ /**
7
+ * Detect which package manager was used to invoke the create script.
8
+ * Uses the npm_config_user_agent environment variable set by package managers.
9
+ */
10
+ function getUserPkgManager() {
11
+ const userAgent = process.env.npm_config_user_agent;
12
+ if (userAgent) {
13
+ if (userAgent.startsWith("yarn")) return "yarn";
14
+ if (userAgent.startsWith("pnpm")) return "pnpm";
15
+ if (userAgent.startsWith("bun")) return "bun";
16
+ }
17
+ return "npm";
18
+ }
19
+ /**
20
+ * Execute a package manager command with a spinner for progress indication.
21
+ */
22
+ async function execWithSpinner(projectDir, pkgManager, options) {
23
+ const { onDataHandle, args = ["install"], stdout = "pipe" } = options;
24
+ const spinner = ora(`Running ${pkgManager} install...`).start();
25
+ const subprocess = execa(pkgManager, args, {
26
+ cwd: projectDir,
27
+ stdout
28
+ });
29
+ await new Promise((res, rej) => {
30
+ if (onDataHandle) subprocess.stdout?.on("data", onDataHandle(spinner));
31
+ subprocess.on("error", (e) => rej(e));
32
+ subprocess.on("close", () => res());
33
+ });
34
+ return spinner;
35
+ }
36
+ /**
37
+ * Run the appropriate install command for the detected package manager.
38
+ */
39
+ async function runInstallCommand(pkgManager, projectDir) {
40
+ switch (pkgManager) {
41
+ case "npm":
42
+ await execa(pkgManager, ["install"], {
43
+ cwd: projectDir,
44
+ stderr: "inherit"
45
+ });
46
+ return null;
47
+ case "pnpm": return execWithSpinner(projectDir, pkgManager, { onDataHandle: (spinner) => (data) => {
48
+ const text = data.toString();
49
+ if (text.includes("Progress")) spinner.text = text.includes("|") ? text.split(" | ")[1] ?? "" : text;
50
+ } });
51
+ case "yarn": return execWithSpinner(projectDir, pkgManager, { onDataHandle: (spinner) => (data) => {
52
+ spinner.text = data.toString().trim();
53
+ } });
54
+ case "bun": return execWithSpinner(projectDir, pkgManager, { stdout: "ignore" });
55
+ }
56
+ }
57
+ /**
58
+ * Install dependencies in the project directory.
59
+ */
60
+ async function installDependencies(projectDir) {
61
+ const pkgManager = getUserPkgManager();
62
+ try {
63
+ (await runInstallCommand(pkgManager, projectDir) ?? ora()).succeed(chalk.green("Successfully installed dependencies!"));
64
+ return true;
65
+ } catch (error) {
66
+ process.stderr.write(chalk.yellow("\n⚠ Dependency installation failed\n"));
67
+ process.stderr.write(chalk.dim("You can install manually:\n"));
68
+ process.stderr.write(chalk.cyan(` cd ${projectDir.split("/").pop()}\n`));
69
+ process.stderr.write(chalk.cyan(` ${pkgManager} install\n\n`));
70
+ return false;
71
+ }
72
+ }
73
+ /**
74
+ * Install AI agent skills using the ai-agent-skills CLI.
75
+ */
76
+ async function installAgentSkills(projectDir, agent) {
77
+ const spinner = ora("Installing AI agent skills...").start();
78
+ try {
79
+ await execa("npx", [
80
+ "ai-agent-skills",
81
+ "install",
82
+ "editframe/skills",
83
+ ...agent === "all" ? [] : ["--agent", agent]
84
+ ], { cwd: projectDir });
85
+ spinner.succeed(chalk.green(`AI agent skills installed for ${agent}!`));
86
+ return true;
87
+ } catch (error) {
88
+ spinner.fail(chalk.yellow("Failed to install agent skills"));
89
+ process.stderr.write(chalk.dim("\nYou can install manually:\n"));
90
+ process.stderr.write(chalk.cyan(` npx ai-agent-skills install editframe/skills --agent ${agent}\n\n`));
91
+ return false;
92
+ }
93
+ }
94
+ /**
95
+ * Get the appropriate dev command for the package manager.
96
+ */
97
+ function getDevCommand(pkgManager) {
98
+ return pkgManager === "npm" ? "npm run dev" : `${pkgManager} dev`;
99
+ }
100
+
101
+ //#endregion
102
+ export { getDevCommand, getUserPkgManager, installAgentSkills, installDependencies };
103
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { execa } from \"execa\";\nimport ora, { type Ora } from \"ora\";\nimport chalk from \"chalk\";\n\nexport type PackageManager = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\n/**\n * Detect which package manager was used to invoke the create script.\n * Uses the npm_config_user_agent environment variable set by package managers.\n */\nexport function getUserPkgManager(): PackageManager {\n const userAgent = process.env.npm_config_user_agent;\n\n if (userAgent) {\n if (userAgent.startsWith(\"yarn\")) return \"yarn\";\n if (userAgent.startsWith(\"pnpm\")) return \"pnpm\";\n if (userAgent.startsWith(\"bun\")) return \"bun\";\n }\n\n return \"npm\"; // Default fallback\n}\n\n/**\n * Execute a package manager command with a spinner for progress indication.\n */\nasync function execWithSpinner(\n projectDir: string,\n pkgManager: PackageManager,\n options: {\n args?: string[];\n stdout?: \"pipe\" | \"ignore\" | \"inherit\";\n onDataHandle?: (spinner: Ora) => (data: Buffer) => void;\n }\n) {\n const { onDataHandle, args = [\"install\"], stdout = \"pipe\" } = options;\n\n const spinner = ora(`Running ${pkgManager} install...`).start();\n const subprocess = execa(pkgManager, args, { cwd: projectDir, stdout });\n\n await new Promise<void>((res, rej) => {\n if (onDataHandle) {\n subprocess.stdout?.on(\"data\", onDataHandle(spinner));\n }\n\n void subprocess.on(\"error\", (e) => rej(e));\n void subprocess.on(\"close\", () => res());\n });\n\n return spinner;\n}\n\n/**\n * Run the appropriate install command for the detected package manager.\n */\nasync function runInstallCommand(\n pkgManager: PackageManager,\n projectDir: string\n): Promise<Ora | null> {\n switch (pkgManager) {\n // npm has built-in progress bar, inherit stderr to show it\n case \"npm\":\n await execa(pkgManager, [\"install\"], {\n cwd: projectDir,\n stderr: \"inherit\",\n });\n return null;\n\n // pnpm outputs progress to stdout with \"Progress\" prefix\n case \"pnpm\":\n return execWithSpinner(projectDir, pkgManager, {\n onDataHandle: (spinner) => (data) => {\n const text = data.toString();\n if (text.includes(\"Progress\")) {\n spinner.text = text.includes(\"|\")\n ? (text.split(\" | \")[1] ?? \"\")\n : text;\n }\n },\n });\n\n // yarn outputs progress to stdout\n case \"yarn\":\n return execWithSpinner(projectDir, pkgManager, {\n onDataHandle: (spinner) => (data) => {\n spinner.text = data.toString().trim();\n },\n });\n\n // bun is fast, just show a spinner\n case \"bun\":\n return execWithSpinner(projectDir, pkgManager, { stdout: \"ignore\" });\n }\n}\n\n/**\n * Install dependencies in the project directory.\n */\nexport async function installDependencies(projectDir: string): Promise<boolean> {\n const pkgManager = getUserPkgManager();\n\n try {\n const installSpinner = await runInstallCommand(pkgManager, projectDir);\n\n // If the spinner was used, succeed it; otherwise create a new one\n (installSpinner ?? ora()).succeed(\n chalk.green(\"Successfully installed dependencies!\")\n );\n\n return true;\n } catch (error) {\n process.stderr.write(chalk.yellow(\"\\n⚠ Dependency installation failed\\n\"));\n process.stderr.write(chalk.dim(\"You can install manually:\\n\"));\n process.stderr.write(chalk.cyan(` cd ${projectDir.split(\"/\").pop()}\\n`));\n process.stderr.write(chalk.cyan(` ${pkgManager} install\\n\\n`));\n return false;\n }\n}\n\n/**\n * Install AI agent skills using the ai-agent-skills CLI.\n */\nexport async function installAgentSkills(\n projectDir: string,\n agent: string\n): Promise<boolean> {\n const spinner = ora(\"Installing AI agent skills...\").start();\n\n try {\n const agentFlag = agent === \"all\" ? [] : [\"--agent\", agent];\n\n await execa(\n \"npx\",\n [\"ai-agent-skills\", \"install\", \"editframe/skills\", ...agentFlag],\n { cwd: projectDir }\n );\n\n spinner.succeed(chalk.green(`AI agent skills installed for ${agent}!`));\n return true;\n } catch (error) {\n spinner.fail(chalk.yellow(\"Failed to install agent skills\"));\n process.stderr.write(chalk.dim(\"\\nYou can install manually:\\n\"));\n process.stderr.write(\n chalk.cyan(\n ` npx ai-agent-skills install editframe/skills --agent ${agent}\\n\\n`\n )\n );\n return false;\n }\n}\n\n/**\n * Get the appropriate dev command for the package manager.\n */\nexport function getDevCommand(pkgManager: PackageManager): string {\n return pkgManager === \"npm\" ? \"npm run dev\" : `${pkgManager} dev`;\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,oBAAoC;CAClD,MAAM,YAAY,QAAQ,IAAI;AAE9B,KAAI,WAAW;AACb,MAAI,UAAU,WAAW,OAAO,CAAE,QAAO;AACzC,MAAI,UAAU,WAAW,OAAO,CAAE,QAAO;AACzC,MAAI,UAAU,WAAW,MAAM,CAAE,QAAO;;AAG1C,QAAO;;;;;AAMT,eAAe,gBACb,YACA,YACA,SAKA;CACA,MAAM,EAAE,cAAc,OAAO,CAAC,UAAU,EAAE,SAAS,WAAW;CAE9D,MAAM,UAAU,IAAI,WAAW,WAAW,aAAa,CAAC,OAAO;CAC/D,MAAM,aAAa,MAAM,YAAY,MAAM;EAAE,KAAK;EAAY;EAAQ,CAAC;AAEvE,OAAM,IAAI,SAAe,KAAK,QAAQ;AACpC,MAAI,aACF,YAAW,QAAQ,GAAG,QAAQ,aAAa,QAAQ,CAAC;AAGtD,EAAK,WAAW,GAAG,UAAU,MAAM,IAAI,EAAE,CAAC;AAC1C,EAAK,WAAW,GAAG,eAAe,KAAK,CAAC;GACxC;AAEF,QAAO;;;;;AAMT,eAAe,kBACb,YACA,YACqB;AACrB,SAAQ,YAAR;EAEE,KAAK;AACH,SAAM,MAAM,YAAY,CAAC,UAAU,EAAE;IACnC,KAAK;IACL,QAAQ;IACT,CAAC;AACF,UAAO;EAGT,KAAK,OACH,QAAO,gBAAgB,YAAY,YAAY,EAC7C,eAAe,aAAa,SAAS;GACnC,MAAM,OAAO,KAAK,UAAU;AAC5B,OAAI,KAAK,SAAS,WAAW,CAC3B,SAAQ,OAAO,KAAK,SAAS,IAAI,GAC5B,KAAK,MAAM,MAAM,CAAC,MAAM,KACzB;KAGT,CAAC;EAGJ,KAAK,OACH,QAAO,gBAAgB,YAAY,YAAY,EAC7C,eAAe,aAAa,SAAS;AACnC,WAAQ,OAAO,KAAK,UAAU,CAAC,MAAM;KAExC,CAAC;EAGJ,KAAK,MACH,QAAO,gBAAgB,YAAY,YAAY,EAAE,QAAQ,UAAU,CAAC;;;;;;AAO1E,eAAsB,oBAAoB,YAAsC;CAC9E,MAAM,aAAa,mBAAmB;AAEtC,KAAI;AAIF,GAHuB,MAAM,kBAAkB,YAAY,WAAW,IAGnD,KAAK,EAAE,QACxB,MAAM,MAAM,uCAAuC,CACpD;AAED,SAAO;UACA,OAAO;AACd,UAAQ,OAAO,MAAM,MAAM,OAAO,uCAAuC,CAAC;AAC1E,UAAQ,OAAO,MAAM,MAAM,IAAI,8BAA8B,CAAC;AAC9D,UAAQ,OAAO,MAAM,MAAM,KAAK,QAAQ,WAAW,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;AACzE,UAAQ,OAAO,MAAM,MAAM,KAAK,KAAK,WAAW,cAAc,CAAC;AAC/D,SAAO;;;;;;AAOX,eAAsB,mBACpB,YACA,OACkB;CAClB,MAAM,UAAU,IAAI,gCAAgC,CAAC,OAAO;AAE5D,KAAI;AAGF,QAAM,MACJ,OACA;GAAC;GAAmB;GAAW;GAAoB,GAJnC,UAAU,QAAQ,EAAE,GAAG,CAAC,WAAW,MAAM;GAIO,EAChE,EAAE,KAAK,YAAY,CACpB;AAED,UAAQ,QAAQ,MAAM,MAAM,iCAAiC,MAAM,GAAG,CAAC;AACvE,SAAO;UACA,OAAO;AACd,UAAQ,KAAK,MAAM,OAAO,iCAAiC,CAAC;AAC5D,UAAQ,OAAO,MAAM,MAAM,IAAI,gCAAgC,CAAC;AAChE,UAAQ,OAAO,MACb,MAAM,KACJ,0DAA0D,MAAM,MACjE,CACF;AACD,SAAO;;;;;;AAOX,SAAgB,cAAc,YAAoC;AAChE,QAAO,eAAe,QAAQ,gBAAgB,GAAG,WAAW"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@editframe/create",
3
- "version": "0.36.2-beta",
3
+ "version": "0.37.0-beta",
4
4
  "description": "",
5
5
  "bin": {
6
6
  "create-editframe": "dist/index.js"
@@ -22,7 +22,9 @@
22
22
  "license": "UNLICENSED",
23
23
  "dependencies": {
24
24
  "chalk": "^5.3.0",
25
- "prompts": "^2.4.2"
25
+ "prompts": "^2.4.2",
26
+ "execa": "^9.5.2",
27
+ "ora": "^8.1.1"
26
28
  },
27
29
  "module": "./dist/index.js",
28
30
  "types": "./dist/index.d.ts",