mcp-code-context 3.8.1 → 3.9.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/CHANGELOG.md +16 -0
- package/INSTRUCTIONS.md +2 -2
- package/README.md +8 -8
- package/dist/src/core/engine.d.ts +1 -1
- package/dist/src/core/engine.js +1 -1
- package/dist/src/core/indexManager.d.ts +1 -1
- package/dist/src/core/indexManager.js +1 -1
- package/dist/src/core/sessionManager.d.ts +1 -1
- package/dist/src/core/sessionManager.js +1 -1
- package/dist/src/core/validator.d.ts +1 -1
- package/dist/src/core/validator.js +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/operations/astTransform.d.ts +1 -1
- package/dist/src/operations/astTransform.js +1 -1
- package/dist/src/operations/compress.d.ts +1 -1
- package/dist/src/operations/compress.js +53 -2
- package/dist/src/operations/compress.js.map +1 -1
- package/dist/src/operations/confirmationStore.d.ts +1 -1
- package/dist/src/operations/confirmationStore.js +1 -1
- package/dist/src/operations/impactAnalysis.js +11 -0
- package/dist/src/operations/impactAnalysis.js.map +1 -1
- package/dist/src/operations/write.d.ts +1 -1
- package/dist/src/operations/write.js +1 -1
- package/dist/src/parsers/base.d.ts +2 -2
- package/dist/src/parsers/base.js +2 -2
- package/dist/src/parsers/csharp.d.ts +1 -1
- package/dist/src/parsers/csharp.js +1 -1
- package/dist/src/parsers/dartTreeSitter.d.ts +1 -1
- package/dist/src/parsers/dartTreeSitter.js +1 -1
- package/dist/src/parsers/go.d.ts +1 -1
- package/dist/src/parsers/go.js +1 -1
- package/dist/src/parsers/java.d.ts +1 -1
- package/dist/src/parsers/java.js +1 -1
- package/dist/src/parsers/kotlin.d.ts +1 -1
- package/dist/src/parsers/kotlin.js +1 -1
- package/dist/src/parsers/php.d.ts +1 -1
- package/dist/src/parsers/php.js +1 -1
- package/dist/src/parsers/python.d.ts +2 -2
- package/dist/src/parsers/python.js +2 -2
- package/dist/src/parsers/registry.d.ts +1 -1
- package/dist/src/parsers/registry.js +1 -1
- package/dist/src/parsers/ruby.d.ts +2 -2
- package/dist/src/parsers/ruby.js +2 -2
- package/dist/src/parsers/rust.d.ts +1 -1
- package/dist/src/parsers/rust.js +1 -1
- package/dist/src/parsers/typescript.d.ts +1 -1
- package/dist/src/parsers/typescript.js +1 -1
- package/dist/src/tools/pipeline.js +4 -0
- package/dist/src/tools/pipeline.js.map +1 -1
- package/dist/src/tools/readHandlers.d.ts +18 -0
- package/dist/src/tools/readHandlers.js +52 -0
- package/dist/src/tools/readHandlers.js.map +1 -1
- package/dist/src/tools/toolDefinitions.d.ts +45 -0
- package/dist/src/tools/toolDefinitionsCore.d.ts +45 -0
- package/dist/src/tools/toolDefinitionsCore.js +39 -3
- package/dist/src/tools/toolDefinitionsCore.js.map +1 -1
- package/dist/src/utils/appDir.d.ts +1 -1
- package/dist/src/utils/appDir.js +1 -1
- package/dist/src/utils/auditLogger.d.ts +1 -1
- package/dist/src/utils/auditLogger.js +1 -1
- package/dist/src/utils/backupManager.d.ts +1 -1
- package/dist/src/utils/backupManager.js +1 -1
- package/dist/src/utils/constants.d.ts +1 -1
- package/dist/src/utils/constants.js +1 -1
- package/dist/src/utils/diff.d.ts +2 -2
- package/dist/src/utils/diff.js +2 -2
- package/dist/src/utils/fileLock.d.ts +1 -1
- package/dist/src/utils/fileLock.js +1 -1
- package/dist/src/utils/fileWalker.d.ts +1 -1
- package/dist/src/utils/fileWalker.js +1 -1
- package/dist/src/utils/fileWatcher.d.ts +1 -1
- package/dist/src/utils/fileWatcher.js +1 -1
- package/dist/src/utils/fuzzySearch.d.ts +1 -1
- package/dist/src/utils/fuzzySearch.js +1 -1
- package/dist/src/utils/gemDescriptions.json +22 -0
- package/dist/src/utils/gemfileParser.d.ts +17 -0
- package/dist/src/utils/gemfileParser.js +63 -0
- package/dist/src/utils/gemfileParser.js.map +1 -0
- package/dist/src/utils/logger.d.ts +1 -1
- package/dist/src/utils/logger.js +1 -1
- package/dist/src/utils/metaprogramming.d.ts +18 -0
- package/dist/src/utils/metaprogramming.js +139 -0
- package/dist/src/utils/metaprogramming.js.map +1 -0
- package/dist/src/utils/railsRoutes.d.ts +18 -0
- package/dist/src/utils/railsRoutes.js +148 -0
- package/dist/src/utils/railsRoutes.js.map +1 -0
- package/dist/src/utils/railsSchema.d.ts +1 -0
- package/dist/src/utils/railsSchema.js +23 -0
- package/dist/src/utils/railsSchema.js.map +1 -1
- package/dist/src/utils/rateLimiter.d.ts +1 -1
- package/dist/src/utils/rateLimiter.js +1 -1
- package/dist/src/utils/streaming.d.ts +1 -1
- package/dist/src/utils/streaming.js +1 -1
- package/dist/src/utils/telemetry.d.ts +1 -1
- package/dist/src/utils/telemetry.js +1 -1
- package/llms.txt +8 -8
- package/package.json +2 -2
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemfile Parser - v3.9.0
|
|
3
|
+
* Parses Ruby Gemfile to extract gem dependencies and infer implicit behavior.
|
|
4
|
+
* Uses a JSON data file for gem descriptions so they can be updated without recompile.
|
|
5
|
+
*/
|
|
6
|
+
import * as fsSync from "node:fs";
|
|
7
|
+
import * as fs from "node:fs/promises";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
// Load gem descriptions from JSON sibling file at module init time (sync, once)
|
|
11
|
+
function loadGemDescriptions() {
|
|
12
|
+
try {
|
|
13
|
+
const dir = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const jsonPath = path.join(dir, "gemDescriptions.json");
|
|
15
|
+
return JSON.parse(fsSync.readFileSync(jsonPath, "utf-8"));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const GEM_DESCRIPTIONS = loadGemDescriptions();
|
|
22
|
+
// Cache: gemfilePath → { result, mtime }
|
|
23
|
+
const gemfileCache = new Map();
|
|
24
|
+
export async function parseGemfile(projectRoot) {
|
|
25
|
+
const gemfilePath = path.join(projectRoot, "Gemfile");
|
|
26
|
+
let mtime;
|
|
27
|
+
try {
|
|
28
|
+
mtime = (await fs.stat(gemfilePath)).mtimeMs;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null; // No Gemfile — not a Ruby project
|
|
32
|
+
}
|
|
33
|
+
const cached = gemfileCache.get(gemfilePath);
|
|
34
|
+
if (cached?.mtime === mtime)
|
|
35
|
+
return cached.result;
|
|
36
|
+
const content = await fs.readFile(gemfilePath, "utf-8");
|
|
37
|
+
const result = parseGemfileContent(content);
|
|
38
|
+
gemfileCache.set(gemfilePath, { result, mtime });
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
export function parseGemfileContent(content) {
|
|
42
|
+
const gems = [];
|
|
43
|
+
// Match: gem 'name' | gem 'name', '~> 1.0' | gem "name", "version"
|
|
44
|
+
const gemRe = /^\s*gem\s+['"]([^'"]+)['"](?:\s*,\s*['"]([^'"]+)['"])?/gm;
|
|
45
|
+
let match;
|
|
46
|
+
while ((match = gemRe.exec(content)) !== null) {
|
|
47
|
+
const name = match[1].toLowerCase();
|
|
48
|
+
const version = match[2];
|
|
49
|
+
const implicitBehavior = GEM_DESCRIPTIONS[name];
|
|
50
|
+
gems.push({ name, version, implicitBehavior });
|
|
51
|
+
}
|
|
52
|
+
const knownGems = gems.filter(g => g.implicitBehavior !== undefined);
|
|
53
|
+
return { gems, knownGems };
|
|
54
|
+
}
|
|
55
|
+
export function formatGemAnnotation(knownGems) {
|
|
56
|
+
if (knownGems.length === 0)
|
|
57
|
+
return "";
|
|
58
|
+
const lines = knownGems
|
|
59
|
+
.map(g => ` <gem name="${g.name}"${g.version ? ` version="${g.version}"` : ""}>\n ${g.implicitBehavior}\n </gem>`)
|
|
60
|
+
.join("\n");
|
|
61
|
+
return `<!-- Gemfile: installed gems with implicit behavior\n${lines}\n-->`;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=gemfileParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemfileParser.js","sourceRoot":"","sources":["../../../src/utils/gemfileParser.ts"],"names":[],"mappings":"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"}
|
package/dist/src/utils/logger.js
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metaprogramming Entry Point Scanner - v3.9.0
|
|
3
|
+
* Identifies where Ruby's "magic" methods are generated in a codebase.
|
|
4
|
+
* Does not resolve what methods are created — it surfaces WHERE to look.
|
|
5
|
+
*/
|
|
6
|
+
export interface MetaprogrammingMatch {
|
|
7
|
+
file: string;
|
|
8
|
+
line: number;
|
|
9
|
+
pattern: string;
|
|
10
|
+
snippet: string;
|
|
11
|
+
description: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function findMetaprogrammingEntryPoints(params: {
|
|
14
|
+
target: string;
|
|
15
|
+
projectRoot: string;
|
|
16
|
+
isFile?: boolean;
|
|
17
|
+
}): Promise<MetaprogrammingMatch[]>;
|
|
18
|
+
export declare function formatMetaprogrammingResults(matches: MetaprogrammingMatch[]): string;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metaprogramming Entry Point Scanner - v3.9.0
|
|
3
|
+
* Identifies where Ruby's "magic" methods are generated in a codebase.
|
|
4
|
+
* Does not resolve what methods are created — it surfaces WHERE to look.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from "node:fs/promises";
|
|
7
|
+
import { EXCLUDE_DIRS } from "./constants.js";
|
|
8
|
+
import { walkDir } from "./fileWalker.js";
|
|
9
|
+
/** Patterns that generate methods dynamically in Ruby */
|
|
10
|
+
const METAPROGRAMMING_PATTERNS = [
|
|
11
|
+
{
|
|
12
|
+
regex: /\bmethod_missing\b/,
|
|
13
|
+
name: "method_missing",
|
|
14
|
+
description: "Catch-all for undefined method calls — generates methods on demand",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
regex: /\bdefine_method\b/,
|
|
18
|
+
name: "define_method",
|
|
19
|
+
description: "Programmatically defines a method on a class at runtime",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
regex: /\bclass_eval\b|\bmodule_eval\b/,
|
|
23
|
+
name: "class_eval/module_eval",
|
|
24
|
+
description: "Evaluates code in the context of a class — can define methods dynamically",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
regex: /\binstance_eval\b/,
|
|
28
|
+
name: "instance_eval",
|
|
29
|
+
description: "Evaluates code in the context of an object — can define singleton methods",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
regex: /\bsend\s*\(/,
|
|
33
|
+
name: "send",
|
|
34
|
+
description: "Invokes a method dynamically by name — may call generated methods",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
regex: /\bpublic_send\s*\(/,
|
|
38
|
+
name: "public_send",
|
|
39
|
+
description: "Like send but restricted to public methods — dynamic dispatch",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
regex: /\bincluded\s+do\b/,
|
|
43
|
+
name: "included do",
|
|
44
|
+
description: "ActiveSupport::Concern hook — runs when module is included, may add methods/callbacks",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
regex: /\bprepended\s+do\b/,
|
|
48
|
+
name: "prepended do",
|
|
49
|
+
description: "Module prepend hook — methods are added before the including class in the MRO",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
regex: /ActiveSupport::Concern/,
|
|
53
|
+
name: "ActiveSupport::Concern",
|
|
54
|
+
description: "Rails concern module — adds class methods and instance methods when included",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
regex: /\battr_accessor\b|\battr_reader\b|\battr_writer\b/,
|
|
58
|
+
name: "attr_accessor/reader/writer",
|
|
59
|
+
description: "Generates getter/setter methods for the listed attributes",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
regex: /\bdelegate\b.*:to\s*=>/,
|
|
63
|
+
name: "delegate",
|
|
64
|
+
description: "Rails delegate macro — generates forwarding methods to another object",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
regex: /\bhas_many\b.*through:/,
|
|
68
|
+
name: "has_many :through",
|
|
69
|
+
description: "AR association — generates join-table query methods",
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
export async function findMetaprogrammingEntryPoints(params) {
|
|
73
|
+
const matches = [];
|
|
74
|
+
if (params.isFile) {
|
|
75
|
+
const content = await fs.readFile(params.target, "utf-8").catch(() => null);
|
|
76
|
+
if (content) {
|
|
77
|
+
scanContent(content, params.target, matches);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
await walkDir(params.target, {
|
|
82
|
+
extensions: [".rb"],
|
|
83
|
+
excludeDirs: EXCLUDE_DIRS,
|
|
84
|
+
onFile: async (fullPath) => {
|
|
85
|
+
const content = await fs.readFile(fullPath, "utf-8").catch(() => null);
|
|
86
|
+
if (content) {
|
|
87
|
+
scanContent(content, fullPath, matches);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return matches;
|
|
93
|
+
}
|
|
94
|
+
function scanContent(content, filePath, matches) {
|
|
95
|
+
const lines = content.split("\n");
|
|
96
|
+
for (let i = 0; i < lines.length; i++) {
|
|
97
|
+
const line = lines[i];
|
|
98
|
+
for (const { regex, name, description } of METAPROGRAMMING_PATTERNS) {
|
|
99
|
+
if (regex.test(line)) {
|
|
100
|
+
// Get 1 line of context before and after
|
|
101
|
+
const snippet = lines.slice(Math.max(0, i - 1), i + 2).join("\n");
|
|
102
|
+
matches.push({
|
|
103
|
+
file: filePath,
|
|
104
|
+
line: i + 1,
|
|
105
|
+
pattern: name,
|
|
106
|
+
snippet: snippet.trim(),
|
|
107
|
+
description,
|
|
108
|
+
});
|
|
109
|
+
break; // one match per line
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export function formatMetaprogrammingResults(matches) {
|
|
115
|
+
if (matches.length === 0) {
|
|
116
|
+
return JSON.stringify({ found: 0, message: "No metaprogramming entry points detected" });
|
|
117
|
+
}
|
|
118
|
+
// Group by file
|
|
119
|
+
const byFile = new Map();
|
|
120
|
+
for (const m of matches) {
|
|
121
|
+
const existing = byFile.get(m.file) ?? [];
|
|
122
|
+
existing.push(m);
|
|
123
|
+
byFile.set(m.file, existing);
|
|
124
|
+
}
|
|
125
|
+
const result = {
|
|
126
|
+
found: matches.length,
|
|
127
|
+
files: Array.from(byFile.entries()).map(([file, fileMatches]) => ({
|
|
128
|
+
file,
|
|
129
|
+
matches: fileMatches.map(m => ({
|
|
130
|
+
line: m.line,
|
|
131
|
+
pattern: m.pattern,
|
|
132
|
+
description: m.description,
|
|
133
|
+
snippet: m.snippet,
|
|
134
|
+
})),
|
|
135
|
+
})),
|
|
136
|
+
};
|
|
137
|
+
return JSON.stringify(result, null, 2);
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=metaprogramming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metaprogramming.js","sourceRoot":"","sources":["../../../src/utils/metaprogramming.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rails Routes Parser - v3.9.0
|
|
3
|
+
* Parses config/routes.rb to map HTTP routes to controller actions.
|
|
4
|
+
* v1: handles resources, resource, explicit get/post/patch/put/delete/root.
|
|
5
|
+
* v1 limitation: only:/except:/shallow:/nested resources — emits warnings, does not generate false routes.
|
|
6
|
+
*/
|
|
7
|
+
export interface RouteEntry {
|
|
8
|
+
method: string;
|
|
9
|
+
path: string;
|
|
10
|
+
controller: string;
|
|
11
|
+
action: string;
|
|
12
|
+
}
|
|
13
|
+
export interface RoutesResult {
|
|
14
|
+
routes: RouteEntry[];
|
|
15
|
+
warnings: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function parseRailsRoutes(projectRoot: string): Promise<RoutesResult | null>;
|
|
18
|
+
export declare function parseRoutesContent(content: string): RoutesResult;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rails Routes Parser - v3.9.0
|
|
3
|
+
* Parses config/routes.rb to map HTTP routes to controller actions.
|
|
4
|
+
* v1: handles resources, resource, explicit get/post/patch/put/delete/root.
|
|
5
|
+
* v1 limitation: only:/except:/shallow:/nested resources — emits warnings, does not generate false routes.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from "node:fs/promises";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
// Cache: routesPath → { result, mtime }
|
|
10
|
+
const routesCache = new Map();
|
|
11
|
+
/** Standard 7 REST actions for `resources` */
|
|
12
|
+
const RESOURCES_ACTIONS = [
|
|
13
|
+
{ method: "GET", path: "", action: "index", controller: "" },
|
|
14
|
+
{ method: "GET", path: "/new", action: "new", controller: "" },
|
|
15
|
+
{ method: "POST", path: "", action: "create", controller: "" },
|
|
16
|
+
{ method: "GET", path: "/:id", action: "show", controller: "" },
|
|
17
|
+
{ method: "GET", path: "/:id/edit", action: "edit", controller: "" },
|
|
18
|
+
{ method: "PATCH", path: "/:id", action: "update", controller: "" },
|
|
19
|
+
{ method: "DELETE", path: "/:id", action: "destroy", controller: "" },
|
|
20
|
+
];
|
|
21
|
+
/** Standard 6 singular REST actions for `resource` */
|
|
22
|
+
const RESOURCE_ACTIONS = [
|
|
23
|
+
{ method: "GET", path: "/new", action: "new", controller: "" },
|
|
24
|
+
{ method: "POST", path: "", action: "create", controller: "" },
|
|
25
|
+
{ method: "GET", path: "", action: "show", controller: "" },
|
|
26
|
+
{ method: "GET", path: "/edit", action: "edit", controller: "" },
|
|
27
|
+
{ method: "PATCH", path: "", action: "update", controller: "" },
|
|
28
|
+
{ method: "DELETE", path: "", action: "destroy", controller: "" },
|
|
29
|
+
];
|
|
30
|
+
export async function parseRailsRoutes(projectRoot) {
|
|
31
|
+
const routesPath = path.join(projectRoot, "config", "routes.rb");
|
|
32
|
+
let mtime;
|
|
33
|
+
try {
|
|
34
|
+
mtime = (await fs.stat(routesPath)).mtimeMs;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null; // No routes.rb — not a Rails app
|
|
38
|
+
}
|
|
39
|
+
const cached = routesCache.get(routesPath);
|
|
40
|
+
if (cached?.mtime === mtime)
|
|
41
|
+
return cached.result;
|
|
42
|
+
const content = await fs.readFile(routesPath, "utf-8");
|
|
43
|
+
const result = parseRoutesContent(content);
|
|
44
|
+
routesCache.set(routesPath, { result, mtime });
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
export function parseRoutesContent(content) {
|
|
48
|
+
const routes = [];
|
|
49
|
+
const warnings = [];
|
|
50
|
+
// Stack for namespace/scope prefix accumulation
|
|
51
|
+
const prefixStack = [];
|
|
52
|
+
const lines = content.split("\n");
|
|
53
|
+
for (const rawLine of lines) {
|
|
54
|
+
const line = rawLine.trim();
|
|
55
|
+
// Skip comments and blank lines
|
|
56
|
+
if (line.startsWith("#") || line === "")
|
|
57
|
+
continue;
|
|
58
|
+
// Namespace/scope push
|
|
59
|
+
const nsMatch = line.match(/^(?:namespace|scope)\s+[:'"]([^'"]+)['"]/);
|
|
60
|
+
if (nsMatch) {
|
|
61
|
+
prefixStack.push(nsMatch[1].replace(/^:/, ""));
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
// Closing end — pop prefix stack
|
|
65
|
+
if (line === "end" && prefixStack.length > 0) {
|
|
66
|
+
prefixStack.pop();
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const prefix = prefixStack.length > 0 ? "/" + prefixStack.join("/") : "";
|
|
70
|
+
// Detect unsupported options — warn instead of generating wrong output
|
|
71
|
+
const hasOnlyExcept = /\bonly:\s*\[/.test(line) || /\bexcept:\s*\[/.test(line);
|
|
72
|
+
const hasShallow = /\bshallow:\s*true\b/.test(line);
|
|
73
|
+
const hasNested = line.includes("do") && (line.startsWith("resources") || line.startsWith("resource"));
|
|
74
|
+
// resources :name
|
|
75
|
+
const resourcesMatch = line.match(/^resources\s+:(\w+)/);
|
|
76
|
+
if (resourcesMatch) {
|
|
77
|
+
const name = resourcesMatch[1];
|
|
78
|
+
const controller = nameToController(name, prefixStack);
|
|
79
|
+
const basePath = `${prefix}/${name}`;
|
|
80
|
+
if (hasOnlyExcept) {
|
|
81
|
+
warnings.push(`resources :${name} uses only:/except: — route list may be incomplete. Full support planned for v2.`);
|
|
82
|
+
}
|
|
83
|
+
if (hasShallow) {
|
|
84
|
+
warnings.push(`resources :${name} uses shallow: — nested shallow routes not fully parsed.`);
|
|
85
|
+
}
|
|
86
|
+
if (hasNested) {
|
|
87
|
+
warnings.push(`resources :${name} has nested resources (do block) — only top-level routes parsed.`);
|
|
88
|
+
}
|
|
89
|
+
for (const action of RESOURCES_ACTIONS) {
|
|
90
|
+
routes.push({
|
|
91
|
+
method: action.method,
|
|
92
|
+
path: basePath + action.path,
|
|
93
|
+
controller,
|
|
94
|
+
action: action.action,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
// resource :name (singular)
|
|
100
|
+
const resourceMatch = line.match(/^resource\s+:(\w+)/);
|
|
101
|
+
if (resourceMatch) {
|
|
102
|
+
const name = resourceMatch[1];
|
|
103
|
+
const controller = nameToController(name + "s", prefixStack); // pluralize for controller
|
|
104
|
+
const basePath = `${prefix}/${name}`;
|
|
105
|
+
if (hasOnlyExcept) {
|
|
106
|
+
warnings.push(`resource :${name} uses only:/except: — route list may be incomplete.`);
|
|
107
|
+
}
|
|
108
|
+
for (const action of RESOURCE_ACTIONS) {
|
|
109
|
+
routes.push({
|
|
110
|
+
method: action.method,
|
|
111
|
+
path: basePath + action.path,
|
|
112
|
+
controller,
|
|
113
|
+
action: action.action,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
// Explicit HTTP verb routes: get '/path', to: 'controller#action'
|
|
119
|
+
const verbMatch = line.match(/^(get|post|patch|put|delete|head|options)\s+['"]([^'"]+)['"]\s*,\s*to:\s*['"]([^#'"]+)#([^'"]+)['"]/i);
|
|
120
|
+
if (verbMatch) {
|
|
121
|
+
routes.push({
|
|
122
|
+
method: verbMatch[1].toUpperCase(),
|
|
123
|
+
path: prefix + verbMatch[2],
|
|
124
|
+
controller: verbMatch[3].trim(),
|
|
125
|
+
action: verbMatch[4].trim(),
|
|
126
|
+
});
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
// root to: 'controller#action'
|
|
130
|
+
const rootMatch = line.match(/^root\s+(?:to:\s*)?['"]([^#'"]+)#([^'"]+)['"]/);
|
|
131
|
+
if (rootMatch) {
|
|
132
|
+
routes.push({
|
|
133
|
+
method: "GET",
|
|
134
|
+
path: prefix + "/",
|
|
135
|
+
controller: rootMatch[1].trim(),
|
|
136
|
+
action: rootMatch[2].trim(),
|
|
137
|
+
});
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return { routes, warnings };
|
|
142
|
+
}
|
|
143
|
+
/** Convert resource name + namespace stack to controller name */
|
|
144
|
+
function nameToController(name, prefixStack) {
|
|
145
|
+
const ns = prefixStack.length > 0 ? prefixStack.join("/") + "/" : "";
|
|
146
|
+
return `${ns}${name}`;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=railsRoutes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"railsRoutes.js","sourceRoot":"","sources":["../../../src/utils/railsRoutes.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,3 +8,4 @@ export declare function loadRailsSchema(projectRoot: string): Promise<ProjectDbS
|
|
|
8
8
|
export declare function parseSchemaRb(content: string): ProjectDbSchema;
|
|
9
9
|
export declare function modelToTable(className: string): string;
|
|
10
10
|
export declare function formatSchemaAnnotation(tableName: string, columns: TableSchema): string;
|
|
11
|
+
export declare function findRailsConcerns(projectRoot: string): Promise<Map<string, string[]>>;
|
|
@@ -101,4 +101,27 @@ export function formatSchemaAnnotation(tableName, columns) {
|
|
|
101
101
|
.join("\n");
|
|
102
102
|
return `<!-- ActiveRecord Virtual Schema: ${tableName}\n${cols}\n-->`;
|
|
103
103
|
}
|
|
104
|
+
// R5: Concern Resolution - Scan for concerns in app/models/concerns and app/controllers/concerns
|
|
105
|
+
export async function findRailsConcerns(projectRoot) {
|
|
106
|
+
const concernMap = new Map();
|
|
107
|
+
const concernsDirs = [
|
|
108
|
+
path.join(projectRoot, "app", "models", "concerns"),
|
|
109
|
+
path.join(projectRoot, "app", "controllers", "concerns"),
|
|
110
|
+
];
|
|
111
|
+
for (const dir of concernsDirs) {
|
|
112
|
+
try {
|
|
113
|
+
const files = await fs.readdir(dir, { withFileTypes: true });
|
|
114
|
+
for (const file of files) {
|
|
115
|
+
if (file.isFile() && file.name.endsWith(".rb")) {
|
|
116
|
+
const moduleName = file.name.replace(/\.rb$/, "").split("_").map(part => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
117
|
+
concernMap.set(moduleName, [path.join(dir, file.name)]);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Directory doesn't exist, skip
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return concernMap;
|
|
126
|
+
}
|
|
104
127
|
//# sourceMappingURL=railsSchema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"railsSchema.js","sourceRoot":"","sources":["../../../src/utils/railsSchema.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"railsSchema.js","sourceRoot":"","sources":["../../../src/utils/railsSchema.ts"],"names":[],"mappings":"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"}
|
package/llms.txt
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# mcp-code-context v3.
|
|
1
|
+
# mcp-code-context v3.9.0
|
|
2
2
|
|
|
3
3
|
> A Model Context Protocol (MCP) server with **Tree-sitter WASM parsers** for 100% AST accuracy. Zero native dependencies. Production-ready with middleware pipeline, session-scoped state, and crash recovery.
|
|
4
4
|
|
|
5
|
-
## What's New in v3.
|
|
5
|
+
## What's New in v3.9.0
|
|
6
6
|
|
|
7
7
|
🚀 **CRITICAL FIXES - Production Readiness Release**:
|
|
8
8
|
- ✅ **Session-scoped state**: Each MCP client gets isolated locks, confirmation store, rate limiter (no state leakage)
|
|
@@ -149,13 +149,13 @@ This MCP server solves two problems:
|
|
|
149
149
|
- `steps` (optional): Number of versions to go back (1-5, default: 1).
|
|
150
150
|
**What it does:** Reverts the file to the state it was in before the last 1-5 modifications.
|
|
151
151
|
|
|
152
|
-
### Write Tools (v3.
|
|
152
|
+
### Write Tools (v3.9.0 Two-Phase Workflow)
|
|
153
153
|
|
|
154
154
|
All write tools follow a **Two-Phase Workflow**:
|
|
155
155
|
1. **Phase 1 (Preview)**: Call without a token to get a unified `diff` and a `confirmationToken`.
|
|
156
156
|
2. **Phase 2 (Apply)**: Call with `confirmationToken` and `confirm: true` to apply the changes.
|
|
157
157
|
|
|
158
|
-
**Important Notes (v3.
|
|
158
|
+
**Important Notes (v3.9.0):**
|
|
159
159
|
- ✅ **Windows CRLF Support**: Fully resolved. All operations work correctly on Windows files with CRLF line endings.
|
|
160
160
|
- ✅ **Parameter Brace Handling**: Methods with braces in parameters (e.g., `{int? cart}`) are now handled correctly.
|
|
161
161
|
- ✅ **Session-scoped state**: Each MCP client gets isolated state (locks, confirmation store, rate limiter).
|
|
@@ -236,7 +236,7 @@ All write tools follow a **Two-Phase Workflow**:
|
|
|
236
236
|
|
|
237
237
|
**Best used when:** Cleaning up deprecated functions or unused code.
|
|
238
238
|
|
|
239
|
-
## New Tools (v3.
|
|
239
|
+
## New Tools (v3.9.0)
|
|
240
240
|
|
|
241
241
|
#### 11. `get_session_stats`
|
|
242
242
|
**Purpose:** Get statistics for the current MCP client session.
|
|
@@ -268,7 +268,7 @@ All write tools follow a **Two-Phase Workflow**:
|
|
|
268
268
|
|
|
269
269
|
**Best used when:** Recovering work after a server crash.
|
|
270
270
|
|
|
271
|
-
## Previously Added Tools (v3.
|
|
271
|
+
## Previously Added Tools (v3.9.0)
|
|
272
272
|
|
|
273
273
|
#### 14. `parse_file`
|
|
274
274
|
**Purpose:** Parse a file using Tree-sitter and extract all symbols.
|
|
@@ -313,7 +313,7 @@ All write tools follow a **Two-Phase Workflow**:
|
|
|
313
313
|
5. **Phase 2: Apply Edit** → Verify the diff, then call with the token and `confirm: true`.
|
|
314
314
|
6. **Recovery** → Use `rollback_file` if needed.
|
|
315
315
|
|
|
316
|
-
## Session State Configuration (v3.
|
|
316
|
+
## Session State Configuration (v3.9.0+)
|
|
317
317
|
|
|
318
318
|
### Critical: Session-Scoped State
|
|
319
319
|
|
|
@@ -429,6 +429,6 @@ No additional configuration is needed beyond adding the MCP server definition. S
|
|
|
429
429
|
|
|
430
430
|
---
|
|
431
431
|
|
|
432
|
-
**Version**: 3.
|
|
432
|
+
**Version**: 3.9.0
|
|
433
433
|
**Last Updated**: June 8, 2026
|
|
434
434
|
**Status**: Production-ready with session-scoped state and crash recovery
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-code-context",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.0",
|
|
4
4
|
"description": "Powerful MCP server with Tree-sitter WASM parsers for 100% AST accuracy. Zero native dependencies. Production-ready with persistent caching, structured logging, file watching, fuzzy search, rate limiting, file locking, and ReDoS protection. Supports TypeScript, JavaScript, PHP, Dart, Python, and Ruby (with ActiveRecord Virtual Schema extraction).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"mcp-code-context": "dist/src/index.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
11
|
+
"build": "tsc && node -e \"require('fs').copyFileSync('src/utils/gemDescriptions.json', 'dist/src/utils/gemDescriptions.json')\"",
|
|
12
12
|
"test": "npm run build && npm run build:tests && node dist-tests/tests/test-security.js && node dist-tests/tests/test-file-lock.js && node dist-tests/tests/test-rate-limiter.js && node dist-tests/tests/test-v3.4.js && node dist-tests/tests/test-backup-manager.js && node dist-tests/tests/test-index-manager.js && node dist-tests/tests/test-wasm-parsers.js",
|
|
13
13
|
"test:ui": "vitest --ui",
|
|
14
14
|
"test:run": "vitest run",
|