leadcode 1.0.0 → 1.2.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/README.md +52 -47
- package/dist/context7/fetch-all.d.ts +13 -0
- package/dist/context7/fetch-all.d.ts.map +1 -0
- package/dist/context7/fetch-all.js +104 -0
- package/dist/context7/fetch-all.js.map +1 -0
- package/dist/context7/index.d.ts +2 -0
- package/dist/context7/index.d.ts.map +1 -1
- package/dist/context7/index.js +1 -0
- package/dist/context7/index.js.map +1 -1
- package/dist/data/tech-queries.d.ts +11 -0
- package/dist/data/tech-queries.d.ts.map +1 -0
- package/dist/data/tech-queries.js +229 -0
- package/dist/data/tech-queries.js.map +1 -0
- package/dist/index.js +155 -22
- package/dist/index.js.map +1 -1
- package/dist/resources/tech-queries.d.ts +3 -0
- package/dist/resources/tech-queries.d.ts.map +1 -0
- package/dist/resources/tech-queries.js +16 -0
- package/dist/resources/tech-queries.js.map +1 -0
- package/dist/templates/claude-md.d.ts +1 -1
- package/dist/templates/claude-md.d.ts.map +1 -1
- package/dist/tools/analyze-repo.js +1 -1
- package/dist/tools/analyze-repo.js.map +1 -1
- package/dist/tools/fetch-docs.d.ts +0 -10
- package/dist/tools/fetch-docs.d.ts.map +1 -1
- package/dist/tools/fetch-docs.js +2 -104
- package/dist/tools/fetch-docs.js.map +1 -1
- package/dist/tools/generate-claude-md.d.ts.map +1 -1
- package/dist/tools/generate-claude-md.js +14 -3
- package/dist/tools/generate-claude-md.js.map +1 -1
- package/dist/tools/update-claude-md.d.ts.map +1 -1
- package/dist/tools/update-claude-md.js +3 -57
- package/dist/tools/update-claude-md.js.map +1 -1
- package/dist/tools/validate-claude-md.js +1 -1
- package/dist/tools/validate-claude-md.js.map +1 -1
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,44 +2,177 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
import * as z from "zod";
|
|
4
4
|
import { registerAnalyzeRepo } from "./tools/analyze-repo.js";
|
|
5
|
-
import { registerFetchDocs } from "./tools/fetch-docs.js";
|
|
6
5
|
import { registerGenerateClaudeMd } from "./tools/generate-claude-md.js";
|
|
7
6
|
import { registerValidateClaudeMd } from "./tools/validate-claude-md.js";
|
|
8
|
-
import {
|
|
7
|
+
import { registerTechQueriesResource } from "./resources/tech-queries.js";
|
|
9
8
|
const server = new McpServer({
|
|
10
9
|
name: "leadcode",
|
|
11
|
-
version: "1.
|
|
10
|
+
version: "1.1.0",
|
|
12
11
|
});
|
|
13
12
|
// Register tools
|
|
14
13
|
registerAnalyzeRepo(server);
|
|
15
|
-
registerFetchDocs(server);
|
|
16
14
|
registerGenerateClaudeMd(server);
|
|
17
15
|
registerValidateClaudeMd(server);
|
|
18
|
-
|
|
16
|
+
// Register resources
|
|
17
|
+
registerTechQueriesResource(server);
|
|
19
18
|
// Register prompts
|
|
20
|
-
server.prompt("setup-project", "
|
|
21
|
-
projectPath: z.string().describe("Absolute path to the project root"),
|
|
19
|
+
server.prompt("setup-project", "Generate a CLAUDE.md for a project. Use when the user wants to setup, init, configure, or generate rules/CLAUDE.md for any project.", {
|
|
20
|
+
projectPath: z.string().describe("Absolute path to the project root. Use the current working directory if not specified."),
|
|
22
21
|
language: z.string().optional().describe("Output language: 'fr' for French, 'en' for English (default: en)"),
|
|
23
22
|
}, ({ projectPath, language }) => {
|
|
24
23
|
const isFr = language === "fr";
|
|
25
24
|
const steps = isFr
|
|
26
25
|
? [
|
|
27
|
-
`
|
|
26
|
+
`Tu configures LeadCode pour le projet à ${projectPath}. Suis ces étapes dans l'ordre :`,
|
|
28
27
|
"",
|
|
29
|
-
|
|
30
|
-
"2. Lance fetch-docs avec l'analyse pour récupérer la documentation à jour de chaque technologie détectée via Context7.",
|
|
31
|
-
"3. Présente un résumé clair : stack détecté, documentation récupérée, techs sans documentation.",
|
|
32
|
-
"4. Lance generate-claude-md avec l'analyse et la documentation pour créer le CLAUDE.md.",
|
|
28
|
+
"## Étape 1 : Analyser le projet",
|
|
33
29
|
"",
|
|
34
|
-
|
|
30
|
+
`Appelle l'outil analyze-repo avec projectPath="${projectPath}".`,
|
|
31
|
+
"Présente un résumé clair du stack détecté (framework, ORM, auth, CSS, testing, etc.).",
|
|
32
|
+
"",
|
|
33
|
+
"## Étape 2 : Lire le mapping tech-queries",
|
|
34
|
+
"",
|
|
35
|
+
'Lis la ressource LeadCode "leadcode://tech-queries".',
|
|
36
|
+
"Elle contient pour chaque technologie détectée :",
|
|
37
|
+
"- libraryName : le nom de la librairie sur Context7",
|
|
38
|
+
"- queries : les questions à poser",
|
|
39
|
+
"- crossQueries : les questions pour les combinaisons de techs",
|
|
40
|
+
"",
|
|
41
|
+
"## Étape 3 : Récupérer et synthétiser la documentation",
|
|
42
|
+
"",
|
|
43
|
+
"Pour chaque technologie détectée qui a un mapping dans tech-queries :",
|
|
44
|
+
"",
|
|
45
|
+
"a) Appelle l'outil Context7 resolve-library-id avec le libraryName et la query",
|
|
46
|
+
"b) Appelle l'outil Context7 query-docs avec l'ID résolu et les queries",
|
|
47
|
+
"c) SYNTHÉTISE les docs brutes en 3-5 règles concises et actionnables :",
|
|
48
|
+
" - Conventions (organisation des fichiers, nommage, quand utiliser quoi)",
|
|
49
|
+
" - Patterns importants (singleton, data access layer, etc.)",
|
|
50
|
+
" - Pièges à éviter (restrictions d'import, limites runtime)",
|
|
51
|
+
" - PAS de blocs de code complets — juste des exemples inline courts si nécessaire",
|
|
52
|
+
"",
|
|
53
|
+
"Pour les combinaisons cross-tech (ex: Next.js + Prisma) :",
|
|
54
|
+
"d) Si les deux techs sont détectées et qu'il y a une crossQuery, appelle Context7",
|
|
55
|
+
"e) Synthétise en 3-5 règles spécifiques à cette combinaison",
|
|
56
|
+
"",
|
|
57
|
+
"## Étape 4 : Construire le JSON docs",
|
|
58
|
+
"",
|
|
59
|
+
"Construis un objet JSON avec cette structure :",
|
|
60
|
+
'{ "techDocs": { "next": "- règle 1\\n- règle 2...", ... }, "crossDocs": { "next+prisma": "- règle 1...", ... } }',
|
|
61
|
+
"",
|
|
62
|
+
"## Étape 5 : Générer le CLAUDE.md",
|
|
63
|
+
"",
|
|
64
|
+
"Appelle generate-claude-md avec :",
|
|
65
|
+
"- analysis : le JSON de l'analyse (étape 1)",
|
|
66
|
+
"- docs : le JSON des docs synthétisées (étape 4)",
|
|
67
|
+
"",
|
|
68
|
+
"## Si Context7 n'est pas disponible",
|
|
69
|
+
"",
|
|
70
|
+
"Si les outils Context7 (resolve-library-id) ne sont pas disponibles,",
|
|
71
|
+
"passe directement à l'étape 5 sans docs. Informe l'utilisateur que la documentation",
|
|
72
|
+
"n'a pas pu être récupérée et que le CLAUDE.md ne contiendra que l'analyse du projet.",
|
|
73
|
+
"",
|
|
74
|
+
"Réponds en français.",
|
|
35
75
|
]
|
|
36
76
|
: [
|
|
37
|
-
`
|
|
77
|
+
`You are setting up LeadCode for the project at ${projectPath}. Follow these steps in order:`,
|
|
78
|
+
"",
|
|
79
|
+
"## Step 1: Analyze the project",
|
|
80
|
+
"",
|
|
81
|
+
`Call the analyze-repo tool with projectPath="${projectPath}".`,
|
|
82
|
+
"Present a clear summary of the detected stack (framework, ORM, auth, CSS, testing, etc.).",
|
|
83
|
+
"",
|
|
84
|
+
"## Step 2: Read the tech-queries mapping",
|
|
85
|
+
"",
|
|
86
|
+
'Read the LeadCode resource "leadcode://tech-queries".',
|
|
87
|
+
"It contains for each detected technology:",
|
|
88
|
+
"- libraryName: the Context7 library identifier",
|
|
89
|
+
"- queries: questions to ask Context7",
|
|
90
|
+
"- crossQueries: questions for technology combinations",
|
|
91
|
+
"",
|
|
92
|
+
"## Step 3: Fetch and synthesize documentation",
|
|
93
|
+
"",
|
|
94
|
+
"For each detected technology that has a mapping in tech-queries:",
|
|
95
|
+
"",
|
|
96
|
+
"a) Call Context7 resolve-library-id with the libraryName and the query",
|
|
97
|
+
"b) Call Context7 query-docs with the resolved libraryId and the queries",
|
|
98
|
+
"c) SYNTHESIZE the raw docs into 3-5 concise, actionable rules:",
|
|
99
|
+
" - Conventions (file organization, naming, when to use what)",
|
|
100
|
+
" - Important patterns (singleton, data access layer, etc.)",
|
|
101
|
+
" - Gotchas to avoid (import restrictions, runtime boundaries)",
|
|
102
|
+
" - NO full code blocks — only short inline examples if needed",
|
|
103
|
+
"",
|
|
104
|
+
"For cross-technology combinations (e.g. Next.js + Prisma):",
|
|
105
|
+
"d) If both techs are detected and there is a crossQuery, call Context7",
|
|
106
|
+
"e) Synthesize into 3-5 rules specific to that combination",
|
|
107
|
+
"",
|
|
108
|
+
"## Step 4: Build the docs JSON",
|
|
109
|
+
"",
|
|
110
|
+
"Build a JSON object with this structure:",
|
|
111
|
+
'{ "techDocs": { "next": "- rule 1\\n- rule 2...", ... }, "crossDocs": { "next+prisma": "- rule 1...", ... } }',
|
|
112
|
+
"",
|
|
113
|
+
"## Step 5: Generate CLAUDE.md",
|
|
114
|
+
"",
|
|
115
|
+
"Call generate-claude-md with:",
|
|
116
|
+
"- analysis: the JSON from step 1",
|
|
117
|
+
"- docs: the JSON of synthesized docs from step 4",
|
|
118
|
+
"",
|
|
119
|
+
"## If Context7 is not available",
|
|
120
|
+
"",
|
|
121
|
+
"If Context7 tools (resolve-library-id) are not available,",
|
|
122
|
+
"skip to step 5 without docs. Inform the user that documentation",
|
|
123
|
+
"could not be fetched and the CLAUDE.md will only contain project analysis.",
|
|
124
|
+
"",
|
|
125
|
+
"Be thorough and explain the results clearly.",
|
|
126
|
+
];
|
|
127
|
+
return {
|
|
128
|
+
messages: [
|
|
129
|
+
{
|
|
130
|
+
role: "user",
|
|
131
|
+
content: {
|
|
132
|
+
type: "text",
|
|
133
|
+
text: steps.join("\n"),
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
server.prompt("update-project", "Update or refresh an existing CLAUDE.md. Re-analyzes the project, fetches fresh documentation, and regenerates while preserving user decisions.", {
|
|
140
|
+
projectPath: z.string().describe("Absolute path to the project root. Use the current working directory if not specified."),
|
|
141
|
+
language: z.string().optional().describe("Output language: 'fr' for French, 'en' for English (default: en)"),
|
|
142
|
+
}, ({ projectPath, language }) => {
|
|
143
|
+
const isFr = language === "fr";
|
|
144
|
+
const steps = isFr
|
|
145
|
+
? [
|
|
146
|
+
`Tu mets à jour le CLAUDE.md du projet à ${projectPath}.`,
|
|
147
|
+
"",
|
|
148
|
+
"## Étape préalable : Extraire les décisions existantes",
|
|
149
|
+
"",
|
|
150
|
+
`Lis le fichier ${projectPath}/CLAUDE.md s'il existe.`,
|
|
151
|
+
'Cherche la section "## Project Decisions".',
|
|
152
|
+
'Extrais toutes les entrées au format "- **Sujet**: Choix".',
|
|
153
|
+
"Garde-les pour l'étape finale.",
|
|
154
|
+
"",
|
|
155
|
+
"## Ensuite : même flow que setup-project",
|
|
156
|
+
"",
|
|
157
|
+
"Suis les mêmes étapes que setup-project (analyze → tech-queries → Context7 → synthèse → generate),",
|
|
158
|
+
"mais passe les décisions extraites en paramètre choices à generate-claude-md.",
|
|
159
|
+
"",
|
|
160
|
+
"Réponds en français.",
|
|
161
|
+
]
|
|
162
|
+
: [
|
|
163
|
+
`You are updating the CLAUDE.md for the project at ${projectPath}.`,
|
|
164
|
+
"",
|
|
165
|
+
"## Preliminary step: Extract existing decisions",
|
|
166
|
+
"",
|
|
167
|
+
`Read the file ${projectPath}/CLAUDE.md if it exists.`,
|
|
168
|
+
'Look for the "## Project Decisions" section.',
|
|
169
|
+
'Extract all entries in the format "- **Topic**: Choice".',
|
|
170
|
+
"Keep them for the final step.",
|
|
171
|
+
"",
|
|
172
|
+
"## Then: same flow as setup-project",
|
|
38
173
|
"",
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
"3. Present a summary: detected stack, fetched documentation, any techs without docs.",
|
|
42
|
-
"4. Call generate-claude-md with the analysis and docs to create the CLAUDE.md file.",
|
|
174
|
+
"Follow the same steps as setup-project (analyze → tech-queries → Context7 → synthesize → generate),",
|
|
175
|
+
"but pass the extracted decisions as the choices parameter to generate-claude-md.",
|
|
43
176
|
"",
|
|
44
177
|
"Be thorough and explain the results clearly.",
|
|
45
178
|
];
|
|
@@ -55,8 +188,8 @@ server.prompt("setup-project", "Full LeadCode workflow: analyze repo → fetch d
|
|
|
55
188
|
],
|
|
56
189
|
};
|
|
57
190
|
});
|
|
58
|
-
server.prompt("validate-project", "Check if
|
|
59
|
-
projectPath: z.string().describe("Absolute path to the project root"),
|
|
191
|
+
server.prompt("validate-project", "Check if a CLAUDE.md is still up to date. Use when the user wants to validate, check, verify, or audit their CLAUDE.md.", {
|
|
192
|
+
projectPath: z.string().describe("Absolute path to the project root. Use the current working directory if not specified."),
|
|
60
193
|
language: z.string().optional().describe("Output language: 'fr' for French, 'en' for English (default: en)"),
|
|
61
194
|
}, ({ projectPath, language }) => {
|
|
62
195
|
const isFr = language === "fr";
|
|
@@ -66,7 +199,7 @@ server.prompt("validate-project", "Check if an existing CLAUDE.md is still in sy
|
|
|
66
199
|
"",
|
|
67
200
|
`1. Lance validate-claude-md avec projectPath="${projectPath}".`,
|
|
68
201
|
"2. Présente les décalages trouvés avec des explications claires.",
|
|
69
|
-
"3. Si des décalages existent, suggère
|
|
202
|
+
"3. Si des décalages existent, suggère de lancer update-project pour régénérer.",
|
|
70
203
|
"",
|
|
71
204
|
"Réponds en français.",
|
|
72
205
|
]
|
|
@@ -75,7 +208,7 @@ server.prompt("validate-project", "Check if an existing CLAUDE.md is still in sy
|
|
|
75
208
|
"",
|
|
76
209
|
`1. Call validate-claude-md with projectPath="${projectPath}".`,
|
|
77
210
|
"2. Present any drifts found with clear explanations.",
|
|
78
|
-
"3. If drifts are found, suggest
|
|
211
|
+
"3. If drifts are found, suggest running the update-project prompt to regenerate.",
|
|
79
212
|
];
|
|
80
213
|
return {
|
|
81
214
|
messages: [
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tech-queries.d.ts","sourceRoot":"","sources":["../../src/resources/tech-queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmBnE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TECH_QUERIES } from "../data/tech-queries.js";
|
|
2
|
+
export function registerTechQueriesResource(server) {
|
|
3
|
+
server.resource("tech-queries", "leadcode://tech-queries", {
|
|
4
|
+
description: "Maps detected technology identifiers to Context7 library names and recommended queries. Read this after analyze-repo to know what to ask Context7 for each detected tech.",
|
|
5
|
+
mimeType: "application/json",
|
|
6
|
+
}, async () => ({
|
|
7
|
+
contents: [
|
|
8
|
+
{
|
|
9
|
+
uri: "leadcode://tech-queries",
|
|
10
|
+
mimeType: "application/json",
|
|
11
|
+
text: JSON.stringify(TECH_QUERIES, null, 2),
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=tech-queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tech-queries.js","sourceRoot":"","sources":["../../src/resources/tech-queries.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,QAAQ,CACb,cAAc,EACd,yBAAyB,EACzB;QACE,WAAW,EACT,2KAA2K;QAC7K,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,IAAI,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,yBAAyB;gBAC9B,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;aAC5C;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RepoAnalysis } from "../types.js";
|
|
2
2
|
import type { CodePatterns } from "../analyzers/patterns.js";
|
|
3
|
-
import type { FetchedDocs } from "../
|
|
3
|
+
import type { FetchedDocs } from "../types.js";
|
|
4
4
|
import type { Locale } from "../i18n/types.js";
|
|
5
5
|
export declare function generateClaudeMd(analysis: RepoAnalysis, docs: FetchedDocs, choices: Record<string, string>, patterns?: CodePatterns, locale?: Locale): string;
|
|
6
6
|
//# sourceMappingURL=claude-md.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-md.d.ts","sourceRoot":"","sources":["../../src/templates/claude-md.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"claude-md.d.ts","sourceRoot":"","sources":["../../src/templates/claude-md.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAmI/C,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,QAAQ,CAAC,EAAE,YAAY,EACvB,MAAM,GAAE,MAAa,GACpB,MAAM,CAoLR"}
|
|
@@ -7,7 +7,7 @@ import { detectFramework, detectStack } from "../analyzers/detection.js";
|
|
|
7
7
|
export function registerAnalyzeRepo(server) {
|
|
8
8
|
server.registerTool("analyze-repo", {
|
|
9
9
|
title: "Analyze Repository",
|
|
10
|
-
description: "
|
|
10
|
+
description: "Scan and analyze a project to detect its full tech stack: framework, ORM, auth, CSS, testing, state management, API style, and more. Use this when the user wants to know what technologies a project uses, or as the first step before generating a CLAUDE.md.",
|
|
11
11
|
inputSchema: {
|
|
12
12
|
projectPath: z
|
|
13
13
|
.string()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze-repo.js","sourceRoot":"","sources":["../../src/tools/analyze-repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGzE,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"analyze-repo.js","sourceRoot":"","sources":["../../src/tools/analyze-repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGzE,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,iQAAiQ;QACnQ,WAAW,EAAE;YACX,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,CAAC,6CAA6C,CAAC;SAC3D;KACF,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;QACxB,IAAI,CAAC;YACH,qBAAqB;YACrB,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC;YAC1B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,wBAAwB,WAAW,EAAE,EAAE,CAAC;iBAClF,CAAC;YACJ,CAAC;YAED,6BAA6B;YAC7B,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;YAChD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,4BAA4B,WAAW,wCAAwC,EAAE,CAAC;iBAC5H,CAAC;YACJ,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;YACnD,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,eAAe,CAC/B,GAAG,CAAC,YAAY,EAChB,GAAG,CAAC,eAAe,EACnB,SAAS,CACV,CAAC;YACF,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC;YACpE,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC,eAAe,CAAC;YAE7C,MAAM,QAAQ,GAAiB;gBAC7B,WAAW;gBACX,WAAW,EAAE,GAAG,CAAC,IAAI;gBACrB,SAAS;gBACT,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,eAAe,EAAE,GAAG,CAAC,eAAe;gBACpC,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,SAAS;gBACT,QAAQ;aACT,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACnE;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,wBAAwB,OAAO,EAAE,EAAE,CAAC;aAC9E,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,13 +1,3 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
export interface FetchedDocs {
|
|
3
|
-
techDocs: Record<string, string>;
|
|
4
|
-
crossDocs: Record<string, string>;
|
|
5
|
-
metadata: {
|
|
6
|
-
techCount: number;
|
|
7
|
-
snippetCount: number;
|
|
8
|
-
failedTechs: string[];
|
|
9
|
-
warning?: string;
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
2
|
export declare function registerFetchDocs(server: McpServer): void;
|
|
13
3
|
//# sourceMappingURL=fetch-docs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-docs.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,
|
|
1
|
+
{"version":3,"file":"fetch-docs.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwCzD"}
|
package/dist/tools/fetch-docs.js
CHANGED
|
@@ -1,111 +1,9 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
-
import {
|
|
3
|
-
/** Collect all detected tech identifiers from analysis */
|
|
4
|
-
function collectTechs(analysis) {
|
|
5
|
-
const techs = [];
|
|
6
|
-
if (analysis.framework) {
|
|
7
|
-
techs.push(analysis.framework.name);
|
|
8
|
-
}
|
|
9
|
-
const d = analysis.detected;
|
|
10
|
-
const fields = [
|
|
11
|
-
"orm", "auth", "validation", "css", "testing",
|
|
12
|
-
"stateManagement", "dataFetching", "formLibrary", "apiStyle",
|
|
13
|
-
"i18n", "payments", "realtime", "email", "cms", "jobs",
|
|
14
|
-
"uiComponents",
|
|
15
|
-
];
|
|
16
|
-
for (const field of fields) {
|
|
17
|
-
const value = d[field];
|
|
18
|
-
if (typeof value === "string") {
|
|
19
|
-
techs.push(value);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return [...new Set(techs)];
|
|
23
|
-
}
|
|
24
|
-
/** Run promises with concurrency limit */
|
|
25
|
-
async function pMap(items, fn, concurrency) {
|
|
26
|
-
const results = [];
|
|
27
|
-
let index = 0;
|
|
28
|
-
async function next() {
|
|
29
|
-
while (index < items.length) {
|
|
30
|
-
const i = index++;
|
|
31
|
-
results[i] = await fn(items[i]);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
const workers = Array.from({ length: Math.min(concurrency, items.length) }, () => next());
|
|
35
|
-
await Promise.all(workers);
|
|
36
|
-
return results;
|
|
37
|
-
}
|
|
38
|
-
async function fetchAllDocs(analysis) {
|
|
39
|
-
const techs = collectTechs(analysis);
|
|
40
|
-
const techDocs = {};
|
|
41
|
-
const crossDocs = {};
|
|
42
|
-
const failedTechs = [];
|
|
43
|
-
let snippetCount = 0;
|
|
44
|
-
// Fetch per-tech docs
|
|
45
|
-
const techTasks = techs
|
|
46
|
-
.filter((t) => t in TECH_QUERIES)
|
|
47
|
-
.map((tech) => ({
|
|
48
|
-
tech,
|
|
49
|
-
query: TECH_QUERIES[tech],
|
|
50
|
-
}));
|
|
51
|
-
await pMap(techTasks, async ({ tech, query }) => {
|
|
52
|
-
const allQueries = query.queries.join(". ");
|
|
53
|
-
const docs = await resolveAndFetch(query.libraryName, allQueries);
|
|
54
|
-
if (docs) {
|
|
55
|
-
techDocs[tech] = docs;
|
|
56
|
-
snippetCount++;
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
failedTechs.push(tech);
|
|
60
|
-
}
|
|
61
|
-
}, 5);
|
|
62
|
-
// Fetch cross-tech docs
|
|
63
|
-
const crossTasks = [];
|
|
64
|
-
for (const tech of techs) {
|
|
65
|
-
const mapping = TECH_QUERIES[tech];
|
|
66
|
-
if (!mapping?.crossQueries)
|
|
67
|
-
continue;
|
|
68
|
-
for (const [otherTech, crossQuery] of Object.entries(mapping.crossQueries)) {
|
|
69
|
-
if (techs.includes(otherTech)) {
|
|
70
|
-
const key = `${tech}+${otherTech}`;
|
|
71
|
-
// Avoid duplicates (a+b and b+a)
|
|
72
|
-
const reverseKey = `${otherTech}+${tech}`;
|
|
73
|
-
if (!(reverseKey in crossDocs) && !crossTasks.some((t) => t.key === reverseKey)) {
|
|
74
|
-
crossTasks.push({ key, libraryName: mapping.libraryName, query: crossQuery });
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
await pMap(crossTasks, async ({ key, libraryName, query }) => {
|
|
80
|
-
const docs = await resolveAndFetch(libraryName, query);
|
|
81
|
-
if (docs) {
|
|
82
|
-
crossDocs[key] = docs;
|
|
83
|
-
snippetCount++;
|
|
84
|
-
}
|
|
85
|
-
}, 5);
|
|
86
|
-
// Track techs with no mapping at all
|
|
87
|
-
for (const tech of techs) {
|
|
88
|
-
if (!(tech in TECH_QUERIES) && !failedTechs.includes(tech)) {
|
|
89
|
-
failedTechs.push(tech);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return {
|
|
93
|
-
techDocs,
|
|
94
|
-
crossDocs,
|
|
95
|
-
metadata: {
|
|
96
|
-
techCount: Object.keys(techDocs).length,
|
|
97
|
-
snippetCount,
|
|
98
|
-
failedTechs,
|
|
99
|
-
...(failedTechs.length > 0 && {
|
|
100
|
-
warning: `No documentation found for: ${failedTechs.join(", ")}`,
|
|
101
|
-
}),
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
}
|
|
2
|
+
import { fetchAllDocs } from "../context7/index.js";
|
|
105
3
|
export function registerFetchDocs(server) {
|
|
106
4
|
server.registerTool("fetch-docs", {
|
|
107
5
|
title: "Fetch Documentation",
|
|
108
|
-
description: "
|
|
6
|
+
description: "Fetch up-to-date documentation from Context7 for each technology in a project. Returns documentation organized by technology and cross-technology combinations. Useful for inspecting what docs Context7 provides before generating a CLAUDE.md.",
|
|
109
7
|
inputSchema: {
|
|
110
8
|
analysis: z
|
|
111
9
|
.string()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-docs.js","sourceRoot":"","sources":["../../src/tools/fetch-docs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"fetch-docs.js","sourceRoot":"","sources":["../../src/tools/fetch-docs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,kPAAkP;QACpP,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,CAAC,sDAAsD,CAAC;SACpE;KACF,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAiB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACvD,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;YAE1C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;qBACpC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,sBAAsB,OAAO,EAAE;qBACtC;iBACF;aACF,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-claude-md.d.ts","sourceRoot":"","sources":["../../src/tools/generate-claude-md.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"generate-claude-md.d.ts","sourceRoot":"","sources":["../../src/tools/generate-claude-md.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiGhE"}
|
|
@@ -6,14 +6,15 @@ import { analyzePatterns } from "../analyzers/patterns.js";
|
|
|
6
6
|
export function registerGenerateClaudeMd(server) {
|
|
7
7
|
server.registerTool("generate-claude-md", {
|
|
8
8
|
title: "Generate CLAUDE.md",
|
|
9
|
-
description: "
|
|
9
|
+
description: "Generate a CLAUDE.md file for a project. Takes the analysis from analyze-repo and synthesized documentation rules (from Context7 via Claude). Use this when the user wants to create, setup, init, or generate project rules, a CLAUDE.md, or configure Claude Code for a project.",
|
|
10
10
|
inputSchema: {
|
|
11
11
|
analysis: z
|
|
12
12
|
.string()
|
|
13
13
|
.describe("JSON string of RepoAnalysis (output of analyze-repo)"),
|
|
14
14
|
docs: z
|
|
15
15
|
.string()
|
|
16
|
-
.
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('JSON string of synthesized documentation: { "techDocs": Record<string, string>, "crossDocs": Record<string, string> }. Each value should be concise, actionable rules (not raw code snippets). If omitted, CLAUDE.md is generated without technology documentation.'),
|
|
17
18
|
choices: z
|
|
18
19
|
.string()
|
|
19
20
|
.optional()
|
|
@@ -22,10 +23,20 @@ export function registerGenerateClaudeMd(server) {
|
|
|
22
23
|
}, async ({ analysis: analysisStr, docs: docsStr, choices: choicesStr }) => {
|
|
23
24
|
try {
|
|
24
25
|
const analysis = JSON.parse(analysisStr);
|
|
25
|
-
const docs = JSON.parse(docsStr);
|
|
26
26
|
const choices = choicesStr
|
|
27
27
|
? JSON.parse(choicesStr)
|
|
28
28
|
: {};
|
|
29
|
+
const docs = docsStr
|
|
30
|
+
? JSON.parse(docsStr)
|
|
31
|
+
: { techDocs: {}, crossDocs: {}, metadata: { techCount: 0, snippetCount: 0, failedTechs: [] } };
|
|
32
|
+
// Ensure metadata exists
|
|
33
|
+
if (!docs.metadata) {
|
|
34
|
+
docs.metadata = {
|
|
35
|
+
techCount: Object.keys(docs.techDocs ?? {}).length,
|
|
36
|
+
snippetCount: Object.keys(docs.techDocs ?? {}).length + Object.keys(docs.crossDocs ?? {}).length,
|
|
37
|
+
failedTechs: [],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
29
40
|
// Verify project path still exists
|
|
30
41
|
try {
|
|
31
42
|
await stat(analysis.projectPath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-claude-md.js","sourceRoot":"","sources":["../../src/tools/generate-claude-md.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"generate-claude-md.js","sourceRoot":"","sources":["../../src/tools/generate-claude-md.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-claude-md.d.ts","sourceRoot":"","sources":["../../src/tools/update-claude-md.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"update-claude-md.d.ts","sourceRoot":"","sources":["../../src/tools/update-claude-md.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA+BzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgG9D"}
|
|
@@ -5,7 +5,7 @@ import { analyzeDependencies } from "../analyzers/dependencies.js";
|
|
|
5
5
|
import { analyzeStructure } from "../analyzers/structure.js";
|
|
6
6
|
import { detectFramework, detectStack } from "../analyzers/detection.js";
|
|
7
7
|
import { analyzePatterns } from "../analyzers/patterns.js";
|
|
8
|
-
import {
|
|
8
|
+
import { fetchAllDocs } from "../context7/index.js";
|
|
9
9
|
import { generateClaudeMd } from "../templates/claude-md.js";
|
|
10
10
|
/**
|
|
11
11
|
* Extract user-added sections from an existing CLAUDE.md.
|
|
@@ -25,64 +25,10 @@ function extractUserChoices(existingContent) {
|
|
|
25
25
|
}
|
|
26
26
|
return choices;
|
|
27
27
|
}
|
|
28
|
-
/** Collect techs and fetch docs (same logic as fetch-docs tool but inline) */
|
|
29
|
-
async function fetchDocsForAnalysis(analysis) {
|
|
30
|
-
const techs = [];
|
|
31
|
-
if (analysis.framework)
|
|
32
|
-
techs.push(analysis.framework.name);
|
|
33
|
-
const d = analysis.detected;
|
|
34
|
-
for (const value of Object.values(d)) {
|
|
35
|
-
if (typeof value === "string")
|
|
36
|
-
techs.push(value);
|
|
37
|
-
}
|
|
38
|
-
const uniqueTechs = [...new Set(techs)];
|
|
39
|
-
const techDocs = {};
|
|
40
|
-
const crossDocs = {};
|
|
41
|
-
const failedTechs = [];
|
|
42
|
-
let snippetCount = 0;
|
|
43
|
-
for (const tech of uniqueTechs) {
|
|
44
|
-
const mapping = TECH_QUERIES[tech];
|
|
45
|
-
if (!mapping) {
|
|
46
|
-
failedTechs.push(tech);
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
const docs = await resolveAndFetch(mapping.libraryName, mapping.queries.join(". "));
|
|
50
|
-
if (docs) {
|
|
51
|
-
techDocs[tech] = docs;
|
|
52
|
-
snippetCount++;
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
failedTechs.push(tech);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
for (const tech of uniqueTechs) {
|
|
59
|
-
const mapping = TECH_QUERIES[tech];
|
|
60
|
-
if (!mapping?.crossQueries)
|
|
61
|
-
continue;
|
|
62
|
-
for (const [other, query] of Object.entries(mapping.crossQueries)) {
|
|
63
|
-
if (!uniqueTechs.includes(other))
|
|
64
|
-
continue;
|
|
65
|
-
const key = `${tech}+${other}`;
|
|
66
|
-
const rev = `${other}+${tech}`;
|
|
67
|
-
if (key in crossDocs || rev in crossDocs)
|
|
68
|
-
continue;
|
|
69
|
-
const docs = await resolveAndFetch(mapping.libraryName, query);
|
|
70
|
-
if (docs) {
|
|
71
|
-
crossDocs[key] = docs;
|
|
72
|
-
snippetCount++;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return {
|
|
77
|
-
techDocs,
|
|
78
|
-
crossDocs,
|
|
79
|
-
metadata: { techCount: Object.keys(techDocs).length, snippetCount, failedTechs },
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
28
|
export function registerUpdateClaudeMd(server) {
|
|
83
29
|
server.registerTool("update-claude-md", {
|
|
84
30
|
title: "Update CLAUDE.md",
|
|
85
|
-
description: "Re-analyzes the project, fetches fresh documentation from Context7, and regenerates
|
|
31
|
+
description: "Update or refresh an existing CLAUDE.md. Re-analyzes the project, fetches fresh documentation from Context7, and regenerates the file while preserving user choices. Use this when the user wants to update, refresh, regenerate, or re-sync their CLAUDE.md after changing dependencies.",
|
|
86
32
|
inputSchema: {
|
|
87
33
|
projectPath: z
|
|
88
34
|
.string()
|
|
@@ -127,7 +73,7 @@ export function registerUpdateClaudeMd(server) {
|
|
|
127
73
|
detected,
|
|
128
74
|
};
|
|
129
75
|
// Fetch fresh docs
|
|
130
|
-
const docs = await
|
|
76
|
+
const docs = await fetchAllDocs(analysis);
|
|
131
77
|
const content = generateClaudeMd(analysis, docs, previousChoices, patterns);
|
|
132
78
|
await writeFile(claudeMdPath, content, "utf-8");
|
|
133
79
|
return {
|