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.
- package/LICENSE +21 -0
- package/README.md +335 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/scanner/actions.d.ts +9 -0
- package/dist/scanner/actions.js +77 -0
- package/dist/scanner/actions.js.map +1 -0
- package/dist/scanner/cache.d.ts +4 -0
- package/dist/scanner/cache.js +34 -0
- package/dist/scanner/cache.js.map +1 -0
- package/dist/scanner/components.d.ts +17 -0
- package/dist/scanner/components.js +74 -0
- package/dist/scanner/components.js.map +1 -0
- package/dist/scanner/prisma.d.ts +17 -0
- package/dist/scanner/prisma.js +75 -0
- package/dist/scanner/prisma.js.map +1 -0
- package/dist/scanner/routes.d.ts +11 -0
- package/dist/scanner/routes.js +98 -0
- package/dist/scanner/routes.js.map +1 -0
- package/dist/setup.d.ts +10 -0
- package/dist/setup.js +289 -0
- package/dist/setup.js.map +1 -0
- package/dist/tools/env/index.d.ts +2 -0
- package/dist/tools/env/index.js +152 -0
- package/dist/tools/env/index.js.map +1 -0
- package/dist/tools/generate/index.d.ts +2 -0
- package/dist/tools/generate/index.js +320 -0
- package/dist/tools/generate/index.js.map +1 -0
- package/dist/tools/project/index.d.ts +2 -0
- package/dist/tools/project/index.js +193 -0
- package/dist/tools/project/index.js.map +1 -0
- package/package.json +35 -0
- package/skills/commit.md +109 -0
- package/skills/infra.md +218 -0
- package/skills/nextauth.md +256 -0
- package/skills/nextjs.md +262 -0
- package/skills/prisma.md +281 -0
- package/skills/project-intelligence.SKILL.md +141 -0
- package/skills/security.md +353 -0
- package/skills/shadcn.md +299 -0
- package/skills/testing.md +188 -0
- 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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"}
|
package/dist/setup.d.ts
ADDED
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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"}
|