create-nyoworks 2.3.0 → 2.4.0
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/checks.d.ts +2 -0
- package/dist/checks.js +114 -0
- package/dist/init.js +64 -55
- package/package.json +1 -1
package/dist/checks.d.ts
ADDED
package/dist/checks.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import { execa } from "execa";
|
|
3
|
+
const DEPENDENCIES = [
|
|
4
|
+
{
|
|
5
|
+
name: "Node.js",
|
|
6
|
+
cmd: "node",
|
|
7
|
+
args: ["-v"],
|
|
8
|
+
required: true,
|
|
9
|
+
minVersion: "20.0.0",
|
|
10
|
+
url: "https://nodejs.org",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
name: "pnpm",
|
|
14
|
+
cmd: "pnpm",
|
|
15
|
+
args: ["-v"],
|
|
16
|
+
required: true,
|
|
17
|
+
install: "npm i -g pnpm",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "Docker",
|
|
21
|
+
cmd: "docker",
|
|
22
|
+
args: ["-v"],
|
|
23
|
+
required: true,
|
|
24
|
+
url: "https://docker.com/download",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "Claude CLI",
|
|
28
|
+
cmd: "claude",
|
|
29
|
+
args: ["-v"],
|
|
30
|
+
required: false,
|
|
31
|
+
install: "npm i -g @anthropic-ai/claude-code",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "VS Code",
|
|
35
|
+
cmd: "code",
|
|
36
|
+
args: ["-v"],
|
|
37
|
+
required: false,
|
|
38
|
+
url: "https://code.visualstudio.com",
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
async function checkCommand(cmd, args = []) {
|
|
42
|
+
try {
|
|
43
|
+
const result = await execa(cmd, args);
|
|
44
|
+
return result.stdout.trim().replace(/^v/, "");
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function compareVersions(current, minimum) {
|
|
51
|
+
const curr = current.split(".").map(Number);
|
|
52
|
+
const min = minimum.split(".").map(Number);
|
|
53
|
+
for (let i = 0; i < 3; i++) {
|
|
54
|
+
if ((curr[i] || 0) > (min[i] || 0))
|
|
55
|
+
return true;
|
|
56
|
+
if ((curr[i] || 0) < (min[i] || 0))
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
export async function checkDependencies() {
|
|
62
|
+
console.log();
|
|
63
|
+
console.log(pc.cyan("Checking dependencies..."));
|
|
64
|
+
let hasError = false;
|
|
65
|
+
for (const dep of DEPENDENCIES) {
|
|
66
|
+
const version = await checkCommand(dep.cmd, dep.args);
|
|
67
|
+
if (!version) {
|
|
68
|
+
if (dep.required) {
|
|
69
|
+
console.log(pc.red(` ✗ ${dep.name} is required`));
|
|
70
|
+
hasError = true;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
console.log(pc.yellow(` ⚠ ${dep.name} (recommended)`));
|
|
74
|
+
}
|
|
75
|
+
if (dep.install) {
|
|
76
|
+
console.log(pc.dim(` Install: ${dep.install}`));
|
|
77
|
+
}
|
|
78
|
+
if (dep.url) {
|
|
79
|
+
console.log(pc.dim(` Download: ${dep.url}`));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
if (dep.minVersion && !compareVersions(version, dep.minVersion)) {
|
|
84
|
+
console.log(pc.yellow(` ⚠ ${dep.name} ${version} (minimum: ${dep.minVersion})`));
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
console.log(pc.green(` ✓ ${dep.name} ${version}`));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (hasError) {
|
|
92
|
+
console.log();
|
|
93
|
+
console.log(pc.red("Please install the required dependencies before continuing."));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export function showClaudeMaxWarning() {
|
|
97
|
+
console.log();
|
|
98
|
+
console.log(pc.yellow("╔═══════════════════════════════════════════════════════════════════════╗"));
|
|
99
|
+
console.log(pc.yellow("║") + pc.bold(" ⚠️ MCP Server requires Claude Max subscription ") + pc.yellow("║"));
|
|
100
|
+
console.log(pc.yellow("╠═══════════════════════════════════════════════════════════════════════╣"));
|
|
101
|
+
console.log(pc.yellow("║") + " " + pc.yellow("║"));
|
|
102
|
+
console.log(pc.yellow("║") + " The AI agents in this framework use Model Context Protocol (MCP). " + pc.yellow("║"));
|
|
103
|
+
console.log(pc.yellow("║") + " MCP requires Claude Max subscription. " + pc.yellow("║"));
|
|
104
|
+
console.log(pc.yellow("║") + " " + pc.yellow("║"));
|
|
105
|
+
console.log(pc.yellow("║") + pc.bold(" Pricing: $100/month") + " (5x usage vs Pro) " + pc.yellow("║"));
|
|
106
|
+
console.log(pc.yellow("║") + " Subscribe: " + pc.cyan("https://claude.ai/settings/billing") + " " + pc.yellow("║"));
|
|
107
|
+
console.log(pc.yellow("║") + " " + pc.yellow("║"));
|
|
108
|
+
console.log(pc.yellow("║") + " Without Claude Max: " + pc.yellow("║"));
|
|
109
|
+
console.log(pc.yellow("║") + pc.green(" ✓ You can still use the codebase manually") + " " + pc.yellow("║"));
|
|
110
|
+
console.log(pc.yellow("║") + pc.red(" ✗ AI agents (/lead, /backend, /frontend, etc.) won't work") + " " + pc.yellow("║"));
|
|
111
|
+
console.log(pc.yellow("║") + pc.red(" ✗ MCP tools will not be available") + " " + pc.yellow("║"));
|
|
112
|
+
console.log(pc.yellow("║") + " " + pc.yellow("║"));
|
|
113
|
+
console.log(pc.yellow("╚═══════════════════════════════════════════════════════════════════════╝"));
|
|
114
|
+
}
|
package/dist/init.js
CHANGED
|
@@ -2,8 +2,10 @@ import prompts from "prompts";
|
|
|
2
2
|
import pc from "picocolors";
|
|
3
3
|
import fs from "fs-extra";
|
|
4
4
|
import path from "path";
|
|
5
|
+
import os from "os";
|
|
5
6
|
import { execa } from "execa";
|
|
6
7
|
import { replacePlaceholders } from "./replace.js";
|
|
8
|
+
import { checkDependencies, showClaudeMaxWarning } from "./checks.js";
|
|
7
9
|
const REPO = "naimozcan/nyoworks-framework";
|
|
8
10
|
const BRANCH = "main";
|
|
9
11
|
const AVAILABLE_FEATURES = [
|
|
@@ -39,22 +41,14 @@ function generateDatabaseName(name) {
|
|
|
39
41
|
.replace(/[^a-z0-9]+/g, "_")
|
|
40
42
|
.replace(/^_|_$/g, "") + "_dev";
|
|
41
43
|
}
|
|
42
|
-
async function
|
|
43
|
-
const url = `https://
|
|
44
|
-
const tempDir = path.join(
|
|
44
|
+
async function downloadRepo(repo, branch) {
|
|
45
|
+
const url = `https://github.com/${repo}/archive/refs/heads/${branch}.tar.gz`;
|
|
46
|
+
const tempDir = path.join(os.tmpdir(), `nyoworks-${Date.now()}`);
|
|
47
|
+
const tarFile = path.join(tempDir, "repo.tar.gz");
|
|
45
48
|
await fs.ensureDir(tempDir);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const extractedDir = path.join(tempDir, `nyoworks-framework-${branch}`);
|
|
50
|
-
const sourcePath = subPath ? path.join(extractedDir, subPath) : extractedDir;
|
|
51
|
-
if (await fs.pathExists(sourcePath)) {
|
|
52
|
-
await fs.copy(sourcePath, targetDir, { overwrite: true });
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
finally {
|
|
56
|
-
await fs.remove(tempDir);
|
|
57
|
-
}
|
|
49
|
+
await execa("curl", ["-L", "-o", tarFile, url]);
|
|
50
|
+
await execa("tar", ["-xzf", tarFile, "-C", tempDir]);
|
|
51
|
+
return path.join(tempDir, `nyoworks-framework-${branch}`);
|
|
58
52
|
}
|
|
59
53
|
export async function createProject(projectName) {
|
|
60
54
|
console.log();
|
|
@@ -102,22 +96,47 @@ export async function createProject(projectName) {
|
|
|
102
96
|
console.log(pc.red(`Directory ${slug} already exists.`));
|
|
103
97
|
process.exit(1);
|
|
104
98
|
}
|
|
105
|
-
await fs.ensureDir(targetDir);
|
|
106
99
|
console.log();
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
100
|
+
process.stdout.write(pc.cyan("Downloading from GitHub..."));
|
|
101
|
+
let repoDir;
|
|
102
|
+
try {
|
|
103
|
+
repoDir = await downloadRepo(REPO, BRANCH);
|
|
104
|
+
console.log(pc.green(" done"));
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
console.log(pc.red(" failed"));
|
|
108
|
+
console.error(pc.red("Failed to download from GitHub. Check your internet connection."));
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
process.stdout.write(pc.dim(" Copying files..."));
|
|
112
|
+
await fs.ensureDir(targetDir);
|
|
113
|
+
const corePaths = [
|
|
114
|
+
"packages/api",
|
|
115
|
+
"packages/api-client",
|
|
116
|
+
"packages/database",
|
|
117
|
+
"packages/validators",
|
|
118
|
+
"packages/shared",
|
|
119
|
+
"packages/ui",
|
|
120
|
+
"packages/assets",
|
|
121
|
+
"apps/server",
|
|
122
|
+
"docs",
|
|
123
|
+
"mcp-server",
|
|
124
|
+
".claude",
|
|
120
125
|
];
|
|
126
|
+
for (const p of corePaths) {
|
|
127
|
+
const src = path.join(repoDir, p);
|
|
128
|
+
const dest = path.join(targetDir, p);
|
|
129
|
+
if (await fs.pathExists(src)) {
|
|
130
|
+
await fs.copy(src, dest);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
for (const platform of platforms) {
|
|
134
|
+
const src = path.join(repoDir, `apps/${platform}`);
|
|
135
|
+
const dest = path.join(targetDir, `apps/${platform}`);
|
|
136
|
+
if (await fs.pathExists(src)) {
|
|
137
|
+
await fs.copy(src, dest);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
121
140
|
const rootFiles = [
|
|
122
141
|
"package.json",
|
|
123
142
|
"pnpm-workspace.yaml",
|
|
@@ -127,32 +146,15 @@ export async function createProject(projectName) {
|
|
|
127
146
|
".gitignore",
|
|
128
147
|
"nyoworks.config.yaml",
|
|
129
148
|
];
|
|
130
|
-
for (const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
for (const platform of platforms) {
|
|
136
|
-
process.stdout.write(pc.dim(` Downloading apps/${platform}...`));
|
|
137
|
-
await downloadFromGitHub(REPO, `apps/${platform}`, path.join(targetDir, `apps/${platform}`), BRANCH);
|
|
138
|
-
console.log(pc.green(" ✓"));
|
|
139
|
-
}
|
|
140
|
-
process.stdout.write(pc.dim(" Downloading root files..."));
|
|
141
|
-
await downloadFromGitHub(REPO, "", targetDir, BRANCH);
|
|
142
|
-
const allPlatforms = ["web", "mobile", "desktop"];
|
|
143
|
-
for (const platform of allPlatforms) {
|
|
144
|
-
if (!platforms.includes(platform)) {
|
|
145
|
-
const platformDir = path.join(targetDir, "apps", platform);
|
|
146
|
-
if (await fs.pathExists(platformDir)) {
|
|
147
|
-
await fs.remove(platformDir);
|
|
148
|
-
}
|
|
149
|
+
for (const file of rootFiles) {
|
|
150
|
+
const src = path.join(repoDir, file);
|
|
151
|
+
const dest = path.join(targetDir, file);
|
|
152
|
+
if (await fs.pathExists(src)) {
|
|
153
|
+
await fs.copy(src, dest);
|
|
149
154
|
}
|
|
150
155
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
await fs.remove(createNyoworksDir);
|
|
154
|
-
}
|
|
155
|
-
console.log(pc.green(" ✓"));
|
|
156
|
+
await fs.remove(path.dirname(repoDir));
|
|
157
|
+
console.log(pc.green(" done"));
|
|
156
158
|
const placeholders = {
|
|
157
159
|
"${PROJECT_NAME}": name,
|
|
158
160
|
"${PROJECT_CODE}": code,
|
|
@@ -161,7 +163,7 @@ export async function createProject(projectName) {
|
|
|
161
163
|
};
|
|
162
164
|
process.stdout.write(pc.dim(" Replacing placeholders..."));
|
|
163
165
|
await replacePlaceholders(targetDir, placeholders);
|
|
164
|
-
console.log(pc.green("
|
|
166
|
+
console.log(pc.green(" done"));
|
|
165
167
|
for (const feature of features) {
|
|
166
168
|
const featureDoc = path.join(targetDir, "docs", "bible", "features", `${feature}.md`);
|
|
167
169
|
const content = `# Feature: ${feature.charAt(0).toUpperCase() + feature.slice(1)}
|
|
@@ -211,13 +213,20 @@ See \`docs/bible/data/schema.md\`
|
|
|
211
213
|
}
|
|
212
214
|
console.log();
|
|
213
215
|
console.log(pc.green(pc.bold("Project created successfully!")));
|
|
216
|
+
await checkDependencies();
|
|
217
|
+
showClaudeMaxWarning();
|
|
214
218
|
console.log();
|
|
215
|
-
console.log(" Next steps:");
|
|
219
|
+
console.log(pc.bold(" Next steps:"));
|
|
216
220
|
console.log();
|
|
217
221
|
console.log(pc.cyan(` cd ${slug}`));
|
|
218
222
|
console.log(pc.cyan(" pnpm install"));
|
|
223
|
+
console.log(pc.cyan(" docker compose up -d ") + pc.dim("# Start PostgreSQL & Redis"));
|
|
219
224
|
console.log(pc.cyan(" pnpm dev"));
|
|
220
225
|
console.log();
|
|
226
|
+
console.log(pc.dim(" Optional:"));
|
|
227
|
+
console.log(pc.dim(" code . # Open in VS Code"));
|
|
228
|
+
console.log(pc.dim(" claude # Start Claude Code CLI"));
|
|
229
|
+
console.log();
|
|
221
230
|
console.log(pc.dim(" Configuration:"));
|
|
222
231
|
console.log(pc.dim(` Name: ${name}`));
|
|
223
232
|
console.log(pc.dim(` Code: ${code}`));
|