create-nevex-agent 0.1.1 → 0.1.2
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/bin/create-nevex-agent.mjs +61 -5
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@ import { execFileSync } from "node:child_process";
|
|
|
15
15
|
import { tmpdir } from "node:os";
|
|
16
16
|
|
|
17
17
|
const args = parseArgs(process.argv.slice(2));
|
|
18
|
+
|
|
18
19
|
const projectName = args._[0];
|
|
19
20
|
|
|
20
21
|
if (!projectName || args.help) {
|
|
@@ -23,14 +24,20 @@ if (!projectName || args.help) {
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
const slug = normalizeSlug(projectName);
|
|
27
|
+
|
|
26
28
|
const target = resolve(args.output ?? projectName);
|
|
29
|
+
|
|
27
30
|
assertTargetIsSafe(target);
|
|
28
31
|
|
|
29
32
|
const source = args["template-path"]
|
|
30
33
|
? resolve(args["template-path"])
|
|
31
|
-
: await materializeTemplate(
|
|
34
|
+
: await materializeTemplate(
|
|
35
|
+
args["template-repo"] ?? process.env.NEVEX_AGENT_TEMPLATE_REPO,
|
|
36
|
+
args["template-ref"],
|
|
37
|
+
);
|
|
32
38
|
|
|
33
39
|
mkdirSync(target, { recursive: true });
|
|
40
|
+
|
|
34
41
|
cpSync(source, target, {
|
|
35
42
|
recursive: true,
|
|
36
43
|
filter: (entry) => !shouldSkip(entry, source),
|
|
@@ -39,24 +46,48 @@ cpSync(source, target, {
|
|
|
39
46
|
customizeProject(target, {
|
|
40
47
|
slug,
|
|
41
48
|
displayName: args["display-name"] ?? titleCase(slug),
|
|
49
|
+
templateRepo:
|
|
50
|
+
args["template-path"] ?? args["template-repo"] ?? process.env.NEVEX_AGENT_TEMPLATE_REPO ?? null,
|
|
51
|
+
templateRef: args["template-path"] ? null : (args["template-ref"] ?? null),
|
|
52
|
+
templateCommit: args["template-path"] ? null : readTemplateCommit(source),
|
|
42
53
|
});
|
|
43
54
|
|
|
44
55
|
if (!args["template-path"]) rmSync(source, { recursive: true, force: true });
|
|
45
56
|
|
|
46
57
|
console.log(`\nProyecto creado en ${target}`);
|
|
58
|
+
|
|
47
59
|
console.log("\nSiguientes pasos:\n");
|
|
60
|
+
|
|
48
61
|
console.log(` cd ${JSON.stringify(target)}`);
|
|
62
|
+
|
|
49
63
|
console.log(" pnpm install");
|
|
64
|
+
|
|
50
65
|
console.log(" cp .env.example .env.local");
|
|
66
|
+
|
|
51
67
|
console.log(" pnpm dev\n");
|
|
52
68
|
|
|
53
|
-
async function materializeTemplate(repository) {
|
|
69
|
+
async function materializeTemplate(repository, ref) {
|
|
54
70
|
const repo = repository ?? "git@github.com:nevex-labs/nevex-agent-template.git";
|
|
55
71
|
const directory = join(tmpdir(), `nevex-agent-template-${randomUUID()}`);
|
|
56
|
-
|
|
72
|
+
const refArgs = ref ? ["--branch", ref] : [];
|
|
73
|
+
execFileSync("git", ["clone", "--depth", "1", ...refArgs, repo, directory], {
|
|
74
|
+
stdio: "inherit",
|
|
75
|
+
});
|
|
76
|
+
|
|
57
77
|
return directory;
|
|
58
78
|
}
|
|
59
79
|
|
|
80
|
+
function readTemplateCommit(directory) {
|
|
81
|
+
try {
|
|
82
|
+
return execFileSync("git", ["rev-parse", "HEAD"], {
|
|
83
|
+
cwd: directory,
|
|
84
|
+
encoding: "utf8",
|
|
85
|
+
}).trim();
|
|
86
|
+
} catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
60
91
|
function customizeProject(directory, values) {
|
|
61
92
|
const packagePath = join(directory, "package.json");
|
|
62
93
|
const packageJson = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
@@ -66,8 +97,8 @@ function customizeProject(directory, values) {
|
|
|
66
97
|
|
|
67
98
|
replaceInFile(
|
|
68
99
|
join(directory, "src/lib/config.ts"),
|
|
69
|
-
|
|
70
|
-
`APP_NAME = ${JSON.stringify(values.displayName)}
|
|
100
|
+
/^export const APP_NAME = .*;$/m,
|
|
101
|
+
`export const APP_NAME = ${JSON.stringify(values.displayName)};`,
|
|
71
102
|
);
|
|
72
103
|
replaceInFile(
|
|
73
104
|
join(directory, "wrangler.jsonc"),
|
|
@@ -84,15 +115,33 @@ function customizeProject(directory, values) {
|
|
|
84
115
|
/^# Nevex Agent Template/m,
|
|
85
116
|
`# ${values.displayName}`,
|
|
86
117
|
);
|
|
118
|
+
|
|
119
|
+
const lines = [
|
|
120
|
+
"# Template origin",
|
|
121
|
+
"",
|
|
122
|
+
`- Template: ${values.templateRepo ?? "git@github.com:nevex-labs/nevex-agent-template.git"}`,
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
if (values.templateRef) lines.push(`- Ref: ${values.templateRef}`);
|
|
126
|
+
|
|
127
|
+
if (values.templateCommit) lines.push(`- Commit: ${values.templateCommit}`);
|
|
128
|
+
lines.push(`- Generated: ${new Date().toISOString().slice(0, 10)}`, "");
|
|
129
|
+
writeFileSync(join(directory, "TEMPLATE.md"), `${lines.join("\n")}`);
|
|
87
130
|
}
|
|
88
131
|
|
|
89
132
|
function replaceInFile(path, pattern, replacement) {
|
|
90
133
|
const content = readFileSync(path, "utf8");
|
|
134
|
+
|
|
135
|
+
if (!pattern.test(content)) {
|
|
136
|
+
throw new Error(`El patrón ${pattern} no matcheó en ${path}.`);
|
|
137
|
+
}
|
|
138
|
+
|
|
91
139
|
writeFileSync(path, content.replace(pattern, replacement));
|
|
92
140
|
}
|
|
93
141
|
|
|
94
142
|
function shouldSkip(entry, source) {
|
|
95
143
|
const relative = entry.slice(source.length + 1);
|
|
144
|
+
|
|
96
145
|
return (
|
|
97
146
|
relative === ".git" ||
|
|
98
147
|
relative.startsWith(".git/") ||
|
|
@@ -110,6 +159,7 @@ function shouldSkip(entry, source) {
|
|
|
110
159
|
|
|
111
160
|
function assertTargetIsSafe(directory) {
|
|
112
161
|
if (!existsSync(directory)) return;
|
|
162
|
+
|
|
113
163
|
if (readdirSync(directory).length > 0) {
|
|
114
164
|
throw new Error(`El directorio ${directory} ya existe y no está vacío.`);
|
|
115
165
|
}
|
|
@@ -120,7 +170,9 @@ function normalizeSlug(value) {
|
|
|
120
170
|
.toLowerCase()
|
|
121
171
|
.replace(/[^a-z0-9]+/g, "-")
|
|
122
172
|
.replace(/^-|-$/g, "");
|
|
173
|
+
|
|
123
174
|
if (!slug) throw new Error("El nombre del proyecto no es válido.");
|
|
175
|
+
|
|
124
176
|
return slug;
|
|
125
177
|
}
|
|
126
178
|
|
|
@@ -130,12 +182,15 @@ function titleCase(value) {
|
|
|
130
182
|
|
|
131
183
|
function parseArgs(argv) {
|
|
132
184
|
const result = { _: [] };
|
|
185
|
+
|
|
133
186
|
for (let index = 0; index < argv.length; index += 1) {
|
|
134
187
|
const value = argv[index];
|
|
188
|
+
|
|
135
189
|
if (value === "--help" || value === "-h") result.help = true;
|
|
136
190
|
else if (value.startsWith("--")) result[value.slice(2)] = argv[++index];
|
|
137
191
|
else result._.push(value);
|
|
138
192
|
}
|
|
193
|
+
|
|
139
194
|
return result;
|
|
140
195
|
}
|
|
141
196
|
|
|
@@ -147,5 +202,6 @@ Opciones:
|
|
|
147
202
|
--output <directorio> Directorio de destino
|
|
148
203
|
--template-path <path> Usar un template local, útil para desarrollo
|
|
149
204
|
--template-repo <repo> URL o ruta del repositorio template
|
|
205
|
+
--template-ref <ref> Rama o tag del template (default: rama por defecto)
|
|
150
206
|
-h, --help Mostrar esta ayuda`);
|
|
151
207
|
}
|