create-nevex-agent 0.1.0 → 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.
@@ -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(args["template-repo"] ?? process.env.NEVEX_AGENT_TEMPLATE_REPO);
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
- execFileSync("git", ["clone", "--depth", "1", repo, directory], { stdio: "inherit" });
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
- /APP_NAME = "[^"]*"/,
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,22 +182,26 @@ 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
 
142
197
  function printHelp() {
143
- console.log(`Uso: npx @nevex/create-nevex-agent <nombre> [opciones]
198
+ console.log(`Uso: npx create-nevex-agent <nombre> [opciones]
144
199
 
145
200
  Opciones:
146
201
  --display-name <nombre> Nombre visible del agente
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nevex-agent",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Create a custom Nevex WhatsApp agent project",
5
5
  "bin": {
6
6
  "create-nevex-agent": "bin/create-nevex-agent.mjs"