typegraph-mcp 0.9.43 → 0.9.44
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/check.ts +61 -0
- package/cli.ts +110 -3
- package/dist/check.js +41 -0
- package/dist/cli.js +139 -2
- package/install-oxlint-test.ts +18 -4
- package/package.json +1 -1
package/check.ts
CHANGED
|
@@ -170,6 +170,64 @@ function hasTrustedCodexProject(projectRoot: string): boolean | null {
|
|
|
170
170
|
return matchesTrustedProject();
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
function hasCompleteJsonTypegraphRegistration(
|
|
174
|
+
config: unknown,
|
|
175
|
+
serverName: string,
|
|
176
|
+
projectRoot: string
|
|
177
|
+
): boolean {
|
|
178
|
+
if (typeof config !== "object" || config === null) return false;
|
|
179
|
+
const servers = (config as Record<string, unknown>)["mcpServers"];
|
|
180
|
+
if (typeof servers !== "object" || servers === null) return false;
|
|
181
|
+
const entry = (servers as Record<string, unknown>)[serverName];
|
|
182
|
+
if (typeof entry !== "object" || entry === null) return false;
|
|
183
|
+
|
|
184
|
+
const record = entry as Record<string, unknown>;
|
|
185
|
+
const command = record["command"];
|
|
186
|
+
const args = record["args"];
|
|
187
|
+
const env = record["env"];
|
|
188
|
+
const serializedArgs = JSON.stringify(args ?? []);
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
typeof command === "string" &&
|
|
192
|
+
command.length > 0 &&
|
|
193
|
+
Array.isArray(args) &&
|
|
194
|
+
serializedArgs.includes("server.ts") &&
|
|
195
|
+
serializedArgs.includes("tsx") &&
|
|
196
|
+
typeof env === "object" &&
|
|
197
|
+
env !== null &&
|
|
198
|
+
(env as Record<string, unknown>)["TYPEGRAPH_PROJECT_ROOT"] === projectRoot &&
|
|
199
|
+
typeof (env as Record<string, unknown>)["TYPEGRAPH_TSCONFIG"] === "string"
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function readJsonConfig(configPath: string): unknown | null {
|
|
204
|
+
if (!fs.existsSync(configPath)) return null;
|
|
205
|
+
try {
|
|
206
|
+
return JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
207
|
+
} catch {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function getAntigravityMcpConfigPaths(): string[] {
|
|
213
|
+
const home = process.env.HOME || "";
|
|
214
|
+
return [
|
|
215
|
+
path.join(home, ".gemini/antigravity/mcp_config.json"),
|
|
216
|
+
path.join(home, ".gemini/antigravity-cli/plugins/typegraph-mcp/mcp_config.json"),
|
|
217
|
+
];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function findAntigravityRegistration(projectRoot: string): string | null {
|
|
221
|
+
const home = process.env.HOME || "";
|
|
222
|
+
for (const configPath of getAntigravityMcpConfigPaths()) {
|
|
223
|
+
const config = readJsonConfig(configPath);
|
|
224
|
+
if (hasCompleteJsonTypegraphRegistration(config, "typegraph-mcp", projectRoot)) {
|
|
225
|
+
return configPath.replace(home, "~");
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
|
|
173
231
|
function readProjectPackageJson(projectRoot: string): Record<string, unknown> | null {
|
|
174
232
|
const packageJsonPath = path.resolve(projectRoot, "package.json");
|
|
175
233
|
if (!fs.existsSync(packageJsonPath)) return null;
|
|
@@ -346,6 +404,7 @@ export async function main(configOverride?: TypegraphConfig): Promise<CheckResul
|
|
|
346
404
|
encoding: "utf-8",
|
|
347
405
|
});
|
|
348
406
|
const hasGlobalCodexRegistration = codexGet.status === 0;
|
|
407
|
+
const antigravityRegistrationPath = findAntigravityRegistration(projectRoot);
|
|
349
408
|
if (process.env.CLAUDE_PLUGIN_ROOT) {
|
|
350
409
|
pass("MCP registered via plugin (CLAUDE_PLUGIN_ROOT set)");
|
|
351
410
|
} else if (hasPluginMcp) {
|
|
@@ -382,6 +441,8 @@ export async function main(configOverride?: TypegraphConfig): Promise<CheckResul
|
|
|
382
441
|
}
|
|
383
442
|
} else if (hasGlobalCodexRegistration) {
|
|
384
443
|
pass("MCP registered in global Codex CLI config");
|
|
444
|
+
} else if (antigravityRegistrationPath !== null) {
|
|
445
|
+
pass(`MCP registered in Antigravity config (${antigravityRegistrationPath})`);
|
|
385
446
|
} else {
|
|
386
447
|
const codexConfigPath = path.resolve(projectRoot, ".codex/config.toml");
|
|
387
448
|
const mcpJsonPath = path.resolve(projectRoot, ".claude/mcp.json");
|
package/cli.ts
CHANGED
|
@@ -22,7 +22,7 @@ import { resolveConfig } from "./config.js";
|
|
|
22
22
|
|
|
23
23
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
24
24
|
|
|
25
|
-
type AgentId = "claude-code" | "cursor" | "codex" | "gemini" | "copilot";
|
|
25
|
+
type AgentId = "claude-code" | "cursor" | "codex" | "gemini" | "copilot" | "antigravity";
|
|
26
26
|
|
|
27
27
|
interface AgentDef {
|
|
28
28
|
name: string;
|
|
@@ -80,7 +80,7 @@ const CLAUDE_NODE_PLACEHOLDER = "__TYPEGRAPH_NODE__";
|
|
|
80
80
|
|
|
81
81
|
const PLUGIN_DIR_NAME = "plugins/typegraph-mcp";
|
|
82
82
|
|
|
83
|
-
const AGENT_IDS: AgentId[] = ["claude-code", "cursor", "codex", "gemini", "copilot"];
|
|
83
|
+
const AGENT_IDS: AgentId[] = ["claude-code", "cursor", "codex", "gemini", "copilot", "antigravity"];
|
|
84
84
|
|
|
85
85
|
const AGENTS: Record<AgentId, AgentDef> = {
|
|
86
86
|
"claude-code": {
|
|
@@ -129,6 +129,13 @@ const AGENTS: Record<AgentId, AgentDef> = {
|
|
|
129
129
|
detect: (root) =>
|
|
130
130
|
fs.existsSync(path.join(root, ".github/copilot-instructions.md")),
|
|
131
131
|
},
|
|
132
|
+
antigravity: {
|
|
133
|
+
name: "Antigravity",
|
|
134
|
+
pluginFiles: [],
|
|
135
|
+
agentFile: "AGENTS.md",
|
|
136
|
+
needsAgentsSkills: true,
|
|
137
|
+
detect: (root) => fs.existsSync(path.join(root, ".gemini/antigravity")),
|
|
138
|
+
},
|
|
132
139
|
};
|
|
133
140
|
|
|
134
141
|
/** Core files always installed (server, modules, config, package manifest) */
|
|
@@ -250,6 +257,35 @@ function getCodexConfigPath(projectRoot: string): string {
|
|
|
250
257
|
return path.resolve(projectRoot, ".codex/config.toml");
|
|
251
258
|
}
|
|
252
259
|
|
|
260
|
+
function getAntigravityMcpConfigPaths(): string[] {
|
|
261
|
+
const home = process.env.HOME || "";
|
|
262
|
+
return [
|
|
263
|
+
path.join(home, ".gemini/antigravity/mcp_config.json"),
|
|
264
|
+
path.join(home, ".gemini/antigravity-cli/plugins/typegraph-mcp/mcp_config.json"),
|
|
265
|
+
];
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function ensureAntigravityCliPlugin(): void {
|
|
269
|
+
const home = process.env.HOME || "";
|
|
270
|
+
const pluginDir = path.join(home, ".gemini/antigravity-cli/plugins/typegraph-mcp");
|
|
271
|
+
const pluginJsonPath = path.join(pluginDir, "plugin.json");
|
|
272
|
+
if (!fs.existsSync(pluginJsonPath)) {
|
|
273
|
+
fs.mkdirSync(pluginDir, { recursive: true });
|
|
274
|
+
fs.writeFileSync(
|
|
275
|
+
pluginJsonPath,
|
|
276
|
+
JSON.stringify(
|
|
277
|
+
{
|
|
278
|
+
name: "typegraph-mcp",
|
|
279
|
+
version: "1.0.0",
|
|
280
|
+
description: "TypeGraph MCP server for TypeScript navigation",
|
|
281
|
+
},
|
|
282
|
+
null,
|
|
283
|
+
2
|
|
284
|
+
) + "\n"
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
253
289
|
function isTomlSectionGroup(sectionName: string | null, prefix: string): boolean {
|
|
254
290
|
return sectionName === prefix || sectionName?.startsWith(`${prefix}.`) === true;
|
|
255
291
|
}
|
|
@@ -476,6 +512,9 @@ function registerMcpServers(projectRoot: string, selectedAgents: AgentId[]): voi
|
|
|
476
512
|
if (selectedAgents.includes("copilot")) {
|
|
477
513
|
registerJsonMcp(projectRoot, ".vscode/mcp.json", "servers");
|
|
478
514
|
}
|
|
515
|
+
if (selectedAgents.includes("antigravity")) {
|
|
516
|
+
registerAntigravityMcp(projectRoot);
|
|
517
|
+
}
|
|
479
518
|
}
|
|
480
519
|
|
|
481
520
|
/** Deregister the typegraph MCP server from all agent config files */
|
|
@@ -483,6 +522,7 @@ function deregisterMcpServers(projectRoot: string): void {
|
|
|
483
522
|
deregisterJsonMcp(projectRoot, ".cursor/mcp.json", "mcpServers");
|
|
484
523
|
deregisterCodexMcp(projectRoot);
|
|
485
524
|
deregisterJsonMcp(projectRoot, ".vscode/mcp.json", "servers");
|
|
525
|
+
deregisterAntigravityMcp(projectRoot);
|
|
486
526
|
}
|
|
487
527
|
|
|
488
528
|
/** Register MCP server in a JSON config file (Cursor or Copilot format) */
|
|
@@ -593,6 +633,73 @@ function deregisterCodexMcp(projectRoot: string): void {
|
|
|
593
633
|
}
|
|
594
634
|
}
|
|
595
635
|
|
|
636
|
+
/** Register MCP server in Antigravity's config files */
|
|
637
|
+
function registerAntigravityMcp(projectRoot: string): void {
|
|
638
|
+
const home = process.env.HOME || "";
|
|
639
|
+
const pluginDir = path.resolve(projectRoot, PLUGIN_DIR_NAME);
|
|
640
|
+
const tsConfigPath = path.resolve(projectRoot, "tsconfig.json");
|
|
641
|
+
ensureAntigravityCliPlugin();
|
|
642
|
+
|
|
643
|
+
const entry = {
|
|
644
|
+
command: process.execPath,
|
|
645
|
+
args: [
|
|
646
|
+
path.join(pluginDir, "node_modules/tsx/dist/cli.mjs"),
|
|
647
|
+
path.join(pluginDir, "server.ts"),
|
|
648
|
+
],
|
|
649
|
+
env: {
|
|
650
|
+
TYPEGRAPH_PROJECT_ROOT: projectRoot,
|
|
651
|
+
TYPEGRAPH_TSCONFIG: tsConfigPath,
|
|
652
|
+
},
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
for (const configPath of getAntigravityMcpConfigPaths()) {
|
|
656
|
+
let config: any = { mcpServers: {} };
|
|
657
|
+
if (fs.existsSync(configPath)) {
|
|
658
|
+
try {
|
|
659
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
660
|
+
} catch {
|
|
661
|
+
p.log.warn(`Could not parse ~${configPath.replace(home, "")} — skipping MCP registration`);
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (!config.mcpServers) config.mcpServers = {};
|
|
666
|
+
config.mcpServers["typegraph-mcp"] = entry;
|
|
667
|
+
|
|
668
|
+
const dir = path.dirname(configPath);
|
|
669
|
+
if (!fs.existsSync(dir)) {
|
|
670
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
671
|
+
}
|
|
672
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
673
|
+
p.log.success(`~${configPath.replace(home, "")}: registered typegraph-mcp server`);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/** Deregister MCP server from Antigravity's config files */
|
|
678
|
+
function deregisterAntigravityMcp(projectRoot: string): void {
|
|
679
|
+
const home = process.env.HOME || "";
|
|
680
|
+
|
|
681
|
+
for (const configPath of getAntigravityMcpConfigPaths()) {
|
|
682
|
+
if (!fs.existsSync(configPath)) continue;
|
|
683
|
+
try {
|
|
684
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
685
|
+
if (config.mcpServers && config.mcpServers["typegraph-mcp"]) {
|
|
686
|
+
delete config.mcpServers["typegraph-mcp"];
|
|
687
|
+
if (Object.keys(config.mcpServers).length === 0) {
|
|
688
|
+
delete config.mcpServers;
|
|
689
|
+
}
|
|
690
|
+
if (Object.keys(config).length === 0) {
|
|
691
|
+
fs.unlinkSync(configPath);
|
|
692
|
+
} else {
|
|
693
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
694
|
+
}
|
|
695
|
+
p.log.info(`~${configPath.replace(home, "")}: removed typegraph-mcp server`);
|
|
696
|
+
}
|
|
697
|
+
} catch {
|
|
698
|
+
// Ignore
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
596
703
|
// ─── TSConfig Exclude ─────────────────────────────────────────────────────────
|
|
597
704
|
|
|
598
705
|
function ensureTsconfigExclude(projectRoot: string): void {
|
|
@@ -876,7 +983,7 @@ async function setup(yes: boolean): Promise<void> {
|
|
|
876
983
|
// 3. Agent selection
|
|
877
984
|
const selectedAgents = await selectAgents(projectRoot, yes);
|
|
878
985
|
|
|
879
|
-
const needsPluginSkills = selectedAgents.includes("claude-code") || selectedAgents.includes("cursor");
|
|
986
|
+
const needsPluginSkills = selectedAgents.includes("claude-code") || selectedAgents.includes("cursor") || selectedAgents.includes("antigravity");
|
|
880
987
|
const needsAgentsSkills = selectedAgents.some((id) => AGENTS[id].needsAgentsSkills);
|
|
881
988
|
|
|
882
989
|
p.log.step(`Installing to ${PLUGIN_DIR_NAME}/...`);
|
package/dist/check.js
CHANGED
|
@@ -478,6 +478,44 @@ function hasTrustedCodexProject(projectRoot) {
|
|
|
478
478
|
}
|
|
479
479
|
return matchesTrustedProject();
|
|
480
480
|
}
|
|
481
|
+
function hasCompleteJsonTypegraphRegistration(config, serverName, projectRoot) {
|
|
482
|
+
if (typeof config !== "object" || config === null) return false;
|
|
483
|
+
const servers = config["mcpServers"];
|
|
484
|
+
if (typeof servers !== "object" || servers === null) return false;
|
|
485
|
+
const entry = servers[serverName];
|
|
486
|
+
if (typeof entry !== "object" || entry === null) return false;
|
|
487
|
+
const record = entry;
|
|
488
|
+
const command = record["command"];
|
|
489
|
+
const args = record["args"];
|
|
490
|
+
const env = record["env"];
|
|
491
|
+
const serializedArgs = JSON.stringify(args ?? []);
|
|
492
|
+
return typeof command === "string" && command.length > 0 && Array.isArray(args) && serializedArgs.includes("server.ts") && serializedArgs.includes("tsx") && typeof env === "object" && env !== null && env["TYPEGRAPH_PROJECT_ROOT"] === projectRoot && typeof env["TYPEGRAPH_TSCONFIG"] === "string";
|
|
493
|
+
}
|
|
494
|
+
function readJsonConfig(configPath) {
|
|
495
|
+
if (!fs2.existsSync(configPath)) return null;
|
|
496
|
+
try {
|
|
497
|
+
return JSON.parse(fs2.readFileSync(configPath, "utf-8"));
|
|
498
|
+
} catch {
|
|
499
|
+
return null;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
function getAntigravityMcpConfigPaths() {
|
|
503
|
+
const home = process.env.HOME || "";
|
|
504
|
+
return [
|
|
505
|
+
path3.join(home, ".gemini/antigravity/mcp_config.json"),
|
|
506
|
+
path3.join(home, ".gemini/antigravity-cli/plugins/typegraph-mcp/mcp_config.json")
|
|
507
|
+
];
|
|
508
|
+
}
|
|
509
|
+
function findAntigravityRegistration(projectRoot) {
|
|
510
|
+
const home = process.env.HOME || "";
|
|
511
|
+
for (const configPath of getAntigravityMcpConfigPaths()) {
|
|
512
|
+
const config = readJsonConfig(configPath);
|
|
513
|
+
if (hasCompleteJsonTypegraphRegistration(config, "typegraph-mcp", projectRoot)) {
|
|
514
|
+
return configPath.replace(home, "~");
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
481
519
|
function readProjectPackageJson(projectRoot) {
|
|
482
520
|
const packageJsonPath = path3.resolve(projectRoot, "package.json");
|
|
483
521
|
if (!fs2.existsSync(packageJsonPath)) return null;
|
|
@@ -611,6 +649,7 @@ async function main(configOverride) {
|
|
|
611
649
|
encoding: "utf-8"
|
|
612
650
|
});
|
|
613
651
|
const hasGlobalCodexRegistration = codexGet.status === 0;
|
|
652
|
+
const antigravityRegistrationPath = findAntigravityRegistration(projectRoot);
|
|
614
653
|
if (process.env.CLAUDE_PLUGIN_ROOT) {
|
|
615
654
|
pass("MCP registered via plugin (CLAUDE_PLUGIN_ROOT set)");
|
|
616
655
|
} else if (hasPluginMcp) {
|
|
@@ -647,6 +686,8 @@ async function main(configOverride) {
|
|
|
647
686
|
}
|
|
648
687
|
} else if (hasGlobalCodexRegistration) {
|
|
649
688
|
pass("MCP registered in global Codex CLI config");
|
|
689
|
+
} else if (antigravityRegistrationPath !== null) {
|
|
690
|
+
pass(`MCP registered in Antigravity config (${antigravityRegistrationPath})`);
|
|
650
691
|
} else {
|
|
651
692
|
const codexConfigPath = path3.resolve(projectRoot, ".codex/config.toml");
|
|
652
693
|
const mcpJsonPath = path3.resolve(projectRoot, ".claude/mcp.json");
|
package/dist/cli.js
CHANGED
|
@@ -485,6 +485,44 @@ function hasTrustedCodexProject(projectRoot3) {
|
|
|
485
485
|
}
|
|
486
486
|
return matchesTrustedProject();
|
|
487
487
|
}
|
|
488
|
+
function hasCompleteJsonTypegraphRegistration(config, serverName, projectRoot3) {
|
|
489
|
+
if (typeof config !== "object" || config === null) return false;
|
|
490
|
+
const servers = config["mcpServers"];
|
|
491
|
+
if (typeof servers !== "object" || servers === null) return false;
|
|
492
|
+
const entry = servers[serverName];
|
|
493
|
+
if (typeof entry !== "object" || entry === null) return false;
|
|
494
|
+
const record = entry;
|
|
495
|
+
const command2 = record["command"];
|
|
496
|
+
const args2 = record["args"];
|
|
497
|
+
const env = record["env"];
|
|
498
|
+
const serializedArgs = JSON.stringify(args2 ?? []);
|
|
499
|
+
return typeof command2 === "string" && command2.length > 0 && Array.isArray(args2) && serializedArgs.includes("server.ts") && serializedArgs.includes("tsx") && typeof env === "object" && env !== null && env["TYPEGRAPH_PROJECT_ROOT"] === projectRoot3 && typeof env["TYPEGRAPH_TSCONFIG"] === "string";
|
|
500
|
+
}
|
|
501
|
+
function readJsonConfig(configPath) {
|
|
502
|
+
if (!fs2.existsSync(configPath)) return null;
|
|
503
|
+
try {
|
|
504
|
+
return JSON.parse(fs2.readFileSync(configPath, "utf-8"));
|
|
505
|
+
} catch {
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
function getAntigravityMcpConfigPaths() {
|
|
510
|
+
const home = process.env.HOME || "";
|
|
511
|
+
return [
|
|
512
|
+
path3.join(home, ".gemini/antigravity/mcp_config.json"),
|
|
513
|
+
path3.join(home, ".gemini/antigravity-cli/plugins/typegraph-mcp/mcp_config.json")
|
|
514
|
+
];
|
|
515
|
+
}
|
|
516
|
+
function findAntigravityRegistration(projectRoot3) {
|
|
517
|
+
const home = process.env.HOME || "";
|
|
518
|
+
for (const configPath of getAntigravityMcpConfigPaths()) {
|
|
519
|
+
const config = readJsonConfig(configPath);
|
|
520
|
+
if (hasCompleteJsonTypegraphRegistration(config, "typegraph-mcp", projectRoot3)) {
|
|
521
|
+
return configPath.replace(home, "~");
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
488
526
|
function readProjectPackageJson(projectRoot3) {
|
|
489
527
|
const packageJsonPath = path3.resolve(projectRoot3, "package.json");
|
|
490
528
|
if (!fs2.existsSync(packageJsonPath)) return null;
|
|
@@ -605,6 +643,7 @@ async function main(configOverride) {
|
|
|
605
643
|
encoding: "utf-8"
|
|
606
644
|
});
|
|
607
645
|
const hasGlobalCodexRegistration = codexGet.status === 0;
|
|
646
|
+
const antigravityRegistrationPath = findAntigravityRegistration(projectRoot3);
|
|
608
647
|
if (process.env.CLAUDE_PLUGIN_ROOT) {
|
|
609
648
|
pass("MCP registered via plugin (CLAUDE_PLUGIN_ROOT set)");
|
|
610
649
|
} else if (hasPluginMcp) {
|
|
@@ -641,6 +680,8 @@ async function main(configOverride) {
|
|
|
641
680
|
}
|
|
642
681
|
} else if (hasGlobalCodexRegistration) {
|
|
643
682
|
pass("MCP registered in global Codex CLI config");
|
|
683
|
+
} else if (antigravityRegistrationPath !== null) {
|
|
684
|
+
pass(`MCP registered in Antigravity config (${antigravityRegistrationPath})`);
|
|
644
685
|
} else {
|
|
645
686
|
const codexConfigPath = path3.resolve(projectRoot3, ".codex/config.toml");
|
|
646
687
|
const mcpJsonPath = path3.resolve(projectRoot3, ".claude/mcp.json");
|
|
@@ -3217,7 +3258,7 @@ Practical rule:
|
|
|
3217
3258
|
var SNIPPET_MARKER = "## TypeScript Navigation (typegraph-mcp)";
|
|
3218
3259
|
var CLAUDE_NODE_PLACEHOLDER = "__TYPEGRAPH_NODE__";
|
|
3219
3260
|
var PLUGIN_DIR_NAME = "plugins/typegraph-mcp";
|
|
3220
|
-
var AGENT_IDS = ["claude-code", "cursor", "codex", "gemini", "copilot"];
|
|
3261
|
+
var AGENT_IDS = ["claude-code", "cursor", "codex", "gemini", "copilot", "antigravity"];
|
|
3221
3262
|
var AGENTS = {
|
|
3222
3263
|
"claude-code": {
|
|
3223
3264
|
name: "Claude Code",
|
|
@@ -3261,6 +3302,13 @@ var AGENTS = {
|
|
|
3261
3302
|
agentFile: ".github/copilot-instructions.md",
|
|
3262
3303
|
needsAgentsSkills: true,
|
|
3263
3304
|
detect: (root) => fs8.existsSync(path9.join(root, ".github/copilot-instructions.md"))
|
|
3305
|
+
},
|
|
3306
|
+
antigravity: {
|
|
3307
|
+
name: "Antigravity",
|
|
3308
|
+
pluginFiles: [],
|
|
3309
|
+
agentFile: "AGENTS.md",
|
|
3310
|
+
needsAgentsSkills: true,
|
|
3311
|
+
detect: (root) => fs8.existsSync(path9.join(root, ".gemini/antigravity"))
|
|
3264
3312
|
}
|
|
3265
3313
|
};
|
|
3266
3314
|
var CORE_FILES = [
|
|
@@ -3346,6 +3394,33 @@ function getCodexMcpServerEntry(projectRoot3) {
|
|
|
3346
3394
|
function getCodexConfigPath(projectRoot3) {
|
|
3347
3395
|
return path9.resolve(projectRoot3, ".codex/config.toml");
|
|
3348
3396
|
}
|
|
3397
|
+
function getAntigravityMcpConfigPaths2() {
|
|
3398
|
+
const home = process.env.HOME || "";
|
|
3399
|
+
return [
|
|
3400
|
+
path9.join(home, ".gemini/antigravity/mcp_config.json"),
|
|
3401
|
+
path9.join(home, ".gemini/antigravity-cli/plugins/typegraph-mcp/mcp_config.json")
|
|
3402
|
+
];
|
|
3403
|
+
}
|
|
3404
|
+
function ensureAntigravityCliPlugin() {
|
|
3405
|
+
const home = process.env.HOME || "";
|
|
3406
|
+
const pluginDir = path9.join(home, ".gemini/antigravity-cli/plugins/typegraph-mcp");
|
|
3407
|
+
const pluginJsonPath = path9.join(pluginDir, "plugin.json");
|
|
3408
|
+
if (!fs8.existsSync(pluginJsonPath)) {
|
|
3409
|
+
fs8.mkdirSync(pluginDir, { recursive: true });
|
|
3410
|
+
fs8.writeFileSync(
|
|
3411
|
+
pluginJsonPath,
|
|
3412
|
+
JSON.stringify(
|
|
3413
|
+
{
|
|
3414
|
+
name: "typegraph-mcp",
|
|
3415
|
+
version: "1.0.0",
|
|
3416
|
+
description: "TypeGraph MCP server for TypeScript navigation"
|
|
3417
|
+
},
|
|
3418
|
+
null,
|
|
3419
|
+
2
|
|
3420
|
+
) + "\n"
|
|
3421
|
+
);
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3349
3424
|
function isTomlSectionGroup(sectionName, prefix) {
|
|
3350
3425
|
return sectionName === prefix || sectionName?.startsWith(`${prefix}.`) === true;
|
|
3351
3426
|
}
|
|
@@ -3519,11 +3594,15 @@ function registerMcpServers(projectRoot3, selectedAgents) {
|
|
|
3519
3594
|
if (selectedAgents.includes("copilot")) {
|
|
3520
3595
|
registerJsonMcp(projectRoot3, ".vscode/mcp.json", "servers");
|
|
3521
3596
|
}
|
|
3597
|
+
if (selectedAgents.includes("antigravity")) {
|
|
3598
|
+
registerAntigravityMcp(projectRoot3);
|
|
3599
|
+
}
|
|
3522
3600
|
}
|
|
3523
3601
|
function deregisterMcpServers(projectRoot3) {
|
|
3524
3602
|
deregisterJsonMcp(projectRoot3, ".cursor/mcp.json", "mcpServers");
|
|
3525
3603
|
deregisterCodexMcp(projectRoot3);
|
|
3526
3604
|
deregisterJsonMcp(projectRoot3, ".vscode/mcp.json", "servers");
|
|
3605
|
+
deregisterAntigravityMcp(projectRoot3);
|
|
3527
3606
|
}
|
|
3528
3607
|
function registerJsonMcp(projectRoot3, configPath, rootKey) {
|
|
3529
3608
|
const fullPath = path9.resolve(projectRoot3, configPath);
|
|
@@ -3609,6 +3688,64 @@ function deregisterCodexMcp(projectRoot3) {
|
|
|
3609
3688
|
}
|
|
3610
3689
|
}
|
|
3611
3690
|
}
|
|
3691
|
+
function registerAntigravityMcp(projectRoot3) {
|
|
3692
|
+
const home = process.env.HOME || "";
|
|
3693
|
+
const pluginDir = path9.resolve(projectRoot3, PLUGIN_DIR_NAME);
|
|
3694
|
+
const tsConfigPath = path9.resolve(projectRoot3, "tsconfig.json");
|
|
3695
|
+
ensureAntigravityCliPlugin();
|
|
3696
|
+
const entry = {
|
|
3697
|
+
command: process.execPath,
|
|
3698
|
+
args: [
|
|
3699
|
+
path9.join(pluginDir, "node_modules/tsx/dist/cli.mjs"),
|
|
3700
|
+
path9.join(pluginDir, "server.ts")
|
|
3701
|
+
],
|
|
3702
|
+
env: {
|
|
3703
|
+
TYPEGRAPH_PROJECT_ROOT: projectRoot3,
|
|
3704
|
+
TYPEGRAPH_TSCONFIG: tsConfigPath
|
|
3705
|
+
}
|
|
3706
|
+
};
|
|
3707
|
+
for (const configPath of getAntigravityMcpConfigPaths2()) {
|
|
3708
|
+
let config = { mcpServers: {} };
|
|
3709
|
+
if (fs8.existsSync(configPath)) {
|
|
3710
|
+
try {
|
|
3711
|
+
config = JSON.parse(fs8.readFileSync(configPath, "utf-8"));
|
|
3712
|
+
} catch {
|
|
3713
|
+
p.log.warn(`Could not parse ~${configPath.replace(home, "")} \u2014 skipping MCP registration`);
|
|
3714
|
+
continue;
|
|
3715
|
+
}
|
|
3716
|
+
}
|
|
3717
|
+
if (!config.mcpServers) config.mcpServers = {};
|
|
3718
|
+
config.mcpServers["typegraph-mcp"] = entry;
|
|
3719
|
+
const dir = path9.dirname(configPath);
|
|
3720
|
+
if (!fs8.existsSync(dir)) {
|
|
3721
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
3722
|
+
}
|
|
3723
|
+
fs8.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
3724
|
+
p.log.success(`~${configPath.replace(home, "")}: registered typegraph-mcp server`);
|
|
3725
|
+
}
|
|
3726
|
+
}
|
|
3727
|
+
function deregisterAntigravityMcp(projectRoot3) {
|
|
3728
|
+
const home = process.env.HOME || "";
|
|
3729
|
+
for (const configPath of getAntigravityMcpConfigPaths2()) {
|
|
3730
|
+
if (!fs8.existsSync(configPath)) continue;
|
|
3731
|
+
try {
|
|
3732
|
+
const config = JSON.parse(fs8.readFileSync(configPath, "utf-8"));
|
|
3733
|
+
if (config.mcpServers && config.mcpServers["typegraph-mcp"]) {
|
|
3734
|
+
delete config.mcpServers["typegraph-mcp"];
|
|
3735
|
+
if (Object.keys(config.mcpServers).length === 0) {
|
|
3736
|
+
delete config.mcpServers;
|
|
3737
|
+
}
|
|
3738
|
+
if (Object.keys(config).length === 0) {
|
|
3739
|
+
fs8.unlinkSync(configPath);
|
|
3740
|
+
} else {
|
|
3741
|
+
fs8.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
3742
|
+
}
|
|
3743
|
+
p.log.info(`~${configPath.replace(home, "")}: removed typegraph-mcp server`);
|
|
3744
|
+
}
|
|
3745
|
+
} catch {
|
|
3746
|
+
}
|
|
3747
|
+
}
|
|
3748
|
+
}
|
|
3612
3749
|
function ensureTsconfigExclude(projectRoot3) {
|
|
3613
3750
|
const tsconfigPath3 = path9.resolve(projectRoot3, "tsconfig.json");
|
|
3614
3751
|
if (!fs8.existsSync(tsconfigPath3)) return;
|
|
@@ -3831,7 +3968,7 @@ async function setup(yes2) {
|
|
|
3831
3968
|
}
|
|
3832
3969
|
}
|
|
3833
3970
|
const selectedAgents = await selectAgents(projectRoot3, yes2);
|
|
3834
|
-
const needsPluginSkills = selectedAgents.includes("claude-code") || selectedAgents.includes("cursor");
|
|
3971
|
+
const needsPluginSkills = selectedAgents.includes("claude-code") || selectedAgents.includes("cursor") || selectedAgents.includes("antigravity");
|
|
3835
3972
|
const needsAgentsSkills = selectedAgents.some((id) => AGENTS[id].needsAgentsSkills);
|
|
3836
3973
|
p.log.step(`Installing to ${PLUGIN_DIR_NAME}/...`);
|
|
3837
3974
|
const s = p.spinner();
|
package/install-oxlint-test.ts
CHANGED
|
@@ -22,13 +22,14 @@ function copyDir(src: string, dest: string): void {
|
|
|
22
22
|
function runTsx(
|
|
23
23
|
toolRoot: string,
|
|
24
24
|
args: string[],
|
|
25
|
-
cwd: string
|
|
25
|
+
cwd: string,
|
|
26
|
+
env: NodeJS.ProcessEnv = process.env
|
|
26
27
|
): string {
|
|
27
28
|
return execFileSync(path.join(toolRoot, "node_modules/.bin/tsx"), args, {
|
|
28
29
|
cwd,
|
|
29
30
|
encoding: "utf-8",
|
|
30
31
|
maxBuffer: 10 * 1024 * 1024,
|
|
31
|
-
env
|
|
32
|
+
env,
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -44,6 +45,7 @@ async function main(): Promise<void> {
|
|
|
44
45
|
const fixtureRoot = path.join(repoRoot, ".fixtures/install-oxlint");
|
|
45
46
|
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "typegraph-install-oxlint-"));
|
|
46
47
|
const projectRoot = path.join(tempRoot, "project");
|
|
48
|
+
const homeRoot = path.join(tempRoot, "home");
|
|
47
49
|
|
|
48
50
|
copyDir(fixtureRoot, projectRoot);
|
|
49
51
|
fs.mkdirSync(path.join(projectRoot, "node_modules"), { recursive: true });
|
|
@@ -54,7 +56,14 @@ async function main(): Promise<void> {
|
|
|
54
56
|
);
|
|
55
57
|
|
|
56
58
|
try {
|
|
57
|
-
|
|
59
|
+
fs.mkdirSync(homeRoot, { recursive: true });
|
|
60
|
+
const testEnv = { ...process.env, HOME: homeRoot };
|
|
61
|
+
const setupOutput = runTsx(
|
|
62
|
+
repoRoot,
|
|
63
|
+
[path.join(repoRoot, "cli.ts"), "setup", "--yes"],
|
|
64
|
+
projectRoot,
|
|
65
|
+
testEnv
|
|
66
|
+
);
|
|
58
67
|
const pluginRoot = path.join(projectRoot, "plugins/typegraph-mcp");
|
|
59
68
|
|
|
60
69
|
const tsconfig = fs.readFileSync(path.join(projectRoot, "tsconfig.json"), "utf-8");
|
|
@@ -70,7 +79,12 @@ async function main(): Promise<void> {
|
|
|
70
79
|
assertIncludes(setupOutput, 'Added "plugins/**" to .oxlintrc.json ignorePatterns');
|
|
71
80
|
assertIncludes(setupOutput, "Oxlint ignores plugins/ (.oxlintrc.json)");
|
|
72
81
|
|
|
73
|
-
const checkOutput = runTsx(
|
|
82
|
+
const checkOutput = runTsx(
|
|
83
|
+
pluginRoot,
|
|
84
|
+
[path.join(pluginRoot, "cli.ts"), "check"],
|
|
85
|
+
projectRoot,
|
|
86
|
+
testEnv
|
|
87
|
+
);
|
|
74
88
|
assertIncludes(checkOutput, "Oxlint ignores plugins/ (.oxlintrc.json)");
|
|
75
89
|
assert.ok(
|
|
76
90
|
!checkOutput.includes("Lint config check (no ESLint or Oxlint config found)"),
|