project-mcp-server 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +335 -0
  3. package/dist/config.d.ts +15 -0
  4. package/dist/config.js +38 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +28 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/scanner/actions.d.ts +9 -0
  10. package/dist/scanner/actions.js +77 -0
  11. package/dist/scanner/actions.js.map +1 -0
  12. package/dist/scanner/cache.d.ts +4 -0
  13. package/dist/scanner/cache.js +34 -0
  14. package/dist/scanner/cache.js.map +1 -0
  15. package/dist/scanner/components.d.ts +17 -0
  16. package/dist/scanner/components.js +74 -0
  17. package/dist/scanner/components.js.map +1 -0
  18. package/dist/scanner/prisma.d.ts +17 -0
  19. package/dist/scanner/prisma.js +75 -0
  20. package/dist/scanner/prisma.js.map +1 -0
  21. package/dist/scanner/routes.d.ts +11 -0
  22. package/dist/scanner/routes.js +98 -0
  23. package/dist/scanner/routes.js.map +1 -0
  24. package/dist/setup.d.ts +10 -0
  25. package/dist/setup.js +289 -0
  26. package/dist/setup.js.map +1 -0
  27. package/dist/tools/env/index.d.ts +2 -0
  28. package/dist/tools/env/index.js +152 -0
  29. package/dist/tools/env/index.js.map +1 -0
  30. package/dist/tools/generate/index.d.ts +2 -0
  31. package/dist/tools/generate/index.js +320 -0
  32. package/dist/tools/generate/index.js.map +1 -0
  33. package/dist/tools/project/index.d.ts +2 -0
  34. package/dist/tools/project/index.js +193 -0
  35. package/dist/tools/project/index.js.map +1 -0
  36. package/package.json +35 -0
  37. package/skills/commit.md +109 -0
  38. package/skills/infra.md +218 -0
  39. package/skills/nextauth.md +256 -0
  40. package/skills/nextjs.md +262 -0
  41. package/skills/prisma.md +281 -0
  42. package/skills/project-intelligence.SKILL.md +141 -0
  43. package/skills/security.md +353 -0
  44. package/skills/shadcn.md +299 -0
  45. package/skills/testing.md +188 -0
  46. package/skills/zod.md +253 -0
@@ -0,0 +1,74 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import { join, relative } from "node:path";
3
+ import { existsSync } from "node:fs";
4
+ import { config } from "../config.js";
5
+ import { cached } from "./cache.js";
6
+ async function scanUiComponents() {
7
+ const uiDir = join(config.projectRoot, config.scanner.componentsUiDir);
8
+ if (!existsSync(uiDir))
9
+ return [];
10
+ const entries = await readdir(uiDir, { withFileTypes: true }).catch(() => []);
11
+ const components = [];
12
+ for (const entry of entries) {
13
+ if (!entry.isFile() || (!entry.name.endsWith(".tsx") && !entry.name.endsWith(".ts")))
14
+ continue;
15
+ const filePath = join(uiDir, entry.name);
16
+ const content = await readFile(filePath, "utf-8").catch(() => "");
17
+ if (!content)
18
+ continue;
19
+ // Extraer exports nombrados
20
+ const exports = [...content.matchAll(/export\s+(?:function|const|class)\s+(\w+)/g)]
21
+ .map(m => m[1] ?? "")
22
+ .filter(Boolean);
23
+ const name = entry.name.replace(/\.(tsx?|jsx?)$/, "");
24
+ components.push({
25
+ name: name.charAt(0).toUpperCase() + name.slice(1),
26
+ file: relative(config.projectRoot, filePath),
27
+ exports,
28
+ usesRadix: content.includes("@radix-ui"),
29
+ usesCva: content.includes("cva(") || content.includes("class-variance-authority")
30
+ });
31
+ }
32
+ return components.sort((a, b) => a.name.localeCompare(b.name));
33
+ }
34
+ async function walkForCustom(dir, feature) {
35
+ const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
36
+ const components = [];
37
+ for (const entry of entries) {
38
+ const full = join(dir, entry.name);
39
+ if (entry.isDirectory()) {
40
+ components.push(...await walkForCustom(full, entry.name));
41
+ }
42
+ else if ((entry.name.endsWith(".tsx") || entry.name.endsWith(".jsx")) &&
43
+ !entry.name.endsWith(".test.tsx") &&
44
+ !entry.name.endsWith(".spec.tsx")) {
45
+ const content = await readFile(full, "utf-8").catch(() => "");
46
+ const name = entry.name.replace(/\.(tsx?|jsx?)$/, "");
47
+ components.push({
48
+ name: name.charAt(0).toUpperCase() + name.slice(1),
49
+ file: relative(config.projectRoot, full),
50
+ feature,
51
+ isClient: content.slice(0, 200).includes('"use client"')
52
+ });
53
+ }
54
+ }
55
+ return components;
56
+ }
57
+ export async function scanComponents() {
58
+ return cached("components", async () => {
59
+ const [ui, custom] = await Promise.all([
60
+ scanUiComponents(),
61
+ (async () => {
62
+ const componentsDir = join(config.projectRoot, "src/components");
63
+ if (!existsSync(componentsDir))
64
+ return [];
65
+ const entries = await readdir(componentsDir, { withFileTypes: true });
66
+ const featureDirs = entries.filter(e => e.isDirectory() && e.name !== "ui");
67
+ const results = await Promise.all(featureDirs.map(e => walkForCustom(join(componentsDir, e.name), e.name)));
68
+ return results.flat();
69
+ })()
70
+ ]);
71
+ return { ui, custom };
72
+ });
73
+ }
74
+ //# sourceMappingURL=components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.js","sourceRoot":"","sources":["../../src/scanner/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAiBnC,KAAK,UAAU,gBAAgB;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IACtE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAEjC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;IAC7E,MAAM,UAAU,GAAyB,EAAE,CAAA;IAE3C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAAE,SAAQ;QAE9F,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QACxC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;QACjE,IAAI,CAAC,OAAO;YAAE,SAAQ;QAEtB,4BAA4B;QAC5B,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,4CAA4C,CAAC,CAAC;aAChF,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAA;QAElB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAA;QACrD,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAClD,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC;YAC5C,OAAO;YACP,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;YACxC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC;SAClF,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;AAChE,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,OAAe;IACvD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;IAC3E,MAAM,UAAU,GAAsB,EAAE,CAAA;IAExC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QAClC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QAC3D,CAAC;aAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC5D,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YACjC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC7C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;YAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAA;YACrD,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBAClD,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC;gBACxC,OAAO;gBACP,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;aACzD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAIlC,OAAO,MAAM,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACrC,gBAAgB,EAAE;YAClB,CAAC,KAAK,IAAI,EAAE;gBACV,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAA;gBAChE,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;oBAAE,OAAO,EAAE,CAAA;gBACzC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;gBACrE,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACrC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CACnC,CAAA;gBACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CACzE,CAAA;gBACD,OAAO,OAAO,CAAC,IAAI,EAAE,CAAA;YACvB,CAAC,CAAC,EAAE;SACL,CAAC,CAAA;QAEF,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAA;IACvB,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ export interface PrismaField {
2
+ name: string;
3
+ type: string;
4
+ isOptional: boolean;
5
+ isArray: boolean;
6
+ isRelation: boolean;
7
+ attributes: string[];
8
+ }
9
+ export interface PrismaModel {
10
+ name: string;
11
+ schema: string;
12
+ file: string;
13
+ fields: PrismaField[];
14
+ hasId: boolean;
15
+ hasTimestamps: boolean;
16
+ }
17
+ export declare function scanPrismaSchemas(): Promise<PrismaModel[]>;
@@ -0,0 +1,75 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import { join, relative } from "node:path";
3
+ import { existsSync } from "node:fs";
4
+ import { config } from "../config.js";
5
+ import { cached } from "./cache.js";
6
+ function parseFields(block) {
7
+ const fields = [];
8
+ const lines = block.split("\n");
9
+ for (const line of lines) {
10
+ const trimmed = line.trim();
11
+ if (!trimmed || trimmed.startsWith("//") || trimmed.startsWith("@@"))
12
+ continue;
13
+ // Patrón: fieldName Type?[] @attribute1 @attribute2
14
+ const match = trimmed.match(/^(\w+)\s+(\w+)(\??)(\[\])?(.*)$/);
15
+ if (!match)
16
+ continue;
17
+ const [, name = "", type = "", optional = "", array = "", rest = ""] = match;
18
+ const attributes = (rest.match(/@[\w.()]+/g) ?? []).map(a => a.trim());
19
+ // Detectar si es relación (tipo empieza con mayúscula pero no es primitivo)
20
+ const primitives = new Set(["String", "Int", "Float", "Boolean", "DateTime", "Json",
21
+ "Bytes", "Decimal", "BigInt"]);
22
+ const isRelation = /^[A-Z]/.test(type) && !primitives.has(type);
23
+ fields.push({
24
+ name,
25
+ type,
26
+ isOptional: optional === "?",
27
+ isArray: array === "[]",
28
+ isRelation,
29
+ attributes
30
+ });
31
+ }
32
+ return fields;
33
+ }
34
+ function extractSchema(content, modelName) {
35
+ // Buscar @@schema("auth") dentro del bloque del modelo
36
+ const modelBlock = content.match(new RegExp(`model\\s+${modelName}\\s*\\{([^}]+)\\}`, "s"))?.[1] ?? "";
37
+ const schemaMatch = modelBlock.match(/@@schema\("(\w+)"\)/);
38
+ return schemaMatch?.[1] ?? "base";
39
+ }
40
+ async function parseFile(filePath, projectRoot) {
41
+ const content = await readFile(filePath, "utf-8").catch(() => "");
42
+ if (!content)
43
+ return [];
44
+ const models = [];
45
+ const modelRegex = /model\s+(\w+)\s*\{([^}]+)\}/gs;
46
+ let match;
47
+ while ((match = modelRegex.exec(content)) !== null) {
48
+ const name = match[1] ?? "";
49
+ const block = match[2] ?? "";
50
+ const fields = parseFields(block);
51
+ models.push({
52
+ name,
53
+ schema: extractSchema(content, name),
54
+ file: relative(projectRoot, filePath),
55
+ fields,
56
+ hasId: fields.some(f => f.attributes.some(a => a.includes("@id"))),
57
+ hasTimestamps: fields.some(f => f.name === "createdAt" || f.name === "updatedAt")
58
+ });
59
+ }
60
+ return models;
61
+ }
62
+ export async function scanPrismaSchemas() {
63
+ return cached("prisma", async () => {
64
+ const prismaDir = join(config.projectRoot, config.scanner.prismaDir);
65
+ if (!existsSync(prismaDir))
66
+ return [];
67
+ const entries = await readdir(prismaDir, { withFileTypes: true }).catch(() => []);
68
+ const prismaFiles = entries
69
+ .filter(e => e.isFile() && e.name.endsWith(".prisma"))
70
+ .map(e => join(prismaDir, e.name));
71
+ const results = await Promise.all(prismaFiles.map(f => parseFile(f, config.projectRoot)));
72
+ return results.flat().sort((a, b) => a.name.localeCompare(b.name));
73
+ });
74
+ }
75
+ //# sourceMappingURL=prisma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/scanner/prisma.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface AppRoute {
2
+ path: string;
3
+ fsPath: string;
4
+ type: "page" | "layout" | "route-handler";
5
+ rendering: "rsc" | "client" | "unknown";
6
+ dynamicParams: string[];
7
+ hasLoading: boolean;
8
+ hasError: boolean;
9
+ methods?: string[];
10
+ }
11
+ export declare function scanRoutes(): Promise<AppRoute[]>;
@@ -0,0 +1,98 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import { join, relative, dirname } from "node:path";
3
+ import { existsSync } from "node:fs";
4
+ import { config } from "../config.js";
5
+ import { cached } from "./cache.js";
6
+ async function walkDir(dir) {
7
+ const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
8
+ const files = [];
9
+ for (const entry of entries) {
10
+ const full = join(dir, entry.name);
11
+ if (entry.isDirectory()) {
12
+ // Ignorar grupos de rutas (parenthesis) y carpetas privadas (_)
13
+ files.push(...await walkDir(full));
14
+ }
15
+ else if (entry.isFile()) {
16
+ files.push(full);
17
+ }
18
+ }
19
+ return files;
20
+ }
21
+ function extractDynamicParams(path) {
22
+ return [...path.matchAll(/\[([^\]]+)\]/g)].map(m => m[1] ?? "").filter(Boolean);
23
+ }
24
+ function filePathToRoute(filePath, appDir) {
25
+ const rel = relative(appDir, dirname(filePath));
26
+ return "/" + rel
27
+ .replace(/\\/g, "/")
28
+ .replace(/\([\w-]+\)\//g, "") // eliminar grupos (auth)/ etc.
29
+ .replace(/\/$/, "")
30
+ || "/";
31
+ }
32
+ async function detectRendering(filePath) {
33
+ try {
34
+ const content = await readFile(filePath, "utf-8");
35
+ const firstLines = content.slice(0, 500);
36
+ if (firstLines.includes('"use client"') || firstLines.includes("'use client'"))
37
+ return "client";
38
+ if (firstLines.includes("export default async function") || firstLines.includes("async function"))
39
+ return "rsc";
40
+ return "unknown";
41
+ }
42
+ catch {
43
+ return "unknown";
44
+ }
45
+ }
46
+ async function extractHandlerMethods(filePath) {
47
+ try {
48
+ const content = await readFile(filePath, "utf-8");
49
+ const methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
50
+ return methods.filter(m => {
51
+ return content.includes(`export async function ${m}`) ||
52
+ content.includes(`export function ${m}`);
53
+ });
54
+ }
55
+ catch {
56
+ return [];
57
+ }
58
+ }
59
+ export async function scanRoutes() {
60
+ return cached("routes", async () => {
61
+ const appDir = join(config.projectRoot, config.scanner.appDir);
62
+ if (!existsSync(appDir))
63
+ return [];
64
+ const files = await walkDir(appDir);
65
+ const routes = [];
66
+ for (const file of files) {
67
+ const name = file.split("/").pop() ?? "";
68
+ if (name === "page.tsx" || name === "page.ts" || name === "page.jsx") {
69
+ const routePath = filePathToRoute(file, appDir);
70
+ const dir = dirname(file);
71
+ routes.push({
72
+ path: routePath,
73
+ fsPath: relative(config.projectRoot, file),
74
+ type: "page",
75
+ rendering: await detectRendering(file),
76
+ dynamicParams: extractDynamicParams(routePath),
77
+ hasLoading: existsSync(join(dir, "loading.tsx")) || existsSync(join(dir, "loading.ts")),
78
+ hasError: existsSync(join(dir, "error.tsx")) || existsSync(join(dir, "error.ts"))
79
+ });
80
+ }
81
+ if (name === "route.ts" || name === "route.tsx") {
82
+ const routePath = filePathToRoute(file, appDir);
83
+ routes.push({
84
+ path: routePath,
85
+ fsPath: relative(config.projectRoot, file),
86
+ type: "route-handler",
87
+ rendering: "rsc",
88
+ dynamicParams: extractDynamicParams(routePath),
89
+ hasLoading: false,
90
+ hasError: false,
91
+ methods: await extractHandlerMethods(file)
92
+ });
93
+ }
94
+ }
95
+ return routes.sort((a, b) => a.path.localeCompare(b.path));
96
+ });
97
+ }
98
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/scanner/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Setup interactivo para project-mcp-server.
4
+ * Detecta agentes instalados, configura el MCP y copia skills.
5
+ *
6
+ * Uso:
7
+ * npx project-mcp-server setup
8
+ * npx github:fernandosecchi/project-mcp-server setup
9
+ */
10
+ export {};
package/dist/setup.js ADDED
@@ -0,0 +1,289 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Setup interactivo para project-mcp-server.
4
+ * Detecta agentes instalados, configura el MCP y copia skills.
5
+ *
6
+ * Uso:
7
+ * npx project-mcp-server setup
8
+ * npx github:fernandosecchi/project-mcp-server setup
9
+ */
10
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, readdirSync } from "node:fs";
11
+ import { join, resolve, dirname } from "node:path";
12
+ import { createInterface } from "node:readline";
13
+ import { homedir } from "node:os";
14
+ import { fileURLToPath } from "node:url";
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const SKILLS_DIR = join(__dirname, "..", "skills");
17
+ const SERVER_ENTRY = join(__dirname, "index.js");
18
+ const HOME = homedir();
19
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
20
+ function ask(question) {
21
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
22
+ return new Promise(resolve => {
23
+ rl.question(question, answer => {
24
+ rl.close();
25
+ resolve(answer.trim());
26
+ });
27
+ });
28
+ }
29
+ async function confirm(question, defaultYes = true) {
30
+ const hint = defaultYes ? "[Y/n]" : "[y/N]";
31
+ const answer = await ask(`${question} ${hint} `);
32
+ if (answer === "")
33
+ return defaultYes;
34
+ return answer.toLowerCase().startsWith("y");
35
+ }
36
+ function ensureDir(dir) {
37
+ if (!existsSync(dir))
38
+ mkdirSync(dir, { recursive: true });
39
+ }
40
+ function readJson(path) {
41
+ try {
42
+ return JSON.parse(readFileSync(path, "utf-8"));
43
+ }
44
+ catch {
45
+ return {};
46
+ }
47
+ }
48
+ function writeJson(path, data) {
49
+ ensureDir(dirname(path));
50
+ writeFileSync(path, JSON.stringify(data, null, 2) + "\n", "utf-8");
51
+ }
52
+ function log(msg) {
53
+ console.log(` ${msg}`);
54
+ }
55
+ function success(msg) {
56
+ console.log(` ✓ ${msg}`);
57
+ }
58
+ function warn(msg) {
59
+ console.log(` ⚠ ${msg}`);
60
+ }
61
+ function detectAgents() {
62
+ const agents = [
63
+ {
64
+ id: "claude-code",
65
+ name: "Claude Code",
66
+ configPath: join(HOME, ".claude", "config.json"),
67
+ skillsDir: join(HOME, ".claude", "skills"),
68
+ detected: existsSync(join(HOME, ".claude")),
69
+ writeConfig(projectRoot, serverPath) {
70
+ const configPath = join(HOME, ".claude", "config.json");
71
+ const config = readJson(configPath);
72
+ const servers = (config.mcpServers ?? {});
73
+ servers.project = {
74
+ command: "node",
75
+ args: [serverPath],
76
+ env: { MCP_PROJECT_ROOT: projectRoot }
77
+ };
78
+ config.mcpServers = servers;
79
+ writeJson(configPath, config);
80
+ }
81
+ },
82
+ {
83
+ id: "open-code",
84
+ name: "Open Code",
85
+ configPath: join(HOME, ".config", "opencode", "config.json"),
86
+ detected: existsSync(join(HOME, ".config", "opencode")),
87
+ writeConfig(projectRoot, serverPath) {
88
+ const configPath = join(HOME, ".config", "opencode", "config.json");
89
+ const config = readJson(configPath);
90
+ const mcp = (config.mcp ?? {});
91
+ mcp.project = {
92
+ type: "local",
93
+ command: "node",
94
+ args: [serverPath],
95
+ env: { MCP_PROJECT_ROOT: projectRoot }
96
+ };
97
+ config.mcp = mcp;
98
+ writeJson(configPath, config);
99
+ }
100
+ },
101
+ {
102
+ id: "gemini-cli",
103
+ name: "Gemini CLI",
104
+ configPath: join(HOME, ".gemini", "config.json"),
105
+ detected: existsSync(join(HOME, ".gemini")),
106
+ writeConfig(projectRoot, serverPath) {
107
+ const configPath = join(HOME, ".gemini", "config.json");
108
+ const config = readJson(configPath);
109
+ const servers = (config.mcpServers ?? {});
110
+ servers.project = {
111
+ command: "node",
112
+ args: [serverPath],
113
+ env: { MCP_PROJECT_ROOT: projectRoot }
114
+ };
115
+ config.mcpServers = servers;
116
+ writeJson(configPath, config);
117
+ }
118
+ },
119
+ {
120
+ id: "codex-cli",
121
+ name: "Codex CLI",
122
+ configPath: join(HOME, ".codex", "config.json"),
123
+ detected: existsSync(join(HOME, ".codex")),
124
+ writeConfig(projectRoot, serverPath) {
125
+ const configPath = join(HOME, ".codex", "config.json");
126
+ const config = readJson(configPath);
127
+ const servers = (config.mcpServers ?? {});
128
+ servers.project = {
129
+ command: "node",
130
+ args: [serverPath],
131
+ env: { MCP_PROJECT_ROOT: projectRoot }
132
+ };
133
+ config.mcpServers = servers;
134
+ writeJson(configPath, config);
135
+ }
136
+ },
137
+ {
138
+ id: "cursor",
139
+ name: "Cursor",
140
+ configPath: join(HOME, ".cursor", "mcp.json"),
141
+ detected: existsSync(join(HOME, ".cursor")),
142
+ writeConfig(projectRoot, serverPath) {
143
+ const configPath = join(HOME, ".cursor", "mcp.json");
144
+ const config = readJson(configPath);
145
+ const servers = (config.mcpServers ?? {});
146
+ servers.project = {
147
+ command: "node",
148
+ args: [serverPath],
149
+ env: { MCP_PROJECT_ROOT: projectRoot }
150
+ };
151
+ config.mcpServers = servers;
152
+ writeJson(configPath, config);
153
+ }
154
+ }
155
+ ];
156
+ // Add copySkills for agents that support it
157
+ for (const agent of agents) {
158
+ if (agent.skillsDir) {
159
+ agent.copySkills = () => copySkillsTo(agent.skillsDir);
160
+ }
161
+ }
162
+ return agents;
163
+ }
164
+ function copySkillsTo(targetDir) {
165
+ ensureDir(targetDir);
166
+ const files = readdirSync(SKILLS_DIR).filter(f => f.endsWith(".md"));
167
+ let count = 0;
168
+ for (const file of files) {
169
+ const src = join(SKILLS_DIR, file);
170
+ const dest = join(targetDir, file);
171
+ copyFileSync(src, dest);
172
+ count++;
173
+ }
174
+ return count;
175
+ }
176
+ // ─── VS Code (per-project) ──────────────────────────────────────────────────
177
+ function setupVsCode(projectRoot, serverPath) {
178
+ const vscodeDir = join(projectRoot, ".vscode");
179
+ const mcpPath = join(vscodeDir, "mcp.json");
180
+ ensureDir(vscodeDir);
181
+ const config = readJson(mcpPath);
182
+ const servers = (config.servers ?? {});
183
+ servers.project = {
184
+ type: "stdio",
185
+ command: "node",
186
+ args: [serverPath],
187
+ env: { MCP_PROJECT_ROOT: "${workspaceFolder}" }
188
+ };
189
+ config.servers = servers;
190
+ writeJson(mcpPath, config);
191
+ }
192
+ // ─── Main ────────────────────────────────────────────────────────────────────
193
+ async function main() {
194
+ console.log();
195
+ console.log(" project-mcp-server — setup");
196
+ console.log(" ──────────────────────────");
197
+ console.log();
198
+ // 1. Detectar proyecto
199
+ let projectRoot = process.cwd();
200
+ const markers = ["next.config.ts", "next.config.js", "next.config.mjs", "package.json"];
201
+ const isProject = markers.some(m => existsSync(join(projectRoot, m)));
202
+ if (isProject) {
203
+ const useThis = await confirm(`Proyecto detectado: ${projectRoot}\n ¿Usar este directorio?`);
204
+ if (!useThis) {
205
+ const custom = await ask(" Ruta al proyecto: ");
206
+ projectRoot = resolve(custom);
207
+ }
208
+ }
209
+ else {
210
+ const custom = await ask(" Ruta al proyecto Next.js: ");
211
+ projectRoot = resolve(custom);
212
+ }
213
+ if (!existsSync(projectRoot)) {
214
+ console.error(` ✗ No existe: ${projectRoot}`);
215
+ process.exit(1);
216
+ }
217
+ projectRoot = resolve(projectRoot);
218
+ log(`Proyecto: ${projectRoot}`);
219
+ console.log();
220
+ // 2. Detectar agentes
221
+ const agents = detectAgents();
222
+ const detected = agents.filter(a => a.detected);
223
+ if (detected.length === 0) {
224
+ warn("No se detectaron agentes de IA instalados.");
225
+ log("Agentes soportados: Claude Code, Open Code, Gemini CLI, Codex CLI, Cursor");
226
+ log("Instalá alguno y volvé a correr el setup.");
227
+ process.exit(0);
228
+ }
229
+ log("Agentes detectados:");
230
+ for (const agent of detected) {
231
+ log(` → ${agent.name}`);
232
+ }
233
+ console.log();
234
+ // 3. Configurar MCP en cada agente
235
+ const configureAll = await confirm("¿Configurar el MCP server en todos los agentes detectados?");
236
+ const toConfig = configureAll ? detected : [];
237
+ if (!configureAll) {
238
+ for (const agent of detected) {
239
+ const yes = await confirm(` ¿Configurar ${agent.name}?`, false);
240
+ if (yes)
241
+ toConfig.push(agent);
242
+ }
243
+ }
244
+ for (const agent of toConfig) {
245
+ agent.writeConfig(projectRoot, SERVER_ENTRY);
246
+ success(`${agent.name} configurado → ${agent.configPath}`);
247
+ }
248
+ // 4. VS Code (per-project)
249
+ const hasVsCode = existsSync(join(projectRoot, ".vscode")) ||
250
+ existsSync("/Applications/Visual Studio Code.app") ||
251
+ existsSync(join(HOME, ".vscode"));
252
+ if (hasVsCode) {
253
+ const setupVsc = await confirm("¿Configurar VS Code (GitHub Copilot) para este proyecto?");
254
+ if (setupVsc) {
255
+ setupVsCode(projectRoot, SERVER_ENTRY);
256
+ success(`VS Code configurado → ${join(projectRoot, ".vscode", "mcp.json")}`);
257
+ }
258
+ }
259
+ console.log();
260
+ // 5. Copiar skills
261
+ const agentsWithSkills = toConfig.filter(a => a.copySkills);
262
+ if (agentsWithSkills.length > 0) {
263
+ const copyAll = await confirm("¿Copiar skills (Next.js, Prisma, security, etc.) a los agentes configurados?");
264
+ if (copyAll) {
265
+ for (const agent of agentsWithSkills) {
266
+ const count = agent.copySkills();
267
+ success(`${count} skills copiadas a ${agent.skillsDir}`);
268
+ }
269
+ }
270
+ }
271
+ console.log();
272
+ // 6. Resumen
273
+ console.log(" ──────────────────────────");
274
+ console.log(" Setup completado.");
275
+ console.log();
276
+ log("Para verificar, abrí tu agente en el proyecto y ejecutá:");
277
+ log(" Claude Code → /mcp → debe aparecer 'project' con 10 tools");
278
+ log(" Open Code → tab → debe aparecer el MCP server");
279
+ console.log();
280
+ log("Para usar con Gentleman AI (Engram + SDD):");
281
+ log(" brew install gentleman-programming/tap/gentle-ai");
282
+ log(" Las skills ya están copiadas en formato compatible.");
283
+ console.log();
284
+ }
285
+ main().catch((err) => {
286
+ console.error("Error:", err);
287
+ process.exit(1);
288
+ });
289
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerEnvTools(server: McpServer): void;