@damenor/agent-docs 0.1.2 → 0.4.1
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/README.md +65 -29
- package/dist/index.js +3848 -217
- package/package.json +5 -2
- package/templates/modules/agents/.agents/agents/doc-designer.md +39 -37
- package/templates/modules/agents/.agents/agents/doc-maintainer.md +35 -35
- package/templates/modules/agents/.agents/agents/doc-reviewer.md +55 -46
- package/templates/modules/agents/.agents/agents/doc-writer.md +34 -33
- package/templates/modules/agents/.agents/agents/reviewer.md +114 -100
- package/templates/modules/agents/.agents/skills/doc-design/SKILL.md +176 -174
- package/templates/modules/agents/.agents/skills/doc-design/references/design-system-format.md +241 -247
- package/templates/modules/agents/.agents/skills/doc-maintain/SKILL.md +61 -51
- package/templates/modules/agents/.agents/skills/doc-maintain/references/triggers.md +171 -165
- package/templates/modules/agents/.agents/skills/doc-review/SKILL.md +39 -34
- package/templates/modules/agents/.agents/skills/doc-review/references/health-checklist.md +115 -112
- package/templates/modules/agents/.agents/skills/doc-scaffold/SKILL.md +19 -12
- package/templates/modules/agents/.agents/skills/doc-scaffold/references/diataxis-quick-ref.md +110 -110
- package/templates/modules/agents/.agents/skills/doc-write/SKILL.md +47 -18
- package/templates/modules/agents/.agents/skills/doc-write/references/adr-format.md +99 -93
- package/templates/modules/agents/.agents/skills/doc-write/references/diataxis-patterns.md +221 -200
- package/templates/base/AGENTS.md +0 -177
- package/templates/base/CHANGELOG.md +0 -86
- package/templates/base/README.md +0 -105
- package/templates/base/docs/CONTEXT.md +0 -111
- package/templates/base/docs/README.md +0 -131
- package/templates/base/docs/adr/TEMPLATE.md +0 -83
- package/templates/modules/design/docs/DESIGN.md +0 -253
- package/templates/modules/explanation/docs/explanation/agent-flow.md +0 -15
- package/templates/modules/explanation/docs/explanation/architecture.md +0 -138
- package/templates/modules/guides/docs/guides/deployment.md +0 -189
- package/templates/modules/guides/docs/guides/runbooks/TEMPLATE.md +0 -86
- package/templates/modules/guides/docs/guides/troubleshooting.md +0 -65
- package/templates/modules/operations/docs/operations/README.md +0 -115
- package/templates/modules/product/docs/product/overview.md +0 -90
- package/templates/modules/product/docs/roadmap.md +0 -80
- package/templates/modules/reference/docs/reference/api.md +0 -131
- package/templates/modules/reference/docs/reference/code-style.md +0 -275
- package/templates/modules/reference/docs/reference/configuration.md +0 -117
- package/templates/modules/reference/docs/reference/infrastructure.md +0 -191
- package/templates/modules/tutorials/docs/tutorials/environment-setup.md +0 -212
- package/templates/modules/tutorials/docs/tutorials/first-task.md +0 -246
- package/templates/modules/tutorials/docs/tutorials/quick-start.md +0 -146
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import * as
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
4
|
+
import * as p2 from "@clack/prompts";
|
|
5
|
+
import pc4 from "picocolors";
|
|
6
|
+
import path7 from "path";
|
|
7
|
+
import fs7 from "fs";
|
|
8
8
|
import url from "url";
|
|
9
9
|
|
|
10
10
|
// src/utils/colors.ts
|
|
@@ -55,34 +55,21 @@ var DOC_MODULES = [
|
|
|
55
55
|
label: "Tutoriales",
|
|
56
56
|
hint: "quick-start, environment, first-task",
|
|
57
57
|
templateDir: "tutorials",
|
|
58
|
-
files: [
|
|
59
|
-
"docs/tutorials/quick-start.md",
|
|
60
|
-
"docs/tutorials/environment-setup.md",
|
|
61
|
-
"docs/tutorials/first-task.md"
|
|
62
|
-
]
|
|
58
|
+
files: ["docs/tutorials/quick-start.md", "docs/tutorials/environment-setup.md", "docs/tutorials/first-task.md"]
|
|
63
59
|
},
|
|
64
60
|
{
|
|
65
61
|
value: "guides",
|
|
66
62
|
label: "Gu\xEDas",
|
|
67
63
|
hint: "deployment, troubleshooting, runbooks",
|
|
68
64
|
templateDir: "guides",
|
|
69
|
-
files: [
|
|
70
|
-
"docs/guides/deployment.md",
|
|
71
|
-
"docs/guides/troubleshooting.md",
|
|
72
|
-
"docs/guides/runbooks/TEMPLATE.md"
|
|
73
|
-
]
|
|
65
|
+
files: ["docs/guides/deployment.md", "docs/guides/troubleshooting.md", "docs/guides/runbooks/TEMPLATE.md"]
|
|
74
66
|
},
|
|
75
67
|
{
|
|
76
68
|
value: "reference",
|
|
77
69
|
label: "Referencia",
|
|
78
70
|
hint: "API, config, infra, code-style",
|
|
79
71
|
templateDir: "reference",
|
|
80
|
-
files: [
|
|
81
|
-
"docs/reference/api.md",
|
|
82
|
-
"docs/reference/configuration.md",
|
|
83
|
-
"docs/reference/infrastructure.md",
|
|
84
|
-
"docs/reference/code-style.md"
|
|
85
|
-
]
|
|
72
|
+
files: ["docs/reference/api.md", "docs/reference/configuration.md", "docs/reference/infrastructure.md", "docs/reference/code-style.md"]
|
|
86
73
|
},
|
|
87
74
|
{
|
|
88
75
|
value: "explanation",
|
|
@@ -225,96 +212,3743 @@ function detectStack(targetDir) {
|
|
|
225
212
|
}
|
|
226
213
|
return null;
|
|
227
214
|
}
|
|
228
|
-
function detectNodeStack(packageJsonContent, dir) {
|
|
229
|
-
const pkg2 = JSON.parse(packageJsonContent);
|
|
230
|
-
const deps = { ...pkg2.dependencies, ...pkg2.devDependencies };
|
|
231
|
-
let framework;
|
|
232
|
-
if (deps["next"]) framework = `Next.js ${deps["next"].replace("^", "").replace("~", "")}`;
|
|
233
|
-
else if (deps["nuxt"]) framework = `Nuxt ${deps["nuxt"].replace("^", "").replace("~", "")}`;
|
|
234
|
-
else if (deps["astro"]) framework = `Astro ${deps["astro"].replace("^", "").replace("~", "")}`;
|
|
235
|
-
else if (deps["svelte"] || deps["@sveltejs/kit"]) framework = "SvelteKit";
|
|
236
|
-
else if (deps["react"]) framework = `React ${deps["react"].replace("^", "").replace("~", "")}`;
|
|
237
|
-
else if (deps["vue"]) framework = `Vue ${deps["vue"].replace("^", "").replace("~", "")}`;
|
|
238
|
-
else if (deps["express"]) framework = "Express";
|
|
239
|
-
else if (deps["fastify"]) framework = "Fastify";
|
|
240
|
-
else if (deps["hono"]) framework = "Hono";
|
|
241
|
-
else if (deps["@nestjs/core"]) framework = "NestJS";
|
|
242
|
-
let packageManager = "npm";
|
|
243
|
-
if (fs.existsSync(path.join(dir, "pnpm-lock.yaml"))) packageManager = "pnpm";
|
|
244
|
-
else if (fs.existsSync(path.join(dir, "yarn.lock"))) packageManager = "yarn";
|
|
245
|
-
else if (fs.existsSync(path.join(dir, "bun.lockb"))) packageManager = "bun";
|
|
246
|
-
const scripts = pkg2.scripts || {};
|
|
247
|
-
const run = packageManager === "npm" ? "npm run" : packageManager;
|
|
248
|
-
const hasTypeScript = deps["typescript"] || fs.existsSync(path.join(dir, "tsconfig.json"));
|
|
249
|
-
return {
|
|
250
|
-
language: hasTypeScript ? "TypeScript" : "JavaScript",
|
|
251
|
-
framework,
|
|
252
|
-
packageManager,
|
|
253
|
-
devCommand: scripts.dev ? `${run} dev` : void 0,
|
|
254
|
-
buildCommand: scripts.build ? `${run} build` : void 0,
|
|
255
|
-
testCommand: scripts.test ? `${run} test` : void 0,
|
|
256
|
-
lintCommand: scripts.lint ? `${run} lint` : void 0
|
|
257
|
-
};
|
|
215
|
+
function detectNodeStack(packageJsonContent, dir) {
|
|
216
|
+
const pkg2 = JSON.parse(packageJsonContent);
|
|
217
|
+
const deps = { ...pkg2.dependencies, ...pkg2.devDependencies };
|
|
218
|
+
let framework;
|
|
219
|
+
if (deps["next"]) framework = `Next.js ${deps["next"].replace("^", "").replace("~", "")}`;
|
|
220
|
+
else if (deps["nuxt"]) framework = `Nuxt ${deps["nuxt"].replace("^", "").replace("~", "")}`;
|
|
221
|
+
else if (deps["astro"]) framework = `Astro ${deps["astro"].replace("^", "").replace("~", "")}`;
|
|
222
|
+
else if (deps["svelte"] || deps["@sveltejs/kit"]) framework = "SvelteKit";
|
|
223
|
+
else if (deps["react"]) framework = `React ${deps["react"].replace("^", "").replace("~", "")}`;
|
|
224
|
+
else if (deps["vue"]) framework = `Vue ${deps["vue"].replace("^", "").replace("~", "")}`;
|
|
225
|
+
else if (deps["express"]) framework = "Express";
|
|
226
|
+
else if (deps["fastify"]) framework = "Fastify";
|
|
227
|
+
else if (deps["hono"]) framework = "Hono";
|
|
228
|
+
else if (deps["@nestjs/core"]) framework = "NestJS";
|
|
229
|
+
let packageManager = "npm";
|
|
230
|
+
if (fs.existsSync(path.join(dir, "pnpm-lock.yaml"))) packageManager = "pnpm";
|
|
231
|
+
else if (fs.existsSync(path.join(dir, "yarn.lock"))) packageManager = "yarn";
|
|
232
|
+
else if (fs.existsSync(path.join(dir, "bun.lockb"))) packageManager = "bun";
|
|
233
|
+
const scripts = pkg2.scripts || {};
|
|
234
|
+
const run = packageManager === "npm" ? "npm run" : packageManager;
|
|
235
|
+
const hasTypeScript = deps["typescript"] || fs.existsSync(path.join(dir, "tsconfig.json"));
|
|
236
|
+
return {
|
|
237
|
+
language: hasTypeScript ? "TypeScript" : "JavaScript",
|
|
238
|
+
framework,
|
|
239
|
+
packageManager,
|
|
240
|
+
devCommand: scripts.dev ? `${run} dev` : void 0,
|
|
241
|
+
buildCommand: scripts.build ? `${run} build` : void 0,
|
|
242
|
+
testCommand: scripts.test ? `${run} test` : void 0,
|
|
243
|
+
lintCommand: scripts.lint ? `${run} lint` : void 0
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function formatStack(stack) {
|
|
247
|
+
const parts = [stack.language];
|
|
248
|
+
if (stack.framework) parts.push(stack.framework);
|
|
249
|
+
if (stack.packageManager) parts.push(`(${stack.packageManager})`);
|
|
250
|
+
return parts.join(" + ");
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// src/generator.ts
|
|
254
|
+
import path6 from "path";
|
|
255
|
+
import { fileURLToPath } from "url";
|
|
256
|
+
import fs6 from "fs";
|
|
257
|
+
|
|
258
|
+
// src/conflict-resolver.ts
|
|
259
|
+
import * as p from "@clack/prompts";
|
|
260
|
+
import pc3 from "picocolors";
|
|
261
|
+
import fs5 from "fs";
|
|
262
|
+
import path5 from "path";
|
|
263
|
+
|
|
264
|
+
// src/conflict-detector.ts
|
|
265
|
+
import fs2 from "fs";
|
|
266
|
+
import path2 from "path";
|
|
267
|
+
function detectConflicts(plannedFiles, targetDir) {
|
|
268
|
+
const entries = [];
|
|
269
|
+
for (const plannedFile of plannedFiles) {
|
|
270
|
+
const targetPath = path2.join(targetDir, plannedFile.relativePath);
|
|
271
|
+
const exists = fs2.existsSync(targetPath);
|
|
272
|
+
const status = exists ? "conflict" : "no-conflict";
|
|
273
|
+
entries.push({
|
|
274
|
+
plannedFile,
|
|
275
|
+
status,
|
|
276
|
+
resolution: "skip",
|
|
277
|
+
result: exists ? "skipped" : "created"
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
return entries;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// src/merge-agents.ts
|
|
284
|
+
var HEADING_RE = /^## (.+)$/gm;
|
|
285
|
+
function parseSections(content) {
|
|
286
|
+
const sections = [];
|
|
287
|
+
let preamble = "";
|
|
288
|
+
let match;
|
|
289
|
+
HEADING_RE.lastIndex = 0;
|
|
290
|
+
const headingMatches = [];
|
|
291
|
+
while ((match = HEADING_RE.exec(content)) !== null) {
|
|
292
|
+
headingMatches.push({ index: match.index, heading: match[1] });
|
|
293
|
+
}
|
|
294
|
+
if (headingMatches.length === 0) {
|
|
295
|
+
return { preamble: content, sections: [] };
|
|
296
|
+
}
|
|
297
|
+
preamble = content.slice(0, headingMatches[0].index).trimEnd();
|
|
298
|
+
for (let i = 0; i < headingMatches.length; i++) {
|
|
299
|
+
const current = headingMatches[i];
|
|
300
|
+
const next = headingMatches[i + 1];
|
|
301
|
+
const sectionContent = next ? content.slice(current.index, next.index) : content.slice(current.index);
|
|
302
|
+
sections.push({
|
|
303
|
+
heading: current.heading,
|
|
304
|
+
content: sectionContent.trimEnd()
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
return { preamble, sections };
|
|
308
|
+
}
|
|
309
|
+
function mergeAgentsMd(existingContent, templateContent) {
|
|
310
|
+
const existing = parseSections(existingContent);
|
|
311
|
+
const template = parseSections(templateContent);
|
|
312
|
+
const existingHeadings = new Set(existing.sections.map((s) => s.heading));
|
|
313
|
+
const resultParts = [existing.preamble, ""];
|
|
314
|
+
for (const section of existing.sections) {
|
|
315
|
+
resultParts.push(section.content);
|
|
316
|
+
}
|
|
317
|
+
for (const section of template.sections) {
|
|
318
|
+
if (!existingHeadings.has(section.heading)) {
|
|
319
|
+
resultParts.push(section.content);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return resultParts.join("\n\n").trim() + "\n";
|
|
323
|
+
}
|
|
324
|
+
function isAgentsMd(relativePath) {
|
|
325
|
+
return relativePath.toLowerCase().endsWith("agents.md");
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// src/report.ts
|
|
329
|
+
import pc2 from "picocolors";
|
|
330
|
+
function groupByResult(entries) {
|
|
331
|
+
const groups = { created: [], overwritten: [], skipped: [], merged: [] };
|
|
332
|
+
for (const entry of entries) {
|
|
333
|
+
switch (entry.result) {
|
|
334
|
+
case "created":
|
|
335
|
+
groups.created.push(entry.plannedFile.relativePath);
|
|
336
|
+
break;
|
|
337
|
+
case "overwritten":
|
|
338
|
+
groups.overwritten.push(entry.plannedFile.relativePath);
|
|
339
|
+
break;
|
|
340
|
+
case "skipped":
|
|
341
|
+
groups.skipped.push(entry.plannedFile.relativePath);
|
|
342
|
+
break;
|
|
343
|
+
case "merged":
|
|
344
|
+
groups.merged.push(entry.plannedFile.relativePath);
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return groups;
|
|
349
|
+
}
|
|
350
|
+
function formatFileList(files, maxDisplay = 5) {
|
|
351
|
+
if (files.length === 0) return "";
|
|
352
|
+
const display = files.slice(0, maxDisplay);
|
|
353
|
+
const remaining = files.length - maxDisplay;
|
|
354
|
+
const suffix = remaining > 0 ? `, ... (+${remaining})` : "";
|
|
355
|
+
return display.join(", ") + suffix;
|
|
356
|
+
}
|
|
357
|
+
function printReport(entries) {
|
|
358
|
+
const groups = groupByResult(entries);
|
|
359
|
+
const rows = [];
|
|
360
|
+
const statusMap = [
|
|
361
|
+
{ icon: "\u2705", label: "Created", files: groups.created, count: groups.created.length },
|
|
362
|
+
{ icon: "\u{1F504}", label: "Overwritten", files: groups.overwritten, count: groups.overwritten.length },
|
|
363
|
+
{ icon: "\u23ED\uFE0F", label: "Skipped", files: groups.skipped, count: groups.skipped.length },
|
|
364
|
+
{ icon: "\u{1F500}", label: "Merged", files: groups.merged, count: groups.merged.length }
|
|
365
|
+
];
|
|
366
|
+
rows.push(`
|
|
367
|
+
${pc2.bold("\u{1F4CA} Report:")}
|
|
368
|
+
`);
|
|
369
|
+
rows.push(` ${pc2.dim("Status".padEnd(20))} ${pc2.dim("Count")}`);
|
|
370
|
+
rows.push(` ${pc2.dim("\u2500".repeat(20))} ${pc2.dim("\u2500".repeat(5))}`);
|
|
371
|
+
for (const { icon, label, files, count } of statusMap) {
|
|
372
|
+
if (count > 0) {
|
|
373
|
+
const fileList = formatFileList(files);
|
|
374
|
+
rows.push(` ${icon} ${pc2.bold(label.padEnd(14))} ${String(count).padStart(3)} ${pc2.dim(fileList)}`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
console.log(rows.join("\n"));
|
|
378
|
+
}
|
|
379
|
+
function printSkippedWarning(entries) {
|
|
380
|
+
const skipped = entries.filter((e) => e.result === "skipped");
|
|
381
|
+
if (skipped.length === 0) return;
|
|
382
|
+
const fileList = skipped.map((e) => ` - ${e.plannedFile.relativePath}`).join("\n");
|
|
383
|
+
console.log(
|
|
384
|
+
`
|
|
385
|
+
${pc2.yellow(`${icons.warning} ${pc2.bold(`${skipped.length} archivo${skipped.length > 1 ? "s" : ""} saltado${skipped.length > 1 ? "s" : ""}`)} \u2014 tu documentaci\xF3n puede estar incompleta:`)}
|
|
386
|
+
${pc2.yellow(fileList)}
|
|
387
|
+
|
|
388
|
+
${pc2.dim("\u{1F4A1} Ejecuta de nuevo con ")}${pc2.cyan("--force")}${pc2.dim(' para sobrescribir, o elige "overwrite" para esos archivos.')}`
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
function printDryRunReport(entries) {
|
|
392
|
+
const conflicts = entries.filter((e) => e.status === "conflict");
|
|
393
|
+
const clean = entries.filter((e) => e.status === "no-conflict");
|
|
394
|
+
console.log(`
|
|
395
|
+
${pc2.blue("\u2139 Dry run \u2014 no files will be written")}
|
|
396
|
+
`);
|
|
397
|
+
console.log(`${pc2.bold("\u{1F4CA} Would generate:")}
|
|
398
|
+
`);
|
|
399
|
+
if (clean.length > 0) {
|
|
400
|
+
const fileList = formatFileList(clean.map((e) => e.plannedFile.relativePath));
|
|
401
|
+
console.log(` \u2705 ${pc2.bold("Would create".padEnd(14))} ${String(clean.length).padStart(3)} ${pc2.dim(fileList)}`);
|
|
402
|
+
}
|
|
403
|
+
if (conflicts.length > 0) {
|
|
404
|
+
const fileList = formatFileList(conflicts.map((e) => e.plannedFile.relativePath));
|
|
405
|
+
console.log(` \u26A0\uFE0F ${pc2.yellow(pc2.bold("Conflict".padEnd(14)))} ${String(conflicts.length).padStart(3)} ${pc2.dim(fileList)}`);
|
|
406
|
+
}
|
|
407
|
+
console.log(`
|
|
408
|
+
${pc2.dim("Run without --dry-run to execute.")}`);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// src/utils/fs.ts
|
|
412
|
+
import fs3 from "fs";
|
|
413
|
+
import path3 from "path";
|
|
414
|
+
function ensureDir(dirPath) {
|
|
415
|
+
if (!fs3.existsSync(dirPath)) {
|
|
416
|
+
fs3.mkdirSync(dirPath, { recursive: true });
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function isDirEmpty(dirPath) {
|
|
420
|
+
if (!fs3.existsSync(dirPath)) return true;
|
|
421
|
+
const files = fs3.readdirSync(dirPath);
|
|
422
|
+
return files.length === 0 || files.length === 1 && files[0] === ".git";
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// src/conditional.ts
|
|
426
|
+
import fs4 from "fs";
|
|
427
|
+
import path4 from "path";
|
|
428
|
+
var FRONTEND_FRAMEWORKS = ["next.js", "nuxt", "astro", "svelte", "sveltekit", "react", "vue", "angular", "solid", "qwik"];
|
|
429
|
+
var BACKEND_FRAMEWORKS = [
|
|
430
|
+
"express",
|
|
431
|
+
"fastify",
|
|
432
|
+
"hono",
|
|
433
|
+
"nestjs",
|
|
434
|
+
"nest",
|
|
435
|
+
"django",
|
|
436
|
+
"fastapi",
|
|
437
|
+
"flask",
|
|
438
|
+
"gin",
|
|
439
|
+
"echo",
|
|
440
|
+
"fiber",
|
|
441
|
+
"actix",
|
|
442
|
+
"axum",
|
|
443
|
+
"rocket",
|
|
444
|
+
"spring boot"
|
|
445
|
+
];
|
|
446
|
+
var DB_FILE_PATTERNS = [
|
|
447
|
+
"prisma/schema.prisma",
|
|
448
|
+
"drizzle.config.ts",
|
|
449
|
+
"drizzle.config.js",
|
|
450
|
+
"typeorm.config.ts",
|
|
451
|
+
"knexfile.ts",
|
|
452
|
+
"knexfile.js",
|
|
453
|
+
"sequelize.config.js",
|
|
454
|
+
"alembic.ini",
|
|
455
|
+
"migrations"
|
|
456
|
+
];
|
|
457
|
+
function buildConditionContext(stack, targetDir) {
|
|
458
|
+
const lang = (stack?.language || "").toLowerCase();
|
|
459
|
+
const fw = (stack?.framework || "").toLowerCase();
|
|
460
|
+
const isNode = lang.includes("javascript") || lang.includes("typescript");
|
|
461
|
+
const isPython = lang.includes("python");
|
|
462
|
+
const isGo = lang.includes("go");
|
|
463
|
+
const isRust = lang.includes("rust");
|
|
464
|
+
const isJava = lang.includes("java") || lang.includes("kotlin");
|
|
465
|
+
const hasFrontend = FRONTEND_FRAMEWORKS.some((f) => fw.includes(f));
|
|
466
|
+
const hasBackend = BACKEND_FRAMEWORKS.some((f) => fw.includes(f));
|
|
467
|
+
const hasTypeScript = lang.includes("typescript");
|
|
468
|
+
let hasDatabase = false;
|
|
469
|
+
if (targetDir) {
|
|
470
|
+
hasDatabase = DB_FILE_PATTERNS.some((pattern) => {
|
|
471
|
+
const fullPath = path4.join(targetDir, pattern);
|
|
472
|
+
return fs4.existsSync(fullPath);
|
|
473
|
+
});
|
|
474
|
+
if (!hasDatabase && (fw.includes("django") || fw.includes("spring"))) {
|
|
475
|
+
hasDatabase = true;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
let hasDocker = false;
|
|
479
|
+
if (targetDir) {
|
|
480
|
+
hasDocker = fs4.existsSync(path4.join(targetDir, "Dockerfile")) || fs4.existsSync(path4.join(targetDir, "docker-compose.yml")) || fs4.existsSync(path4.join(targetDir, "docker-compose.yaml"));
|
|
481
|
+
}
|
|
482
|
+
let hasCI = false;
|
|
483
|
+
if (targetDir) {
|
|
484
|
+
hasCI = fs4.existsSync(path4.join(targetDir, ".github", "workflows")) || fs4.existsSync(path4.join(targetDir, ".gitlab-ci.yml")) || fs4.existsSync(path4.join(targetDir, ".circleci"));
|
|
485
|
+
}
|
|
486
|
+
let hasMonorepo = false;
|
|
487
|
+
if (targetDir) {
|
|
488
|
+
const pkgPath = path4.join(targetDir, "package.json");
|
|
489
|
+
if (fs4.existsSync(pkgPath)) {
|
|
490
|
+
try {
|
|
491
|
+
const pkg2 = JSON.parse(fs4.readFileSync(pkgPath, "utf-8"));
|
|
492
|
+
hasMonorepo = !!(pkg2.workspaces || pkg2.pnpm?.workspaces);
|
|
493
|
+
} catch {
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (!hasMonorepo) {
|
|
497
|
+
hasMonorepo = fs4.existsSync(path4.join(targetDir, "packages"));
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return {
|
|
501
|
+
hasDatabase,
|
|
502
|
+
hasFrontend,
|
|
503
|
+
hasBackend,
|
|
504
|
+
hasDocker,
|
|
505
|
+
hasCI,
|
|
506
|
+
isNode,
|
|
507
|
+
isPython,
|
|
508
|
+
isGo,
|
|
509
|
+
isRust,
|
|
510
|
+
isJava,
|
|
511
|
+
hasMonorepo,
|
|
512
|
+
hasTypeScript
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
function renderConditionalBlocks(content, ctx) {
|
|
516
|
+
const blockRegex = /\{\{#if\s+(\w+)\}\}([\s\S]*?)\{\{\/if\s+\1\}\}/g;
|
|
517
|
+
let result = content;
|
|
518
|
+
let prevResult = "";
|
|
519
|
+
let iterations = 0;
|
|
520
|
+
const MAX_ITERATIONS = 10;
|
|
521
|
+
while (result !== prevResult && iterations < MAX_ITERATIONS) {
|
|
522
|
+
prevResult = result;
|
|
523
|
+
result = result.replace(blockRegex, (_match, condition, block) => {
|
|
524
|
+
const value = ctx[condition];
|
|
525
|
+
return value ? block : "";
|
|
526
|
+
});
|
|
527
|
+
iterations++;
|
|
528
|
+
}
|
|
529
|
+
result = result.replace(/\n{3,}/g, "\n\n");
|
|
530
|
+
return result;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// src/conflict-resolver.ts
|
|
534
|
+
async function resolveConflicts(entries, options) {
|
|
535
|
+
const conflicts = entries.filter((e) => e.status === "conflict");
|
|
536
|
+
if (options.dryRun) {
|
|
537
|
+
printDryRunReport(entries);
|
|
538
|
+
return entries;
|
|
539
|
+
}
|
|
540
|
+
if (options.force) {
|
|
541
|
+
for (const entry of entries) {
|
|
542
|
+
if (entry.status === "conflict") {
|
|
543
|
+
entry.resolution = "overwrite";
|
|
544
|
+
entry.result = "overwritten";
|
|
545
|
+
} else {
|
|
546
|
+
entry.resolution = "skip";
|
|
547
|
+
entry.result = "created";
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return entries;
|
|
551
|
+
}
|
|
552
|
+
if (conflicts.length === 0) {
|
|
553
|
+
for (const entry of entries) {
|
|
554
|
+
entry.resolution = "skip";
|
|
555
|
+
entry.result = "created";
|
|
556
|
+
}
|
|
557
|
+
return entries;
|
|
558
|
+
}
|
|
559
|
+
if (!isInteractive()) {
|
|
560
|
+
const skipped = conflicts.map((e) => e.plannedFile.relativePath).join(", ");
|
|
561
|
+
console.log(`${icons.warning} ${pc3.yellow(`${conflicts.length} file(s) conflict \u2014 skipping (non-interactive): ${skipped}`)}`);
|
|
562
|
+
for (const entry of entries) {
|
|
563
|
+
if (entry.status === "conflict") {
|
|
564
|
+
entry.resolution = "skip";
|
|
565
|
+
entry.result = "skipped";
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return entries;
|
|
569
|
+
}
|
|
570
|
+
console.log(`
|
|
571
|
+
${icons.warning} ${pc3.yellow(pc3.bold(`${conflicts.length} conflicting file${conflicts.length > 1 ? "s" : ""} detected:`))}
|
|
572
|
+
`);
|
|
573
|
+
const MAX_DISPLAY = 10;
|
|
574
|
+
const displayedConflicts = conflicts.slice(0, MAX_DISPLAY);
|
|
575
|
+
const remaining = conflicts.length - MAX_DISPLAY;
|
|
576
|
+
for (const entry of displayedConflicts) {
|
|
577
|
+
const isAgent = isAgentsMd(entry.plannedFile.relativePath);
|
|
578
|
+
const actionHint = isAgent ? `${pc3.dim("(merge recommended)")}` : "";
|
|
579
|
+
console.log(` ${icons.docs} ${brand.path(entry.plannedFile.relativePath)} ${actionHint}`);
|
|
580
|
+
}
|
|
581
|
+
if (remaining > 0) {
|
|
582
|
+
console.log(` ${pc3.dim(`...and ${remaining} more`)}`);
|
|
583
|
+
}
|
|
584
|
+
console.log("");
|
|
585
|
+
const defaultAction = await p.select({
|
|
586
|
+
message: "Default action for conflicting files",
|
|
587
|
+
options: [
|
|
588
|
+
{ value: "skip", label: "Skip", hint: "keep existing files (recommended)" },
|
|
589
|
+
{ value: "overwrite", label: "Overwrite", hint: "replace all with template content" }
|
|
590
|
+
]
|
|
591
|
+
});
|
|
592
|
+
if (p.isCancel(defaultAction)) {
|
|
593
|
+
p.cancel("Operation cancelled.");
|
|
594
|
+
process.exit(0);
|
|
595
|
+
}
|
|
596
|
+
let perFileOverride = false;
|
|
597
|
+
if (conflicts.length <= 10) {
|
|
598
|
+
perFileOverride = true;
|
|
599
|
+
} else {
|
|
600
|
+
const wantsOverride = await p.confirm({
|
|
601
|
+
message: `You have ${conflicts.length} conflicts. Override per file?`,
|
|
602
|
+
initialValue: false
|
|
603
|
+
});
|
|
604
|
+
if (!p.isCancel(wantsOverride)) {
|
|
605
|
+
perFileOverride = wantsOverride;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
for (const entry of conflicts) {
|
|
609
|
+
let resolution = defaultAction;
|
|
610
|
+
if (perFileOverride) {
|
|
611
|
+
const isAgent = isAgentsMd(entry.plannedFile.relativePath);
|
|
612
|
+
const options2 = [
|
|
613
|
+
{ value: "skip", label: "Skip", hint: "keep existing" },
|
|
614
|
+
{ value: "overwrite", label: "Overwrite", hint: "replace" }
|
|
615
|
+
];
|
|
616
|
+
if (isAgent) {
|
|
617
|
+
options2.push({ value: "merge", label: "Merge", hint: "add missing sections" });
|
|
618
|
+
}
|
|
619
|
+
const picked = await p.select({
|
|
620
|
+
message: `${entry.plannedFile.relativePath}`,
|
|
621
|
+
options: options2,
|
|
622
|
+
initialValue: isAgent ? "merge" : "skip"
|
|
623
|
+
});
|
|
624
|
+
if (p.isCancel(picked)) {
|
|
625
|
+
p.cancel("Operation cancelled.");
|
|
626
|
+
process.exit(0);
|
|
627
|
+
}
|
|
628
|
+
resolution = picked;
|
|
629
|
+
}
|
|
630
|
+
entry.resolution = resolution;
|
|
631
|
+
}
|
|
632
|
+
return entries;
|
|
633
|
+
}
|
|
634
|
+
function executePlan(entries, options) {
|
|
635
|
+
for (const entry of entries) {
|
|
636
|
+
const targetPath = path5.join(options.targetDir, entry.plannedFile.relativePath);
|
|
637
|
+
switch (entry.resolution) {
|
|
638
|
+
case "skip": {
|
|
639
|
+
if (entry.status === "no-conflict") {
|
|
640
|
+
ensureDir(path5.dirname(targetPath));
|
|
641
|
+
writeWithReplacements(targetPath, entry.plannedFile.sourcePath, entry.plannedFile.replacements, options.conditionCtx, entry.plannedFile.content);
|
|
642
|
+
entry.result = "created";
|
|
643
|
+
} else {
|
|
644
|
+
entry.result = "skipped";
|
|
645
|
+
}
|
|
646
|
+
break;
|
|
647
|
+
}
|
|
648
|
+
case "overwrite": {
|
|
649
|
+
ensureDir(path5.dirname(targetPath));
|
|
650
|
+
writeWithReplacements(targetPath, entry.plannedFile.sourcePath, entry.plannedFile.replacements, options.conditionCtx, entry.plannedFile.content);
|
|
651
|
+
entry.result = entry.status === "conflict" ? "overwritten" : "created";
|
|
652
|
+
break;
|
|
653
|
+
}
|
|
654
|
+
case "merge": {
|
|
655
|
+
const existingContent = fs5.readFileSync(targetPath, "utf-8");
|
|
656
|
+
let templateContent = fs5.readFileSync(entry.plannedFile.sourcePath, "utf-8");
|
|
657
|
+
if (options.conditionCtx) {
|
|
658
|
+
templateContent = renderConditionalBlocks(templateContent, options.conditionCtx);
|
|
659
|
+
}
|
|
660
|
+
const merged = mergeAgentsMd(existingContent, templateContent);
|
|
661
|
+
let finalContent = merged;
|
|
662
|
+
for (const [key, value] of Object.entries(entry.plannedFile.replacements)) {
|
|
663
|
+
finalContent = finalContent.replaceAll(key, value);
|
|
664
|
+
}
|
|
665
|
+
fs5.writeFileSync(targetPath, finalContent, "utf-8");
|
|
666
|
+
entry.result = "merged";
|
|
667
|
+
break;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
return entries;
|
|
672
|
+
}
|
|
673
|
+
function writeWithReplacements(targetPath, sourcePath, replacements, conditionCtx, inlineContent) {
|
|
674
|
+
let content;
|
|
675
|
+
if (inlineContent !== void 0) {
|
|
676
|
+
content = inlineContent;
|
|
677
|
+
} else {
|
|
678
|
+
content = fs5.readFileSync(sourcePath, "utf-8");
|
|
679
|
+
if (conditionCtx) {
|
|
680
|
+
content = renderConditionalBlocks(content, conditionCtx);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
for (const [key, value] of Object.entries(replacements)) {
|
|
684
|
+
content = content.replaceAll(key, value);
|
|
685
|
+
}
|
|
686
|
+
fs5.writeFileSync(targetPath, content, "utf-8");
|
|
687
|
+
}
|
|
688
|
+
function isInteractive() {
|
|
689
|
+
if (process.env.CI === "true" || process.env.CI === "1") return false;
|
|
690
|
+
if (process.env.NODE_ENV === "test") return false;
|
|
691
|
+
return process.stdout.isTTY === true;
|
|
692
|
+
}
|
|
693
|
+
async function processConflicts(plannedFiles, options) {
|
|
694
|
+
const entries = detectConflicts(plannedFiles, options.targetDir);
|
|
695
|
+
const resolved = await resolveConflicts(entries, options);
|
|
696
|
+
if (options.dryRun) {
|
|
697
|
+
return [];
|
|
698
|
+
}
|
|
699
|
+
const results = executePlan(resolved, {
|
|
700
|
+
targetDir: options.targetDir,
|
|
701
|
+
conditionCtx: options.conditionCtx
|
|
702
|
+
});
|
|
703
|
+
printReport(results);
|
|
704
|
+
printSkippedWarning(results);
|
|
705
|
+
return results.filter((e) => e.result === "created" || e.result === "overwritten" || e.result === "merged").map((e) => e.plannedFile.relativePath);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// src/generators/i18n.ts
|
|
709
|
+
var registry = {};
|
|
710
|
+
function registerLabels(template, language, labels31) {
|
|
711
|
+
if (!registry[template]) {
|
|
712
|
+
registry[template] = {};
|
|
713
|
+
}
|
|
714
|
+
registry[template][language] = labels31;
|
|
715
|
+
}
|
|
716
|
+
function loadLabels(template, language) {
|
|
717
|
+
const langLabels = registry[template]?.[language];
|
|
718
|
+
if (langLabels) return langLabels;
|
|
719
|
+
const esLabels = registry[template]?.["es"];
|
|
720
|
+
if (esLabels) return esLabels;
|
|
721
|
+
return {};
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// src/generators/agents/labels/es.ts
|
|
725
|
+
var labels = {
|
|
726
|
+
// ── Frontmatter ──
|
|
727
|
+
fmType: "agent-protocol",
|
|
728
|
+
fmTags: "agents, protocolo, operativo, ia",
|
|
729
|
+
// ── Título ──
|
|
730
|
+
title: "AGENTS.md \u2014 Protocolo Operativo",
|
|
731
|
+
subtitle: "Reglas que TODO agente de IA debe seguir al trabajar en este proyecto. Gu\xEDa extendida: `docs/internal/agent-guide.md`.",
|
|
732
|
+
// ── STOP ──
|
|
733
|
+
stopTitle: "STOP \u2014 Lee esto ANTES de hacer nada",
|
|
734
|
+
stop1: "**TRIAGE**: Clasifica la tarea (SMALL/MEDIUM/LARGE). No saltes este paso.",
|
|
735
|
+
stop2: "**LEE**: Lee la documentaci\xF3n indicada en la tabla ANTES de escribir c\xF3digo.",
|
|
736
|
+
stop3: "**PREGUNTA**: Si hay ambig\xFCedad, haz TODAS las preguntas en UN solo mensaje.",
|
|
737
|
+
stop4: "**NO IMPLEMENTES** sin seguir el protocolo completo (MEDIUM/LARGE).",
|
|
738
|
+
stop5: "**@reviewer**: Invoca ANTES de marcar la tarea como completada (MEDIUM/LARGE).",
|
|
739
|
+
// ── Triage ──
|
|
740
|
+
triageTitle: "Triage de tarea",
|
|
741
|
+
triageIntro: "Antes de ejecutar el protocolo, clasificar la tarea:",
|
|
742
|
+
triageSizeHeader: "Tama\xF1o",
|
|
743
|
+
triageCriteriaHeader: "Criterio",
|
|
744
|
+
triageProtocolHeader: "Protocolo",
|
|
745
|
+
triageSmall: "**SMALL**",
|
|
746
|
+
triageSmallCriteria: "\u22642 archivos, <50 l\xEDneas",
|
|
747
|
+
triageSmallProtocol: "Leer CONTEXT.md \u2192 implementar \u2192 lint \u2192 done",
|
|
748
|
+
triageMedium: "**MEDIUM**",
|
|
749
|
+
triageMediumCriteria: "3-10 archivos, feature moderada",
|
|
750
|
+
triageMediumProtocol: "Protocolo completo (sin subdelegaci\xF3n)",
|
|
751
|
+
triageLarge: "**LARGE**",
|
|
752
|
+
triageLargeCriteria: "Multi-d\xEDa, arquitectural",
|
|
753
|
+
triageLargeProtocol: "Protocolo completo + ADR + subdelegaci\xF3n",
|
|
754
|
+
triageExamples: "**Ejemplos**: SMALL = fix typo, cambiar color, corregir import. MEDIUM = nuevo endpoint, nuevo componente, nuevo servicio simple. LARGE = sistema de auth, integraci\xF3n con provider externo, sistema de notificaciones multi-canal.",
|
|
755
|
+
triageEscalate: "Si empiezas SMALL y la tarea crece \u2192 escalar a MEDIUM.",
|
|
756
|
+
// ── Stack ──
|
|
757
|
+
stackTitle: "Stack y convenciones",
|
|
758
|
+
stackSectionTitle: "Stack",
|
|
759
|
+
stackFrontend: "**Frontend**",
|
|
760
|
+
stackBackend: "**Backend**",
|
|
761
|
+
stackDatabase: "**Base de datos**",
|
|
762
|
+
stackCICD: "**CI/CD**",
|
|
763
|
+
stackPlaceholder: "[framework y versi\xF3n \u2014 ej.",
|
|
764
|
+
stackDbPlaceholder: "[tipo y versi\xF3n \u2014 ej.",
|
|
765
|
+
stackCIPlaceholder: "[plataforma \u2014 ej.",
|
|
766
|
+
stackAutoDetectTitle: "Detecci\xF3n autom\xE1tica de stack",
|
|
767
|
+
stackAutoDetectDesc: "Si el stack no est\xE1 rellenado arriba, el agente debe detectarlo:",
|
|
768
|
+
stackFileHeader: "Archivo detectado",
|
|
769
|
+
stackEcosystemHeader: "Ecosistema",
|
|
770
|
+
stackCommandsHeader: "Comandos probables",
|
|
771
|
+
// ── Convenciones ──
|
|
772
|
+
conventionsTitle: "Convenios obligatorios",
|
|
773
|
+
convLang: "**Idioma del proyecto**: La documentaci\xF3n est\xE1 configurada en **{{PROJECT_LANGUAGE_LABEL}}** ({{PROJECT_LANGUAGE_CODE}}). Genera y actualiza toda la documentaci\xF3n en {{PROJECT_LANGUAGE_LABEL}}, independientemente del idioma en que te hable el usuario. El c\xF3digo fuente sigue en ingl\xE9s.",
|
|
774
|
+
convNaming: "**Nombramiento**: [convenci\xF3n de nombres \u2014 ej. camelCase variables/funciones, PascalCase componentes]",
|
|
775
|
+
convStructure: "**Estructura**: [convenci\xF3n \u2014 ej. feature-based folders]",
|
|
776
|
+
convTesting: "**Testing**: Todo c\xF3digo nuevo DEBE incluir tests.",
|
|
777
|
+
convLinting: "**Linting**: Pasar `npm run lint` sin errores antes de completar.",
|
|
778
|
+
convCommits: "**Commits**: Conventional Commits en espa\xF1ol: `tipo(alcance): descripci\xF3n`.",
|
|
779
|
+
convSecurity: "**Seguridad**: Nunca commitear secrets. Usar variables de entorno.",
|
|
780
|
+
convDeps: "**Dependencias**: No a\xF1adir sin justificaci\xF3n. Si se a\xF1ade \u2192 documentar en ADR.",
|
|
781
|
+
convA11y: "**Accesibilidad**: Todo componente UI cumple WCAG 2.1 AA.",
|
|
782
|
+
// ── Comandos ──
|
|
783
|
+
commandsTitle: "Comandos",
|
|
784
|
+
commandsHeaderCmd: "Comando",
|
|
785
|
+
commandsHeaderUsage: "Uso",
|
|
786
|
+
cmdDev: "Desarrollo con hot-reload",
|
|
787
|
+
cmdBuild: "Build producci\xF3n",
|
|
788
|
+
cmdTest: "Tests unitarios e integraci\xF3n",
|
|
789
|
+
cmdTestE2E: "Tests end-to-end",
|
|
790
|
+
cmdLint: "Linter (debe pasar sin errores)",
|
|
791
|
+
cmdTypecheck: "Verificaci\xF3n de tipos",
|
|
792
|
+
commandsDetail: "> **Detalle completo** de convenciones de git, commits, PRs y testing en [`docs/dev-workflow.md`](docs/dev-workflow.md).",
|
|
793
|
+
// ── ANTES ──
|
|
794
|
+
beforeTitle: "ANTES de cada tarea (MEDIUM/LARGE)",
|
|
795
|
+
before1Title: "1. Leer docs seg\xFAn tipo de tarea",
|
|
796
|
+
beforeTaskTypeHeader: "Tipo de tarea",
|
|
797
|
+
beforeDocHeader: "Documentaci\xF3n a leer primero",
|
|
798
|
+
beforeAny: "Cualquier tarea",
|
|
799
|
+
beforeFeature: "Feature nueva",
|
|
800
|
+
beforeBug: "Bug/UI/Estilo",
|
|
801
|
+
beforeAPI: "API/Backend",
|
|
802
|
+
beforeDeploy: "Deploy/Infra",
|
|
803
|
+
beforeArch: "Arquitectura",
|
|
804
|
+
before2Title: "2. Verificar ADRs existentes",
|
|
805
|
+
before2Desc: "Buscar en `docs/adr/` antes de tomar decisiones:",
|
|
806
|
+
before2Accept: "**Existe ADR aceptado** \u2192 SEGUIRLO. No reinventar.",
|
|
807
|
+
before2Contradict: "**Contradice lo que vas a hacer** \u2192 Plantear discusi\xF3n antes.",
|
|
808
|
+
before2None: "**No existe** \u2192 Evaluar si merece ADR (ver criterio y ejemplos en [`docs/adr/TEMPLATE.md`](docs/adr/TEMPLATE.md)).",
|
|
809
|
+
before3Title: "3. Verificar CONTEXT.md",
|
|
810
|
+
before3Desc: "Si la tarea usa t\xE9rminos que no est\xE1n en `docs/CONTEXT.md` \u2192 preparar para actualizar al terminar.",
|
|
811
|
+
before3Completeness: "Si `CONTEXT.md` tiene `completeness < 50%` \u2192 prioridad: completar CONTEXT.md antes de implementar features.",
|
|
812
|
+
before4Title: "4. Preguntar si hay ambig\xFCedad",
|
|
813
|
+
before4Desc: "Si despu\xE9s de leer la documentaci\xF3n hay ambig\xFCedad \u2192 **batch TODAS las preguntas en un solo mensaje**. Cada pregunta con opciones cuando sea posible. No preguntar una por una.",
|
|
814
|
+
before4DontAsk: "No preguntes si la tarea est\xE1 clara, es implementaci\xF3n est\xE1ndar, o la info est\xE1 en los docs.",
|
|
815
|
+
// ── DESPUÉS ──
|
|
816
|
+
afterTitle: "DESPU\xC9S de cada tarea (MEDIUM/LARGE)",
|
|
817
|
+
afterTreeTitle: "\xC1rbol post-tarea",
|
|
818
|
+
afterTreeNode1: "\xBFTomaste una decisi\xF3n?",
|
|
819
|
+
afterTreeNode1a: "Arquitect\xF3nica \u2192 docs/adr/ (ADR formal)",
|
|
820
|
+
afterTreeNode1b: "Implementaci\xF3n no obvia \u2192 JSDoc + docs/adr/ai-decisions.md",
|
|
821
|
+
afterTreeNode1c: "No \u2192 siguiente",
|
|
822
|
+
afterTreeNode2: "\xBFT\xE9rminos nuevos del dominio? \u2192 docs/CONTEXT.md",
|
|
823
|
+
afterTreeNode3: "\xBFEndpoints cambiados? \u2192 docs/reference/api.md",
|
|
824
|
+
afterTreeNode4: "\xBFUI/UX cambiada? \u2192 docs/DESIGN.md",
|
|
825
|
+
afterTreeNode5: "\xBFDeploy a producci\xF3n? \u2192 CHANGELOG.md + docs/guides/deployment.md",
|
|
826
|
+
afterTreeNode6: "\xBFFeature completado? \u2192 docs/roadmap.md",
|
|
827
|
+
afterTreeNode7: "\xBFGotcha descubierto? \u2192 docs/guides/troubleshooting.md",
|
|
828
|
+
afterTreeNode8: "\xBFRefactor de patrones? \u2192 Revisar architecture.md y ADRs",
|
|
829
|
+
afterGuide: "> **Gu\xEDa extendida** con diagramas y ejemplos en [`docs/internal/agent-guide.md`](docs/internal/agent-guide.md).",
|
|
830
|
+
afterSkill: "> **Alternativa**: Invocar skill `doc-maintain` para detectar cambios y sugerir actualizaciones autom\xE1ticamente.",
|
|
831
|
+
afterGoldenRule: "**Regla de oro**: Si cambias el c\xF3digo, cambias la documentaci\xF3n.",
|
|
832
|
+
// ── Quality Gate ──
|
|
833
|
+
qgTitle: "Quality Gate \u2014 @reviewer (MEDIUM/LARGE)",
|
|
834
|
+
qgIntro: "**ANTES de completar**, invocar `@reviewer` para verificar:",
|
|
835
|
+
qgItem1: "\u2705 Code style conforme a convenciones",
|
|
836
|
+
qgItem2: "\u2705 Sin duplicaci\xF3n \u2014 usa componentes/utilidades existentes",
|
|
837
|
+
qgItem3: "\u2705 Sigue la arquitectura del proyecto y respeta ADRs",
|
|
838
|
+
qgItem4: "\u2705 Sin vulnerabilidades de seguridad",
|
|
839
|
+
qgItem5: "\u2705 Tests incluidos para c\xF3digo nuevo",
|
|
840
|
+
qgItem6: "\u2705 Documentaci\xF3n actualizada",
|
|
841
|
+
qgItem7: "\u2705 Sin problemas de performance evidentes",
|
|
842
|
+
qgBlocking: "**\u274C BLOQUEANTE** \u2192 arreglar antes de completar.",
|
|
843
|
+
qgSuggested: "**\u26A0\uFE0F SUGERIDO** \u2192 recomendado pero no bloquea.",
|
|
844
|
+
// ── Subdelegación ──
|
|
845
|
+
subdelTitle: "Subdelegaci\xF3n",
|
|
846
|
+
subdelIntro: "Instrucciones m\xEDnimas al subagente:",
|
|
847
|
+
subdelExample: "> Lee AGENTS.md y sigue el protocolo completo. Tarea: [descripci\xF3n]. Docs relevantes: [lista].",
|
|
848
|
+
subdelNote: "No repitas convenciones \u2014 ya est\xE1n en AGENTS.md. Ver ejemplo completo en `docs/internal/agent-guide.md`.",
|
|
849
|
+
// ── Skills ──
|
|
850
|
+
skillsTitle: "Skills y agentes disponibles",
|
|
851
|
+
skillsList: "**Skills**: `doc-scaffold`, `doc-write`, `doc-design`, `doc-review`, `doc-maintain` \u2014 ver `.agents/skills/`",
|
|
852
|
+
agentsList: "**Agentes**: `@reviewer` (quality gate), `@doc-writer`, `@doc-reviewer`, `@doc-designer`, `@doc-maintainer` \u2014 ver `.agents/agents/`",
|
|
853
|
+
skillsGuide: "**Gu\xEDa extendida**: `docs/internal/agent-guide.md`",
|
|
854
|
+
// ── Tabla de detección de stack ──
|
|
855
|
+
stackRowPackage: "`package.json`",
|
|
856
|
+
stackRowNodeEco: "Node.js (npm/pnpm/yarn)",
|
|
857
|
+
stackRowNodeCmds: "`npm run dev`, `npm run build`",
|
|
858
|
+
stackRowPyReq: "`requirements.txt` / `pyproject.toml`",
|
|
859
|
+
stackRowPyEco: "Python (pip/poetry)",
|
|
860
|
+
stackRowPyCmds: "`python manage.py runserver`, `pytest`",
|
|
861
|
+
stackRowGo: "`go.mod`",
|
|
862
|
+
stackRowGoEco: "Go",
|
|
863
|
+
stackRowGoCmds: "`go run .`, `go test ./...`",
|
|
864
|
+
stackRowRust: "`Cargo.toml`",
|
|
865
|
+
stackRowRustEco: "Rust",
|
|
866
|
+
stackRowRustCmds: "`cargo run`, `cargo test`",
|
|
867
|
+
stackRowJava: "`pom.xml` / `build.gradle`",
|
|
868
|
+
stackRowJavaEco: "Java/Kotlin",
|
|
869
|
+
stackRowJavaCmds: "`mvn spring-boot:run`, `gradle bootRun`",
|
|
870
|
+
// ── Tabla de docs (ANTES) ──
|
|
871
|
+
beforeDocAny: "`docs/CONTEXT.md`",
|
|
872
|
+
beforeDocFeature: "`docs/roadmap.md`, `docs/explanation/architecture.md`, ADRs relevantes",
|
|
873
|
+
beforeDocBug: "`docs/DESIGN.md`, `docs/CONTEXT.md`",
|
|
874
|
+
beforeDocApi: "`docs/reference/api.md`, `docs/reference/configuration.md`",
|
|
875
|
+
beforeDocDeploy: "`docs/guides/deployment.md`, `docs/reference/infrastructure.md`",
|
|
876
|
+
beforeDocArch: "`docs/explanation/architecture.md`, `docs/adr/` (todos)",
|
|
877
|
+
// ── Comandos (valores) ──
|
|
878
|
+
cmdDevVal: "{{DEV_COMMAND}}",
|
|
879
|
+
cmdBuildVal: "{{BUILD_COMMAND}}",
|
|
880
|
+
cmdTestVal: "{{TEST_COMMAND}}",
|
|
881
|
+
cmdTestE2EVal: "[comando e2e]",
|
|
882
|
+
cmdLintVal: "{{LINT_COMMAND}}",
|
|
883
|
+
cmdTypecheckVal: "[comando typecheck]"
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
// src/generators/agents/labels/en.ts
|
|
887
|
+
var labels2 = {
|
|
888
|
+
// ── Frontmatter ──
|
|
889
|
+
fmType: "agent-protocol",
|
|
890
|
+
fmTags: "agents, protocol, operational, ai",
|
|
891
|
+
// ── Title ──
|
|
892
|
+
title: "AGENTS.md \u2014 Operational Protocol",
|
|
893
|
+
subtitle: "Rules that EVERY AI agent must follow when working on this project. Extended guide: `docs/internal/agent-guide.md`.",
|
|
894
|
+
// ── STOP ──
|
|
895
|
+
stopTitle: "STOP \u2014 Read this BEFORE doing anything",
|
|
896
|
+
stop1: "**TRIAGE**: Classify the task (SMALL/MEDIUM/LARGE). Don't skip this step.",
|
|
897
|
+
stop2: "**READ**: Read the documentation indicated in the table BEFORE writing code.",
|
|
898
|
+
stop3: "**ASK**: If there's ambiguity, ask ALL questions in ONE message.",
|
|
899
|
+
stop4: "**DON'T IMPLEMENT** without following the full protocol (MEDIUM/LARGE).",
|
|
900
|
+
stop5: "**@reviewer**: Invoke BEFORE marking the task as completed (MEDIUM/LARGE).",
|
|
901
|
+
// ── Triage ──
|
|
902
|
+
triageTitle: "Task Triage",
|
|
903
|
+
triageIntro: "Before executing the protocol, classify the task:",
|
|
904
|
+
triageSizeHeader: "Size",
|
|
905
|
+
triageCriteriaHeader: "Criteria",
|
|
906
|
+
triageProtocolHeader: "Protocol",
|
|
907
|
+
triageSmall: "**SMALL**",
|
|
908
|
+
triageSmallCriteria: "\u22642 files, <50 lines",
|
|
909
|
+
triageSmallProtocol: "Read CONTEXT.md \u2192 implement \u2192 lint \u2192 done",
|
|
910
|
+
triageMedium: "**MEDIUM**",
|
|
911
|
+
triageMediumCriteria: "3-10 files, moderate feature",
|
|
912
|
+
triageMediumProtocol: "Full protocol (no sub-delegation)",
|
|
913
|
+
triageLarge: "**LARGE**",
|
|
914
|
+
triageLargeCriteria: "Multi-day, architectural",
|
|
915
|
+
triageLargeProtocol: "Full protocol + ADR + sub-delegation",
|
|
916
|
+
triageExamples: "**Examples**: SMALL = fix typo, change color, correct import. MEDIUM = new endpoint, new component, simple service. LARGE = auth system, external provider integration, multi-channel notification system.",
|
|
917
|
+
triageEscalate: "If you start SMALL and the task grows \u2192 escalate to MEDIUM.",
|
|
918
|
+
// ── Stack ──
|
|
919
|
+
stackTitle: "Stack and Conventions",
|
|
920
|
+
stackSectionTitle: "Stack",
|
|
921
|
+
stackFrontend: "**Frontend**",
|
|
922
|
+
stackBackend: "**Backend**",
|
|
923
|
+
stackDatabase: "**Database**",
|
|
924
|
+
stackCICD: "**CI/CD**",
|
|
925
|
+
stackPlaceholder: "[framework and version \u2014 e.g.",
|
|
926
|
+
stackDbPlaceholder: "[type and version \u2014 e.g.",
|
|
927
|
+
stackCIPlaceholder: "[platform \u2014 e.g.",
|
|
928
|
+
stackAutoDetectTitle: "Automatic Stack Detection",
|
|
929
|
+
stackAutoDetectDesc: "If the stack is not filled above, the agent should detect it:",
|
|
930
|
+
stackFileHeader: "Detected File",
|
|
931
|
+
stackEcosystemHeader: "Ecosystem",
|
|
932
|
+
stackCommandsHeader: "Probable Commands",
|
|
933
|
+
// ── Conventions ──
|
|
934
|
+
conventionsTitle: "Mandatory Conventions",
|
|
935
|
+
convLang: "**Project Language**: Documentation is configured in **{{PROJECT_LANGUAGE_LABEL}}** ({{PROJECT_LANGUAGE_CODE}}). Generate and update all documentation in {{PROJECT_LANGUAGE_LABEL}}, regardless of the language the user speaks to you. Source code remains in English.",
|
|
936
|
+
convNaming: "**Naming**: [naming convention \u2014 e.g. camelCase variables/functions, PascalCase components]",
|
|
937
|
+
convStructure: "**Structure**: [convention \u2014 e.g. feature-based folders]",
|
|
938
|
+
convTesting: "**Testing**: All new code MUST include tests.",
|
|
939
|
+
convLinting: "**Linting**: Pass `npm run lint` without errors before completing.",
|
|
940
|
+
convCommits: "**Commits**: Conventional Commits in English: `type(scope): description`.",
|
|
941
|
+
convSecurity: "**Security**: Never commit secrets. Use environment variables.",
|
|
942
|
+
convDeps: "**Dependencies**: Don't add without justification. If added \u2192 document in ADR.",
|
|
943
|
+
convA11y: "**Accessibility**: All UI components comply with WCAG 2.1 AA.",
|
|
944
|
+
// ── Commands ──
|
|
945
|
+
commandsTitle: "Commands",
|
|
946
|
+
commandsHeaderCmd: "Command",
|
|
947
|
+
commandsHeaderUsage: "Usage",
|
|
948
|
+
cmdDev: "Development with hot-reload",
|
|
949
|
+
cmdBuild: "Production build",
|
|
950
|
+
cmdTest: "Unit and integration tests",
|
|
951
|
+
cmdTestE2E: "End-to-end tests",
|
|
952
|
+
cmdLint: "Linter (must pass without errors)",
|
|
953
|
+
cmdTypecheck: "Type verification",
|
|
954
|
+
commandsDetail: "> **Full details** of git conventions, commits, PRs and testing in [`docs/dev-workflow.md`](docs/dev-workflow.md).",
|
|
955
|
+
// ── BEFORE ──
|
|
956
|
+
beforeTitle: "BEFORE each task (MEDIUM/LARGE)",
|
|
957
|
+
before1Title: "1. Read docs based on task type",
|
|
958
|
+
beforeTaskTypeHeader: "Task Type",
|
|
959
|
+
beforeDocHeader: "Documentation to read first",
|
|
960
|
+
beforeAny: "Any task",
|
|
961
|
+
beforeFeature: "New feature",
|
|
962
|
+
beforeBug: "Bug/UI/Style",
|
|
963
|
+
beforeAPI: "API/Backend",
|
|
964
|
+
beforeDeploy: "Deploy/Infra",
|
|
965
|
+
beforeArch: "Architecture",
|
|
966
|
+
before2Title: "2. Check existing ADRs",
|
|
967
|
+
before2Desc: "Search in `docs/adr/` before making decisions:",
|
|
968
|
+
before2Accept: "**Accepted ADR exists** \u2192 FOLLOW IT. Don't reinvent.",
|
|
969
|
+
before2Contradict: "**Contradicts what you're about to do** \u2192 Raise discussion first.",
|
|
970
|
+
before2None: "**Doesn't exist** \u2192 Evaluate if it deserves an ADR (see criteria and examples in [`docs/adr/TEMPLATE.md`](docs/adr/TEMPLATE.md)).",
|
|
971
|
+
before3Title: "3. Check CONTEXT.md",
|
|
972
|
+
before3Desc: "If the task uses terms not in `docs/CONTEXT.md` \u2192 prepare to update when done.",
|
|
973
|
+
before3Completeness: "If `CONTEXT.md` has `completeness < 50%` \u2192 priority: complete CONTEXT.md before implementing features.",
|
|
974
|
+
before4Title: "4. Ask if there's ambiguity",
|
|
975
|
+
before4Desc: "After reading the documentation, if there's ambiguity \u2192 **batch ALL questions in one message**. Each question with options when possible. Don't ask one by one.",
|
|
976
|
+
before4DontAsk: "Don't ask if the task is clear, it's standard implementation, or the info is in the docs.",
|
|
977
|
+
// ── AFTER ──
|
|
978
|
+
afterTitle: "AFTER each task (MEDIUM/LARGE)",
|
|
979
|
+
afterTreeTitle: "Post-task tree",
|
|
980
|
+
afterTreeNode1: "Did you make a decision?",
|
|
981
|
+
afterTreeNode1a: "Architectural \u2192 docs/adr/ (formal ADR)",
|
|
982
|
+
afterTreeNode1b: "Non-obvious implementation \u2192 JSDoc + docs/adr/ai-decisions.md",
|
|
983
|
+
afterTreeNode1c: "No \u2192 next",
|
|
984
|
+
afterTreeNode2: "New domain terms? \u2192 docs/CONTEXT.md",
|
|
985
|
+
afterTreeNode3: "Endpoints changed? \u2192 docs/reference/api.md",
|
|
986
|
+
afterTreeNode4: "UI/UX changed? \u2192 docs/DESIGN.md",
|
|
987
|
+
afterTreeNode5: "Deploy to production? \u2192 CHANGELOG.md + docs/guides/deployment.md",
|
|
988
|
+
afterTreeNode6: "Feature completed? \u2192 docs/roadmap.md",
|
|
989
|
+
afterTreeNode7: "Gotcha discovered? \u2192 docs/guides/troubleshooting.md",
|
|
990
|
+
afterTreeNode8: "Pattern refactor? \u2192 Review architecture.md and ADRs",
|
|
991
|
+
afterGuide: "> **Extended guide** with diagrams and examples in [`docs/internal/agent-guide.md`](docs/internal/agent-guide.md).",
|
|
992
|
+
afterSkill: "> **Alternative**: Invoke skill `doc-maintain` to detect changes and suggest updates automatically.",
|
|
993
|
+
afterGoldenRule: "**Golden rule**: If you change the code, change the documentation.",
|
|
994
|
+
// ── Quality Gate ──
|
|
995
|
+
qgTitle: "Quality Gate \u2014 @reviewer (MEDIUM/LARGE)",
|
|
996
|
+
qgIntro: "**BEFORE completing**, invoke `@reviewer` to verify:",
|
|
997
|
+
qgItem1: "\u2705 Code style conforms to conventions",
|
|
998
|
+
qgItem2: "\u2705 No duplication \u2014 uses existing components/utilities",
|
|
999
|
+
qgItem3: "\u2705 Follows project architecture and respects ADRs",
|
|
1000
|
+
qgItem4: "\u2705 No security vulnerabilities",
|
|
1001
|
+
qgItem5: "\u2705 Tests included for new code",
|
|
1002
|
+
qgItem6: "\u2705 Documentation updated",
|
|
1003
|
+
qgItem7: "\u2705 No obvious performance issues",
|
|
1004
|
+
qgBlocking: "**\u274C BLOCKING** \u2192 fix before completing.",
|
|
1005
|
+
qgSuggested: "**\u26A0\uFE0F SUGGESTED** \u2192 recommended but doesn't block.",
|
|
1006
|
+
// ── Sub-delegation ──
|
|
1007
|
+
subdelTitle: "Sub-delegation",
|
|
1008
|
+
subdelIntro: "Minimum instructions to sub-agent:",
|
|
1009
|
+
subdelExample: "> Read AGENTS.md and follow the full protocol. Task: [description]. Relevant docs: [list].",
|
|
1010
|
+
subdelNote: "Don't repeat conventions \u2014 they're already in AGENTS.md. See complete example in `docs/internal/agent-guide.md`.",
|
|
1011
|
+
// ── Skills ──
|
|
1012
|
+
skillsTitle: "Available Skills and Agents",
|
|
1013
|
+
skillsList: "**Skills**: `doc-scaffold`, `doc-write`, `doc-design`, `doc-review`, `doc-maintain` \u2014 see `.agents/skills/`",
|
|
1014
|
+
agentsList: "**Agents**: `@reviewer` (quality gate), `@doc-writer`, `@doc-reviewer`, `@doc-designer`, `@doc-maintainer` \u2014 see `.agents/agents/`",
|
|
1015
|
+
skillsGuide: "**Extended guide**: `docs/internal/agent-guide.md`",
|
|
1016
|
+
// ── Stack detection table ──
|
|
1017
|
+
stackRowPackage: "`package.json`",
|
|
1018
|
+
stackRowNodeEco: "Node.js (npm/pnpm/yarn)",
|
|
1019
|
+
stackRowNodeCmds: "`npm run dev`, `npm run build`",
|
|
1020
|
+
stackRowPyReq: "`requirements.txt` / `pyproject.toml`",
|
|
1021
|
+
stackRowPyEco: "Python (pip/poetry)",
|
|
1022
|
+
stackRowPyCmds: "`python manage.py runserver`, `pytest`",
|
|
1023
|
+
stackRowGo: "`go.mod`",
|
|
1024
|
+
stackRowGoEco: "Go",
|
|
1025
|
+
stackRowGoCmds: "`go run .`, `go test ./...`",
|
|
1026
|
+
stackRowRust: "`Cargo.toml`",
|
|
1027
|
+
stackRowRustEco: "Rust",
|
|
1028
|
+
stackRowRustCmds: "`cargo run`, `cargo test`",
|
|
1029
|
+
stackRowJava: "`pom.xml` / `build.gradle`",
|
|
1030
|
+
stackRowJavaEco: "Java/Kotlin",
|
|
1031
|
+
stackRowJavaCmds: "`mvn spring-boot:run`, `gradle bootRun`",
|
|
1032
|
+
// ── Docs table (BEFORE) ──
|
|
1033
|
+
beforeDocAny: "`docs/CONTEXT.md`",
|
|
1034
|
+
beforeDocFeature: "`docs/roadmap.md`, `docs/explanation/architecture.md`, relevant ADRs",
|
|
1035
|
+
beforeDocBug: "`docs/DESIGN.md`, `docs/CONTEXT.md`",
|
|
1036
|
+
beforeDocApi: "`docs/reference/api.md`, `docs/reference/configuration.md`",
|
|
1037
|
+
beforeDocDeploy: "`docs/guides/deployment.md`, `docs/reference/infrastructure.md`",
|
|
1038
|
+
beforeDocArch: "`docs/explanation/architecture.md`, `docs/adr/` (all)",
|
|
1039
|
+
// ── Commands (values) ──
|
|
1040
|
+
cmdDevVal: "{{DEV_COMMAND}}",
|
|
1041
|
+
cmdBuildVal: "{{BUILD_COMMAND}}",
|
|
1042
|
+
cmdTestVal: "{{TEST_COMMAND}}",
|
|
1043
|
+
cmdTestE2EVal: "[e2e command]",
|
|
1044
|
+
cmdLintVal: "{{LINT_COMMAND}}",
|
|
1045
|
+
cmdTypecheckVal: "[typecheck command]"
|
|
1046
|
+
};
|
|
1047
|
+
|
|
1048
|
+
// src/generators/agents/generator.ts
|
|
1049
|
+
registerLabels("agents", "es", labels);
|
|
1050
|
+
registerLabels("agents", "en", labels2);
|
|
1051
|
+
function fmtStack(options) {
|
|
1052
|
+
const s = options.stack;
|
|
1053
|
+
if (!s) return "[TECNOLOG\xCDA PRINCIPAL]";
|
|
1054
|
+
const parts = [s.language];
|
|
1055
|
+
if (s.framework) parts.push(s.framework);
|
|
1056
|
+
return parts.join(" + ");
|
|
1057
|
+
}
|
|
1058
|
+
function fmtFramework(options) {
|
|
1059
|
+
return options.stack?.framework || "[framework]";
|
|
1060
|
+
}
|
|
1061
|
+
function generate(options) {
|
|
1062
|
+
const labels31 = loadLabels("agents", options.language);
|
|
1063
|
+
const t = (key) => labels31[key] || `[${key}]`;
|
|
1064
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1065
|
+
const stackStr = fmtStack(options);
|
|
1066
|
+
const fw = fmtFramework(options);
|
|
1067
|
+
let md = `---
|
|
1068
|
+
project: "${options.projectName}"
|
|
1069
|
+
stack: "${stackStr}"
|
|
1070
|
+
created: "2025-01-01"
|
|
1071
|
+
updated: "${today}"
|
|
1072
|
+
status: active
|
|
1073
|
+
type: ${t("fmType")}
|
|
1074
|
+
tags: [${t("fmTags")}]
|
|
1075
|
+
---
|
|
1076
|
+
|
|
1077
|
+
`;
|
|
1078
|
+
md += `# ${t("title")}
|
|
1079
|
+
|
|
1080
|
+
`;
|
|
1081
|
+
md += `${t("subtitle")}
|
|
1082
|
+
|
|
1083
|
+
`;
|
|
1084
|
+
md += "---\n\n";
|
|
1085
|
+
md += `## ${t("stopTitle")}
|
|
1086
|
+
|
|
1087
|
+
`;
|
|
1088
|
+
md += `1. ${t("stop1")}
|
|
1089
|
+
`;
|
|
1090
|
+
md += `2. ${t("stop2")}
|
|
1091
|
+
`;
|
|
1092
|
+
md += `3. ${t("stop3")}
|
|
1093
|
+
`;
|
|
1094
|
+
md += `4. ${t("stop4")}
|
|
1095
|
+
`;
|
|
1096
|
+
md += `5. ${t("stop5")}
|
|
1097
|
+
|
|
1098
|
+
`;
|
|
1099
|
+
md += "---\n\n";
|
|
1100
|
+
md += `## ${t("triageTitle")}
|
|
1101
|
+
|
|
1102
|
+
`;
|
|
1103
|
+
md += `${t("triageIntro")}
|
|
1104
|
+
|
|
1105
|
+
`;
|
|
1106
|
+
md += `| ${t("triageSizeHeader")} | ${t("triageCriteriaHeader")} | ${t("triageProtocolHeader")} |
|
|
1107
|
+
`;
|
|
1108
|
+
md += `|--------|----------|-----------|
|
|
1109
|
+
`;
|
|
1110
|
+
md += `| ${t("triageSmall")} | ${t("triageSmallCriteria")} | ${t("triageSmallProtocol")} |
|
|
1111
|
+
`;
|
|
1112
|
+
md += `| ${t("triageMedium")} | ${t("triageMediumCriteria")} | ${t("triageMediumProtocol")} |
|
|
1113
|
+
`;
|
|
1114
|
+
md += `| ${t("triageLarge")} | ${t("triageLargeCriteria")} | ${t("triageLargeProtocol")} |
|
|
1115
|
+
|
|
1116
|
+
`;
|
|
1117
|
+
md += `${t("triageExamples")}
|
|
1118
|
+
|
|
1119
|
+
`;
|
|
1120
|
+
md += `${t("triageEscalate")}
|
|
1121
|
+
|
|
1122
|
+
`;
|
|
1123
|
+
md += "---\n\n";
|
|
1124
|
+
md += `## ${t("stackTitle")}
|
|
1125
|
+
|
|
1126
|
+
`;
|
|
1127
|
+
md += `### ${t("stackSectionTitle")}
|
|
1128
|
+
`;
|
|
1129
|
+
if (options.conditionCtx.hasFrontend) {
|
|
1130
|
+
md += `- ${t("stackFrontend")}: ${t("stackPlaceholder")} ${fw}]
|
|
1131
|
+
`;
|
|
1132
|
+
}
|
|
1133
|
+
if (options.conditionCtx.hasBackend) {
|
|
1134
|
+
md += `- ${t("stackBackend")}: ${t("stackPlaceholder")} ${fw}]
|
|
1135
|
+
`;
|
|
1136
|
+
}
|
|
1137
|
+
if (options.conditionCtx.hasDatabase) {
|
|
1138
|
+
md += `- ${t("stackDatabase")}: ${t("stackDbPlaceholder")} ${stackStr}]
|
|
1139
|
+
`;
|
|
1140
|
+
}
|
|
1141
|
+
md += `- ${t("stackCICD")}: ${t("stackCIPlaceholder")} ${stackStr}]
|
|
1142
|
+
|
|
1143
|
+
`;
|
|
1144
|
+
md += `### ${t("stackAutoDetectTitle")}
|
|
1145
|
+
|
|
1146
|
+
`;
|
|
1147
|
+
md += `${t("stackAutoDetectDesc")}
|
|
1148
|
+
|
|
1149
|
+
`;
|
|
1150
|
+
md += `| ${t("stackFileHeader")} | ${t("stackEcosystemHeader")} | ${t("stackCommandsHeader")} |
|
|
1151
|
+
`;
|
|
1152
|
+
md += `|-------------------|------------|--------------------|
|
|
1153
|
+
`;
|
|
1154
|
+
md += `| ${t("stackRowPackage")} | ${t("stackRowNodeEco")} | ${t("stackRowNodeCmds")} |
|
|
1155
|
+
`;
|
|
1156
|
+
md += `| ${t("stackRowPyReq")} | ${t("stackRowPyEco")} | ${t("stackRowPyCmds")} |
|
|
1157
|
+
`;
|
|
1158
|
+
md += `| ${t("stackRowGo")} | ${t("stackRowGoEco")} | ${t("stackRowGoCmds")} |
|
|
1159
|
+
`;
|
|
1160
|
+
md += `| ${t("stackRowRust")} | ${t("stackRowRustEco")} | ${t("stackRowRustCmds")} |
|
|
1161
|
+
`;
|
|
1162
|
+
md += `| ${t("stackRowJava")} | ${t("stackRowJavaEco")} | ${t("stackRowJavaCmds")} |
|
|
1163
|
+
|
|
1164
|
+
`;
|
|
1165
|
+
const LANG_LABELS = { es: "espa\xF1ol", en: "English" };
|
|
1166
|
+
const langLabel = LANG_LABELS[options.language] ?? options.language;
|
|
1167
|
+
const langCode = options.language;
|
|
1168
|
+
md += `### ${t("conventionsTitle")}
|
|
1169
|
+
`;
|
|
1170
|
+
md += `1. ${t("convLang").replaceAll("{{PROJECT_LANGUAGE_LABEL}}", langLabel).replaceAll("{{PROJECT_LANGUAGE_CODE}}", langCode)}
|
|
1171
|
+
`;
|
|
1172
|
+
md += `2. ${t("convNaming")}
|
|
1173
|
+
`;
|
|
1174
|
+
md += `3. ${t("convStructure")}
|
|
1175
|
+
`;
|
|
1176
|
+
md += `4. ${t("convTesting")}
|
|
1177
|
+
`;
|
|
1178
|
+
md += `5. ${t("convLinting")}
|
|
1179
|
+
`;
|
|
1180
|
+
md += `6. ${t("convCommits")}
|
|
1181
|
+
`;
|
|
1182
|
+
md += `7. ${t("convSecurity")}
|
|
1183
|
+
`;
|
|
1184
|
+
md += `8. ${t("convDeps")}
|
|
1185
|
+
`;
|
|
1186
|
+
md += `9. ${t("convA11y")}
|
|
1187
|
+
|
|
1188
|
+
`;
|
|
1189
|
+
md += `### ${t("commandsTitle")}
|
|
1190
|
+
|
|
1191
|
+
`;
|
|
1192
|
+
md += `| ${t("commandsHeaderCmd")} | ${t("commandsHeaderUsage")} |
|
|
1193
|
+
`;
|
|
1194
|
+
md += `|---------|-----|
|
|
1195
|
+
`;
|
|
1196
|
+
md += `| \`${t("cmdDevVal")}\` | ${t("cmdDev")} |
|
|
1197
|
+
`;
|
|
1198
|
+
md += `| \`${t("cmdBuildVal")}\` | ${t("cmdBuild")} |
|
|
1199
|
+
`;
|
|
1200
|
+
md += `| \`${t("cmdTestVal")}\` | ${t("cmdTest")} |
|
|
1201
|
+
`;
|
|
1202
|
+
md += `| \`${t("cmdTestE2EVal")}\` | ${t("cmdTestE2E")} |
|
|
1203
|
+
`;
|
|
1204
|
+
md += `| \`${t("cmdLintVal")}\` | ${t("cmdLint")} |
|
|
1205
|
+
`;
|
|
1206
|
+
md += `| \`${t("cmdTypecheckVal")}\` | ${t("cmdTypecheck")} |
|
|
1207
|
+
|
|
1208
|
+
`;
|
|
1209
|
+
md += `${t("commandsDetail")}
|
|
1210
|
+
|
|
1211
|
+
`;
|
|
1212
|
+
md += "---\n\n";
|
|
1213
|
+
md += `## ${t("beforeTitle")}
|
|
1214
|
+
|
|
1215
|
+
`;
|
|
1216
|
+
md += `### ${t("before1Title")}
|
|
1217
|
+
|
|
1218
|
+
`;
|
|
1219
|
+
md += `| ${t("beforeTaskTypeHeader")} | ${t("beforeDocHeader")} |
|
|
1220
|
+
`;
|
|
1221
|
+
md += `|---------------|------------------------------|
|
|
1222
|
+
`;
|
|
1223
|
+
md += `| ${t("beforeAny")} | ${t("beforeDocAny")} |
|
|
1224
|
+
`;
|
|
1225
|
+
md += `| ${t("beforeFeature")} | ${t("beforeDocFeature")} |
|
|
1226
|
+
`;
|
|
1227
|
+
md += `| ${t("beforeBug")} | ${t("beforeDocBug")} |
|
|
1228
|
+
`;
|
|
1229
|
+
md += `| ${t("beforeAPI")} | ${t("beforeDocApi")} |
|
|
1230
|
+
`;
|
|
1231
|
+
md += `| ${t("beforeDeploy")} | ${t("beforeDocDeploy")} |
|
|
1232
|
+
`;
|
|
1233
|
+
md += `| ${t("beforeArch")} | ${t("beforeDocArch")} |
|
|
1234
|
+
|
|
1235
|
+
`;
|
|
1236
|
+
md += `### ${t("before2Title")}
|
|
1237
|
+
|
|
1238
|
+
`;
|
|
1239
|
+
md += `${t("before2Desc")}
|
|
1240
|
+
`;
|
|
1241
|
+
md += `- ${t("before2Accept")}
|
|
1242
|
+
`;
|
|
1243
|
+
md += `- ${t("before2Contradict")}
|
|
1244
|
+
`;
|
|
1245
|
+
md += `- ${t("before2None")}
|
|
1246
|
+
|
|
1247
|
+
`;
|
|
1248
|
+
md += `### ${t("before3Title")}
|
|
1249
|
+
|
|
1250
|
+
`;
|
|
1251
|
+
md += `${t("before3Desc")}
|
|
1252
|
+
|
|
1253
|
+
`;
|
|
1254
|
+
md += `${t("before3Completeness")}
|
|
1255
|
+
|
|
1256
|
+
`;
|
|
1257
|
+
md += `### ${t("before4Title")}
|
|
1258
|
+
|
|
1259
|
+
`;
|
|
1260
|
+
md += `${t("before4Desc")}
|
|
1261
|
+
|
|
1262
|
+
`;
|
|
1263
|
+
md += `${t("before4DontAsk")}
|
|
1264
|
+
|
|
1265
|
+
`;
|
|
1266
|
+
md += "---\n\n";
|
|
1267
|
+
md += `## ${t("afterTitle")}
|
|
1268
|
+
|
|
1269
|
+
`;
|
|
1270
|
+
md += `### ${t("afterTreeTitle")}
|
|
1271
|
+
|
|
1272
|
+
`;
|
|
1273
|
+
md += "```\n";
|
|
1274
|
+
md += `${t("afterTreeNode1")}
|
|
1275
|
+
`;
|
|
1276
|
+
md += ` \u251C\u2500\u2500 ${t("afterTreeNode1a")}
|
|
1277
|
+
`;
|
|
1278
|
+
md += ` \u251C\u2500\u2500 ${t("afterTreeNode1b")}
|
|
1279
|
+
`;
|
|
1280
|
+
md += ` \u2514\u2500\u2500 ${t("afterTreeNode1c")}
|
|
1281
|
+
`;
|
|
1282
|
+
md += `${t("afterTreeNode2")}
|
|
1283
|
+
`;
|
|
1284
|
+
md += `${t("afterTreeNode3")}
|
|
1285
|
+
`;
|
|
1286
|
+
md += `${t("afterTreeNode4")}
|
|
1287
|
+
`;
|
|
1288
|
+
md += `${t("afterTreeNode5")}
|
|
1289
|
+
`;
|
|
1290
|
+
md += `${t("afterTreeNode6")}
|
|
1291
|
+
`;
|
|
1292
|
+
md += `${t("afterTreeNode7")}
|
|
1293
|
+
`;
|
|
1294
|
+
md += `${t("afterTreeNode8")}
|
|
1295
|
+
`;
|
|
1296
|
+
md += "```\n\n";
|
|
1297
|
+
md += `${t("afterGuide")}
|
|
1298
|
+
`;
|
|
1299
|
+
md += `${t("afterSkill")}
|
|
1300
|
+
|
|
1301
|
+
`;
|
|
1302
|
+
md += `${t("afterGoldenRule")}
|
|
1303
|
+
|
|
1304
|
+
`;
|
|
1305
|
+
md += "---\n\n";
|
|
1306
|
+
md += `## ${t("qgTitle")}
|
|
1307
|
+
|
|
1308
|
+
`;
|
|
1309
|
+
md += `${t("qgIntro")}
|
|
1310
|
+
`;
|
|
1311
|
+
md += `- ${t("qgItem1")}
|
|
1312
|
+
`;
|
|
1313
|
+
md += `- ${t("qgItem2")}
|
|
1314
|
+
`;
|
|
1315
|
+
md += `- ${t("qgItem3")}
|
|
1316
|
+
`;
|
|
1317
|
+
md += `- ${t("qgItem4")}
|
|
1318
|
+
`;
|
|
1319
|
+
md += `- ${t("qgItem5")}
|
|
1320
|
+
`;
|
|
1321
|
+
md += `- ${t("qgItem6")}
|
|
1322
|
+
`;
|
|
1323
|
+
md += `- ${t("qgItem7")}
|
|
1324
|
+
|
|
1325
|
+
`;
|
|
1326
|
+
md += `- ${t("qgBlocking")}
|
|
1327
|
+
`;
|
|
1328
|
+
md += `- ${t("qgSuggested")}
|
|
1329
|
+
|
|
1330
|
+
`;
|
|
1331
|
+
md += "---\n\n";
|
|
1332
|
+
md += `## ${t("subdelTitle")}
|
|
1333
|
+
|
|
1334
|
+
`;
|
|
1335
|
+
md += `${t("subdelIntro")}
|
|
1336
|
+
`;
|
|
1337
|
+
md += `${t("subdelExample")}
|
|
1338
|
+
|
|
1339
|
+
`;
|
|
1340
|
+
md += `${t("subdelNote")}
|
|
1341
|
+
|
|
1342
|
+
`;
|
|
1343
|
+
md += "---\n\n";
|
|
1344
|
+
md += `## ${t("skillsTitle")}
|
|
1345
|
+
|
|
1346
|
+
`;
|
|
1347
|
+
md += `- ${t("skillsList")}
|
|
1348
|
+
`;
|
|
1349
|
+
md += `- ${t("agentsList")}
|
|
1350
|
+
`;
|
|
1351
|
+
md += `- ${t("skillsGuide")}
|
|
1352
|
+
`;
|
|
1353
|
+
return md;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
// src/generators/context/labels/es.ts
|
|
1357
|
+
var labels3 = {
|
|
1358
|
+
fmType: "domain-language",
|
|
1359
|
+
fmTags: "contexto, dominio, vocabulario, glosario",
|
|
1360
|
+
title: "CONTEXT.md \u2014 Lenguaje del Dominio",
|
|
1361
|
+
intro: "Este archivo define el vocabulario compartido que se usa en este proyecto. Todo t\xE9rmino de negocio o concepto clave del dominio debe estar documentado aqu\xED.",
|
|
1362
|
+
introGap: "Si un t\xE9rmino aparece en el c\xF3digo, la documentaci\xF3n o las conversaciones del equipo y NO est\xE1 en este archivo, es un gap que debe cubrirse.",
|
|
1363
|
+
entitiesTitle: "Entidades principales",
|
|
1364
|
+
entitiesTerm: "T\xE9rmino",
|
|
1365
|
+
entitiesDef: "Definici\xF3n",
|
|
1366
|
+
entitiesExample: "Ejemplo de uso",
|
|
1367
|
+
entitiesTech: "Equivalente t\xE9cnico",
|
|
1368
|
+
statesTitle: "Estados y flujos",
|
|
1369
|
+
statesState: "Estado",
|
|
1370
|
+
statesMeaning: "Significa",
|
|
1371
|
+
statesTransitions: "Transiciones posibles",
|
|
1372
|
+
rolesTitle: "Roles y permisos",
|
|
1373
|
+
rolesRole: "Rol",
|
|
1374
|
+
rolesWho: "Qui\xE9n es",
|
|
1375
|
+
rolesWhat: "Qu\xE9 puede hacer",
|
|
1376
|
+
bizTermsTitle: "T\xE9rminos de negocio",
|
|
1377
|
+
bizTermsTerm: "T\xE9rmino",
|
|
1378
|
+
bizTermsDef: "Definici\xF3n",
|
|
1379
|
+
bizTermsNotes: "Notas",
|
|
1380
|
+
projectLangTerm: "Idioma del proyecto",
|
|
1381
|
+
projectLangDef: "{{PROJECT_LANGUAGE_LABEL}} ({{PROJECT_LANGUAGE_CODE}}) \u2014 Idioma oficial de la documentaci\xF3n generada por el CLI",
|
|
1382
|
+
projectLangNotes: "Ver AGENTS.md \xA7 Stack y convenciones",
|
|
1383
|
+
techTermsTitle: "T\xE9rminos t\xE9cnicos internos",
|
|
1384
|
+
techTermsTerm: "T\xE9rmino",
|
|
1385
|
+
techTermsDef: "Definici\xF3n",
|
|
1386
|
+
techTermsWhy: "Por qu\xE9 existe",
|
|
1387
|
+
relationsTitle: "Relaciones entre conceptos",
|
|
1388
|
+
relationsCode: "[Entidad 1] \u2500\u2500\u2500 1:N \u2500\u2500\u2500\u2192 [Entidad 2]\n \u2514\u2500\u2500\u2192 [Entidad 3] (a trav\xE9s de [Entidad 4])",
|
|
1389
|
+
dialogTitle: "Ejemplo de di\xE1logo usando el dominio",
|
|
1390
|
+
dialogIntro: "Este ejemplo muestra c\xF3mo se usa el vocabulario en una conversaci\xF3n real del equipo:",
|
|
1391
|
+
dialogPM: '**Product Manager**: "El cliente necesita que los [T\xE9rmino 1] en estado [Estado A] se puedan convertir autom\xE1ticamente en [T\xE9rmino 2] cuando pasen a [Estado B]."',
|
|
1392
|
+
dialogDev: '**Developer**: "Entendido. \xBFEsa conversaci\xF3n aplica para todos los [Rol 1] o solo para los que tienen permiso de [acci\xF3n]?"',
|
|
1393
|
+
dialogPM2: '**Product Manager**: "Solo para [Rol 1]. Los [Rol 2] solo ven el [T\xE9rmino 1] pero no pueden convertirlo."',
|
|
1394
|
+
dialogDev2: '**Developer**: "Perfecto. Voy a a\xF1adir un bot\xF3n de conversi\xF3n en la vista de [T\xE9rmino 1] para [Rol 1], visible solo cuando est\xE9 en [Estado A]. \xBFEl [T\xE9rmino 2] resultante empieza en [Estado C]?"',
|
|
1395
|
+
dialogPM3: '**Product Manager**: "S\xED, empieza en [Estado C] y necesita aprobaci\xF3n de un [Rol 2] para pasar a [Estado D]."',
|
|
1396
|
+
ambTitle: "Ambig\xFCedades flagadas",
|
|
1397
|
+
ambIntro: "Estos t\xE9rminos tienen significados que podr\xEDan confundirse. Prestar atenci\xF3n al contexto:",
|
|
1398
|
+
ambTerm: "T\xE9rmino",
|
|
1399
|
+
ambConfusion: "Confusi\xF3n posible",
|
|
1400
|
+
ambClarification: "Aclaraci\xF3n",
|
|
1401
|
+
updateTitle: "C\xF3mo actualizar este archivo",
|
|
1402
|
+
update1: "Identificar si es una **entidad**, un **estado**, un **rol**, un **t\xE9rmino de negocio** o un **t\xE9rmino t\xE9cnico**.",
|
|
1403
|
+
update2: "A\xF1adirlo en la secci\xF3n correspondiente con: definici\xF3n, ejemplo de uso, y equivalente t\xE9cnico.",
|
|
1404
|
+
update3: "Si tiene relaciones con otras entidades, actualizar el diagrama de relaciones.",
|
|
1405
|
+
update4: 'Si es ambiguo o se confunde con otro t\xE9rmino, a\xF1adirlo en "Ambig\xFCedades flagadas".',
|
|
1406
|
+
update5: "Si se introdujo un nuevo estado o flujo, actualizar la tabla de estados.",
|
|
1407
|
+
updateRule: "**Regla**: Todo t\xE9rmino que aparezca en c\xF3digo, APIs, UI o conversaciones del equipo DEBE estar aqu\xED. Si no est\xE1, es un bug de documentaci\xF3n.",
|
|
1408
|
+
updateIntro: "Cuando se a\xF1ada un nuevo t\xE9rmino al dominio:"
|
|
1409
|
+
};
|
|
1410
|
+
|
|
1411
|
+
// src/generators/context/labels/en.ts
|
|
1412
|
+
var labels4 = {
|
|
1413
|
+
fmType: "domain-language",
|
|
1414
|
+
fmTags: "context, domain, vocabulary, glossary",
|
|
1415
|
+
title: "CONTEXT.md \u2014 Domain Language",
|
|
1416
|
+
intro: "This file defines the shared vocabulary used in this project. Every business term or key domain concept must be documented here.",
|
|
1417
|
+
introGap: "If a term appears in code, documentation or team conversations and is NOT in this file, it's a gap that needs to be covered.",
|
|
1418
|
+
entitiesTitle: "Main Entities",
|
|
1419
|
+
entitiesTerm: "Term",
|
|
1420
|
+
entitiesDef: "Definition",
|
|
1421
|
+
entitiesExample: "Usage Example",
|
|
1422
|
+
entitiesTech: "Technical Equivalent",
|
|
1423
|
+
statesTitle: "States and Flows",
|
|
1424
|
+
statesState: "State",
|
|
1425
|
+
statesMeaning: "Meaning",
|
|
1426
|
+
statesTransitions: "Possible Transitions",
|
|
1427
|
+
rolesTitle: "Roles and Permissions",
|
|
1428
|
+
rolesRole: "Role",
|
|
1429
|
+
rolesWho: "Who it is",
|
|
1430
|
+
rolesWhat: "What they can do",
|
|
1431
|
+
bizTermsTitle: "Business Terms",
|
|
1432
|
+
bizTermsTerm: "Term",
|
|
1433
|
+
bizTermsDef: "Definition",
|
|
1434
|
+
bizTermsNotes: "Notes",
|
|
1435
|
+
projectLangTerm: "Project language",
|
|
1436
|
+
projectLangDef: "{{PROJECT_LANGUAGE_LABEL}} ({{PROJECT_LANGUAGE_CODE}}) \u2014 Official documentation language set by the CLI",
|
|
1437
|
+
projectLangNotes: "See AGENTS.md \xA7 Stack and Conventions",
|
|
1438
|
+
techTermsTitle: "Internal Technical Terms",
|
|
1439
|
+
techTermsTerm: "Term",
|
|
1440
|
+
techTermsDef: "Definition",
|
|
1441
|
+
techTermsWhy: "Why it exists",
|
|
1442
|
+
relationsTitle: "Relationships Between Concepts",
|
|
1443
|
+
relationsCode: "[Entity 1] \u2500\u2500\u2500 1:N \u2500\u2500\u2500\u2192 [Entity 2]\n \u2514\u2500\u2500\u2192 [Entity 3] (via [Entity 4])",
|
|
1444
|
+
dialogTitle: "Example Dialogue Using Domain Terms",
|
|
1445
|
+
dialogIntro: "This example shows how vocabulary is used in a real team conversation:",
|
|
1446
|
+
dialogPM: '**Product Manager**: "The client needs [Term 1] in state [State A] to be automatically converted to [Term 2] when they reach [State B]."',
|
|
1447
|
+
dialogDev: '**Developer**: "Understood. Does this conversion apply to all [Role 1] or only those with [action] permission?"',
|
|
1448
|
+
dialogPM2: '**Product Manager**: "Only for [Role 1]. [Role 2] can only see the [Term 1] but cannot convert it."',
|
|
1449
|
+
dialogDev2: `**Developer**: "Perfect. I'll add a conversion button on the [Term 1] view for [Role 1], visible only when in [State A]. Does the resulting [Term 2] start in [State C]?"`,
|
|
1450
|
+
dialogPM3: '**Product Manager**: "Yes, it starts in [State C] and needs approval from a [Role 2] to move to [State D]."',
|
|
1451
|
+
ambTitle: "Flagged Ambiguities",
|
|
1452
|
+
ambIntro: "These terms have meanings that could be confused. Pay attention to context:",
|
|
1453
|
+
ambTerm: "Term",
|
|
1454
|
+
ambConfusion: "Possible Confusion",
|
|
1455
|
+
ambClarification: "Clarification",
|
|
1456
|
+
updateTitle: "How to Update This File",
|
|
1457
|
+
update1: "Identify if it's an **entity**, **state**, **role**, **business term** or **technical term**.",
|
|
1458
|
+
update2: "Add it in the corresponding section with: definition, usage example, and technical equivalent.",
|
|
1459
|
+
update3: "If it has relationships with other entities, update the relationship diagram.",
|
|
1460
|
+
update4: `If it's ambiguous or confused with another term, add it in "Flagged Ambiguities".`,
|
|
1461
|
+
update5: "If a new state or flow was introduced, update the states table.",
|
|
1462
|
+
updateRule: "**Rule**: Every term that appears in code, APIs, UI or team conversations MUST be here. If it's not, it's a documentation bug.",
|
|
1463
|
+
updateIntro: "When adding a new domain term:"
|
|
1464
|
+
};
|
|
1465
|
+
|
|
1466
|
+
// src/generators/context/generator.ts
|
|
1467
|
+
registerLabels("context", "es", labels3);
|
|
1468
|
+
registerLabels("context", "en", labels4);
|
|
1469
|
+
function generate2(options) {
|
|
1470
|
+
const labels31 = loadLabels("context", options.language);
|
|
1471
|
+
const t = (key) => labels31[key] || `[${key}]`;
|
|
1472
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1473
|
+
const LANG_LABELS = { es: "Espa\xF1ol", en: "English" };
|
|
1474
|
+
const langLabel = LANG_LABELS[options.language] ?? options.language;
|
|
1475
|
+
const langCode = options.language;
|
|
1476
|
+
const projectLangDef = t("projectLangDef").replaceAll("{{PROJECT_LANGUAGE_LABEL}}", langLabel).replaceAll("{{PROJECT_LANGUAGE_CODE}}", langCode);
|
|
1477
|
+
let md = `---
|
|
1478
|
+
created: "2025-01-01"
|
|
1479
|
+
updated: "${today}"
|
|
1480
|
+
status: active
|
|
1481
|
+
completeness: "15%"
|
|
1482
|
+
type: ${t("fmType")}
|
|
1483
|
+
tags: [${t("fmTags")}]
|
|
1484
|
+
---
|
|
1485
|
+
|
|
1486
|
+
# ${t("title")}
|
|
1487
|
+
|
|
1488
|
+
${t("intro")}
|
|
1489
|
+
|
|
1490
|
+
${t("introGap")}
|
|
1491
|
+
|
|
1492
|
+
---
|
|
1493
|
+
|
|
1494
|
+
## ${t("entitiesTitle")}
|
|
1495
|
+
|
|
1496
|
+
| ${t("entitiesTerm")} | ${t("entitiesDef")} | ${t("entitiesExample")} | ${t("entitiesTech")} |
|
|
1497
|
+
|---------|-----------|----------------|-------------------|
|
|
1498
|
+
| **${t("placeholder")}** | [definici\xF3n] | "ejemplo de uso" | \`[codigo]\` |
|
|
1499
|
+
|
|
1500
|
+
## ${t("statesTitle")}
|
|
1501
|
+
|
|
1502
|
+
| ${t("statesState")} | ${t("statesMeaning")} | ${t("statesTransitions")} |
|
|
1503
|
+
|-------|---------|----------------------|
|
|
1504
|
+
| **[Estado]** | [significado] | \u2192 [otro estado] |
|
|
1505
|
+
|
|
1506
|
+
## ${t("rolesTitle")}
|
|
1507
|
+
|
|
1508
|
+
| ${t("rolesRole")} | ${t("rolesWho")} | ${t("rolesWhat")} |
|
|
1509
|
+
|-----|----------|----------------|
|
|
1510
|
+
| **[Rol]** | [descripci\xF3n] | [acciones] |
|
|
1511
|
+
|
|
1512
|
+
## ${t("bizTermsTitle")}
|
|
1513
|
+
|
|
1514
|
+
| ${t("bizTermsTerm")} | ${t("bizTermsDef")} | ${t("bizTermsNotes")} |
|
|
1515
|
+
|---------|-----------|-------|
|
|
1516
|
+
| **${t("projectLangTerm")}** | ${projectLangDef} | ${t("projectLangNotes")} |
|
|
1517
|
+
| **[T\xE9rmino]** | [definici\xF3n] | [notas] |
|
|
1518
|
+
|
|
1519
|
+
## ${t("techTermsTitle")}
|
|
1520
|
+
|
|
1521
|
+
| ${t("techTermsTerm")} | ${t("techTermsDef")} | ${t("techTermsWhy")} |
|
|
1522
|
+
|---------|-----------|----------------|
|
|
1523
|
+
| **[T\xE9rmino]** | [definici\xF3n] | [raz\xF3n] |
|
|
1524
|
+
|
|
1525
|
+
---
|
|
1526
|
+
|
|
1527
|
+
## ${t("relationsTitle")}
|
|
1528
|
+
|
|
1529
|
+
\`\`\`
|
|
1530
|
+
${t("relationsCode")}
|
|
1531
|
+
\`\`\`
|
|
1532
|
+
|
|
1533
|
+
---
|
|
1534
|
+
|
|
1535
|
+
## ${t("dialogTitle")}
|
|
1536
|
+
|
|
1537
|
+
${t("dialogIntro")}
|
|
1538
|
+
|
|
1539
|
+
> ${t("dialogPM")}
|
|
1540
|
+
>
|
|
1541
|
+
> ${t("dialogDev")}
|
|
1542
|
+
>
|
|
1543
|
+
> ${t("dialogPM2")}
|
|
1544
|
+
>
|
|
1545
|
+
> ${t("dialogDev2")}
|
|
1546
|
+
>
|
|
1547
|
+
> ${t("dialogPM3")}
|
|
1548
|
+
|
|
1549
|
+
---
|
|
1550
|
+
|
|
1551
|
+
## ${t("ambTitle")}
|
|
1552
|
+
|
|
1553
|
+
${t("ambIntro")}
|
|
1554
|
+
|
|
1555
|
+
| ${t("ambTerm")} | ${t("ambConfusion")} | ${t("ambClarification")} |
|
|
1556
|
+
|------|-------------------|-----------|
|
|
1557
|
+
| **[t\xE9rmino]** | [confusi\xF3n] | [aclaraci\xF3n] |
|
|
1558
|
+
|
|
1559
|
+
---
|
|
1560
|
+
|
|
1561
|
+
## ${t("updateTitle")}
|
|
1562
|
+
|
|
1563
|
+
${t("updateIntro")}
|
|
1564
|
+
|
|
1565
|
+
1. ${t("update1")}
|
|
1566
|
+
2. ${t("update2")}
|
|
1567
|
+
3. ${t("update3")}
|
|
1568
|
+
4. ${t("update4")}
|
|
1569
|
+
5. ${t("update5")}
|
|
1570
|
+
|
|
1571
|
+
${t("updateRule")}
|
|
1572
|
+
`;
|
|
1573
|
+
return md;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
// src/generators/changelog/labels/es.ts
|
|
1577
|
+
var labels5 = {
|
|
1578
|
+
fmType: "changelog",
|
|
1579
|
+
fmTags: "changelog, releases, cambios",
|
|
1580
|
+
title: "Changelog",
|
|
1581
|
+
intro: "Todos los cambios notables de este proyecto se documentar\xE1n en este archivo.",
|
|
1582
|
+
format: "El formato est\xE1 basado en [Keep a Changelog](https://keepachangelog.com/es-ES/1.1.0/).",
|
|
1583
|
+
unreleased: "Unreleased",
|
|
1584
|
+
added: "Added",
|
|
1585
|
+
addedInitial: "Documentaci\xF3n del proyecto inicializada con `@damenor/agent-docs`",
|
|
1586
|
+
addedProtocol: "Agents.md como protocolo operativo para agentes de IA",
|
|
1587
|
+
addedContext: "Contexto de lenguaje del dominio (CONTEXT.md)",
|
|
1588
|
+
addedDiataxis: "Estructura de documentaci\xF3n Di\xE1taxis (tutorials, guides, reference, explanation)",
|
|
1589
|
+
templateTitle: "Template \u2014 C\xF3mo usar este archivo",
|
|
1590
|
+
whenTitle: "Cu\xE1ndo actualizar",
|
|
1591
|
+
whenFeature: "**Feature nueva** \u2192 `### Added`",
|
|
1592
|
+
whenBug: "**Bug fix** \u2192 `### Fixed`",
|
|
1593
|
+
whenChange: "**Cambio de comportamiento** \u2192 `### Changed`",
|
|
1594
|
+
whenRemove: "**Feature eliminada** \u2192 `### Removed`",
|
|
1595
|
+
whenSecurity: "**Fix de seguridad** \u2192 `### Security`",
|
|
1596
|
+
whenDep: "**Nueva dependencia** \u2192 `### Added` + explicar motivo en ADR si es significativa",
|
|
1597
|
+
formatTitle: "Formato",
|
|
1598
|
+
formatExample: "## [versi\xF3n] \u2014 YYYY-MM-DD\n\n### Added\n- Feature X que hace Y (#issue)\n\n### Fixed\n- Bug donde Z pasaba cuando W (#issue)\n\n### Changed\n- Comportamiento de V cambi\xF3 para mejorar U (#issue)",
|
|
1599
|
+
rulesTitle: "Reglas",
|
|
1600
|
+
rule1: "**Una entrada por cambio** \u2014 no agrupar cambios no relacionados.",
|
|
1601
|
+
rule2: "**Referenciar issues** \u2014 incluir n\xFAmero de issue/PR cuando sea posible.",
|
|
1602
|
+
rule3: "**Perspectiva del usuario** \u2014 describir qu\xE9 cambi\xF3 para el USUARIO, no la implementaci\xF3n.",
|
|
1603
|
+
rule4: "**Orden cronol\xF3gico inverso** \u2014 versi\xF3n m\xE1s reciente arriba.",
|
|
1604
|
+
rule5: "**No editar entradas pasadas** \u2014 una vez publicadas, son inmutables."
|
|
1605
|
+
};
|
|
1606
|
+
|
|
1607
|
+
// src/generators/changelog/labels/en.ts
|
|
1608
|
+
var labels6 = {
|
|
1609
|
+
fmType: "changelog",
|
|
1610
|
+
fmTags: "changelog, releases, changes",
|
|
1611
|
+
title: "Changelog",
|
|
1612
|
+
intro: "All notable changes to this project will be documented in this file.",
|
|
1613
|
+
format: "The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).",
|
|
1614
|
+
unreleased: "Unreleased",
|
|
1615
|
+
added: "Added",
|
|
1616
|
+
addedInitial: "Project documentation initialized with `@damenor/agent-docs`",
|
|
1617
|
+
addedProtocol: "Agents.md operational protocol for AI agents",
|
|
1618
|
+
addedContext: "Domain language context (CONTEXT.md)",
|
|
1619
|
+
addedDiataxis: "Di\xE1taxis documentation structure (tutorials, guides, reference, explanation)",
|
|
1620
|
+
templateTitle: "Template \u2014 How to use this file",
|
|
1621
|
+
whenTitle: "When to update",
|
|
1622
|
+
whenFeature: "**New feature** \u2192 `### Added`",
|
|
1623
|
+
whenBug: "**Bug fix** \u2192 `### Fixed`",
|
|
1624
|
+
whenChange: "**Behavior change** \u2192 `### Changed`",
|
|
1625
|
+
whenRemove: "**Removed feature** \u2192 `### Removed`",
|
|
1626
|
+
whenSecurity: "**Security fix** \u2192 `### Security`",
|
|
1627
|
+
whenDep: "**New dependency** \u2192 `### Added` + explain why in ADR if significant",
|
|
1628
|
+
formatTitle: "Format",
|
|
1629
|
+
formatExample: "## [version] \u2014 YYYY-MM-DD\n\n### Added\n- Feature X that does Y (#issue)\n\n### Fixed\n- Bug where Z happened when W (#issue)\n\n### Changed\n- Behavior of V changed to improve U (#issue)",
|
|
1630
|
+
rulesTitle: "Rules",
|
|
1631
|
+
rule1: "**One entry per change** \u2014 don't group unrelated changes.",
|
|
1632
|
+
rule2: "**Reference issues** \u2014 include the issue/PR number when possible.",
|
|
1633
|
+
rule3: "**User perspective** \u2014 describe what changed for the USER, not the implementation.",
|
|
1634
|
+
rule4: "**Reverse chronological** \u2014 newest version at the top.",
|
|
1635
|
+
rule5: "**Don't edit past entries** \u2014 once published, they're immutable."
|
|
1636
|
+
};
|
|
1637
|
+
|
|
1638
|
+
// src/generators/changelog/generator.ts
|
|
1639
|
+
registerLabels("changelog", "es", labels5);
|
|
1640
|
+
registerLabels("changelog", "en", labels6);
|
|
1641
|
+
function generate3(options) {
|
|
1642
|
+
const labels31 = loadLabels("changelog", options.language);
|
|
1643
|
+
const t = (key) => labels31[key] || `[${key}]`;
|
|
1644
|
+
return `---
|
|
1645
|
+
created: "2025-01-01"
|
|
1646
|
+
updated: "${options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0]}"
|
|
1647
|
+
type: ${t("fmType")}
|
|
1648
|
+
tags: [${t("fmTags")}]
|
|
1649
|
+
---
|
|
1650
|
+
|
|
1651
|
+
# ${t("title")}
|
|
1652
|
+
|
|
1653
|
+
${t("intro")}
|
|
1654
|
+
|
|
1655
|
+
${t("format")}
|
|
1656
|
+
|
|
1657
|
+
## [${t("unreleased")}]
|
|
1658
|
+
|
|
1659
|
+
### ${t("added")}
|
|
1660
|
+
- ${t("addedInitial")}
|
|
1661
|
+
- ${t("addedProtocol")}
|
|
1662
|
+
- ${t("addedContext")}
|
|
1663
|
+
- ${t("addedDiataxis")}
|
|
1664
|
+
|
|
1665
|
+
---
|
|
1666
|
+
|
|
1667
|
+
## ${t("templateTitle")}
|
|
1668
|
+
|
|
1669
|
+
### ${t("whenTitle")}
|
|
1670
|
+
|
|
1671
|
+
- ${t("whenFeature")}
|
|
1672
|
+
- ${t("whenBug")}
|
|
1673
|
+
- ${t("whenChange")}
|
|
1674
|
+
- ${t("whenRemove")}
|
|
1675
|
+
- ${t("whenSecurity")}
|
|
1676
|
+
- ${t("whenDep")}
|
|
1677
|
+
|
|
1678
|
+
### ${t("formatTitle")}
|
|
1679
|
+
|
|
1680
|
+
\`\`\`markdown
|
|
1681
|
+
${t("formatExample")}
|
|
1682
|
+
\`\`\`
|
|
1683
|
+
|
|
1684
|
+
### ${t("rulesTitle")}
|
|
1685
|
+
|
|
1686
|
+
1. ${t("rule1")}
|
|
1687
|
+
2. ${t("rule2")}
|
|
1688
|
+
3. ${t("rule3")}
|
|
1689
|
+
4. ${t("rule4")}
|
|
1690
|
+
5. ${t("rule5")}
|
|
1691
|
+
`;
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
// src/generators/quick-start/labels/es.ts
|
|
1695
|
+
var labels7 = {
|
|
1696
|
+
fmType: "tutorial",
|
|
1697
|
+
fmTags: "tutorial, quick-start, inicio, setup",
|
|
1698
|
+
title: "Quick Start \u2014 Arrancar en 15 minutos",
|
|
1699
|
+
intro: "Este tutorial te lleva desde cero hasta tener el proyecto corriendo localmente. Al terminar, tendr\xE1s el servidor de desarrollo funcionando y podr\xE1s hacer tu primer cambio.",
|
|
1700
|
+
time: "**Tiempo estimado**",
|
|
1701
|
+
audience: "**Audiencia**",
|
|
1702
|
+
prereqTitle: "Prerrequisitos",
|
|
1703
|
+
prereqTool: "Herramienta",
|
|
1704
|
+
prereqVersion: "Versi\xF3n m\xEDnima",
|
|
1705
|
+
prereqVerify: "C\xF3mo verificar",
|
|
1706
|
+
prereqInstall: "C\xF3mo instalar",
|
|
1707
|
+
step1Title: "Paso 1: Clonar el repositorio",
|
|
1708
|
+
step1Clone: "git clone [URL_DEL_REPOSITORIO]",
|
|
1709
|
+
step1Cd: "cd [NOMBRE_DEL_PROYECTO]",
|
|
1710
|
+
step1Check: "Verificar que est\xE1s en la branch correcta:",
|
|
1711
|
+
step1Result: "# Deber\xEDa mostrar: * main",
|
|
1712
|
+
step2Title: "Paso 2: Instalar dependencias",
|
|
1713
|
+
step2Install: "[npm install]",
|
|
1714
|
+
step2Error: "Si hay errores:",
|
|
1715
|
+
step2Error1: "Verificar que la versi\xF3n de [Node / Python] sea la correcta.",
|
|
1716
|
+
step2Error2: "Borrar `[node_modules]` y `[package-lock.json]` y volver a ejecutar.",
|
|
1717
|
+
step2Error3: "Si persiste, ver [`troubleshooting.md`](../guides/troubleshooting.md).",
|
|
1718
|
+
step3Title: "Paso 3: Configurar variables de entorno",
|
|
1719
|
+
step3Copy: "Copiar el archivo de ejemplo:",
|
|
1720
|
+
step3Env: "Abrir `.env` y completar los valores necesarios. Los valores m\xEDnimos para desarrollo local son:",
|
|
1721
|
+
step3Ref: "Ver la referencia completa de variables en [`docs/reference/configuration.md`](../reference/configuration.md).",
|
|
1722
|
+
step4Title: "Paso 4: Inicializar la base de datos *(si aplica)*",
|
|
1723
|
+
step4Migrate: "[comando de migraci\xF3n \u2014 ej. npm run db:migrate]",
|
|
1724
|
+
step4Seed: "[comando de seed \u2014 ej. npm run db:seed]",
|
|
1725
|
+
step5Title: "Paso 5: Arrancar el servidor de desarrollo",
|
|
1726
|
+
step5Cmd: "[npm run dev]",
|
|
1727
|
+
step5Result: "Deber\xEDas ver algo como:",
|
|
1728
|
+
step5Open: "Abrir `http://localhost:3000` en el navegador.",
|
|
1729
|
+
step6Title: "Paso 6: Verificar que todo funciona",
|
|
1730
|
+
step6Test: "Ejecutar los tests:",
|
|
1731
|
+
step6TestCmd: "[npm run test]",
|
|
1732
|
+
step6TestFail: "Si alg\xFAn test falla:",
|
|
1733
|
+
step6TestFail1: "Verificar que la base de datos est\xE9 configurada correctamente.",
|
|
1734
|
+
step6TestFail2: "Verificar que las variables de entorno est\xE9n completas.",
|
|
1735
|
+
step6TestFail3: "Ver [`troubleshooting.md`](../guides/troubleshooting.md).",
|
|
1736
|
+
step6Lint: "Ejecutar el linter:",
|
|
1737
|
+
step6LintCmd: "[npm run lint]",
|
|
1738
|
+
nextTitle: "Siguientes pasos",
|
|
1739
|
+
next1: "Para configurar tu entorno completo (editor, extensiones, herramientas):",
|
|
1740
|
+
next2: "Para hacer tu primera contribuci\xF3n (branch \u2192 c\xF3digo \u2192 PR):",
|
|
1741
|
+
next3: "Para entender la arquitectura del proyecto:",
|
|
1742
|
+
next4: "Para conocer el vocabulario del dominio:",
|
|
1743
|
+
envBlock: "# Obligatorios para arrancar\nAPP_ENV=development\nAPP_PORT=3000\n[DATABASE_URL]=[URL de desarrollo local]\n\n# Opcionales (tienen defaults para desarrollo)\n[LOG_LEVEL]=debug"
|
|
1744
|
+
};
|
|
1745
|
+
|
|
1746
|
+
// src/generators/quick-start/labels/en.ts
|
|
1747
|
+
var labels8 = {
|
|
1748
|
+
fmType: "tutorial",
|
|
1749
|
+
fmTags: "tutorial, quick-start, setup",
|
|
1750
|
+
title: "Quick Start \u2014 Get Running in 15 Minutes",
|
|
1751
|
+
intro: "This tutorial takes you from zero to having the project running locally. When done, you'll have the development server working and be able to make your first change.",
|
|
1752
|
+
time: "**Estimated time**",
|
|
1753
|
+
audience: "**Audience**",
|
|
1754
|
+
prereqTitle: "Prerequisites",
|
|
1755
|
+
prereqTool: "Tool",
|
|
1756
|
+
prereqVersion: "Minimum Version",
|
|
1757
|
+
prereqVerify: "How to Verify",
|
|
1758
|
+
prereqInstall: "How to Install",
|
|
1759
|
+
step1Title: "Step 1: Clone the repository",
|
|
1760
|
+
step1Clone: "git clone [REPOSITORY_URL]",
|
|
1761
|
+
step1Cd: "cd [PROJECT_NAME]",
|
|
1762
|
+
step1Check: "Verify you're on the correct branch:",
|
|
1763
|
+
step1Result: "# Should show: * main",
|
|
1764
|
+
step2Title: "Step 2: Install dependencies",
|
|
1765
|
+
step2Install: "[npm install]",
|
|
1766
|
+
step2Error: "If there are errors:",
|
|
1767
|
+
step2Error1: "Verify that [Node / Python] version is correct.",
|
|
1768
|
+
step2Error2: "Delete `[node_modules]` and `[package-lock.json]` and re-run.",
|
|
1769
|
+
step2Error3: "If it persists, see [`troubleshooting.md`](../guides/troubleshooting.md).",
|
|
1770
|
+
step3Title: "Step 3: Configure environment variables",
|
|
1771
|
+
step3Copy: "Copy the example file:",
|
|
1772
|
+
step3Env: "Open `.env` and fill in the necessary values. The minimum values for local development are:",
|
|
1773
|
+
step3Ref: "See the full variable reference in [`docs/reference/configuration.md`](../reference/configuration.md).",
|
|
1774
|
+
step4Title: "Step 4: Initialize the database *(if applicable)*",
|
|
1775
|
+
step4Migrate: "[migration command \u2014 e.g. npm run db:migrate]",
|
|
1776
|
+
step4Seed: "[seed command \u2014 e.g. npm run db:seed]",
|
|
1777
|
+
step5Title: "Step 5: Start the development server",
|
|
1778
|
+
step5Cmd: "[npm run dev]",
|
|
1779
|
+
step5Result: "You should see something like:",
|
|
1780
|
+
step5Open: "Open `http://localhost:3000` in the browser.",
|
|
1781
|
+
step6Title: "Step 6: Verify everything works",
|
|
1782
|
+
step6Test: "Run the tests:",
|
|
1783
|
+
step6TestCmd: "[npm run test]",
|
|
1784
|
+
step6TestFail: "If any test fails:",
|
|
1785
|
+
step6TestFail1: "Verify the database is configured correctly.",
|
|
1786
|
+
step6TestFail2: "Verify environment variables are complete.",
|
|
1787
|
+
step6TestFail3: "See [`troubleshooting.md`](../guides/troubleshooting.md).",
|
|
1788
|
+
step6Lint: "Run the linter:",
|
|
1789
|
+
step6LintCmd: "[npm run lint]",
|
|
1790
|
+
nextTitle: "Next Steps",
|
|
1791
|
+
next1: "To set up your complete environment (editor, extensions, tools):",
|
|
1792
|
+
next2: "To make your first contribution (branch \u2192 code \u2192 PR):",
|
|
1793
|
+
next3: "To understand the project architecture:",
|
|
1794
|
+
next4: "To learn the domain vocabulary:",
|
|
1795
|
+
envBlock: "# Required to start\nAPP_ENV=development\nAPP_PORT=3000\n[DATABASE_URL]=[local development URL]\n\n# Optional (have defaults for development)\n[LOG_LEVEL]=debug"
|
|
1796
|
+
};
|
|
1797
|
+
|
|
1798
|
+
// src/generators/quick-start/generator.ts
|
|
1799
|
+
registerLabels("quick-start", "es", labels7);
|
|
1800
|
+
registerLabels("quick-start", "en", labels8);
|
|
1801
|
+
function generate4(options) {
|
|
1802
|
+
const labels31 = loadLabels("quick-start", options.language);
|
|
1803
|
+
const t = (key) => labels31[key] || `[${key}]`;
|
|
1804
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1805
|
+
const isEs = options.language === "es";
|
|
1806
|
+
let md = `---
|
|
1807
|
+
created: "${today}"
|
|
1808
|
+
status: active
|
|
1809
|
+
type: ${t("fmType")}
|
|
1810
|
+
tags: [${t("fmTags")}]
|
|
1811
|
+
---
|
|
1812
|
+
|
|
1813
|
+
# ${t("title")}
|
|
1814
|
+
|
|
1815
|
+
${t("intro")}
|
|
1816
|
+
|
|
1817
|
+
${t("time")}: 15 minutos.
|
|
1818
|
+
${t("audience")}: Developers que se incorporan al proyecto por primera vez.
|
|
1819
|
+
|
|
1820
|
+
---
|
|
1821
|
+
|
|
1822
|
+
## ${t("prereqTitle")}
|
|
1823
|
+
|
|
1824
|
+
Antes de empezar, necesitas tener instalado:
|
|
1825
|
+
|
|
1826
|
+
| ${t("prereqTool")} | ${t("prereqVersion")} | ${t("prereqVerify")} | ${t("prereqInstall")} |
|
|
1827
|
+
|------------|---------------|----------------|---------------|
|
|
1828
|
+
| **[Node.js / Python / etc.]** | [versi\xF3n] | \`[node --version]\` | [nodejs.org / enlace] |
|
|
1829
|
+
| **[Git]** | [versi\xF3n] | \`git --version\` | [git-scm.com] |
|
|
1830
|
+
| **[Package manager]** | [versi\xF3n] | \`[npm --version]\` | Viene con Node.js |
|
|
1831
|
+
| **[Editor recomendado]** | \u2014 | \u2014 | [VS Code / etc.] |
|
|
1832
|
+
|
|
1833
|
+
Si necesitas ayuda con la instalaci\xF3n completa, ver [\`environment-setup.md\`](environment-setup.md).
|
|
1834
|
+
|
|
1835
|
+
---
|
|
1836
|
+
|
|
1837
|
+
## ${t("step1Title")}
|
|
1838
|
+
|
|
1839
|
+
\`\`\`bash
|
|
1840
|
+
${t("step1Clone")}
|
|
1841
|
+
${t("step1Cd")}
|
|
1842
|
+
\`\`\`
|
|
1843
|
+
|
|
1844
|
+
${t("step1Check")}
|
|
1845
|
+
|
|
1846
|
+
\`\`\`bash
|
|
1847
|
+
git branch
|
|
1848
|
+
${t("step1Result")}
|
|
1849
|
+
\`\`\`
|
|
1850
|
+
|
|
1851
|
+
---
|
|
1852
|
+
|
|
1853
|
+
## ${t("step2Title")}
|
|
1854
|
+
|
|
1855
|
+
\`\`\`bash
|
|
1856
|
+
${t("step2Install")}
|
|
1857
|
+
\`\`\`
|
|
1858
|
+
|
|
1859
|
+
${isEs ? "Este comando descarga todas las dependencias del proyecto." : "This command downloads all project dependencies."} ${t("step2Error")}
|
|
1860
|
+
|
|
1861
|
+
- ${t("step2Error1")}
|
|
1862
|
+
- ${t("step2Error2")}
|
|
1863
|
+
- ${t("step2Error3")}
|
|
1864
|
+
|
|
1865
|
+
---
|
|
1866
|
+
|
|
1867
|
+
## ${t("step3Title")}
|
|
1868
|
+
|
|
1869
|
+
${t("step3Copy")}
|
|
1870
|
+
|
|
1871
|
+
\`\`\`bash
|
|
1872
|
+
cp .env.example .env
|
|
1873
|
+
\`\`\`
|
|
1874
|
+
|
|
1875
|
+
${t("step3Env")}
|
|
1876
|
+
|
|
1877
|
+
\`\`\`env
|
|
1878
|
+
${t("envBlock")}
|
|
1879
|
+
\`\`\`
|
|
1880
|
+
|
|
1881
|
+
${t("step3Ref")}
|
|
1882
|
+
|
|
1883
|
+
---
|
|
1884
|
+
|
|
1885
|
+
## ${t("step4Title")}
|
|
1886
|
+
|
|
1887
|
+
${options.conditionCtx.hasDatabase ? `\`\`\`bash
|
|
1888
|
+
${t("step4Migrate")}
|
|
1889
|
+
\`\`\`
|
|
1890
|
+
|
|
1891
|
+
${isEs ? "Opcionalmente, cargar datos de prueba:" : "Optionally, load test data:"}
|
|
1892
|
+
|
|
1893
|
+
\`\`\`bash
|
|
1894
|
+
${t("step4Seed")}
|
|
1895
|
+
\`\`\`` : `*${isEs ? "Este proyecto no usa base de datos \u2014 saltar este paso." : "This project does not use a database \u2014 skip this step."}*`}
|
|
1896
|
+
|
|
1897
|
+
---
|
|
1898
|
+
|
|
1899
|
+
## ${t("step5Title")}
|
|
1900
|
+
|
|
1901
|
+
\`\`\`bash
|
|
1902
|
+
${t("step5Cmd")}
|
|
1903
|
+
\`\`\`
|
|
1904
|
+
|
|
1905
|
+
${t("step5Result")}
|
|
1906
|
+
|
|
1907
|
+
\`\`\`
|
|
1908
|
+
\u2713 Servidor iniciado en http://localhost:3000
|
|
1909
|
+
\u2713 Hot-reload activo
|
|
1910
|
+
\`\`\`
|
|
1911
|
+
|
|
1912
|
+
${t("step5Open")} ${isEs ? "Deber\xEDas ver [la p\xE1gina principal / el dashboard / la landing]." : "You should see [the main page / the dashboard / the landing]."}
|
|
1913
|
+
|
|
1914
|
+
---
|
|
1915
|
+
|
|
1916
|
+
## ${t("step6Title")}
|
|
1917
|
+
|
|
1918
|
+
${t("step6Test")}
|
|
1919
|
+
|
|
1920
|
+
\`\`\`bash
|
|
1921
|
+
${t("step6TestCmd")}
|
|
1922
|
+
\`\`\`
|
|
1923
|
+
|
|
1924
|
+
${isEs ? "Todos deber\xEDan pasar (verde)." : "All should pass (green)."} ${t("step6TestFail")}
|
|
1925
|
+
|
|
1926
|
+
- ${t("step6TestFail1")}
|
|
1927
|
+
- ${t("step6TestFail2")}
|
|
1928
|
+
- ${t("step6TestFail3")}
|
|
1929
|
+
|
|
1930
|
+
${t("step6Lint")}
|
|
1931
|
+
|
|
1932
|
+
\`\`\`bash
|
|
1933
|
+
${t("step6LintCmd")}
|
|
1934
|
+
\`\`\`
|
|
1935
|
+
|
|
1936
|
+
${isEs ? "No deber\xEDa mostrar errores." : "It should show no errors."}
|
|
1937
|
+
|
|
1938
|
+
---
|
|
1939
|
+
|
|
1940
|
+
## ${t("nextTitle")}
|
|
1941
|
+
|
|
1942
|
+
- ${t("next1")} [\`environment-setup.md\`](environment-setup.md).
|
|
1943
|
+
- ${t("next2")} [\`first-task.md\`](first-task.md).
|
|
1944
|
+
- ${t("next3")} [\`docs/explanation/architecture.md\`](../explanation/architecture.md).
|
|
1945
|
+
- ${t("next4")} [\`docs/CONTEXT.md\`](../CONTEXT.md).
|
|
1946
|
+
`;
|
|
1947
|
+
return md;
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
// src/generators/api-reference/labels/es.ts
|
|
1951
|
+
var labels9 = {
|
|
1952
|
+
fmType: "reference",
|
|
1953
|
+
fmTags: "api, reference, endpoints, referencia",
|
|
1954
|
+
title: "Referencia de API",
|
|
1955
|
+
intro: "Documentaci\xF3n de referencia de los endpoints del proyecto.",
|
|
1956
|
+
convention: "> [!tip] Convenci\xF3n\n> Si la API crece a m\xE1s de 10 endpoints, convierte este archivo en una carpeta `api/` con un archivo por dominio.",
|
|
1957
|
+
authTitle: "Autenticaci\xF3n",
|
|
1958
|
+
authFlow: "**Flujo**:\n1. Cliente env\xEDa credenciales a `/auth/login`\n2. Server devuelve `{ token, refreshToken }`\n3. Cliente incluye `Authorization: Bearer <token>` en requests siguientes\n4. Si token expira, usar refresh token en `/auth/refresh`",
|
|
1959
|
+
endpointsTitle: "Endpoints",
|
|
1960
|
+
resource: "[Recurso]",
|
|
1961
|
+
getTitle: "`GET /api/[recurso]`",
|
|
1962
|
+
getDesc: "Lista recursos con paginaci\xF3n.",
|
|
1963
|
+
postTitle: "`POST /api/[recurso]`",
|
|
1964
|
+
postDesc: "Crea un nuevo recurso.",
|
|
1965
|
+
errorsTitle: "C\xF3digos de Error",
|
|
1966
|
+
rateLimitTitle: "Rate Limiting",
|
|
1967
|
+
rateStandard: "Standard",
|
|
1968
|
+
ratePremium: "Premium",
|
|
1969
|
+
rateHeaders: "Headers de respuesta:",
|
|
1970
|
+
versioningTitle: "Versionado",
|
|
1971
|
+
versioningDesc: "La API usa versionado en URL: `/api/v1/`, `/api/v2/`.\n\nVersiones anteriores se mantienen durante 6 meses despu\xE9s del release de una nueva versi\xF3n mayor."
|
|
1972
|
+
};
|
|
1973
|
+
|
|
1974
|
+
// src/generators/api-reference/labels/en.ts
|
|
1975
|
+
var labels10 = {
|
|
1976
|
+
fmType: "reference",
|
|
1977
|
+
fmTags: "api, reference, endpoints",
|
|
1978
|
+
title: "API Reference",
|
|
1979
|
+
intro: "Reference documentation for the project's endpoints.",
|
|
1980
|
+
convention: "> [!tip] Convention\n> If the API grows beyond 10 endpoints, convert this file to an `api/` folder with one file per domain.",
|
|
1981
|
+
authTitle: "Authentication",
|
|
1982
|
+
authFlow: "**Flow**:\n1. Client sends credentials to `/auth/login`\n2. Server returns `{ token, refreshToken }`\n3. Client includes `Authorization: Bearer <token>` in subsequent requests\n4. If token expires, use refresh token at `/auth/refresh`",
|
|
1983
|
+
endpointsTitle: "Endpoints",
|
|
1984
|
+
resource: "[Resource]",
|
|
1985
|
+
getTitle: "`GET /api/[resource]`",
|
|
1986
|
+
getDesc: "Lists resources with pagination.",
|
|
1987
|
+
postTitle: "`POST /api/[resource]`",
|
|
1988
|
+
postDesc: "Creates a new resource.",
|
|
1989
|
+
errorsTitle: "Error Codes",
|
|
1990
|
+
rateLimitTitle: "Rate Limiting",
|
|
1991
|
+
rateStandard: "Standard",
|
|
1992
|
+
ratePremium: "Premium",
|
|
1993
|
+
rateHeaders: "Response headers:",
|
|
1994
|
+
versioningTitle: "Versioning",
|
|
1995
|
+
versioningDesc: "The API uses URL versioning: `/api/v1/`, `/api/v2/`.\n\nPrevious versions are maintained for 6 months after a new major version release."
|
|
1996
|
+
};
|
|
1997
|
+
|
|
1998
|
+
// src/generators/api-reference/generator.ts
|
|
1999
|
+
registerLabels("api-reference", "es", labels9);
|
|
2000
|
+
registerLabels("api-reference", "en", labels10);
|
|
2001
|
+
function generate5(options) {
|
|
2002
|
+
const labels31 = loadLabels("api-reference", options.language);
|
|
2003
|
+
const t = (key) => labels31[key] || `[${key}]`;
|
|
2004
|
+
return `---
|
|
2005
|
+
created: "2026-05-07"
|
|
2006
|
+
updated: "${options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0]}"
|
|
2007
|
+
status: active
|
|
2008
|
+
type: ${t("fmType")}
|
|
2009
|
+
tags: [${t("fmTags")}]
|
|
2010
|
+
---
|
|
2011
|
+
|
|
2012
|
+
# ${t("title")}
|
|
2013
|
+
|
|
2014
|
+
${t("intro")}
|
|
2015
|
+
|
|
2016
|
+
${t("convention")}
|
|
2017
|
+
|
|
2018
|
+
## ${t("authTitle")}
|
|
2019
|
+
|
|
2020
|
+
| M\xE9todo | Descripci\xF3n | Header |
|
|
2021
|
+
|--------|-------------|--------|
|
|
2022
|
+
| Bearer Token | JWT enviado en header | \`Authorization: Bearer <token>\` |
|
|
2023
|
+
|
|
2024
|
+
${t("authFlow")}
|
|
2025
|
+
|
|
2026
|
+
## ${t("endpointsTitle")}
|
|
2027
|
+
|
|
2028
|
+
### ${t("resource")}
|
|
2029
|
+
|
|
2030
|
+
#### ${t("getTitle")}
|
|
2031
|
+
|
|
2032
|
+
${t("getDesc")}
|
|
2033
|
+
|
|
2034
|
+
**Headers**:
|
|
2035
|
+
| Header | Requerido | Descripci\xF3n |
|
|
2036
|
+
|--------|-----------|-------------|
|
|
2037
|
+
| \`Authorization\` | S\xED | Bearer token |
|
|
2038
|
+
|
|
2039
|
+
**Query Parameters**:
|
|
2040
|
+
| Param | Tipo | Default | Descripci\xF3n |
|
|
2041
|
+
|-------|------|---------|-------------|
|
|
2042
|
+
| \`page\` | number | 1 | P\xE1gina actual |
|
|
2043
|
+
| \`limit\` | number | 20 | Items por p\xE1gina (max 100) |
|
|
2044
|
+
| \`sort\` | string | \`-createdAt\` | Campo de orden (\`-\` para desc) |
|
|
2045
|
+
|
|
2046
|
+
**Response 200**:
|
|
2047
|
+
\`\`\`json
|
|
2048
|
+
{
|
|
2049
|
+
"data": [
|
|
2050
|
+
{
|
|
2051
|
+
"id": "string",
|
|
2052
|
+
"name": "string",
|
|
2053
|
+
"createdAt": "ISO 8601"
|
|
2054
|
+
}
|
|
2055
|
+
],
|
|
2056
|
+
"meta": {
|
|
2057
|
+
"page": 1,
|
|
2058
|
+
"limit": 20,
|
|
2059
|
+
"total": 100
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
\`\`\`
|
|
2063
|
+
|
|
2064
|
+
#### ${t("postTitle")}
|
|
2065
|
+
|
|
2066
|
+
${t("postDesc")}
|
|
2067
|
+
|
|
2068
|
+
**Body**:
|
|
2069
|
+
\`\`\`json
|
|
2070
|
+
{
|
|
2071
|
+
"name": "string (required, max 200)",
|
|
2072
|
+
"description": "string (optional)"
|
|
2073
|
+
}
|
|
2074
|
+
\`\`\`
|
|
2075
|
+
|
|
2076
|
+
**Response 201**:
|
|
2077
|
+
\`\`\`json
|
|
2078
|
+
{
|
|
2079
|
+
"id": "string",
|
|
2080
|
+
"name": "string",
|
|
2081
|
+
"description": "string",
|
|
2082
|
+
"createdAt": "ISO 8601",
|
|
2083
|
+
"updatedAt": "ISO 8601"
|
|
2084
|
+
}
|
|
2085
|
+
\`\`\`
|
|
2086
|
+
|
|
2087
|
+
## ${t("errorsTitle")}
|
|
2088
|
+
|
|
2089
|
+
| Status | C\xF3digo | Descripci\xF3n |
|
|
2090
|
+
|--------|--------|-------------|
|
|
2091
|
+
| 400 | \`VALIDATION_ERROR\` | Datos de entrada inv\xE1lidos |
|
|
2092
|
+
| 401 | \`UNAUTHORIZED\` | Token ausente o inv\xE1lido |
|
|
2093
|
+
| 403 | \`FORBIDDEN\` | Sin permisos para el recurso |
|
|
2094
|
+
| 404 | \`NOT_FOUND\` | Recurso no encontrado |
|
|
2095
|
+
| 409 | \`CONFLICT\` | Recurso ya existe |
|
|
2096
|
+
| 422 | \`UNPROCESSABLE\` | Entidad no procesable |
|
|
2097
|
+
| 429 | \`RATE_LIMITED\` | Demasiados requests |
|
|
2098
|
+
| 500 | \`INTERNAL_ERROR\` | Error interno del servidor |
|
|
2099
|
+
|
|
2100
|
+
**Formato de error**:
|
|
2101
|
+
\`\`\`json
|
|
2102
|
+
{
|
|
2103
|
+
"error": {
|
|
2104
|
+
"code": "VALIDATION_ERROR",
|
|
2105
|
+
"message": "Descripci\xF3n legible del error",
|
|
2106
|
+
"details": [
|
|
2107
|
+
{ "field": "name", "message": "Name is required" }
|
|
2108
|
+
]
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
\`\`\`
|
|
2112
|
+
|
|
2113
|
+
## ${t("rateLimitTitle")}
|
|
2114
|
+
|
|
2115
|
+
| Tier | Requests/minuto | Burst |
|
|
2116
|
+
|------|-----------------|-------|
|
|
2117
|
+
| ${t("rateStandard")} | 60 | 10 |
|
|
2118
|
+
| ${t("ratePremium")} | 300 | 50 |
|
|
2119
|
+
|
|
2120
|
+
${t("rateHeaders")}
|
|
2121
|
+
- \`X-RateLimit-Limit\`: L\xEDmite por ventana
|
|
2122
|
+
- \`X-RateLimit-Remaining\`: Requests restantes
|
|
2123
|
+
- \`X-RateLimit-Reset\`: Timestamp cuando se resetea
|
|
2124
|
+
|
|
2125
|
+
## ${t("versioningTitle")}
|
|
2126
|
+
|
|
2127
|
+
${t("versioningDesc")}
|
|
2128
|
+
`;
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
// src/generators/environment-setup/labels/es.ts
|
|
2132
|
+
var labels11 = {
|
|
2133
|
+
fmType: "tutorial",
|
|
2134
|
+
fmTags: "tutorial, environment, setup, herramientas",
|
|
2135
|
+
title: "Configuraci\xF3n del Entorno de Desarrollo",
|
|
2136
|
+
intro: "Gu\xEDa paso a paso para configurar tu entorno de desarrollo. Al terminar, tendr\xE1s todas las herramientas necesarias para trabajar en el proyecto.",
|
|
2137
|
+
time: "**Tiempo estimado**",
|
|
2138
|
+
audience: "**Audiencia**",
|
|
2139
|
+
osTab: "SO",
|
|
2140
|
+
toolTab: "Herramienta",
|
|
2141
|
+
versionTab: "Versi\xF3n",
|
|
2142
|
+
howTab: "Instalaci\xF3n",
|
|
2143
|
+
step1Title: "1. Lenguaje de programaci\xF3n",
|
|
2144
|
+
step1Desc: "El proyecto usa **[LENGUAJE]** [versi\xF3n]. Verificar versi\xF3n:",
|
|
2145
|
+
step1Install: "Si no lo ten\xE9s, instalar desde [enlace oficial].",
|
|
2146
|
+
step2Title: "2. Git",
|
|
2147
|
+
step2Desc: "Git es obligatorio para el control de versiones.",
|
|
2148
|
+
step2Check: "Verificar instalaci\xF3n:",
|
|
2149
|
+
step2Config: "Configurar usuario (solo la primera vez):",
|
|
2150
|
+
step3Title: "3. Package Manager",
|
|
2151
|
+
step3Desc: "El proyecto usa **[PACKAGE_MANAGER]**.",
|
|
2152
|
+
step3Check: "Verificar instalaci\xF3n:",
|
|
2153
|
+
step4Title: "4. Editor de c\xF3digo",
|
|
2154
|
+
step4Desc: "Recomendamos **VS Code** con las siguientes extensiones:",
|
|
2155
|
+
step4Ext1: "**[extensi\xF3n 1]** \u2014 [descripci\xF3n]",
|
|
2156
|
+
step4Ext2: "**[extensi\xF3n 2]** \u2014 [descripci\xF3n]",
|
|
2157
|
+
step4Ext3: "**[extensi\xF3n 3]** \u2014 [descripci\xF3n]",
|
|
2158
|
+
step4Ext4: "**[extensi\xF3n 4]** \u2014 [descripci\xF3n]",
|
|
2159
|
+
step5Title: "5. Docker (opcional)",
|
|
2160
|
+
step5Desc: "Si el proyecto usa Docker para desarrollo local:",
|
|
2161
|
+
step5Check: "Verificar instalaci\xF3n:",
|
|
2162
|
+
step6Title: "6. Base de datos (opcional)",
|
|
2163
|
+
step6Desc: "Si el proyecto usa base de datos local:",
|
|
2164
|
+
step6Install: "**[Herramienta de DB]** \u2014 instalar desde [enlace]",
|
|
2165
|
+
step6Client: "Cliente recomendado: **[cliente de DB]** ([enlace])",
|
|
2166
|
+
verifyTitle: "Verificaci\xF3n final",
|
|
2167
|
+
verifyDesc: "Ejecutar estos comandos para confirmar que todo funciona:",
|
|
2168
|
+
verifyCmd1: "[comando de verificaci\xF3n 1]",
|
|
2169
|
+
verifyCmd2: "[comando de verificaci\xF3n 2]",
|
|
2170
|
+
verifyCmd3: "[comando de verificaci\xF3n 3]",
|
|
2171
|
+
nextTitle: "Siguientes pasos",
|
|
2172
|
+
next1: "Para arrancar el proyecto por primera vez: [`quick-start.md`](quick-start.md)",
|
|
2173
|
+
next2: "Para hacer tu primera contribuci\xF3n (branch \u2192 c\xF3digo \u2192 PR): [`first-task.md`](first-task.md)"
|
|
2174
|
+
};
|
|
2175
|
+
|
|
2176
|
+
// src/generators/environment-setup/labels/en.ts
|
|
2177
|
+
var labels12 = {
|
|
2178
|
+
fmType: "tutorial",
|
|
2179
|
+
fmTags: "tutorial, environment, setup, tools",
|
|
2180
|
+
title: "Development Environment Setup",
|
|
2181
|
+
intro: "Step-by-step guide to configure your development environment. When done, you'll have all the tools needed to work on the project.",
|
|
2182
|
+
time: "**Estimated time**",
|
|
2183
|
+
audience: "**Audience**",
|
|
2184
|
+
osTab: "OS",
|
|
2185
|
+
toolTab: "Tool",
|
|
2186
|
+
versionTab: "Version",
|
|
2187
|
+
howTab: "Installation",
|
|
2188
|
+
step1Title: "1. Programming Language",
|
|
2189
|
+
step1Desc: "The project uses **[LANGUAGE]** [version]. Verify version:",
|
|
2190
|
+
step1Install: "If not installed, install from [official link].",
|
|
2191
|
+
step2Title: "2. Git",
|
|
2192
|
+
step2Desc: "Git is required for version control.",
|
|
2193
|
+
step2Check: "Verify installation:",
|
|
2194
|
+
step2Config: "Configure user (first time only):",
|
|
2195
|
+
step3Title: "3. Package Manager",
|
|
2196
|
+
step3Desc: "The project uses **[PACKAGE_MANAGER]**.",
|
|
2197
|
+
step3Check: "Verify installation:",
|
|
2198
|
+
step4Title: "4. Code Editor",
|
|
2199
|
+
step4Desc: "We recommend **VS Code** with the following extensions:",
|
|
2200
|
+
step4Ext1: "**[extension 1]** \u2014 [description]",
|
|
2201
|
+
step4Ext2: "**[extension 2]** \u2014 [description]",
|
|
2202
|
+
step4Ext3: "**[extension 3]** \u2014 [description]",
|
|
2203
|
+
step4Ext4: "**[extension 4]** \u2014 [description]",
|
|
2204
|
+
step5Title: "5. Docker (optional)",
|
|
2205
|
+
step5Desc: "If the project uses Docker for local development:",
|
|
2206
|
+
step5Check: "Verify installation:",
|
|
2207
|
+
step6Title: "6. Database (optional)",
|
|
2208
|
+
step6Desc: "If the project uses a local database:",
|
|
2209
|
+
step6Install: "**[DB Tool]** \u2014 install from [link]",
|
|
2210
|
+
step6Client: "Recommended client: **[DB client]** ([link])",
|
|
2211
|
+
verifyTitle: "Final Verification",
|
|
2212
|
+
verifyDesc: "Run these commands to confirm everything works:",
|
|
2213
|
+
verifyCmd1: "[verification command 1]",
|
|
2214
|
+
verifyCmd2: "[verification command 2]",
|
|
2215
|
+
verifyCmd3: "[verification command 3]",
|
|
2216
|
+
nextTitle: "Next Steps",
|
|
2217
|
+
next1: "To start the project for the first time: [`quick-start.md`](quick-start.md)",
|
|
2218
|
+
next2: "To make your first contribution (branch \u2192 code \u2192 PR): [`first-task.md`](first-task.md)"
|
|
2219
|
+
};
|
|
2220
|
+
|
|
2221
|
+
// src/generators/environment-setup/generator.ts
|
|
2222
|
+
registerLabels("environment-setup", "es", labels11);
|
|
2223
|
+
registerLabels("environment-setup", "en", labels12);
|
|
2224
|
+
function generate6(options) {
|
|
2225
|
+
const labels31 = loadLabels("environment-setup", options.language);
|
|
2226
|
+
const t = (key) => labels31[key] || `[${key}]`;
|
|
2227
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2228
|
+
return `---
|
|
2229
|
+
created: "${today}"
|
|
2230
|
+
status: active
|
|
2231
|
+
type: ${t("fmType")}
|
|
2232
|
+
tags: [${t("fmTags")}]
|
|
2233
|
+
---
|
|
2234
|
+
|
|
2235
|
+
# ${t("title")}
|
|
2236
|
+
|
|
2237
|
+
${t("intro")}
|
|
2238
|
+
|
|
2239
|
+
${t("time")}: 30-60 minutos.
|
|
2240
|
+
${t("audience")}: Developers que se incorporan al proyecto.
|
|
2241
|
+
|
|
2242
|
+
---
|
|
2243
|
+
|
|
2244
|
+
| ${t("osTab")} | ${t("toolTab")} | ${t("versionTab")} | ${t("howTab")} |
|
|
2245
|
+
|-----|-------|--------|-----------|
|
|
2246
|
+
| Windows / Mac / Linux | **[Lenguaje]** | [versi\xF3n] | [enlace oficial] |
|
|
2247
|
+
| Windows / Mac / Linux | **Git** | 2.40+ | [git-scm.com](https://git-scm.com) |
|
|
2248
|
+
| Windows / Mac / Linux | **[Package Manager]** | [versi\xF3n] | Viene con el lenguaje |
|
|
2249
|
+
| Windows / Mac / Linux | **VS Code** | Latest | [code.visualstudio.com](https://code.visualstudio.com) |
|
|
2250
|
+
|
|
2251
|
+
---
|
|
2252
|
+
|
|
2253
|
+
## ${t("step1Title")}
|
|
2254
|
+
|
|
2255
|
+
${t("step1Desc")}
|
|
2256
|
+
|
|
2257
|
+
\`\`\`bash
|
|
2258
|
+
[comando para verificar versi\xF3n \u2014 ej. node --version]
|
|
2259
|
+
\`\`\`
|
|
2260
|
+
|
|
2261
|
+
${t("step1Install")}
|
|
2262
|
+
|
|
2263
|
+
---
|
|
2264
|
+
|
|
2265
|
+
## ${t("step2Title")}
|
|
2266
|
+
|
|
2267
|
+
${t("step2Desc")}
|
|
2268
|
+
|
|
2269
|
+
${t("step2Check")}
|
|
2270
|
+
|
|
2271
|
+
\`\`\`bash
|
|
2272
|
+
git --version
|
|
2273
|
+
# Deber\xEDa mostrar: git version 2.40+
|
|
2274
|
+
\`\`\`
|
|
2275
|
+
|
|
2276
|
+
${t("step2Config")}
|
|
2277
|
+
|
|
2278
|
+
\`\`\`bash
|
|
2279
|
+
git config --global user.name "Tu Nombre"
|
|
2280
|
+
git config --global user.email "tu@email.com"
|
|
2281
|
+
\`\`\`
|
|
2282
|
+
|
|
2283
|
+
---
|
|
2284
|
+
|
|
2285
|
+
## ${t("step3Title")}
|
|
2286
|
+
|
|
2287
|
+
${t("step3Desc")}
|
|
2288
|
+
|
|
2289
|
+
${t("step3Check")}
|
|
2290
|
+
|
|
2291
|
+
\`\`\`bash
|
|
2292
|
+
[npm --version]
|
|
2293
|
+
# Deber\xEDa mostrar: [versi\xF3n esperada]
|
|
2294
|
+
\`\`\`
|
|
2295
|
+
|
|
2296
|
+
---
|
|
2297
|
+
|
|
2298
|
+
## ${t("step4Title")}
|
|
2299
|
+
|
|
2300
|
+
${t("step4Desc")}
|
|
2301
|
+
|
|
2302
|
+
- ${t("step4Ext1")}
|
|
2303
|
+
- ${t("step4Ext2")}
|
|
2304
|
+
- ${t("step4Ext3")}
|
|
2305
|
+
- ${t("step4Ext4")}
|
|
2306
|
+
|
|
2307
|
+
---
|
|
2308
|
+
|
|
2309
|
+
${options.conditionCtx.hasDocker ? `## ${t("step5Title")}
|
|
2310
|
+
|
|
2311
|
+
${t("step5Desc")}
|
|
2312
|
+
|
|
2313
|
+
${t("step5Check")}
|
|
2314
|
+
|
|
2315
|
+
\`\`\`bash
|
|
2316
|
+
docker --version
|
|
2317
|
+
docker compose version
|
|
2318
|
+
\`\`\`
|
|
2319
|
+
` : ""}
|
|
2320
|
+
---
|
|
2321
|
+
|
|
2322
|
+
${options.conditionCtx.hasDatabase ? `## ${t("step6Title")}
|
|
2323
|
+
|
|
2324
|
+
${t("step6Desc")}
|
|
2325
|
+
|
|
2326
|
+
- ${t("step6Install")}
|
|
2327
|
+
- ${t("step6Client")}
|
|
2328
|
+
` : ""}
|
|
2329
|
+
---
|
|
2330
|
+
|
|
2331
|
+
## ${t("verifyTitle")}
|
|
2332
|
+
|
|
2333
|
+
${t("verifyDesc")}
|
|
2334
|
+
|
|
2335
|
+
\`\`\`bash
|
|
2336
|
+
${t("verifyCmd1")}
|
|
2337
|
+
${t("verifyCmd2")}
|
|
2338
|
+
${t("verifyCmd3")}
|
|
2339
|
+
\`\`\`
|
|
2340
|
+
|
|
2341
|
+
---
|
|
2342
|
+
|
|
2343
|
+
## ${t("nextTitle")}
|
|
2344
|
+
|
|
2345
|
+
- ${t("next1")}
|
|
2346
|
+
- ${t("next2")}
|
|
2347
|
+
`;
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
// src/generators/first-task/labels/es.ts
|
|
2351
|
+
var labels13 = {
|
|
2352
|
+
fmType: "tutorial",
|
|
2353
|
+
fmTags: "tutorial, first-task, contribucion",
|
|
2354
|
+
title: "Primera Tarea \u2014 Tu primera contribuci\xF3n",
|
|
2355
|
+
intro: "Este tutorial te gu\xEDa en tu primera contribuci\xF3n: desde elegir una tarea hasta mergear el PR. Al terminar, habr\xE1s completado el flujo completo de trabajo.",
|
|
2356
|
+
time: "**Tiempo estimado**",
|
|
2357
|
+
audience: "**Audiencia**",
|
|
2358
|
+
prereq: "Haber completado [`quick-start.md`](quick-start.md) y [`environment-setup.md`](environment-setup.md).",
|
|
2359
|
+
step1: "1. Elegir una tarea",
|
|
2360
|
+
step1Good: "Buenas primeras tareas: **issues etiquetados**",
|
|
2361
|
+
step2: "2. Crear una branch",
|
|
2362
|
+
step2Desc: "Siempre crear una branch desde `main`:",
|
|
2363
|
+
step3: "3. Implementar",
|
|
2364
|
+
step3Tests: "Asegurate de que los tests pasen:",
|
|
2365
|
+
step3Lint: "Y que el linter est\xE9 limpio:",
|
|
2366
|
+
step4: "4. Commitear los cambios",
|
|
2367
|
+
step4Format: "Usar Conventional Commits en espa\xF1ol:",
|
|
2368
|
+
step5: "5. Crear un Pull Request",
|
|
2369
|
+
step5Desc: "Push de la branch y crear PR en GitHub.",
|
|
2370
|
+
step5Template: "**Template de PR**:",
|
|
2371
|
+
step6: "6. Revisi\xF3n de c\xF3digo",
|
|
2372
|
+
step6Desc: "Un maintainer revisar\xE1 tu PR.",
|
|
2373
|
+
checklist: "**Checklist antes de enviar el PR**:",
|
|
2374
|
+
next: "Felicidades",
|
|
2375
|
+
nextDesc: "Completaste tu primera contribuci\xF3n. Ahora pod\xE9s tomar tareas m\xE1s grandes."
|
|
2376
|
+
};
|
|
2377
|
+
|
|
2378
|
+
// src/generators/first-task/labels/en.ts
|
|
2379
|
+
var labels14 = {
|
|
2380
|
+
fmType: "tutorial",
|
|
2381
|
+
fmTags: "tutorial, first-task, contribution",
|
|
2382
|
+
title: "First Task \u2014 Your First Contribution",
|
|
2383
|
+
intro: "This tutorial guides you through your first contribution: from choosing a task to merging the PR. When done, you'll have completed the full workflow.",
|
|
2384
|
+
time: "**Estimated time**",
|
|
2385
|
+
audience: "**Audience**",
|
|
2386
|
+
prereq: "Completed [`quick-start.md`](quick-start.md) and [`environment-setup.md`](environment-setup.md).",
|
|
2387
|
+
step1: "1. Choose a task",
|
|
2388
|
+
step1Good: "Good first issues: **tagged issues**",
|
|
2389
|
+
step2: "2. Create a branch",
|
|
2390
|
+
step2Desc: "Always create a branch from `main`:",
|
|
2391
|
+
step3: "3. Implement",
|
|
2392
|
+
step3Tests: "Make sure tests pass:",
|
|
2393
|
+
step3Lint: "And the linter is clean:",
|
|
2394
|
+
step4: "4. Commit changes",
|
|
2395
|
+
step4Format: "Use Conventional Commits in English:",
|
|
2396
|
+
step5: "5. Create a Pull Request",
|
|
2397
|
+
step5Desc: "Push the branch and create PR on GitHub.",
|
|
2398
|
+
step5Template: "**PR Template**:",
|
|
2399
|
+
step6: "6. Code Review",
|
|
2400
|
+
step6Desc: "A maintainer will review your PR.",
|
|
2401
|
+
checklist: "**Checklist before submitting PR**:",
|
|
2402
|
+
next: "Congratulations",
|
|
2403
|
+
nextDesc: "You completed your first contribution. Now you can take on larger tasks."
|
|
2404
|
+
};
|
|
2405
|
+
|
|
2406
|
+
// src/generators/first-task/generator.ts
|
|
2407
|
+
registerLabels("first-task", "es", labels13);
|
|
2408
|
+
registerLabels("first-task", "en", labels14);
|
|
2409
|
+
function generate7(options) {
|
|
2410
|
+
const labels31 = loadLabels("first-task", options.language);
|
|
2411
|
+
const t = (key) => labels31[key] || `[${key}]`;
|
|
2412
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2413
|
+
return `---
|
|
2414
|
+
created: "${today}"
|
|
2415
|
+
status: active
|
|
2416
|
+
type: ${t("fmType")}
|
|
2417
|
+
tags: [${t("fmTags")}]
|
|
2418
|
+
---
|
|
2419
|
+
|
|
2420
|
+
# ${t("title")}
|
|
2421
|
+
|
|
2422
|
+
${t("intro")}
|
|
2423
|
+
|
|
2424
|
+
${t("time")}: 1-2 horas.
|
|
2425
|
+
${t("audience")}: Developers nuevos en el proyecto.
|
|
2426
|
+
|
|
2427
|
+
> **Prerrequisitos**: ${t("prereq")}
|
|
2428
|
+
|
|
2429
|
+
---
|
|
2430
|
+
|
|
2431
|
+
## ${t("step1")}
|
|
2432
|
+
|
|
2433
|
+
${t("step1Good")}:
|
|
2434
|
+
- \`good first issue\` \u2014 tareas introductorias
|
|
2435
|
+
- \`help wanted\` \u2014 tareas que necesitan ayuda
|
|
2436
|
+
- \`bug\` \u2014 bugs confirmados
|
|
2437
|
+
|
|
2438
|
+
Asignate la tarea en GitHub y movela a "In Progress".
|
|
2439
|
+
|
|
2440
|
+
---
|
|
2441
|
+
|
|
2442
|
+
## ${t("step2")}
|
|
2443
|
+
|
|
2444
|
+
${t("step2Desc")}
|
|
2445
|
+
|
|
2446
|
+
\`\`\`bash
|
|
2447
|
+
git checkout main
|
|
2448
|
+
git pull origin main
|
|
2449
|
+
git checkout -b feature/mi-primera-tarea
|
|
2450
|
+
\`\`\`
|
|
2451
|
+
|
|
2452
|
+
---
|
|
2453
|
+
|
|
2454
|
+
## ${t("step3")}
|
|
2455
|
+
|
|
2456
|
+
${t("step3Tests")}
|
|
2457
|
+
|
|
2458
|
+
\`\`\`bash
|
|
2459
|
+
[npm run test]
|
|
2460
|
+
\`\`\`
|
|
2461
|
+
|
|
2462
|
+
${t("step3Lint")}
|
|
2463
|
+
|
|
2464
|
+
\`\`\`bash
|
|
2465
|
+
[npm run lint]
|
|
2466
|
+
\`\`\`
|
|
2467
|
+
|
|
2468
|
+
---
|
|
2469
|
+
|
|
2470
|
+
## ${t("step4")}
|
|
2471
|
+
|
|
2472
|
+
${t("step4Format")}
|
|
2473
|
+
|
|
2474
|
+
\`\`\`bash
|
|
2475
|
+
git add -A
|
|
2476
|
+
git commit -m "feat(scope): descripci\xF3n corta de lo que hiciste"
|
|
2477
|
+
\`\`\`
|
|
2478
|
+
|
|
2479
|
+
---
|
|
2480
|
+
|
|
2481
|
+
## ${t("step5")}
|
|
2482
|
+
|
|
2483
|
+
${t("step5Desc")}
|
|
2484
|
+
|
|
2485
|
+
\`\`\`bash
|
|
2486
|
+
git push origin feature/mi-primera-tarea
|
|
2487
|
+
\`\`\`
|
|
2488
|
+
|
|
2489
|
+
${t("step5Template")}
|
|
2490
|
+
|
|
2491
|
+
\`\`\`markdown
|
|
2492
|
+
## Descripci\xF3n
|
|
2493
|
+
[Qu\xE9 cambia y por qu\xE9]
|
|
2494
|
+
|
|
2495
|
+
## Tipo de cambio
|
|
2496
|
+
- [ ] Bug fix
|
|
2497
|
+
- [ ] Feature nueva
|
|
2498
|
+
- [ ] Refactor
|
|
2499
|
+
- [ ] Documentaci\xF3n
|
|
2500
|
+
|
|
2501
|
+
## C\xF3mo probarlo
|
|
2502
|
+
1. [Paso 1]
|
|
2503
|
+
2. [Paso 2]
|
|
2504
|
+
|
|
2505
|
+
## Screenshots (si aplica)
|
|
2506
|
+
\`\`\`
|
|
2507
|
+
|
|
2508
|
+
---
|
|
2509
|
+
|
|
2510
|
+
## ${t("step6")}
|
|
2511
|
+
|
|
2512
|
+
${t("step6Desc")}
|
|
2513
|
+
- Respond\xE9 a los comentarios
|
|
2514
|
+
- Hac\xE9 los cambios solicitados
|
|
2515
|
+
- El PR se mergea cuando recibe approve
|
|
2516
|
+
|
|
2517
|
+
${t("checklist")}
|
|
2518
|
+
- [ ] Tests pasan
|
|
2519
|
+
- [ ] Linter limpio
|
|
2520
|
+
- [ ] PR description completa
|
|
2521
|
+
- [ ] No hay secrets commiteados
|
|
2522
|
+
- [ ] La branch est\xE1 actualizada con \`main\`
|
|
2523
|
+
|
|
2524
|
+
---
|
|
2525
|
+
|
|
2526
|
+
## ${t("next")} \u{1F389}
|
|
2527
|
+
|
|
2528
|
+
${t("nextDesc")}
|
|
2529
|
+
- Ver el [roadmap](../product/roadmap.md) para features planeadas
|
|
2530
|
+
- Leer la [arquitectura](../explanation/architecture.md) para entender el sistema
|
|
2531
|
+
`;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
// src/generators/deployment/labels/es.ts
|
|
2535
|
+
var labels15 = {
|
|
2536
|
+
fmType: "guide",
|
|
2537
|
+
fmTags: "guide, deploy, production",
|
|
2538
|
+
title: "Gu\xEDa de Deployment",
|
|
2539
|
+
intro: "Procedimiento para desplegar la aplicaci\xF3n en producci\xF3n.",
|
|
2540
|
+
envTitle: "Entornos",
|
|
2541
|
+
envDev: "Desarrollo",
|
|
2542
|
+
envDevDesc: "Local, hot-reload activo.",
|
|
2543
|
+
envStaging: "Staging",
|
|
2544
|
+
envStagingDesc: "Pre-producci\xF3n, datos de prueba.",
|
|
2545
|
+
envProd: "Producci\xF3n",
|
|
2546
|
+
envProdDesc: "Entorno live, datos reales.",
|
|
2547
|
+
prereq: "Prerrequisitos",
|
|
2548
|
+
prereqItems: "Acceso a [plataforma de deploy]. Variables de entorno configuradas.",
|
|
2549
|
+
step1: "1. Preparar el build",
|
|
2550
|
+
step1Desc: "Ejecutar el build de producci\xF3n:",
|
|
2551
|
+
step2: "2. Verificar tests",
|
|
2552
|
+
step2Desc: "Todos los tests deben pasar antes de deployar:",
|
|
2553
|
+
step3: "3. Deploy",
|
|
2554
|
+
step3Desc: "Ejecutar el comando de deploy:",
|
|
2555
|
+
step4: "4. Verificar health",
|
|
2556
|
+
step4Desc: "Confirmar que la aplicaci\xF3n responde:",
|
|
2557
|
+
rollback: "Rollback",
|
|
2558
|
+
rollbackDesc: "Si algo falla, revertir al \xFAltimo deploy estable:",
|
|
2559
|
+
monitoring: "Monitoreo post-deploy",
|
|
2560
|
+
monitoringDesc: "Verificar m\xE9tricas en [dashboard de monitoreo]."
|
|
2561
|
+
};
|
|
2562
|
+
|
|
2563
|
+
// src/generators/deployment/labels/en.ts
|
|
2564
|
+
var labels16 = {
|
|
2565
|
+
fmType: "guide",
|
|
2566
|
+
fmTags: "guide, deploy, production",
|
|
2567
|
+
title: "Deployment Guide",
|
|
2568
|
+
intro: "Procedure to deploy the application to production.",
|
|
2569
|
+
envTitle: "Environments",
|
|
2570
|
+
envDev: "Development",
|
|
2571
|
+
envDevDesc: "Local, hot-reload active.",
|
|
2572
|
+
envStaging: "Staging",
|
|
2573
|
+
envStagingDesc: "Pre-production, test data.",
|
|
2574
|
+
envProd: "Production",
|
|
2575
|
+
envProdDesc: "Live environment, real data.",
|
|
2576
|
+
prereq: "Prerequisites",
|
|
2577
|
+
prereqItems: "Access to [deploy platform]. Environment variables configured.",
|
|
2578
|
+
step1: "1. Prepare the build",
|
|
2579
|
+
step1Desc: "Run the production build:",
|
|
2580
|
+
step2: "2. Verify tests",
|
|
2581
|
+
step2Desc: "All tests must pass before deploying:",
|
|
2582
|
+
step3: "3. Deploy",
|
|
2583
|
+
step3Desc: "Run the deploy command:",
|
|
2584
|
+
step4: "4. Verify health",
|
|
2585
|
+
step4Desc: "Confirm the application responds:",
|
|
2586
|
+
rollback: "Rollback",
|
|
2587
|
+
rollbackDesc: "If something fails, revert to the last stable deploy:",
|
|
2588
|
+
monitoring: "Post-deploy Monitoring",
|
|
2589
|
+
monitoringDesc: "Check metrics at [monitoring dashboard].",
|
|
2590
|
+
dockerDeploy: "Docker",
|
|
2591
|
+
dockerBuild: "docker build -t app .",
|
|
2592
|
+
dockerRun: "docker compose up -d",
|
|
2593
|
+
ciDesc: "CI/CD pipeline \u2014 el deploy se ejecuta autom\xE1ticamente al mergear a main.",
|
|
2594
|
+
healthCheck: "curl https://[url]/health \u2192 200 OK"
|
|
2595
|
+
};
|
|
2596
|
+
|
|
2597
|
+
// src/generators/deployment/generator.ts
|
|
2598
|
+
registerLabels("deployment", "es", labels15);
|
|
2599
|
+
registerLabels("deployment", "en", labels16);
|
|
2600
|
+
function generate8(options) {
|
|
2601
|
+
const t = (k) => loadLabels("deployment", options.language)[k] || `[${k}]`;
|
|
2602
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2603
|
+
const hasDocker = options.conditionCtx.hasDocker;
|
|
2604
|
+
const hasCI = options.conditionCtx.hasCI;
|
|
2605
|
+
return `---
|
|
2606
|
+
created: "${today}"
|
|
2607
|
+
status: active
|
|
2608
|
+
type: ${t("fmType")}
|
|
2609
|
+
tags: [${t("fmTags")}]
|
|
2610
|
+
---
|
|
2611
|
+
|
|
2612
|
+
# ${t("title")}
|
|
2613
|
+
|
|
2614
|
+
${t("intro")}
|
|
2615
|
+
|
|
2616
|
+
## ${t("envTitle")}
|
|
2617
|
+
|
|
2618
|
+
| Entorno | URL | Rama | Descripci\xF3n |
|
|
2619
|
+
|---------|-----|------|-------------|
|
|
2620
|
+
| ${t("envDev")} | http://localhost:3000 | \u2014 | ${t("envDevDesc")} |
|
|
2621
|
+
| ${t("envStaging")} | [URL de staging] | \`develop\` | ${t("envStagingDesc")} |
|
|
2622
|
+
| ${t("envProd")} | [URL de producci\xF3n] | \`main\` | ${t("envProdDesc")} |
|
|
2623
|
+
|
|
2624
|
+
## ${t("prereq")}
|
|
2625
|
+
|
|
2626
|
+
- ${t("prereqItems")}
|
|
2627
|
+
|
|
2628
|
+
## ${t("step1")}
|
|
2629
|
+
|
|
2630
|
+
${t("step1Desc")}
|
|
2631
|
+
|
|
2632
|
+
\`\`\`bash
|
|
2633
|
+
[comando de build]
|
|
2634
|
+
\`\`\`
|
|
2635
|
+
|
|
2636
|
+
## ${t("step2")}
|
|
2637
|
+
|
|
2638
|
+
${t("step2Desc")}
|
|
2639
|
+
|
|
2640
|
+
\`\`\`bash
|
|
2641
|
+
[comando de test]
|
|
2642
|
+
\`\`\`
|
|
2643
|
+
${hasDocker ? `
|
|
2644
|
+
## ${t("dockerDeploy")}
|
|
2645
|
+
|
|
2646
|
+
\`\`\`bash
|
|
2647
|
+
${t("dockerBuild")}
|
|
2648
|
+
${t("dockerRun")}
|
|
2649
|
+
\`\`\`
|
|
2650
|
+
` : ""}
|
|
2651
|
+
## ${t("step3")}
|
|
2652
|
+
|
|
2653
|
+
${t("step3Desc")}
|
|
2654
|
+
${hasCI ? `
|
|
2655
|
+
> \u2139\uFE0F ${t("ciDesc")}
|
|
2656
|
+
` : `
|
|
2657
|
+
\`\`\`bash
|
|
2658
|
+
[comando de deploy manual]
|
|
2659
|
+
\`\`\`
|
|
2660
|
+
`}
|
|
2661
|
+
## ${t("step4")}
|
|
2662
|
+
|
|
2663
|
+
${t("step4Desc")}
|
|
2664
|
+
|
|
2665
|
+
\`\`\`bash
|
|
2666
|
+
${t("healthCheck")}
|
|
2667
|
+
\`\`\`
|
|
2668
|
+
|
|
2669
|
+
## ${t("rollback")}
|
|
2670
|
+
|
|
2671
|
+
${t("rollbackDesc")}
|
|
2672
|
+
|
|
2673
|
+
\`\`\`bash
|
|
2674
|
+
[comando de rollback]
|
|
2675
|
+
\`\`\`
|
|
2676
|
+
|
|
2677
|
+
## ${t("monitoring")}
|
|
2678
|
+
|
|
2679
|
+
${t("monitoringDesc")}
|
|
2680
|
+
`;
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
// src/generators/troubleshooting/labels/es.ts
|
|
2684
|
+
var labels17 = {
|
|
2685
|
+
fmType: "guide",
|
|
2686
|
+
fmTags: "guide, troubleshooting, debugging",
|
|
2687
|
+
title: "Gu\xEDa de Troubleshooting",
|
|
2688
|
+
intro: "Soluciones a problemas comunes durante el desarrollo.",
|
|
2689
|
+
prob1: "Problema 1",
|
|
2690
|
+
prob1Desc: "[Descripci\xF3n del problema com\xFAn #1]",
|
|
2691
|
+
prob1Fix: "[Soluci\xF3n #1]",
|
|
2692
|
+
prob2: "Problema 2",
|
|
2693
|
+
prob2Desc: "[Descripci\xF3n del problema com\xFAn #2]",
|
|
2694
|
+
prob2Fix: "[Soluci\xF3n #2]",
|
|
2695
|
+
prob3: "Problema 3",
|
|
2696
|
+
prob3Desc: "[Descripci\xF3n del problema com\xFAn #3]",
|
|
2697
|
+
prob3Fix: "[Soluci\xF3n #3]",
|
|
2698
|
+
logs: "C\xF3mo obtener logs",
|
|
2699
|
+
logsDesc: "Para debuggear, aumentar el nivel de logs:",
|
|
2700
|
+
support: "\xBFNo encontraste la soluci\xF3n?",
|
|
2701
|
+
supportDesc: "Crear un issue en GitHub con logs y pasos para reproducir."
|
|
2702
|
+
};
|
|
2703
|
+
var en = {
|
|
2704
|
+
title: "Troubleshooting Guide",
|
|
2705
|
+
intro: "Solutions to common development problems.",
|
|
2706
|
+
prob1: "Problem 1",
|
|
2707
|
+
prob1Desc: "[Description of common problem #1]",
|
|
2708
|
+
prob1Fix: "[Solution #1]",
|
|
2709
|
+
prob2: "Problem 2",
|
|
2710
|
+
prob2Desc: "[Description of common problem #2]",
|
|
2711
|
+
prob2Fix: "[Solution #2]",
|
|
2712
|
+
prob3: "Problem 3",
|
|
2713
|
+
prob3Desc: "[Description of common problem #3]",
|
|
2714
|
+
prob3Fix: "[Solution #3]",
|
|
2715
|
+
logs: "How to get logs",
|
|
2716
|
+
logsDesc: "To debug, increase log level:",
|
|
2717
|
+
support: "Didn't find a solution?",
|
|
2718
|
+
supportDesc: "Create a GitHub issue with logs and reproduction steps.",
|
|
2719
|
+
fmType: "guide",
|
|
2720
|
+
fmTags: "guide, troubleshooting, debugging"
|
|
2721
|
+
};
|
|
2722
|
+
|
|
2723
|
+
// src/generators/troubleshooting/generator.ts
|
|
2724
|
+
registerLabels("troubleshooting", "es", labels17);
|
|
2725
|
+
registerLabels("troubleshooting", "en", { ...labels17, ...en });
|
|
2726
|
+
function generate9(options) {
|
|
2727
|
+
const t = (k) => loadLabels("troubleshooting", options.language)[k] || `[${k}]`;
|
|
2728
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2729
|
+
return `---
|
|
2730
|
+
created: "${today}"
|
|
2731
|
+
status: active
|
|
2732
|
+
type: ${t("fmType")}
|
|
2733
|
+
tags: [${t("fmTags")}]
|
|
2734
|
+
---
|
|
2735
|
+
|
|
2736
|
+
# ${t("title")}
|
|
2737
|
+
|
|
2738
|
+
${t("intro")}
|
|
2739
|
+
|
|
2740
|
+
---
|
|
2741
|
+
|
|
2742
|
+
## ${t("prob1")}
|
|
2743
|
+
|
|
2744
|
+
**S\xEDntoma**: ${t("prob1Desc")}
|
|
2745
|
+
|
|
2746
|
+
**Soluci\xF3n**: ${t("prob1Fix")}
|
|
2747
|
+
|
|
2748
|
+
---
|
|
2749
|
+
|
|
2750
|
+
## ${t("prob2")}
|
|
2751
|
+
|
|
2752
|
+
**S\xEDntoma**: ${t("prob2Desc")}
|
|
2753
|
+
|
|
2754
|
+
**Soluci\xF3n**: ${t("prob2Fix")}
|
|
2755
|
+
|
|
2756
|
+
---
|
|
2757
|
+
|
|
2758
|
+
## ${t("prob3")}
|
|
2759
|
+
|
|
2760
|
+
**S\xEDntoma**: ${t("prob3Desc")}
|
|
2761
|
+
|
|
2762
|
+
**Soluci\xF3n**: ${t("prob3Fix")}
|
|
2763
|
+
|
|
2764
|
+
---
|
|
2765
|
+
|
|
2766
|
+
## ${t("logs")}
|
|
2767
|
+
|
|
2768
|
+
${t("logsDesc")}
|
|
2769
|
+
|
|
2770
|
+
\`\`\`bash
|
|
2771
|
+
[comando para ver logs]
|
|
2772
|
+
\`\`\`
|
|
2773
|
+
|
|
2774
|
+
---
|
|
2775
|
+
|
|
2776
|
+
## ${t("support")}
|
|
2777
|
+
|
|
2778
|
+
${t("supportDesc")}
|
|
2779
|
+
`;
|
|
2780
|
+
}
|
|
2781
|
+
|
|
2782
|
+
// src/generators/runbooks/labels/es.ts
|
|
2783
|
+
var labels18 = {
|
|
2784
|
+
fmType: "how-to",
|
|
2785
|
+
fmTags: "runbook, operations, incident",
|
|
2786
|
+
title: "Runbook: [NOMBRE DEL PROCEDIMIENTO]",
|
|
2787
|
+
intro: "Procedimiento operativo para resolver [incidente].",
|
|
2788
|
+
owner: "Owner",
|
|
2789
|
+
severity: "Severidad",
|
|
2790
|
+
time: "Tiempo estimado",
|
|
2791
|
+
prereq: "Prerrequisitos",
|
|
2792
|
+
steps: "Pasos",
|
|
2793
|
+
verification: "Verificaci\xF3n",
|
|
2794
|
+
rollback: "Rollback",
|
|
2795
|
+
notes: "Notas"
|
|
2796
|
+
};
|
|
2797
|
+
var en2 = {
|
|
2798
|
+
title: "Runbook: [PROCEDURE NAME]",
|
|
2799
|
+
intro: "Operational procedure to resolve [incident].",
|
|
2800
|
+
owner: "Owner",
|
|
2801
|
+
severity: "Severity",
|
|
2802
|
+
time: "Estimated time",
|
|
2803
|
+
prereq: "Prerequisites",
|
|
2804
|
+
steps: "Steps",
|
|
2805
|
+
verification: "Verification",
|
|
2806
|
+
rollback: "Rollback",
|
|
2807
|
+
notes: "Notes",
|
|
2808
|
+
fmType: "how-to",
|
|
2809
|
+
fmTags: "runbook, operations, incident"
|
|
2810
|
+
};
|
|
2811
|
+
|
|
2812
|
+
// src/generators/runbooks/generator.ts
|
|
2813
|
+
registerLabels("runbooks", "es", labels18);
|
|
2814
|
+
registerLabels("runbooks", "en", { ...labels18, ...en2 });
|
|
2815
|
+
function generate10(options) {
|
|
2816
|
+
const t = (k) => loadLabels("runbooks", options.language)[k] || `[${k}]`;
|
|
2817
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2818
|
+
return `---
|
|
2819
|
+
created: "${today}"
|
|
2820
|
+
status: active
|
|
2821
|
+
type: ${t("fmType")}
|
|
2822
|
+
tags: [${t("fmTags")}]
|
|
2823
|
+
---
|
|
2824
|
+
|
|
2825
|
+
# ${t("title")}
|
|
2826
|
+
|
|
2827
|
+
${t("intro")}
|
|
2828
|
+
|
|
2829
|
+
| Campo | Valor |
|
|
2830
|
+
|-------|-------|
|
|
2831
|
+
| ${t("owner")} | [Equipo responsable] |
|
|
2832
|
+
| ${t("severity")} | [Cr\xEDtica / Alta / Media / Baja] |
|
|
2833
|
+
| ${t("time")} | [X minutos] |
|
|
2834
|
+
|
|
2835
|
+
## ${t("prereq")}
|
|
2836
|
+
- [Requisito 1]
|
|
2837
|
+
- [Requisito 2]
|
|
2838
|
+
|
|
2839
|
+
## ${t("steps")}
|
|
2840
|
+
1. [Paso 1]
|
|
2841
|
+
2. [Paso 2]
|
|
2842
|
+
3. [Paso 3]
|
|
2843
|
+
|
|
2844
|
+
## ${t("verification")}
|
|
2845
|
+
- [C\xF3mo verificar que el procedimiento funcion\xF3]
|
|
2846
|
+
|
|
2847
|
+
## ${t("rollback")}
|
|
2848
|
+
- [Pasos para revertir si algo falla]
|
|
2849
|
+
|
|
2850
|
+
## ${t("notes")}
|
|
2851
|
+
- [Notas adicionales]
|
|
2852
|
+
`;
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
// src/generators/configuration/labels/es.ts
|
|
2856
|
+
var labels19 = {
|
|
2857
|
+
fmType: "reference",
|
|
2858
|
+
fmTags: "configuration, reference, env",
|
|
2859
|
+
title: "Referencia de Configuraci\xF3n",
|
|
2860
|
+
intro: "Referencia completa de todas las variables de configuraci\xF3n del proyecto.",
|
|
2861
|
+
required: "Variables obligatorias",
|
|
2862
|
+
optional: "Variables opcionales",
|
|
2863
|
+
envName: "Variable",
|
|
2864
|
+
envDesc: "Descripci\xF3n",
|
|
2865
|
+
envDefault: "Default",
|
|
2866
|
+
envRequired: "Requerida",
|
|
2867
|
+
secrets: "Gesti\xF3n de secretos",
|
|
2868
|
+
secretsDesc: "Nunca commitear valores reales al repositorio.",
|
|
2869
|
+
dotenv: "Archivos .env"
|
|
2870
|
+
};
|
|
2871
|
+
var en3 = {
|
|
2872
|
+
fmType: "reference",
|
|
2873
|
+
fmTags: "configuration, reference, env",
|
|
2874
|
+
title: "Configuration Reference",
|
|
2875
|
+
intro: "Complete reference of all project configuration variables.",
|
|
2876
|
+
required: "Required Variables",
|
|
2877
|
+
optional: "Optional Variables",
|
|
2878
|
+
envName: "Variable",
|
|
2879
|
+
envDesc: "Description",
|
|
2880
|
+
envDefault: "Default",
|
|
2881
|
+
envRequired: "Required",
|
|
2882
|
+
secrets: "Secret Management",
|
|
2883
|
+
secretsDesc: "Never commit real values to the repository.",
|
|
2884
|
+
dotenv: ".env Files"
|
|
2885
|
+
};
|
|
2886
|
+
|
|
2887
|
+
// src/generators/configuration/generator.ts
|
|
2888
|
+
registerLabels("configuration", "es", labels19);
|
|
2889
|
+
registerLabels("configuration", "en", { ...labels19, ...en3 });
|
|
2890
|
+
function generate11(options) {
|
|
2891
|
+
const t = (k) => loadLabels("configuration", options.language)[k] || `[${k}]`;
|
|
2892
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2893
|
+
return `---
|
|
2894
|
+
created: "${today}"
|
|
2895
|
+
status: active
|
|
2896
|
+
type: ${t("fmType")}
|
|
2897
|
+
tags: [${t("fmTags")}]
|
|
2898
|
+
---
|
|
2899
|
+
|
|
2900
|
+
# ${t("title")}
|
|
2901
|
+
|
|
2902
|
+
${t("intro")}
|
|
2903
|
+
|
|
2904
|
+
## ${t("required")}
|
|
2905
|
+
|
|
2906
|
+
| ${t("envName")} | ${t("envDesc")} | ${t("envDefault")} | ${t("envRequired")} |
|
|
2907
|
+
|-------|-----------|--------|--------|
|
|
2908
|
+
| \`APP_ENV\` | Entorno actual | \`development\` | S\xED |
|
|
2909
|
+
| \`APP_PORT\` | Puerto | \`3000\` | No |
|
|
2910
|
+
| \`[VARIABLE_1]\` | [Descripci\xF3n] | \u2014 | S\xED |
|
|
2911
|
+
| \`[VARIABLE_2]\` | [Descripci\xF3n] | [default] | S\xED |
|
|
2912
|
+
|
|
2913
|
+
## ${t("optional")}
|
|
2914
|
+
|
|
2915
|
+
| ${t("envName")} | ${t("envDesc")} | ${t("envDefault")} | ${t("envRequired")} |
|
|
2916
|
+
|-------|-----------|--------|--------|
|
|
2917
|
+
| \`LOG_LEVEL\` | Nivel de log | \`debug\` | No |
|
|
2918
|
+
| \`[VARIABLE_3]\` | [Descripci\xF3n] | [default] | No |
|
|
2919
|
+
|
|
2920
|
+
## ${t("secrets")}
|
|
2921
|
+
|
|
2922
|
+
${t("secretsDesc")}
|
|
2923
|
+
|
|
2924
|
+
- Usar \`.env.example\` como template para documentar qu\xE9 variables existen.
|
|
2925
|
+
- En CI/CD, inyectar secretos v\xEDa [GitHub Secrets / Vault / etc.].
|
|
2926
|
+
|
|
2927
|
+
## ${t("dotenv")}
|
|
2928
|
+
|
|
2929
|
+
| Archivo | Prop\xF3sito | \xBFCommiteado? |
|
|
2930
|
+
|---------|----------|-------------|
|
|
2931
|
+
| \`.env.example\` | Template documentando todas las variables | \u2705 S\xED |
|
|
2932
|
+
| \`.env\` | Valores locales de desarrollo | \u274C No |
|
|
2933
|
+
| \`.env.production\` | Valores de producci\xF3n | \u274C No |
|
|
2934
|
+
`;
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
// src/generators/infrastructure/labels/es.ts
|
|
2938
|
+
var labels20 = {
|
|
2939
|
+
fmType: "reference",
|
|
2940
|
+
fmTags: "infrastructure, reference, deploy",
|
|
2941
|
+
title: "Infraestructura",
|
|
2942
|
+
intro: "Documentaci\xF3n de la infraestructura del proyecto.",
|
|
2943
|
+
hosting: "Hosting",
|
|
2944
|
+
hostingDesc: "**[Proveedor de hosting]** \u2014 [plan/regi\xF3n]",
|
|
2945
|
+
ci: "CI/CD",
|
|
2946
|
+
ciDesc: "**[Plataforma de CI]** \u2014 [plan]",
|
|
2947
|
+
db: "Base de datos",
|
|
2948
|
+
dbDesc: "**[Motor de base de datos]** \u2014 [versi\xF3n/plan]",
|
|
2949
|
+
cache: "Cache",
|
|
2950
|
+
cacheDesc: "**[Redis / Memcached / etc.]**",
|
|
2951
|
+
storage: "Almacenamiento",
|
|
2952
|
+
storageDesc: "**[S3 / Cloud Storage / etc.]**",
|
|
2953
|
+
monitoring: "Monitoreo",
|
|
2954
|
+
monitoringDesc: "**[Herramienta de monitoreo]**",
|
|
2955
|
+
domains: "Dominios",
|
|
2956
|
+
scaling: "Escalabilidad"
|
|
2957
|
+
};
|
|
2958
|
+
var en4 = {
|
|
2959
|
+
fmType: "reference",
|
|
2960
|
+
fmTags: "infrastructure, reference, deploy",
|
|
2961
|
+
title: "Infrastructure",
|
|
2962
|
+
intro: "Project infrastructure documentation.",
|
|
2963
|
+
hosting: "Hosting",
|
|
2964
|
+
hostingDesc: "**[Hosting provider]** \u2014 [plan/region]",
|
|
2965
|
+
ci: "CI/CD",
|
|
2966
|
+
ciDesc: "**[CI platform]** \u2014 [plan]",
|
|
2967
|
+
db: "Database",
|
|
2968
|
+
dbDesc: "**[Database engine]** \u2014 [version/plan]",
|
|
2969
|
+
cache: "Cache",
|
|
2970
|
+
cacheDesc: "**[Redis / Memcached / etc.]**",
|
|
2971
|
+
storage: "Storage",
|
|
2972
|
+
storageDesc: "**[S3 / Cloud Storage / etc.]**",
|
|
2973
|
+
monitoring: "Monitoring",
|
|
2974
|
+
monitoringDesc: "**[Monitoring tool]**",
|
|
2975
|
+
domains: "Domains",
|
|
2976
|
+
scaling: "Scalability"
|
|
2977
|
+
};
|
|
2978
|
+
|
|
2979
|
+
// src/generators/infrastructure/generator.ts
|
|
2980
|
+
registerLabels("infrastructure", "es", labels20);
|
|
2981
|
+
registerLabels("infrastructure", "en", { ...labels20, ...en4 });
|
|
2982
|
+
function generate12(options) {
|
|
2983
|
+
const t = (k) => loadLabels("infrastructure", options.language)[k] || `[${k}]`;
|
|
2984
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2985
|
+
return `---
|
|
2986
|
+
created: "${today}"
|
|
2987
|
+
status: active
|
|
2988
|
+
type: ${t("fmType")}
|
|
2989
|
+
tags: [${t("fmTags")}]
|
|
2990
|
+
---
|
|
2991
|
+
|
|
2992
|
+
# ${t("title")}
|
|
2993
|
+
|
|
2994
|
+
${t("intro")}
|
|
2995
|
+
|
|
2996
|
+
## ${t("hosting")}
|
|
2997
|
+
|
|
2998
|
+
${t("hostingDesc")}
|
|
2999
|
+
|
|
3000
|
+
## ${t("ci")}
|
|
3001
|
+
|
|
3002
|
+
${t("ciDesc")}
|
|
3003
|
+
${options.conditionCtx.hasCI ? `
|
|
3004
|
+
- Pipeline configurado en \`.github/workflows/\`
|
|
3005
|
+
- Incluye: lint \u2192 test \u2192 build \u2192 deploy` : ""}
|
|
3006
|
+
|
|
3007
|
+
## ${t("db")}
|
|
3008
|
+
|
|
3009
|
+
${t("dbDesc")}
|
|
3010
|
+
${options.conditionCtx.hasDatabase ? `
|
|
3011
|
+
- Migraciones gestionadas con **[herramienta de migraciones]**
|
|
3012
|
+
- Backups: [frecuencia y ubicaci\xF3n]` : ""}
|
|
3013
|
+
|
|
3014
|
+
## ${t("cache")}
|
|
3015
|
+
|
|
3016
|
+
${t("cacheDesc")}
|
|
3017
|
+
|
|
3018
|
+
## ${t("storage")}
|
|
3019
|
+
|
|
3020
|
+
${t("storageDesc")}
|
|
3021
|
+
|
|
3022
|
+
## ${t("monitoring")}
|
|
3023
|
+
|
|
3024
|
+
${t("monitoringDesc")}
|
|
3025
|
+
|
|
3026
|
+
## ${t("domains")}
|
|
3027
|
+
|
|
3028
|
+
| Entorno | Dominio |
|
|
3029
|
+
|---------|---------|
|
|
3030
|
+
| Producci\xF3n | [app.dominio.com] |
|
|
3031
|
+
| Staging | [staging.dominio.com] |
|
|
3032
|
+
|
|
3033
|
+
## ${t("scaling")}
|
|
3034
|
+
|
|
3035
|
+
- [Estrategia de escalado]
|
|
3036
|
+
- [L\xEDmites actuales]
|
|
3037
|
+
`;
|
|
3038
|
+
}
|
|
3039
|
+
|
|
3040
|
+
// src/generators/code-style/labels/es.ts
|
|
3041
|
+
var labels21 = {
|
|
3042
|
+
fmType: "reference",
|
|
3043
|
+
fmTags: "code-style, reference, conventions",
|
|
3044
|
+
title: "Gu\xEDa de Estilo de C\xF3digo",
|
|
3045
|
+
intro: "Convenciones de c\xF3digo del proyecto.",
|
|
3046
|
+
naming: "Nombramiento",
|
|
3047
|
+
namingDesc: "camelCase para variables/funciones, PascalCase para tipos/clases.",
|
|
3048
|
+
formatting: "Formateo",
|
|
3049
|
+
formattingDesc: "Usamos [Prettier / formatter] con la configuraci\xF3n del proyecto.",
|
|
3050
|
+
imports: "Imports",
|
|
3051
|
+
importsDesc: "Orden: built-in \u2192 externos \u2192 internos. Usar imports con nombre.",
|
|
3052
|
+
types: "Tipos",
|
|
3053
|
+
typesDesc: "Usar TypeScript strict. Evitar `any`. Preferir interfaces sobre types.",
|
|
3054
|
+
comments: "Comentarios",
|
|
3055
|
+
commentsDesc: "En espa\xF1ol. Explicar el POR QU\xC9, no el QU\xC9.",
|
|
3056
|
+
errors: "Manejo de errores",
|
|
3057
|
+
errorsDesc: "Usar Result types o excepciones tipadas.",
|
|
3058
|
+
testing: "Testing",
|
|
3059
|
+
testingDesc: "1 archivo de test por m\xF3dulo. Nombre: `[modulo].test.ts`."
|
|
3060
|
+
};
|
|
3061
|
+
var en5 = {
|
|
3062
|
+
fmType: "reference",
|
|
3063
|
+
fmTags: "code-style, reference, conventions",
|
|
3064
|
+
title: "Code Style Guide",
|
|
3065
|
+
intro: "Project code conventions.",
|
|
3066
|
+
naming: "Naming",
|
|
3067
|
+
namingDesc: "camelCase for variables/functions, PascalCase for types/classes.",
|
|
3068
|
+
formatting: "Formatting",
|
|
3069
|
+
formattingDesc: "We use [Prettier / formatter] with project config.",
|
|
3070
|
+
imports: "Imports",
|
|
3071
|
+
importsDesc: "Order: built-in \u2192 external \u2192 internal. Use named imports.",
|
|
3072
|
+
types: "Types",
|
|
3073
|
+
typesDesc: "Use TypeScript strict. Avoid `any`. Prefer interfaces over types.",
|
|
3074
|
+
comments: "Comments",
|
|
3075
|
+
commentsDesc: "In English. Explain the WHY, not the WHAT.",
|
|
3076
|
+
errors: "Error Handling",
|
|
3077
|
+
errorsDesc: "Use Result types or typed exceptions.",
|
|
3078
|
+
testing: "Testing",
|
|
3079
|
+
testingDesc: "1 test file per module. Name: `[module].test.ts`."
|
|
3080
|
+
};
|
|
3081
|
+
|
|
3082
|
+
// src/generators/code-style/generator.ts
|
|
3083
|
+
registerLabels("code-style", "es", labels21);
|
|
3084
|
+
registerLabels("code-style", "en", { ...labels21, ...en5 });
|
|
3085
|
+
function generate13(options) {
|
|
3086
|
+
const t = (k) => loadLabels("code-style", options.language)[k] || `[${k}]`;
|
|
3087
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
3088
|
+
return `---
|
|
3089
|
+
created: "${today}"
|
|
3090
|
+
status: active
|
|
3091
|
+
type: ${t("fmType")}
|
|
3092
|
+
tags: [${t("fmTags")}]
|
|
3093
|
+
---
|
|
3094
|
+
|
|
3095
|
+
# ${t("title")}
|
|
3096
|
+
|
|
3097
|
+
${t("intro")}
|
|
3098
|
+
|
|
3099
|
+
## ${t("naming")}
|
|
3100
|
+
|
|
3101
|
+
${t("namingDesc")}
|
|
3102
|
+
|
|
3103
|
+
## ${t("formatting")}
|
|
3104
|
+
|
|
3105
|
+
${t("formattingDesc")}
|
|
3106
|
+
|
|
3107
|
+
## ${t("imports")}
|
|
3108
|
+
|
|
3109
|
+
${t("importsDesc")}
|
|
3110
|
+
|
|
3111
|
+
## ${t("types")}
|
|
3112
|
+
|
|
3113
|
+
${t("typesDesc")}
|
|
3114
|
+
|
|
3115
|
+
## ${t("comments")}
|
|
3116
|
+
|
|
3117
|
+
${t("commentsDesc")}
|
|
3118
|
+
|
|
3119
|
+
## ${t("errors")}
|
|
3120
|
+
|
|
3121
|
+
${t("errorsDesc")}
|
|
3122
|
+
|
|
3123
|
+
## ${t("testing")}
|
|
3124
|
+
|
|
3125
|
+
${t("testingDesc")}
|
|
3126
|
+
`;
|
|
258
3127
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
3128
|
+
|
|
3129
|
+
// src/generators/architecture/labels/es.ts
|
|
3130
|
+
var labels22 = {
|
|
3131
|
+
fmType: "explanation",
|
|
3132
|
+
fmTags: "architecture, explanation, design",
|
|
3133
|
+
title: "Arquitectura del Sistema",
|
|
3134
|
+
intro: "Explica la arquitectura del proyecto \u2014 no c\xF3mo usarlo, sino por qu\xE9 est\xE1 dise\xF1ado as\xED.",
|
|
3135
|
+
overview: "Visi\xF3n General",
|
|
3136
|
+
components: "Componentes Principales",
|
|
3137
|
+
decisions: "Decisiones Clave",
|
|
3138
|
+
limits: "L\xEDmites del Sistema",
|
|
3139
|
+
deps: "Dependencias Externas"
|
|
3140
|
+
};
|
|
3141
|
+
var en6 = {
|
|
3142
|
+
fmType: "explanation",
|
|
3143
|
+
fmTags: "architecture, explanation, design",
|
|
3144
|
+
title: "System Architecture",
|
|
3145
|
+
intro: "Explains the project architecture \u2014 not how to use it, but why it's designed this way.",
|
|
3146
|
+
overview: "Overview",
|
|
3147
|
+
components: "Main Components",
|
|
3148
|
+
decisions: "Key Decisions",
|
|
3149
|
+
limits: "System Limits",
|
|
3150
|
+
deps: "External Dependencies"
|
|
3151
|
+
};
|
|
3152
|
+
|
|
3153
|
+
// src/generators/architecture/generator.ts
|
|
3154
|
+
registerLabels("architecture", "es", labels22);
|
|
3155
|
+
registerLabels("architecture", "en", { ...labels22, ...en6 });
|
|
3156
|
+
function generate14(options) {
|
|
3157
|
+
const t = (k) => loadLabels("architecture", options.language)[k] || `[${k}]`;
|
|
3158
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
3159
|
+
return `---
|
|
3160
|
+
created: "${today}"
|
|
3161
|
+
status: active
|
|
3162
|
+
type: ${t("fmType")}
|
|
3163
|
+
tags: [${t("fmTags")}]
|
|
3164
|
+
---
|
|
3165
|
+
|
|
3166
|
+
# ${t("title")}
|
|
3167
|
+
|
|
3168
|
+
${t("intro")}
|
|
3169
|
+
|
|
3170
|
+
## ${t("overview")}
|
|
3171
|
+
|
|
3172
|
+
[Descripci\xF3n general del sistema en 2-3 p\xE1rrafos \u2014 qu\xE9 hace, para qui\xE9n, stack principal.]
|
|
3173
|
+
|
|
3174
|
+
\`\`\`mermaid
|
|
3175
|
+
flowchart TD
|
|
3176
|
+
Client["Cliente"] --> API["API"]
|
|
3177
|
+
API --> DB["Base de datos"]
|
|
3178
|
+
API --> Cache["Cache"]
|
|
3179
|
+
\`\`\`
|
|
3180
|
+
|
|
3181
|
+
## ${t("components")}
|
|
3182
|
+
|
|
3183
|
+
| Componente | Tecnolog\xEDa | Responsabilidad |
|
|
3184
|
+
|-----------|-----------|----------------|
|
|
3185
|
+
| **[Componente 1]** | [Tecnolog\xEDa] | [Qu\xE9 hace] |
|
|
3186
|
+
| **[Componente 2]** | [Tecnolog\xEDa] | [Qu\xE9 hace] |
|
|
3187
|
+
| **[Componente 3]** | [Tecnolog\xEDa] | [Qu\xE9 hace] |
|
|
3188
|
+
|
|
3189
|
+
## ${t("decisions")}
|
|
3190
|
+
|
|
3191
|
+
| Decisi\xF3n | Raz\xF3n |
|
|
3192
|
+
|----------|-------|
|
|
3193
|
+
| **[Tecnolog\xEDa X]** | [Por qu\xE9 se eligi\xF3] |
|
|
3194
|
+
| **[Patr\xF3n Y]** | [Por qu\xE9 se usa] |
|
|
3195
|
+
|
|
3196
|
+
## ${t("limits")}
|
|
3197
|
+
|
|
3198
|
+
- No es responsable de [X]
|
|
3199
|
+
- No escala horizontalmente sin [Y]
|
|
3200
|
+
- L\xEDmite de [Z requests/minuto]
|
|
3201
|
+
|
|
3202
|
+
## ${t("deps")}
|
|
3203
|
+
|
|
3204
|
+
| Dependencia | Versi\xF3n | Prop\xF3sito | Cr\xEDtica |
|
|
3205
|
+
|------------|--------|----------|--------|
|
|
3206
|
+
| **[Dep 1]** | [ver] | [qu\xE9 hace] | S\xED |
|
|
3207
|
+
| **[Dep 2]** | [ver] | [qu\xE9 hace] | No |
|
|
3208
|
+
`;
|
|
264
3209
|
}
|
|
265
3210
|
|
|
266
|
-
// src/
|
|
267
|
-
|
|
268
|
-
|
|
3211
|
+
// src/generators/design/labels/es.ts
|
|
3212
|
+
var labels23 = {
|
|
3213
|
+
fmType: "product",
|
|
3214
|
+
fmTags: "design, tokens, theme",
|
|
3215
|
+
title: "Sistema de Dise\xF1o",
|
|
3216
|
+
intro: "Documentaci\xF3n de los tokens y patrones visuales del proyecto.",
|
|
3217
|
+
colors: "Colores",
|
|
3218
|
+
typography: "Tipograf\xEDa",
|
|
3219
|
+
spacing: "Espaciado",
|
|
3220
|
+
elevation: "Elevaci\xF3n",
|
|
3221
|
+
components: "Componentes"
|
|
3222
|
+
};
|
|
3223
|
+
var en7 = {
|
|
3224
|
+
fmType: "product",
|
|
3225
|
+
fmTags: "design, tokens, theme",
|
|
3226
|
+
title: "Design System",
|
|
3227
|
+
intro: "Documentation of the project's visual tokens and patterns.",
|
|
3228
|
+
colors: "Colors",
|
|
3229
|
+
typography: "Typography",
|
|
3230
|
+
spacing: "Spacing",
|
|
3231
|
+
elevation: "Elevation",
|
|
3232
|
+
components: "Components"
|
|
3233
|
+
};
|
|
269
3234
|
|
|
270
|
-
// src/
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
function
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
3235
|
+
// src/generators/design/generator.ts
|
|
3236
|
+
registerLabels("design", "es", labels23);
|
|
3237
|
+
registerLabels("design", "en", { ...labels23, ...en7 });
|
|
3238
|
+
function generate15(options) {
|
|
3239
|
+
const t = (k) => loadLabels("design", options.language)[k] || `[${k}]`;
|
|
3240
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
3241
|
+
return `---
|
|
3242
|
+
created: "${today}"
|
|
3243
|
+
status: active
|
|
3244
|
+
type: ${t("fmType")}
|
|
3245
|
+
tags: [${t("fmTags")}]
|
|
3246
|
+
---
|
|
3247
|
+
|
|
3248
|
+
# ${t("title")}
|
|
3249
|
+
|
|
3250
|
+
${t("intro")}
|
|
3251
|
+
|
|
3252
|
+
## \u{1F3A8} ${t("colors")}
|
|
3253
|
+
|
|
3254
|
+
| Token | Color | Uso |
|
|
3255
|
+
|-------|-------|-----|
|
|
3256
|
+
| \`--color-primary\` | \`#XXXXXX\` | Color principal |
|
|
3257
|
+
| \`--color-secondary\` | \`#XXXXXX\` | Color secundario |
|
|
3258
|
+
| \`--color-background\` | \`#XXXXXX\` | Fondo general |
|
|
3259
|
+
| \`--color-text\` | \`#XXXXXX\` | Texto principal |
|
|
3260
|
+
| \`--color-muted\` | \`#XXXXXX\` | Texto secundario |
|
|
3261
|
+
|
|
3262
|
+
## \u270F\uFE0F ${t("typography")}
|
|
3263
|
+
|
|
3264
|
+
| Token | Font | Size | Weight |
|
|
3265
|
+
|-------|------|------|--------|
|
|
3266
|
+
| \`--font-family\` | [Font] | \u2014 | \u2014 |
|
|
3267
|
+
| \`--text-xs\` | \u2014 | 0.75rem | \u2014 |
|
|
3268
|
+
| \`--text-base\` | \u2014 | 1rem | \u2014 |
|
|
3269
|
+
| \`--text-lg\` | \u2014 | 1.25rem | \u2014 |
|
|
3270
|
+
| \`--text-xl\` | \u2014 | 1.5rem | 700 |
|
|
3271
|
+
|
|
3272
|
+
## \u{1F4CF} ${t("spacing")}
|
|
3273
|
+
|
|
3274
|
+
| Token | Value |
|
|
3275
|
+
|-------|-------|
|
|
3276
|
+
| \`--space-1\` | 0.25rem |
|
|
3277
|
+
| \`--space-2\` | 0.5rem |
|
|
3278
|
+
| \`--space-4\` | 1rem |
|
|
3279
|
+
| \`--space-8\` | 2rem |
|
|
3280
|
+
|
|
3281
|
+
## \u{1F3D4}\uFE0F ${t("elevation")}
|
|
3282
|
+
|
|
3283
|
+
| Token | Shadow |
|
|
3284
|
+
|-------|--------|
|
|
3285
|
+
| \`--shadow-sm\` | \`0 1px 2px rgba(0,0,0,0.05)\` |
|
|
3286
|
+
| \`--shadow-md\` | \`0 4px 6px rgba(0,0,0,0.1)\` |
|
|
3287
|
+
| \`--shadow-lg\` | \`0 10px 15px rgba(0,0,0,0.1)\` |
|
|
3288
|
+
|
|
3289
|
+
## \u{1F9E9} ${t("components")}
|
|
3290
|
+
|
|
3291
|
+
[Documentar componentes clave del sistema de dise\xF1o aqu\xED.]
|
|
3292
|
+
`;
|
|
277
3293
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
3294
|
+
|
|
3295
|
+
// src/generators/overview/labels/es.ts
|
|
3296
|
+
var labels24 = {
|
|
3297
|
+
fmType: "product",
|
|
3298
|
+
fmTags: "overview, product",
|
|
3299
|
+
title: "Visi\xF3n General",
|
|
3300
|
+
intro: "Resumen ejecutivo del proyecto.",
|
|
3301
|
+
problem: "Problema",
|
|
3302
|
+
solution: "Soluci\xF3n",
|
|
3303
|
+
users: "Usuarios",
|
|
3304
|
+
features: "Features principales"
|
|
3305
|
+
};
|
|
3306
|
+
var en8 = {
|
|
3307
|
+
fmType: "product",
|
|
3308
|
+
fmTags: "overview, product",
|
|
3309
|
+
title: "Overview",
|
|
3310
|
+
intro: "Executive summary of the project.",
|
|
3311
|
+
problem: "Problem",
|
|
3312
|
+
solution: "Solution",
|
|
3313
|
+
users: "Users",
|
|
3314
|
+
features: "Key Features"
|
|
3315
|
+
};
|
|
3316
|
+
|
|
3317
|
+
// src/generators/overview/generator.ts
|
|
3318
|
+
registerLabels("overview", "es", labels24);
|
|
3319
|
+
registerLabels("overview", "en", { ...labels24, ...en8 });
|
|
3320
|
+
function generate16(options) {
|
|
3321
|
+
const t = (k) => loadLabels("overview", options.language)[k] || `[${k}]`;
|
|
3322
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
3323
|
+
return `---
|
|
3324
|
+
created: "${today}"
|
|
3325
|
+
status: active
|
|
3326
|
+
type: ${t("fmType")}
|
|
3327
|
+
tags: [${t("fmTags")}]
|
|
3328
|
+
---
|
|
3329
|
+
|
|
3330
|
+
# ${t("title")}
|
|
3331
|
+
|
|
3332
|
+
${t("intro")}
|
|
3333
|
+
|
|
3334
|
+
## ${t("problem")}
|
|
3335
|
+
|
|
3336
|
+
[Qu\xE9 problema resuelve este proyecto. 2-3 p\xE1rrafos.]
|
|
3337
|
+
|
|
3338
|
+
## ${t("solution")}
|
|
3339
|
+
|
|
3340
|
+
[C\xF3mo lo resuelve. Incluir diagrama de alto nivel si aplica.]
|
|
3341
|
+
|
|
3342
|
+
## ${t("users")}
|
|
3343
|
+
|
|
3344
|
+
| Tipo de usuario | Necesidad principal |
|
|
3345
|
+
|----------------|-------------------|
|
|
3346
|
+
| **[Usuario 1]** | [Qu\xE9 necesita] |
|
|
3347
|
+
| **[Usuario 2]** | [Qu\xE9 necesita] |
|
|
3348
|
+
|
|
3349
|
+
## ${t("features")}
|
|
3350
|
+
|
|
3351
|
+
- **[Feature 1]**: [Descripci\xF3n corta]
|
|
3352
|
+
- **[Feature 2]**: [Descripci\xF3n corta]
|
|
3353
|
+
- **[Feature 3]**: [Descripci\xF3n corta]
|
|
3354
|
+
`;
|
|
281
3355
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
3356
|
+
|
|
3357
|
+
// src/generators/roadmap/labels/es.ts
|
|
3358
|
+
var labels25 = {
|
|
3359
|
+
fmType: "product",
|
|
3360
|
+
fmTags: "roadmap, planning",
|
|
3361
|
+
title: "Roadmap",
|
|
3362
|
+
intro: "Planificaci\xF3n de features y milestones del proyecto.",
|
|
3363
|
+
now: "Ahora",
|
|
3364
|
+
nowDesc: "En desarrollo activo.",
|
|
3365
|
+
next: "Pr\xF3ximo",
|
|
3366
|
+
nextDesc: "Siguiente en prioridad.",
|
|
3367
|
+
later: "Futuro",
|
|
3368
|
+
laterDesc: "Planeado, sin fecha.",
|
|
3369
|
+
done: "Completado",
|
|
3370
|
+
doneDesc: "Entregado."
|
|
3371
|
+
};
|
|
3372
|
+
var en9 = {
|
|
3373
|
+
fmType: "product",
|
|
3374
|
+
fmTags: "roadmap, planning",
|
|
3375
|
+
title: "Roadmap",
|
|
3376
|
+
intro: "Feature and milestone planning for the project.",
|
|
3377
|
+
now: "Now",
|
|
3378
|
+
nowDesc: "In active development.",
|
|
3379
|
+
next: "Next",
|
|
3380
|
+
nextDesc: "Next in priority.",
|
|
3381
|
+
later: "Later",
|
|
3382
|
+
laterDesc: "Planned, no date.",
|
|
3383
|
+
done: "Done",
|
|
3384
|
+
doneDesc: "Delivered."
|
|
3385
|
+
};
|
|
3386
|
+
|
|
3387
|
+
// src/generators/roadmap/generator.ts
|
|
3388
|
+
registerLabels("roadmap", "es", labels25);
|
|
3389
|
+
registerLabels("roadmap", "en", { ...labels25, ...en9 });
|
|
3390
|
+
function generate17(options) {
|
|
3391
|
+
const t = (k) => loadLabels("roadmap", options.language)[k] || `[${k}]`;
|
|
3392
|
+
return `---
|
|
3393
|
+
created: "${options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0]}"
|
|
3394
|
+
status: active
|
|
3395
|
+
type: ${t("fmType")}
|
|
3396
|
+
tags: [${t("fmTags")}]
|
|
3397
|
+
---
|
|
3398
|
+
|
|
3399
|
+
# ${t("title")}
|
|
3400
|
+
|
|
3401
|
+
${t("intro")}
|
|
3402
|
+
|
|
3403
|
+
## \u{1F504} ${t("now")}
|
|
3404
|
+
|
|
3405
|
+
${t("nowDesc")}
|
|
3406
|
+
|
|
3407
|
+
- [Feature actual 1]
|
|
3408
|
+
- [Feature actual 2]
|
|
3409
|
+
|
|
3410
|
+
## \u23E9 ${t("next")}
|
|
3411
|
+
|
|
3412
|
+
${t("nextDesc")}
|
|
3413
|
+
|
|
3414
|
+
- [Feature planeada 1]
|
|
3415
|
+
- [Feature planeada 2]
|
|
3416
|
+
|
|
3417
|
+
## \u{1F52E} ${t("later")}
|
|
3418
|
+
|
|
3419
|
+
${t("laterDesc")}
|
|
3420
|
+
|
|
3421
|
+
- [Idea futura 1]
|
|
3422
|
+
- [Idea futura 2]
|
|
3423
|
+
|
|
3424
|
+
## \u2705 ${t("done")}
|
|
3425
|
+
|
|
3426
|
+
${t("doneDesc")}
|
|
3427
|
+
|
|
3428
|
+
- [Feature completada 1]
|
|
3429
|
+
`;
|
|
286
3430
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
3431
|
+
|
|
3432
|
+
// src/generators/operations/labels/es.ts
|
|
3433
|
+
var labels26 = {
|
|
3434
|
+
fmType: "operations",
|
|
3435
|
+
fmTags: "operations, monitoring, incidents",
|
|
3436
|
+
title: "Operaciones",
|
|
3437
|
+
intro: "Documentaci\xF3n operativa del proyecto.",
|
|
3438
|
+
monitoring: "Monitoreo",
|
|
3439
|
+
alerts: "Alertas",
|
|
3440
|
+
incidents: "Incidentes",
|
|
3441
|
+
backups: "Backups"
|
|
3442
|
+
};
|
|
3443
|
+
var en10 = {
|
|
3444
|
+
fmType: "operations",
|
|
3445
|
+
fmTags: "operations, monitoring, incidents",
|
|
3446
|
+
title: "Operations",
|
|
3447
|
+
intro: "Project operations documentation.",
|
|
3448
|
+
monitoring: "Monitoring",
|
|
3449
|
+
alerts: "Alerts",
|
|
3450
|
+
incidents: "Incidents",
|
|
3451
|
+
backups: "Backups"
|
|
3452
|
+
};
|
|
3453
|
+
|
|
3454
|
+
// src/generators/operations/generator.ts
|
|
3455
|
+
registerLabels("operations", "es", labels26);
|
|
3456
|
+
registerLabels("operations", "en", { ...labels26, ...en10 });
|
|
3457
|
+
function generate18(options) {
|
|
3458
|
+
const t = (k) => loadLabels("operations", options.language)[k] || `[${k}]`;
|
|
3459
|
+
return `---
|
|
3460
|
+
created: "${options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0]}"
|
|
3461
|
+
status: active
|
|
3462
|
+
type: ${t("fmType")}
|
|
3463
|
+
tags: [${t("fmTags")}]
|
|
3464
|
+
---
|
|
3465
|
+
|
|
3466
|
+
# ${t("title")}
|
|
3467
|
+
|
|
3468
|
+
${t("intro")}
|
|
3469
|
+
|
|
3470
|
+
## \u{1F4CA} ${t("monitoring")}
|
|
3471
|
+
|
|
3472
|
+
- [Dashboard de monitoreo]: [URL]
|
|
3473
|
+
- M\xE9tricas clave: [latencia, error rate, throughput]
|
|
3474
|
+
- Logs: [herramienta de logs]
|
|
3475
|
+
|
|
3476
|
+
## \u{1F6A8} ${t("alerts")}
|
|
3477
|
+
|
|
3478
|
+
| Alerta | Severidad | Canal | Responsable |
|
|
3479
|
+
|--------|----------|-------|------------|
|
|
3480
|
+
| [Alerta 1] | Cr\xEDtica | PagerDuty | [Equipo] |
|
|
3481
|
+
| [Alerta 2] | Alta | Slack | [Equipo] |
|
|
3482
|
+
|
|
3483
|
+
## \u{1F525} ${t("incidents")}
|
|
3484
|
+
|
|
3485
|
+
Procedimiento de respuesta a incidentes:
|
|
3486
|
+
1. [Detectar y reconocer]
|
|
3487
|
+
2. [Escalar si es necesario]
|
|
3488
|
+
3. [Mitigar]
|
|
3489
|
+
4. [Resolver]
|
|
3490
|
+
5. [Post-mortem]
|
|
3491
|
+
|
|
3492
|
+
Ver runbooks en [\`docs/guides/runbooks/\`](../guides/runbooks/).
|
|
3493
|
+
|
|
3494
|
+
## \u{1F4BE} ${t("backups")}
|
|
3495
|
+
|
|
3496
|
+
| Dato | Frecuencia | Retenci\xF3n | Ubicaci\xF3n |
|
|
3497
|
+
|------|----------|----------|----------|
|
|
3498
|
+
| Base de datos | [Diaria] | [30 d\xEDas] | [S3] |
|
|
3499
|
+
| Archivos | [Diaria] | [30 d\xEDas] | [S3] |
|
|
3500
|
+
`;
|
|
3501
|
+
}
|
|
3502
|
+
|
|
3503
|
+
// src/generators/project-readme/labels/es.ts
|
|
3504
|
+
var labels27 = {
|
|
3505
|
+
title: "# {{PROJECT_NAME}}",
|
|
3506
|
+
intro: "[Descripci\xF3n corta del proyecto en una o dos frases.]",
|
|
3507
|
+
quick: "\u{1F680} Quick Start",
|
|
3508
|
+
quickDesc: "[Instrucciones m\xEDnimas para arrancar en local.]",
|
|
3509
|
+
docs: "\u{1F4DA} Documentaci\xF3n",
|
|
3510
|
+
docsDesc: "Documentaci\xF3n completa en la carpeta [`docs/`](docs/).",
|
|
3511
|
+
stack: "\u{1F6E0}\uFE0F Stack",
|
|
3512
|
+
license: "\u{1F4C4} Licencia"
|
|
3513
|
+
};
|
|
3514
|
+
var en11 = {
|
|
3515
|
+
title: "# {{PROJECT_NAME}}",
|
|
3516
|
+
intro: "[Short project description in one or two sentences.]",
|
|
3517
|
+
quick: "\u{1F680} Quick Start",
|
|
3518
|
+
quickDesc: "[Minimum instructions to get started locally.]",
|
|
3519
|
+
docs: "\u{1F4DA} Documentation",
|
|
3520
|
+
docsDesc: "Full documentation in the [`docs/`](docs/) folder.",
|
|
3521
|
+
stack: "\u{1F6E0}\uFE0F Stack",
|
|
3522
|
+
license: "\u{1F4C4} License"
|
|
3523
|
+
};
|
|
3524
|
+
|
|
3525
|
+
// src/generators/project-readme/generator.ts
|
|
3526
|
+
registerLabels("project-readme", "es", labels27);
|
|
3527
|
+
registerLabels("project-readme", "en", { ...labels27, ...en11 });
|
|
3528
|
+
function generate19(options) {
|
|
3529
|
+
const t = (k) => loadLabels("project-readme", options.language)[k] || `[${k}]`;
|
|
3530
|
+
const stack = options.stack ? `${options.stack.language}${options.stack.framework ? " + " + options.stack.framework : ""}` : "[TECNOLOG\xCDA]";
|
|
3531
|
+
return `# {{PROJECT_NAME}}
|
|
3532
|
+
|
|
3533
|
+
${t("intro")}
|
|
3534
|
+
|
|
3535
|
+
## ${t("quick")}
|
|
3536
|
+
|
|
3537
|
+
\`\`\`bash
|
|
3538
|
+
git clone [URL]
|
|
3539
|
+
cd {{PROJECT_NAME}}
|
|
3540
|
+
[comando de instalaci\xF3n]
|
|
3541
|
+
[comando de dev]
|
|
3542
|
+
\`\`\`
|
|
3543
|
+
|
|
3544
|
+
${t("quickDesc")}
|
|
3545
|
+
|
|
3546
|
+
## ${t("docs")}
|
|
3547
|
+
|
|
3548
|
+
${t("docsDesc")}
|
|
3549
|
+
|
|
3550
|
+
## ${t("stack")}
|
|
3551
|
+
|
|
3552
|
+
- **Lenguaje**: ${stack}
|
|
3553
|
+
- **Package Manager**: ${options.stack?.packageManager || "[package manager]"}
|
|
3554
|
+
|
|
3555
|
+
## ${t("license")}
|
|
3556
|
+
|
|
3557
|
+
[LICENSE]
|
|
3558
|
+
`;
|
|
3559
|
+
}
|
|
3560
|
+
|
|
3561
|
+
// src/generators/docs-readme/labels/es.ts
|
|
3562
|
+
var labels28 = {
|
|
3563
|
+
title: "\u{1F4DA} Documentaci\xF3n de {{PROJECT_NAME}}",
|
|
3564
|
+
intro: "Bienvenido a la documentaci\xF3n de {{PROJECT_NAME}}.",
|
|
3565
|
+
structure: "Estructura",
|
|
3566
|
+
tutorials: "\u{1F4D6} Tutoriales",
|
|
3567
|
+
guides: "\u{1F4DD} Gu\xEDas",
|
|
3568
|
+
reference: "\u{1F4CB} Referencia",
|
|
3569
|
+
explanation: "\u{1F4A1} Explicaci\xF3n",
|
|
3570
|
+
product: "\u{1F680} Producto",
|
|
3571
|
+
ops: "\u2699\uFE0F Operaciones"
|
|
3572
|
+
};
|
|
3573
|
+
var en12 = {
|
|
3574
|
+
title: "\u{1F4DA} {{PROJECT_NAME}} Documentation",
|
|
3575
|
+
intro: "Welcome to the {{PROJECT_NAME}} documentation.",
|
|
3576
|
+
structure: "Structure",
|
|
3577
|
+
tutorials: "\u{1F4D6} Tutorials",
|
|
3578
|
+
guides: "\u{1F4DD} Guides",
|
|
3579
|
+
reference: "\u{1F4CB} Reference",
|
|
3580
|
+
explanation: "\u{1F4A1} Explanation",
|
|
3581
|
+
product: "\u{1F680} Product",
|
|
3582
|
+
ops: "\u2699\uFE0F Operations"
|
|
3583
|
+
};
|
|
3584
|
+
|
|
3585
|
+
// src/generators/docs-readme/generator.ts
|
|
3586
|
+
registerLabels("docs-readme", "es", labels28);
|
|
3587
|
+
registerLabels("docs-readme", "en", { ...labels28, ...en12 });
|
|
3588
|
+
function generate20(options) {
|
|
3589
|
+
const t = (k) => loadLabels("docs-readme", options.language)[k] || `[${k}]`;
|
|
3590
|
+
return `# ${t("title")}
|
|
3591
|
+
|
|
3592
|
+
${t("intro")}
|
|
3593
|
+
|
|
3594
|
+
## ${t("structure")}
|
|
3595
|
+
|
|
3596
|
+
| Directorio | Tipo | Contenido |
|
|
3597
|
+
|-----------|------|----------|
|
|
3598
|
+
| \`tutorials/\` | ${t("tutorials")} | Aprender haciendo |
|
|
3599
|
+
| \`guides/\` | ${t("guides")} | C\xF3mo resolver tareas |
|
|
3600
|
+
| \`reference/\` | ${t("reference")} | Info t\xE9cnica detallada |
|
|
3601
|
+
| \`explanation/\` | ${t("explanation")} | Razonamiento y decisiones |
|
|
3602
|
+
| \`product/\` | ${t("product")} | Roadmap y visi\xF3n |
|
|
3603
|
+
| \`operations/\` | ${t("ops")} | Runbooks y monitoreo |
|
|
3604
|
+
`;
|
|
3605
|
+
}
|
|
3606
|
+
|
|
3607
|
+
// src/generators/adr-template/labels/es.ts
|
|
3608
|
+
var labels29 = {
|
|
3609
|
+
fmType: "adr-template",
|
|
3610
|
+
fmTags: "adr, template, decisions",
|
|
3611
|
+
title: "ADR-0000: [T\xEDtulo descriptivo de la decisi\xF3n]",
|
|
3612
|
+
statuses: "Propuesto \u2192 Aceptado \u2192 Deprecado \u2192 Reemplazado",
|
|
3613
|
+
context: "Contexto",
|
|
3614
|
+
decision: "Decisi\xF3n",
|
|
3615
|
+
consequences: "Consecuencias",
|
|
3616
|
+
alternatives: "Alternativas",
|
|
3617
|
+
pos: "Positivas",
|
|
3618
|
+
neg: "Negativas",
|
|
3619
|
+
migration: "Migraci\xF3n",
|
|
3620
|
+
rollback: "Rollback"
|
|
3621
|
+
};
|
|
3622
|
+
var en13 = {
|
|
3623
|
+
fmType: "adr-template",
|
|
3624
|
+
fmTags: "adr, template, decisions",
|
|
3625
|
+
title: "ADR-0000: [Descriptive title of the decision]",
|
|
3626
|
+
statuses: "Proposed \u2192 Accepted \u2192 Deprecated \u2192 Superseded",
|
|
3627
|
+
context: "Context",
|
|
3628
|
+
decision: "Decision",
|
|
3629
|
+
consequences: "Consequences",
|
|
3630
|
+
alternatives: "Alternatives",
|
|
3631
|
+
pos: "Positive",
|
|
3632
|
+
neg: "Negative",
|
|
3633
|
+
migration: "Migration",
|
|
3634
|
+
rollback: "Rollback"
|
|
3635
|
+
};
|
|
3636
|
+
|
|
3637
|
+
// src/generators/adr-template/generator.ts
|
|
3638
|
+
registerLabels("adr-template", "es", labels29);
|
|
3639
|
+
registerLabels("adr-template", "en", { ...labels29, ...en13 });
|
|
3640
|
+
function generate21(options) {
|
|
3641
|
+
const t = (k) => loadLabels("adr-template", options.language)[k] || `[${k}]`;
|
|
3642
|
+
const today = options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
3643
|
+
return `---
|
|
3644
|
+
created: "${today}"
|
|
3645
|
+
status: proposed
|
|
3646
|
+
deciders: ["[nombre]"]
|
|
3647
|
+
tags: [${t("fmTags")}]
|
|
3648
|
+
---
|
|
3649
|
+
|
|
3650
|
+
# ${t("title")}
|
|
3651
|
+
|
|
3652
|
+
**Estado**: ${t("statuses")}
|
|
3653
|
+
|
|
3654
|
+
## ${t("context")}
|
|
3655
|
+
|
|
3656
|
+
[Describe el problema, las fuerzas en juego, y las restricciones. \xBFQu\xE9 nos llev\xF3 a tomar esta decisi\xF3n?]
|
|
3657
|
+
|
|
3658
|
+
## ${t("decision")}
|
|
3659
|
+
|
|
3660
|
+
[Describe la decisi\xF3n en una o dos frases. S\xE9 espec\xEDfico.]
|
|
3661
|
+
|
|
3662
|
+
## ${t("consequences")}
|
|
3663
|
+
|
|
3664
|
+
### ${t("pos")}
|
|
3665
|
+
- [Consecuencia positiva 1]
|
|
3666
|
+
- [Consecuencia positiva 2]
|
|
3667
|
+
|
|
3668
|
+
### ${t("neg")}
|
|
3669
|
+
- [Consecuencia negativa 1]
|
|
3670
|
+
- [Trade-off aceptado]
|
|
3671
|
+
|
|
3672
|
+
### ${t("migration")}
|
|
3673
|
+
[Si la decisi\xF3n requiere migraci\xF3n, describir los pasos.]
|
|
3674
|
+
|
|
3675
|
+
### ${t("rollback")}
|
|
3676
|
+
[Si la decisi\xF3n se revierte, \xBFc\xF3mo se vuelve atr\xE1s?]
|
|
3677
|
+
|
|
3678
|
+
## ${t("alternatives")}
|
|
3679
|
+
|
|
3680
|
+
| Alternativa | Rechazada porque... |
|
|
3681
|
+
|------------|-------------------|
|
|
3682
|
+
| **[Alt 1]** | [Raz\xF3n] |
|
|
3683
|
+
| **[Alt 2]** | [Raz\xF3n] |
|
|
3684
|
+
`;
|
|
305
3685
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
3686
|
+
|
|
3687
|
+
// src/generators/agent-flow/labels/es.ts
|
|
3688
|
+
var labels30 = {
|
|
3689
|
+
fmType: "explanation",
|
|
3690
|
+
fmTags: "agent-flow, agents, protocol",
|
|
3691
|
+
title: "Flujo de Agentes",
|
|
3692
|
+
intro: "Diagrama y explicaci\xF3n del flujo de trabajo de agentes de IA en este proyecto.",
|
|
3693
|
+
subdel: "Subdelegaci\xF3n",
|
|
3694
|
+
subdelDesc: "El orquestador delega a agentes especializados.",
|
|
3695
|
+
qg: "Quality Gate",
|
|
3696
|
+
qgDesc: "@reviewer verifica antes de completar.",
|
|
3697
|
+
main: "Mantenimiento",
|
|
3698
|
+
mainDesc: "El skill doc-maintain sincroniza cambios."
|
|
3699
|
+
};
|
|
3700
|
+
var en14 = {
|
|
3701
|
+
fmType: "explanation",
|
|
3702
|
+
fmTags: "agent-flow, agents, protocol",
|
|
3703
|
+
title: "Agent Flow",
|
|
3704
|
+
intro: "Diagram and explanation of the AI agent workflow in this project.",
|
|
3705
|
+
subdel: "Sub-delegation",
|
|
3706
|
+
subdelDesc: "The orchestrator delegates to specialized agents.",
|
|
3707
|
+
qg: "Quality Gate",
|
|
3708
|
+
qgDesc: "@reviewer verifies before completing.",
|
|
3709
|
+
main: "Maintenance",
|
|
3710
|
+
mainDesc: "The doc-maintain skill syncs changes."
|
|
3711
|
+
};
|
|
3712
|
+
|
|
3713
|
+
// src/generators/agent-flow/generator.ts
|
|
3714
|
+
registerLabels("agent-flow", "es", labels30);
|
|
3715
|
+
registerLabels("agent-flow", "en", { ...labels30, ...en14 });
|
|
3716
|
+
function generate22(options) {
|
|
3717
|
+
const t = (k) => loadLabels("agent-flow", options.language)[k] || `[${k}]`;
|
|
3718
|
+
return `---
|
|
3719
|
+
created: "${options.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0]}"
|
|
3720
|
+
status: active
|
|
3721
|
+
type: ${t("fmType")}
|
|
3722
|
+
tags: [${t("fmTags")}]
|
|
3723
|
+
---
|
|
3724
|
+
|
|
3725
|
+
# ${t("title")}
|
|
3726
|
+
|
|
3727
|
+
${t("intro")}
|
|
3728
|
+
|
|
3729
|
+
\`\`\`mermaid
|
|
3730
|
+
sequenceDiagram
|
|
3731
|
+
participant U as Developer
|
|
3732
|
+
participant O as Orchestrator
|
|
3733
|
+
participant A as Agent
|
|
3734
|
+
participant R as @reviewer
|
|
3735
|
+
|
|
3736
|
+
U->>O: Task
|
|
3737
|
+
O->>A: ${t("subdel")}
|
|
3738
|
+
A->>A: Implement
|
|
3739
|
+
A->>R: Request review
|
|
3740
|
+
R-->>A: \u2705 / \u274C
|
|
3741
|
+
A->>O: Done
|
|
3742
|
+
O->>U: Complete
|
|
3743
|
+
\`\`\`
|
|
3744
|
+
|
|
3745
|
+
## ${t("subdel")}
|
|
3746
|
+
|
|
3747
|
+
${t("subdelDesc")}
|
|
3748
|
+
|
|
3749
|
+
## ${t("qg")}
|
|
3750
|
+
|
|
3751
|
+
${t("qgDesc")}
|
|
3752
|
+
|
|
3753
|
+
## ${t("main")}
|
|
3754
|
+
|
|
3755
|
+
${t("mainDesc")}
|
|
3756
|
+
`;
|
|
309
3757
|
}
|
|
310
3758
|
|
|
311
3759
|
// src/generator.ts
|
|
312
|
-
var __dirname =
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
3760
|
+
var __dirname = path6.dirname(fileURLToPath(import.meta.url));
|
|
3761
|
+
var GENERATED_FILES = /* @__PURE__ */ new Set([
|
|
3762
|
+
// Base
|
|
3763
|
+
"AGENTS.md",
|
|
3764
|
+
"AGENTS.en.md",
|
|
3765
|
+
"CHANGELOG.md",
|
|
3766
|
+
"CHANGELOG.en.md",
|
|
3767
|
+
"docs/CONTEXT.md",
|
|
3768
|
+
"docs/CONTEXT.en.md",
|
|
3769
|
+
"README.md",
|
|
3770
|
+
"docs/README.md",
|
|
3771
|
+
"docs/adr/TEMPLATE.md",
|
|
3772
|
+
// Tutorials
|
|
3773
|
+
"docs/tutorials/quick-start.md",
|
|
3774
|
+
"docs/tutorials/quick-start.en.md",
|
|
3775
|
+
"docs/tutorials/environment-setup.md",
|
|
3776
|
+
"docs/tutorials/first-task.md",
|
|
3777
|
+
// Guides
|
|
3778
|
+
"docs/guides/deployment.md",
|
|
3779
|
+
"docs/guides/troubleshooting.md",
|
|
3780
|
+
"docs/guides/runbooks/TEMPLATE.md",
|
|
3781
|
+
// Reference
|
|
3782
|
+
"docs/reference/api.md",
|
|
3783
|
+
"docs/reference/api.en.md",
|
|
3784
|
+
"docs/reference/configuration.md",
|
|
3785
|
+
"docs/reference/infrastructure.md",
|
|
3786
|
+
"docs/reference/code-style.md",
|
|
3787
|
+
// Explanation
|
|
3788
|
+
"docs/explanation/architecture.md",
|
|
3789
|
+
"docs/explanation/agent-flow.md",
|
|
3790
|
+
// Product
|
|
3791
|
+
"docs/product/overview.md",
|
|
3792
|
+
"docs/roadmap.md",
|
|
3793
|
+
// Operations
|
|
3794
|
+
"docs/operations/README.md",
|
|
3795
|
+
// Design
|
|
3796
|
+
"docs/DESIGN.md"
|
|
3797
|
+
]);
|
|
3798
|
+
async function generate23(options) {
|
|
3799
|
+
const { projectName, targetDir, modules } = options;
|
|
3800
|
+
const replacements = buildReplacements(projectName, options.stack);
|
|
3801
|
+
const conditionCtx = buildConditionContext(options.stack, targetDir);
|
|
3802
|
+
const templatesDir = resolveTemplatesDir();
|
|
3803
|
+
const plannedFiles = [];
|
|
3804
|
+
const baseDir = path6.join(templatesDir, "base");
|
|
3805
|
+
if (fs6.existsSync(baseDir)) {
|
|
3806
|
+
collectFiles(baseDir, targetDir, replacements, "base", plannedFiles);
|
|
3807
|
+
}
|
|
3808
|
+
for (const moduleName of modules) {
|
|
3809
|
+
const moduleDir = path6.join(templatesDir, "modules", moduleName);
|
|
3810
|
+
if (fs6.existsSync(moduleDir)) {
|
|
3811
|
+
collectFiles(moduleDir, targetDir, replacements, moduleName, plannedFiles);
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3814
|
+
const sharedDir = path6.join(templatesDir, "shared");
|
|
3815
|
+
if (fs6.existsSync(sharedDir)) {
|
|
3816
|
+
collectFiles(sharedDir, targetDir, replacements, "shared", plannedFiles);
|
|
3817
|
+
}
|
|
3818
|
+
const genOpts = {
|
|
3819
|
+
projectName,
|
|
3820
|
+
stack: options.stack,
|
|
3821
|
+
language: options.language,
|
|
3822
|
+
conditionCtx
|
|
3823
|
+
};
|
|
3824
|
+
plannedFiles.push({
|
|
3825
|
+
relativePath: "AGENTS.md",
|
|
3826
|
+
sourcePath: "",
|
|
3827
|
+
content: generate(genOpts),
|
|
3828
|
+
replacements: {},
|
|
3829
|
+
module: "base"
|
|
3830
|
+
});
|
|
3831
|
+
plannedFiles.push({
|
|
3832
|
+
relativePath: "docs/CONTEXT.md",
|
|
3833
|
+
sourcePath: "",
|
|
3834
|
+
content: generate2(genOpts),
|
|
3835
|
+
replacements: {},
|
|
3836
|
+
module: "base"
|
|
3837
|
+
});
|
|
3838
|
+
plannedFiles.push({
|
|
3839
|
+
relativePath: "CHANGELOG.md",
|
|
3840
|
+
sourcePath: "",
|
|
3841
|
+
content: generate3(genOpts),
|
|
3842
|
+
replacements: {},
|
|
3843
|
+
module: "base"
|
|
3844
|
+
});
|
|
3845
|
+
if (modules.includes("reference")) {
|
|
3846
|
+
plannedFiles.push({ relativePath: "docs/reference/api.md", sourcePath: "", content: generate5(genOpts), replacements: {}, module: "reference" });
|
|
3847
|
+
plannedFiles.push({
|
|
3848
|
+
relativePath: "docs/reference/configuration.md",
|
|
3849
|
+
sourcePath: "",
|
|
3850
|
+
content: generate11(genOpts),
|
|
3851
|
+
replacements: {},
|
|
3852
|
+
module: "reference"
|
|
3853
|
+
});
|
|
3854
|
+
plannedFiles.push({
|
|
3855
|
+
relativePath: "docs/reference/infrastructure.md",
|
|
3856
|
+
sourcePath: "",
|
|
3857
|
+
content: generate12(genOpts),
|
|
3858
|
+
replacements: {},
|
|
3859
|
+
module: "reference"
|
|
3860
|
+
});
|
|
3861
|
+
plannedFiles.push({
|
|
3862
|
+
relativePath: "docs/reference/code-style.md",
|
|
3863
|
+
sourcePath: "",
|
|
3864
|
+
content: generate13(genOpts),
|
|
3865
|
+
replacements: {},
|
|
3866
|
+
module: "reference"
|
|
3867
|
+
});
|
|
3868
|
+
}
|
|
3869
|
+
if (modules.includes("tutorials")) {
|
|
3870
|
+
plannedFiles.push({
|
|
3871
|
+
relativePath: "docs/tutorials/quick-start.md",
|
|
3872
|
+
sourcePath: "",
|
|
3873
|
+
content: generate4(genOpts),
|
|
3874
|
+
replacements: {},
|
|
3875
|
+
module: "tutorials"
|
|
3876
|
+
});
|
|
3877
|
+
plannedFiles.push({
|
|
3878
|
+
relativePath: "docs/tutorials/environment-setup.md",
|
|
3879
|
+
sourcePath: "",
|
|
3880
|
+
content: generate6(genOpts),
|
|
3881
|
+
replacements: {},
|
|
3882
|
+
module: "tutorials"
|
|
3883
|
+
});
|
|
3884
|
+
plannedFiles.push({
|
|
3885
|
+
relativePath: "docs/tutorials/first-task.md",
|
|
3886
|
+
sourcePath: "",
|
|
3887
|
+
content: generate7(genOpts),
|
|
3888
|
+
replacements: {},
|
|
3889
|
+
module: "tutorials"
|
|
3890
|
+
});
|
|
3891
|
+
}
|
|
3892
|
+
if (modules.includes("guides")) {
|
|
3893
|
+
plannedFiles.push({ relativePath: "docs/guides/deployment.md", sourcePath: "", content: generate8(genOpts), replacements: {}, module: "guides" });
|
|
3894
|
+
plannedFiles.push({
|
|
3895
|
+
relativePath: "docs/guides/troubleshooting.md",
|
|
3896
|
+
sourcePath: "",
|
|
3897
|
+
content: generate9(genOpts),
|
|
3898
|
+
replacements: {},
|
|
3899
|
+
module: "guides"
|
|
3900
|
+
});
|
|
3901
|
+
plannedFiles.push({
|
|
3902
|
+
relativePath: "docs/guides/runbooks/TEMPLATE.md",
|
|
3903
|
+
sourcePath: "",
|
|
3904
|
+
content: generate10(genOpts),
|
|
3905
|
+
replacements: {},
|
|
3906
|
+
module: "guides"
|
|
3907
|
+
});
|
|
3908
|
+
}
|
|
3909
|
+
if (modules.includes("explanation")) {
|
|
3910
|
+
plannedFiles.push({
|
|
3911
|
+
relativePath: "docs/explanation/architecture.md",
|
|
3912
|
+
sourcePath: "",
|
|
3913
|
+
content: generate14(genOpts),
|
|
3914
|
+
replacements: {},
|
|
3915
|
+
module: "explanation"
|
|
3916
|
+
});
|
|
3917
|
+
plannedFiles.push({
|
|
3918
|
+
relativePath: "docs/explanation/agent-flow.md",
|
|
3919
|
+
sourcePath: "",
|
|
3920
|
+
content: generate22(genOpts),
|
|
3921
|
+
replacements: {},
|
|
3922
|
+
module: "explanation"
|
|
3923
|
+
});
|
|
3924
|
+
}
|
|
3925
|
+
if (modules.includes("product")) {
|
|
3926
|
+
plannedFiles.push({ relativePath: "docs/product/overview.md", sourcePath: "", content: generate16(genOpts), replacements: {}, module: "product" });
|
|
3927
|
+
plannedFiles.push({ relativePath: "docs/roadmap.md", sourcePath: "", content: generate17(genOpts), replacements: {}, module: "product" });
|
|
3928
|
+
}
|
|
3929
|
+
if (modules.includes("operations")) {
|
|
3930
|
+
plannedFiles.push({ relativePath: "docs/operations/README.md", sourcePath: "", content: generate18(genOpts), replacements: {}, module: "operations" });
|
|
3931
|
+
}
|
|
3932
|
+
if (modules.includes("design")) {
|
|
3933
|
+
plannedFiles.push({ relativePath: "docs/DESIGN.md", sourcePath: "", content: generate15(genOpts), replacements: {}, module: "design" });
|
|
3934
|
+
}
|
|
3935
|
+
plannedFiles.push({ relativePath: "README.md", sourcePath: "", content: generate19(genOpts), replacements: {}, module: "base" });
|
|
3936
|
+
plannedFiles.push({ relativePath: "docs/README.md", sourcePath: "", content: generate20(genOpts), replacements: {}, module: "base" });
|
|
3937
|
+
plannedFiles.push({ relativePath: "docs/adr/TEMPLATE.md", sourcePath: "", content: generate21(genOpts), replacements: {}, module: "base" });
|
|
3938
|
+
const createdFiles = await processConflicts(plannedFiles, {
|
|
3939
|
+
targetDir,
|
|
3940
|
+
force: options.force,
|
|
3941
|
+
dryRun: options.dryRun,
|
|
3942
|
+
conditionCtx
|
|
3943
|
+
});
|
|
3944
|
+
if (options.initGit && !options.dryRun) {
|
|
3945
|
+
await initGit(targetDir);
|
|
3946
|
+
}
|
|
3947
|
+
return createdFiles;
|
|
3948
|
+
}
|
|
3949
|
+
function buildReplacements(projectName, stack) {
|
|
316
3950
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
317
|
-
|
|
3951
|
+
return {
|
|
318
3952
|
"{{PROJECT_NAME}}": projectName,
|
|
319
3953
|
"{{TECH_STACK}}": stack ? formatStackForTemplate(stack) : "[TECNOLOG\xCDA PRINCIPAL]",
|
|
320
3954
|
"{{DEV_COMMAND}}": stack?.devCommand || "[comando de dev]",
|
|
@@ -325,49 +3959,34 @@ async function generate(options) {
|
|
|
325
3959
|
"{{FRAMEWORK}}": stack?.framework || "[framework]",
|
|
326
3960
|
"{{PACKAGE_MANAGER}}": stack?.packageManager || "[package manager]",
|
|
327
3961
|
"{{DATE}}": today,
|
|
328
|
-
// Mantener los placeholders originales para compatibilidad
|
|
329
3962
|
"[NOMBRE DEL PROYECTO]": projectName
|
|
330
3963
|
};
|
|
331
|
-
const templatesDir = await resolveTemplatesDir();
|
|
332
|
-
const baseDir = path3.join(templatesDir, "base");
|
|
333
|
-
copyTemplateDir(baseDir, targetDir, replacements);
|
|
334
|
-
createdFiles.push(...await listGeneratedFiles(baseDir, targetDir));
|
|
335
|
-
for (const moduleName of modules) {
|
|
336
|
-
const moduleDir = path3.join(templatesDir, "modules", moduleName);
|
|
337
|
-
copyTemplateDir(moduleDir, targetDir, replacements);
|
|
338
|
-
createdFiles.push(...await listGeneratedFiles(moduleDir, targetDir));
|
|
339
|
-
}
|
|
340
|
-
const sharedDir = path3.join(templatesDir, "shared");
|
|
341
|
-
copyTemplateDir(sharedDir, targetDir, replacements);
|
|
342
|
-
createdFiles.push(...await listGeneratedFiles(sharedDir, targetDir));
|
|
343
|
-
if (options.initGit) {
|
|
344
|
-
await initGit(targetDir);
|
|
345
|
-
}
|
|
346
|
-
return createdFiles;
|
|
347
|
-
}
|
|
348
|
-
async function resolveTemplatesDir() {
|
|
349
|
-
const prodPath = path3.resolve(__dirname, "..", "templates");
|
|
350
|
-
const devPath = path3.resolve(__dirname, "..", "..", "templates");
|
|
351
|
-
const { existsSync } = await import("fs");
|
|
352
|
-
if (existsSync(prodPath)) return prodPath;
|
|
353
|
-
if (existsSync(devPath)) return devPath;
|
|
354
|
-
throw new Error("No se encontr\xF3 el directorio de templates. \xBFSe instal\xF3 correctamente el paquete?");
|
|
355
3964
|
}
|
|
356
|
-
|
|
357
|
-
const
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
3965
|
+
function collectFiles(templateDir, targetDir, replacements, module, output, prefix = "") {
|
|
3966
|
+
const entries = fs6.readdirSync(templateDir, { withFileTypes: true });
|
|
3967
|
+
for (const entry of entries) {
|
|
3968
|
+
const srcPath = path6.join(templateDir, entry.name);
|
|
3969
|
+
if (entry.isDirectory()) {
|
|
3970
|
+
collectFiles(srcPath, targetDir, replacements, module, output, path6.join(prefix, entry.name));
|
|
3971
|
+
} else {
|
|
3972
|
+
const relativePath = path6.join(prefix, entry.name).replace(/\\/g, "/");
|
|
3973
|
+
if (GENERATED_FILES.has(relativePath)) continue;
|
|
3974
|
+
if (GENERATED_FILES.has(relativePath.replace(/\.en\.md$/, ".md"))) continue;
|
|
3975
|
+
output.push({
|
|
3976
|
+
relativePath,
|
|
3977
|
+
sourcePath: path6.resolve(srcPath),
|
|
3978
|
+
replacements,
|
|
3979
|
+
module
|
|
3980
|
+
});
|
|
367
3981
|
}
|
|
368
3982
|
}
|
|
369
|
-
|
|
370
|
-
|
|
3983
|
+
}
|
|
3984
|
+
function resolveTemplatesDir() {
|
|
3985
|
+
const prodPath = path6.resolve(__dirname, "..", "templates");
|
|
3986
|
+
const devPath = path6.resolve(__dirname, "..", "..", "templates");
|
|
3987
|
+
if (fs6.existsSync(prodPath)) return prodPath;
|
|
3988
|
+
if (fs6.existsSync(devPath)) return devPath;
|
|
3989
|
+
throw new Error("No se encontr\xF3 el directorio de templates. \xBFSe instal\xF3 correctamente el paquete?");
|
|
371
3990
|
}
|
|
372
3991
|
async function initGit(dir) {
|
|
373
3992
|
const { execSync } = await import("child_process");
|
|
@@ -554,43 +4173,45 @@ function generateAgentsGuide() {
|
|
|
554
4173
|
}
|
|
555
4174
|
|
|
556
4175
|
// src/cli.ts
|
|
557
|
-
var __dirname2 =
|
|
558
|
-
var pkg = JSON.parse(
|
|
4176
|
+
var __dirname2 = path7.dirname(url.fileURLToPath(import.meta.url));
|
|
4177
|
+
var pkg = JSON.parse(fs7.readFileSync(path7.join(__dirname2, "..", "package.json"), "utf-8"));
|
|
559
4178
|
function showHelp() {
|
|
560
4179
|
console.log(`
|
|
561
|
-
${
|
|
4180
|
+
${pc4.bold(brand.title("@damenor/agent-docs"))} ${pc4.dim(`v${pkg.version}`)}
|
|
562
4181
|
|
|
563
|
-
${
|
|
564
|
-
${
|
|
565
|
-
${
|
|
566
|
-
${
|
|
4182
|
+
${pc4.bold("USAGE")}
|
|
4183
|
+
${pc4.cyan("npx @damenor/agent-docs")} ${pc4.dim("# Interactive wizard (default)")}
|
|
4184
|
+
${pc4.cyan("npx @damenor/agent-docs --help")} ${pc4.dim("# Show this help")}
|
|
4185
|
+
${pc4.cyan("npx @damenor/agent-docs --version")} ${pc4.dim("# Show version")}
|
|
567
4186
|
|
|
568
|
-
${
|
|
4187
|
+
${pc4.bold("WHAT IT DOES")}
|
|
569
4188
|
Generates a professional documentation structure for your project:
|
|
570
4189
|
Di\xE1taxis (Tutorials/Guides/Reference/Explanation) + AGENTS.md + ADRs + AI agent skills.
|
|
571
4190
|
|
|
572
|
-
${
|
|
573
|
-
1. ${
|
|
574
|
-
2. ${
|
|
575
|
-
3. ${
|
|
576
|
-
4. ${
|
|
577
|
-
5. ${
|
|
578
|
-
6. ${
|
|
579
|
-
7. ${
|
|
4191
|
+
${pc4.bold("WIZARD STEPS")}
|
|
4192
|
+
1. ${pc4.bold("Project name")} \u2014 How your project is called
|
|
4193
|
+
2. ${pc4.bold("Target directory")} \u2014 Where to generate docs (default: ./)
|
|
4194
|
+
3. ${pc4.bold("Stack detection")} \u2014 Auto-detect or configure manually
|
|
4195
|
+
4. ${pc4.bold("Language")} \u2014 Espa\xF1ol or English
|
|
4196
|
+
5. ${pc4.bold("Modules")} \u2014 Pick from 9 available modules
|
|
4197
|
+
6. ${pc4.bold("Git init")} \u2014 Initialize git repo with first commit
|
|
4198
|
+
7. ${pc4.bold("Generate")} \u2014 Confirm and create all files
|
|
580
4199
|
|
|
581
|
-
${
|
|
582
|
-
${DOC_MODULES.map((m) => ` ${
|
|
4200
|
+
${pc4.bold("MODULES")}
|
|
4201
|
+
${DOC_MODULES.map((m) => ` ${pc4.cyan(m.value.padEnd(12))} ${m.label} \u2014 ${m.hint ?? ""}`).join("\n")}
|
|
583
4202
|
|
|
584
|
-
${
|
|
4203
|
+
${pc4.bold("STACK DETECTION")}
|
|
585
4204
|
Reads package.json, pyproject.toml, go.mod, Cargo.toml, pom.xml, build.gradle.
|
|
586
4205
|
Supports Node.js, Python, Go, Rust, Java/Kotlin + 10+ frameworks.
|
|
587
4206
|
|
|
588
|
-
${
|
|
589
|
-
${
|
|
590
|
-
${
|
|
591
|
-
${
|
|
4207
|
+
${pc4.bold("OPTIONS")}
|
|
4208
|
+
${pc4.cyan("-h, --help")} Show this help
|
|
4209
|
+
${pc4.cyan("-v, --version")} Show version
|
|
4210
|
+
${pc4.cyan("--agents-guide")} Output guide for AI agents (what to fill, what to delete, priorities)
|
|
4211
|
+
${pc4.cyan("--force")} Overwrite existing files without prompting
|
|
4212
|
+
${pc4.cyan("--dry-run")} Preview what would be generated without writing
|
|
592
4213
|
|
|
593
|
-
${
|
|
4214
|
+
${pc4.dim("Made with \u2764\uFE0F by damenordev")}
|
|
594
4215
|
`);
|
|
595
4216
|
}
|
|
596
4217
|
function showVersion() {
|
|
@@ -598,6 +4219,8 @@ function showVersion() {
|
|
|
598
4219
|
}
|
|
599
4220
|
async function cli() {
|
|
600
4221
|
const args = process.argv.slice(2);
|
|
4222
|
+
const isForce = args.includes("--force");
|
|
4223
|
+
const isDryRun = args.includes("--dry-run");
|
|
601
4224
|
if (args.includes("--help") || args.includes("-h")) {
|
|
602
4225
|
showHelp();
|
|
603
4226
|
return;
|
|
@@ -611,11 +4234,15 @@ async function cli() {
|
|
|
611
4234
|
process.exit(0);
|
|
612
4235
|
}
|
|
613
4236
|
console.clear();
|
|
614
|
-
|
|
615
|
-
`${
|
|
616
|
-
|
|
4237
|
+
if (isDryRun) {
|
|
4238
|
+
console.log(`${pc4.blue("\u2139")} ${pc4.dim("Dry run mode \u2014 no files will be written")}
|
|
4239
|
+
`);
|
|
4240
|
+
}
|
|
4241
|
+
p2.intro(
|
|
4242
|
+
`${icons.docs} ${brand.title("@damenor/agent-docs")} ${pc4.dim(`v${pkg.version}`)}
|
|
4243
|
+
${pc4.dim("Documentaci\xF3n profesional para proyectos con agentes AI")}`
|
|
617
4244
|
);
|
|
618
|
-
const projectName = await
|
|
4245
|
+
const projectName = await p2.text({
|
|
619
4246
|
message: `${icons.sparkle} Nombre del proyecto`,
|
|
620
4247
|
placeholder: "mi-proyecto",
|
|
621
4248
|
validate: (value) => {
|
|
@@ -625,11 +4252,11 @@ async function cli() {
|
|
|
625
4252
|
}
|
|
626
4253
|
}
|
|
627
4254
|
});
|
|
628
|
-
if (
|
|
629
|
-
|
|
4255
|
+
if (p2.isCancel(projectName)) {
|
|
4256
|
+
p2.cancel("Operaci\xF3n cancelada.");
|
|
630
4257
|
process.exit(0);
|
|
631
4258
|
}
|
|
632
|
-
const targetDir = await
|
|
4259
|
+
const targetDir = await p2.text({
|
|
633
4260
|
message: `${icons.folder} Directorio de destino`,
|
|
634
4261
|
placeholder: "./",
|
|
635
4262
|
initialValue: "./",
|
|
@@ -637,22 +4264,22 @@ async function cli() {
|
|
|
637
4264
|
if (!value.trim()) return "El directorio es obligatorio.";
|
|
638
4265
|
}
|
|
639
4266
|
});
|
|
640
|
-
if (
|
|
641
|
-
|
|
4267
|
+
if (p2.isCancel(targetDir)) {
|
|
4268
|
+
p2.cancel("Operaci\xF3n cancelada.");
|
|
642
4269
|
process.exit(0);
|
|
643
4270
|
}
|
|
644
|
-
const resolvedDir =
|
|
4271
|
+
const resolvedDir = path7.resolve(targetDir.trim());
|
|
645
4272
|
if (!isDirEmpty(resolvedDir)) {
|
|
646
|
-
const overwrite = await
|
|
4273
|
+
const overwrite = await p2.confirm({
|
|
647
4274
|
message: `${icons.warning} El directorio no est\xE1 vac\xEDo. \xBFContinuar? (puede sobrescribir archivos)`,
|
|
648
4275
|
initialValue: false
|
|
649
4276
|
});
|
|
650
|
-
if (
|
|
651
|
-
|
|
4277
|
+
if (p2.isCancel(overwrite) || !overwrite) {
|
|
4278
|
+
p2.cancel("Operaci\xF3n cancelada.");
|
|
652
4279
|
process.exit(0);
|
|
653
4280
|
}
|
|
654
4281
|
}
|
|
655
|
-
const stackOption = await
|
|
4282
|
+
const stackOption = await p2.select({
|
|
656
4283
|
message: `${icons.search} Stack tecnol\xF3gico`,
|
|
657
4284
|
options: [
|
|
658
4285
|
{ value: "auto", label: "Auto-detectar", hint: "recomendado \u2014 analiza el proyecto" },
|
|
@@ -660,13 +4287,13 @@ async function cli() {
|
|
|
660
4287
|
{ value: "skip", label: "Omitir", hint: "rellenar despu\xE9s" }
|
|
661
4288
|
]
|
|
662
4289
|
});
|
|
663
|
-
if (
|
|
664
|
-
|
|
4290
|
+
if (p2.isCancel(stackOption)) {
|
|
4291
|
+
p2.cancel("Operaci\xF3n cancelada.");
|
|
665
4292
|
process.exit(0);
|
|
666
4293
|
}
|
|
667
4294
|
let stack = null;
|
|
668
4295
|
if (stackOption === "auto") {
|
|
669
|
-
const s2 =
|
|
4296
|
+
const s2 = p2.spinner();
|
|
670
4297
|
s2.start("Analizando proyecto...");
|
|
671
4298
|
await new Promise((r) => setTimeout(r, 800));
|
|
672
4299
|
stack = detectStack(resolvedDir);
|
|
@@ -676,9 +4303,9 @@ async function cli() {
|
|
|
676
4303
|
s2.stop(`${icons.warning} No se detect\xF3 stack \u2014 los placeholders se rellenar\xE1n despu\xE9s`);
|
|
677
4304
|
}
|
|
678
4305
|
} else if (stackOption === "manual") {
|
|
679
|
-
const manualStack = await
|
|
4306
|
+
const manualStack = await p2.group(
|
|
680
4307
|
{
|
|
681
|
-
language: () =>
|
|
4308
|
+
language: () => p2.select({
|
|
682
4309
|
message: "Lenguaje principal",
|
|
683
4310
|
options: [
|
|
684
4311
|
{ value: "TypeScript", label: "TypeScript" },
|
|
@@ -690,14 +4317,14 @@ async function cli() {
|
|
|
690
4317
|
{ value: "Other", label: "Otro" }
|
|
691
4318
|
]
|
|
692
4319
|
}),
|
|
693
|
-
framework: () =>
|
|
4320
|
+
framework: () => p2.text({
|
|
694
4321
|
message: "Framework (opcional)",
|
|
695
4322
|
placeholder: "Next.js 14, Django 5, etc."
|
|
696
4323
|
})
|
|
697
4324
|
},
|
|
698
4325
|
{
|
|
699
4326
|
onCancel: () => {
|
|
700
|
-
|
|
4327
|
+
p2.cancel("Operaci\xF3n cancelada.");
|
|
701
4328
|
process.exit(0);
|
|
702
4329
|
}
|
|
703
4330
|
}
|
|
@@ -707,7 +4334,7 @@ async function cli() {
|
|
|
707
4334
|
framework: manualStack.framework?.trim() || void 0
|
|
708
4335
|
};
|
|
709
4336
|
}
|
|
710
|
-
const language = await
|
|
4337
|
+
const language = await p2.select({
|
|
711
4338
|
message: `${icons.docs} Idioma de la documentaci\xF3n`,
|
|
712
4339
|
options: LANGUAGES.map((lang) => ({
|
|
713
4340
|
value: lang.value,
|
|
@@ -715,24 +4342,24 @@ async function cli() {
|
|
|
715
4342
|
hint: lang.hint
|
|
716
4343
|
}))
|
|
717
4344
|
});
|
|
718
|
-
if (
|
|
719
|
-
|
|
4345
|
+
if (p2.isCancel(language)) {
|
|
4346
|
+
p2.cancel("Operaci\xF3n cancelada.");
|
|
720
4347
|
process.exit(0);
|
|
721
4348
|
}
|
|
722
|
-
const allModules = await
|
|
4349
|
+
const allModules = await p2.confirm({
|
|
723
4350
|
message: `${icons.package} \xBFIncluir todos los m\xF3dulos?`,
|
|
724
4351
|
initialValue: true
|
|
725
4352
|
});
|
|
726
|
-
if (
|
|
727
|
-
|
|
4353
|
+
if (p2.isCancel(allModules)) {
|
|
4354
|
+
p2.cancel("Operaci\xF3n cancelada.");
|
|
728
4355
|
process.exit(0);
|
|
729
4356
|
}
|
|
730
4357
|
let selectedModules;
|
|
731
4358
|
if (allModules) {
|
|
732
4359
|
selectedModules = DOC_MODULES.map((mod) => mod.value);
|
|
733
4360
|
} else {
|
|
734
|
-
const picked = await
|
|
735
|
-
message: `${icons.package} M\xF3dulos a incluir ${
|
|
4361
|
+
const picked = await p2.multiselect({
|
|
4362
|
+
message: `${icons.package} M\xF3dulos a incluir ${pc4.dim("(espacio para seleccionar, enter para confirmar)")}`,
|
|
736
4363
|
options: DOC_MODULES.map((mod) => ({
|
|
737
4364
|
value: mod.value,
|
|
738
4365
|
label: mod.label,
|
|
@@ -740,71 +4367,75 @@ async function cli() {
|
|
|
740
4367
|
})),
|
|
741
4368
|
required: false
|
|
742
4369
|
});
|
|
743
|
-
if (
|
|
744
|
-
|
|
4370
|
+
if (p2.isCancel(picked)) {
|
|
4371
|
+
p2.cancel("Operaci\xF3n cancelada.");
|
|
745
4372
|
process.exit(0);
|
|
746
4373
|
}
|
|
747
4374
|
selectedModules = picked;
|
|
748
4375
|
}
|
|
749
|
-
const initGit2 = await
|
|
4376
|
+
const initGit2 = await p2.confirm({
|
|
750
4377
|
message: `${icons.gear} \xBFInicializar repositorio git?`,
|
|
751
4378
|
initialValue: true
|
|
752
4379
|
});
|
|
753
|
-
if (
|
|
754
|
-
|
|
4380
|
+
if (p2.isCancel(initGit2)) {
|
|
4381
|
+
p2.cancel("Operaci\xF3n cancelada.");
|
|
755
4382
|
process.exit(0);
|
|
756
4383
|
}
|
|
757
|
-
const modulesLabel = selectedModules.length > 0 ? selectedModules.join(", ") :
|
|
758
|
-
|
|
4384
|
+
const modulesLabel = selectedModules.length > 0 ? selectedModules.join(", ") : pc4.dim("ninguno (solo archivos base)");
|
|
4385
|
+
p2.note(
|
|
759
4386
|
[
|
|
760
4387
|
`${brand.label("Proyecto")}: ${projectName}`,
|
|
761
4388
|
`${brand.label("Directorio")}: ${brand.path(resolvedDir)}`,
|
|
762
|
-
`${brand.label("Stack")}: ${stack ? formatStack(stack) :
|
|
4389
|
+
`${brand.label("Stack")}: ${stack ? formatStack(stack) : pc4.dim("no detectado")}`,
|
|
763
4390
|
`${brand.label("Idioma")}: ${language === "es" ? "Espa\xF1ol" : "English"}`,
|
|
764
4391
|
`${brand.label("M\xF3dulos")}: ${modulesLabel}`,
|
|
765
4392
|
`${brand.label("Git")}: ${initGit2 ? "S\xED" : "No"}`
|
|
766
4393
|
].join("\n"),
|
|
767
4394
|
`${icons.chart} Resumen`
|
|
768
4395
|
);
|
|
769
|
-
const confirmed = await
|
|
4396
|
+
const confirmed = await p2.confirm({
|
|
770
4397
|
message: "\xBFGenerar documentaci\xF3n?",
|
|
771
4398
|
initialValue: true
|
|
772
4399
|
});
|
|
773
|
-
if (
|
|
774
|
-
|
|
4400
|
+
if (p2.isCancel(confirmed) || !confirmed) {
|
|
4401
|
+
p2.cancel("Operaci\xF3n cancelada.");
|
|
775
4402
|
process.exit(0);
|
|
776
4403
|
}
|
|
777
|
-
const s =
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
s.message("Generando archivos base (AGENTS.md, CONTEXT.md, ADR...)");
|
|
781
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
782
|
-
if (selectedModules.length > 0) {
|
|
783
|
-
s.message(`A\xF1adiendo m\xF3dulos: ${selectedModules.join(", ")}`);
|
|
4404
|
+
const s = p2.spinner();
|
|
4405
|
+
if (!isDryRun) {
|
|
4406
|
+
s.start("Creando estructura de documentaci\xF3n...");
|
|
784
4407
|
await new Promise((r) => setTimeout(r, 400));
|
|
4408
|
+
s.message("Generando archivos base (AGENTS.md, CONTEXT.md, ADR...)");
|
|
4409
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
4410
|
+
if (selectedModules.length > 0) {
|
|
4411
|
+
s.message(`A\xF1adiendo m\xF3dulos: ${selectedModules.join(", ")}`);
|
|
4412
|
+
await new Promise((r) => setTimeout(r, 400));
|
|
4413
|
+
}
|
|
785
4414
|
}
|
|
786
|
-
const createdFiles = await
|
|
4415
|
+
const createdFiles = await generate23({
|
|
787
4416
|
projectName: projectName.trim(),
|
|
788
4417
|
targetDir: resolvedDir,
|
|
789
4418
|
stack,
|
|
790
4419
|
modules: selectedModules,
|
|
791
4420
|
language,
|
|
792
|
-
initGit: initGit2
|
|
4421
|
+
initGit: initGit2,
|
|
4422
|
+
force: isForce,
|
|
4423
|
+
dryRun: isDryRun
|
|
793
4424
|
});
|
|
794
4425
|
if (initGit2) {
|
|
795
4426
|
s.message("Inicializando repositorio git...");
|
|
796
4427
|
await new Promise((r) => setTimeout(r, 300));
|
|
797
4428
|
}
|
|
798
|
-
|
|
4429
|
+
if (!isDryRun) {
|
|
4430
|
+
s.stop(`${icons.check} ${brand.success(`${createdFiles.length} archivos generados`)}`);
|
|
4431
|
+
}
|
|
799
4432
|
const nextSteps = [
|
|
800
|
-
`${
|
|
801
|
-
`${
|
|
802
|
-
`${
|
|
4433
|
+
`${pc4.bold("1.")} Rellenar ${brand.path("docs/CONTEXT.md")} con los t\xE9rminos del dominio`,
|
|
4434
|
+
`${pc4.bold("2.")} Revisar ${brand.path("AGENTS.md")} y ajustar stack/comandos`,
|
|
4435
|
+
`${pc4.bold("3.")} Ejecutar ${pc4.cyan("npx @damenor/agent-docs --help")} para m\xE1s opciones`
|
|
803
4436
|
];
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
`${icons.sparkle} ${brand.title("\xA1Documentaci\xF3n lista!")} ${pc2.dim("\u2014 github.com/damenordev/doc-projects")}`
|
|
807
|
-
);
|
|
4437
|
+
p2.note(nextSteps.join("\n"), `${icons.rocket} Pr\xF3ximos pasos`);
|
|
4438
|
+
p2.outro(`${icons.sparkle} ${brand.title("\xA1Documentaci\xF3n lista!")} ${pc4.dim("\u2014 github.com/damenordev/doc-projects")}`);
|
|
808
4439
|
}
|
|
809
4440
|
|
|
810
4441
|
// src/index.ts
|