mcp-garry-codes 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +133 -0
- package/dist/config/env.d.ts +4 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +27 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/schema.d.ts +28 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +12 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/contracts/common.d.ts +53 -0
- package/dist/contracts/common.d.ts.map +1 -0
- package/dist/contracts/common.js +30 -0
- package/dist/contracts/common.js.map +1 -0
- package/dist/contracts/linter_contracts.d.ts +79 -0
- package/dist/contracts/linter_contracts.d.ts.map +1 -0
- package/dist/contracts/linter_contracts.js +16 -0
- package/dist/contracts/linter_contracts.js.map +1 -0
- package/dist/contracts/scaffold_contracts.d.ts +84 -0
- package/dist/contracts/scaffold_contracts.d.ts.map +1 -0
- package/dist/contracts/scaffold_contracts.js +27 -0
- package/dist/contracts/scaffold_contracts.js.map +1 -0
- package/dist/contracts/security_contracts.d.ts +37 -0
- package/dist/contracts/security_contracts.d.ts.map +1 -0
- package/dist/contracts/security_contracts.js +6 -0
- package/dist/contracts/security_contracts.js.map +1 -0
- package/dist/contracts/test_contracts.d.ts +42 -0
- package/dist/contracts/test_contracts.d.ts.map +1 -0
- package/dist/contracts/test_contracts.js +10 -0
- package/dist/contracts/test_contracts.js.map +1 -0
- package/dist/contracts/wiki_contracts.d.ts +96 -0
- package/dist/contracts/wiki_contracts.d.ts.map +1 -0
- package/dist/contracts/wiki_contracts.js +17 -0
- package/dist/contracts/wiki_contracts.js.map +1 -0
- package/dist/core/cache.d.ts +9 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +56 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/errors.d.ts +37 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +52 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/file_utils.d.ts +13 -0
- package/dist/core/file_utils.d.ts.map +1 -0
- package/dist/core/file_utils.js +90 -0
- package/dist/core/file_utils.js.map +1 -0
- package/dist/core/logger.d.ts +18 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +46 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/process_runner.d.ts +15 -0
- package/dist/core/process_runner.d.ts.map +1 -0
- package/dist/core/process_runner.js +64 -0
- package/dist/core/process_runner.js.map +1 -0
- package/dist/domain/glua/ast.d.ts +12 -0
- package/dist/domain/glua/ast.d.ts.map +1 -0
- package/dist/domain/glua/ast.js +176 -0
- package/dist/domain/glua/ast.js.map +1 -0
- package/dist/domain/glua/lexer.d.ts +42 -0
- package/dist/domain/glua/lexer.d.ts.map +1 -0
- package/dist/domain/glua/lexer.js +232 -0
- package/dist/domain/glua/lexer.js.map +1 -0
- package/dist/domain/networking/net_auditor.d.ts +5 -0
- package/dist/domain/networking/net_auditor.d.ts.map +1 -0
- package/dist/domain/networking/net_auditor.js +188 -0
- package/dist/domain/networking/net_auditor.js.map +1 -0
- package/dist/domain/packaging/validator.d.ts +5 -0
- package/dist/domain/packaging/validator.d.ts.map +1 -0
- package/dist/domain/packaging/validator.js +121 -0
- package/dist/domain/packaging/validator.js.map +1 -0
- package/dist/domain/performance/hot_path_analyzer.d.ts +5 -0
- package/dist/domain/performance/hot_path_analyzer.d.ts.map +1 -0
- package/dist/domain/performance/hot_path_analyzer.js +127 -0
- package/dist/domain/performance/hot_path_analyzer.js.map +1 -0
- package/dist/domain/scaffolding/templates.d.ts +5 -0
- package/dist/domain/scaffolding/templates.d.ts.map +1 -0
- package/dist/domain/scaffolding/templates.js +219 -0
- package/dist/domain/scaffolding/templates.js.map +1 -0
- package/dist/domain/wiki/offline_db.d.ts +3 -0
- package/dist/domain/wiki/offline_db.d.ts.map +1 -0
- package/dist/domain/wiki/offline_db.js +534 -0
- package/dist/domain/wiki/offline_db.js.map +1 -0
- package/dist/domain/wiki/types.d.ts +29 -0
- package/dist/domain/wiki/types.d.ts.map +1 -0
- package/dist/domain/wiki/types.js +2 -0
- package/dist/domain/wiki/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/glualint_adapter.d.ts +6 -0
- package/dist/integrations/glualint_adapter.d.ts.map +1 -0
- package/dist/integrations/glualint_adapter.js +62 -0
- package/dist/integrations/glualint_adapter.js.map +1 -0
- package/dist/integrations/python_test_harness.d.ts +5 -0
- package/dist/integrations/python_test_harness.d.ts.map +1 -0
- package/dist/integrations/python_test_harness.js +67 -0
- package/dist/integrations/python_test_harness.js.map +1 -0
- package/dist/integrations/web_search_adapter.d.ts +6 -0
- package/dist/integrations/web_search_adapter.d.ts.map +1 -0
- package/dist/integrations/web_search_adapter.js +80 -0
- package/dist/integrations/web_search_adapter.js.map +1 -0
- package/dist/integrations/wiki_client.d.ts +13 -0
- package/dist/integrations/wiki_client.d.ts.map +1 -0
- package/dist/integrations/wiki_client.js +110 -0
- package/dist/integrations/wiki_client.js.map +1 -0
- package/dist/prompts/index.d.ts +73 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +127 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/realms_resources.d.ts +2 -0
- package/dist/resources/realms_resources.d.ts.map +1 -0
- package/dist/resources/realms_resources.js +30 -0
- package/dist/resources/realms_resources.js.map +1 -0
- package/dist/resources/schema_resources.d.ts +2 -0
- package/dist/resources/schema_resources.d.ts.map +1 -0
- package/dist/resources/schema_resources.js +43 -0
- package/dist/resources/schema_resources.js.map +1 -0
- package/dist/resources/wiki_resources.d.ts +3 -0
- package/dist/resources/wiki_resources.d.ts.map +1 -0
- package/dist/resources/wiki_resources.js +31 -0
- package/dist/resources/wiki_resources.js.map +1 -0
- package/dist/security/path_guard.d.ts +8 -0
- package/dist/security/path_guard.d.ts.map +1 -0
- package/dist/security/path_guard.js +37 -0
- package/dist/security/path_guard.js.map +1 -0
- package/dist/security/process_guard.d.ts +8 -0
- package/dist/security/process_guard.d.ts.map +1 -0
- package/dist/security/process_guard.js +26 -0
- package/dist/security/process_guard.js.map +1 -0
- package/dist/security/redaction.d.ts +6 -0
- package/dist/security/redaction.d.ts.map +1 -0
- package/dist/security/redaction.js +49 -0
- package/dist/security/redaction.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +364 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/analyze_performance.d.ts +4 -0
- package/dist/tools/analyze_performance.d.ts.map +1 -0
- package/dist/tools/analyze_performance.js +20 -0
- package/dist/tools/analyze_performance.js.map +1 -0
- package/dist/tools/audit_net_security.d.ts +4 -0
- package/dist/tools/audit_net_security.d.ts.map +1 -0
- package/dist/tools/audit_net_security.js +19 -0
- package/dist/tools/audit_net_security.js.map +1 -0
- package/dist/tools/get_gmod_symbol.d.ts +4 -0
- package/dist/tools/get_gmod_symbol.d.ts.map +1 -0
- package/dist/tools/get_gmod_symbol.js +30 -0
- package/dist/tools/get_gmod_symbol.js.map +1 -0
- package/dist/tools/lint_glua.d.ts +4 -0
- package/dist/tools/lint_glua.d.ts.map +1 -0
- package/dist/tools/lint_glua.js +24 -0
- package/dist/tools/lint_glua.js.map +1 -0
- package/dist/tools/package_and_validate.d.ts +4 -0
- package/dist/tools/package_and_validate.d.ts.map +1 -0
- package/dist/tools/package_and_validate.js +23 -0
- package/dist/tools/package_and_validate.js.map +1 -0
- package/dist/tools/run_glua_test.d.ts +4 -0
- package/dist/tools/run_glua_test.d.ts.map +1 -0
- package/dist/tools/run_glua_test.js +15 -0
- package/dist/tools/run_glua_test.js.map +1 -0
- package/dist/tools/scaffold_gmod_component.d.ts +4 -0
- package/dist/tools/scaffold_gmod_component.d.ts.map +1 -0
- package/dist/tools/scaffold_gmod_component.js +16 -0
- package/dist/tools/scaffold_gmod_component.js.map +1 -0
- package/dist/tools/search_gmod_wiki.d.ts +4 -0
- package/dist/tools/search_gmod_wiki.d.ts.map +1 -0
- package/dist/tools/search_gmod_wiki.js +30 -0
- package/dist/tools/search_gmod_wiki.js.map +1 -0
- package/dist/tools/web_search_glua.d.ts +4 -0
- package/dist/tools/web_search_glua.d.ts.map +1 -0
- package/dist/tools/web_search_glua.js +15 -0
- package/dist/tools/web_search_glua.js.map +1 -0
- package/package.json +58 -0
- package/src/test_harness/lua/glua_mock.lua +383 -0
- package/src/test_harness/python/gmod_tester.py +156 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const RunGLuaTestInputSchema: z.ZodEffects<z.ZodObject<{
|
|
3
|
+
test_file_path: z.ZodOptional<z.ZodString>;
|
|
4
|
+
code_to_test: z.ZodOptional<z.ZodString>;
|
|
5
|
+
mock_realm: z.ZodDefault<z.ZodEnum<["client", "server", "shared"]>>;
|
|
6
|
+
timeout_ms: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
mock_realm: "server" | "client" | "shared";
|
|
9
|
+
timeout_ms: number;
|
|
10
|
+
test_file_path?: string | undefined;
|
|
11
|
+
code_to_test?: string | undefined;
|
|
12
|
+
}, {
|
|
13
|
+
test_file_path?: string | undefined;
|
|
14
|
+
code_to_test?: string | undefined;
|
|
15
|
+
mock_realm?: "server" | "client" | "shared" | undefined;
|
|
16
|
+
timeout_ms?: number | undefined;
|
|
17
|
+
}>, {
|
|
18
|
+
mock_realm: "server" | "client" | "shared";
|
|
19
|
+
timeout_ms: number;
|
|
20
|
+
test_file_path?: string | undefined;
|
|
21
|
+
code_to_test?: string | undefined;
|
|
22
|
+
}, {
|
|
23
|
+
test_file_path?: string | undefined;
|
|
24
|
+
code_to_test?: string | undefined;
|
|
25
|
+
mock_realm?: "server" | "client" | "shared" | undefined;
|
|
26
|
+
timeout_ms?: number | undefined;
|
|
27
|
+
}>;
|
|
28
|
+
export type RunGLuaTestInput = z.infer<typeof RunGLuaTestInputSchema>;
|
|
29
|
+
export interface GLuaTestError {
|
|
30
|
+
test_name: string;
|
|
31
|
+
error_message: string;
|
|
32
|
+
stack_trace: string;
|
|
33
|
+
}
|
|
34
|
+
export interface RunGLuaTestOutput {
|
|
35
|
+
passed: boolean;
|
|
36
|
+
tests_run: number;
|
|
37
|
+
failures: number;
|
|
38
|
+
errors: GLuaTestError[];
|
|
39
|
+
output_log: string;
|
|
40
|
+
execution_time_ms: number;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=test_contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test_contracts.d.ts","sourceRoot":"","sources":["../../src/contracts/test_contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;EAOjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const RunGLuaTestInputSchema = z.object({
|
|
3
|
+
test_file_path: z.string().optional().describe("Workspace path to test script (Lua or Python)"),
|
|
4
|
+
code_to_test: z.string().optional().describe("Inline GLua test code with assertions"),
|
|
5
|
+
mock_realm: z.enum(["client", "server", "shared"]).default("shared").describe("Mock simulation realm"),
|
|
6
|
+
timeout_ms: z.number().int().min(500).max(30000).default(5000).describe("Maximum execution timeout in milliseconds")
|
|
7
|
+
}).refine(data => data.test_file_path || data.code_to_test, {
|
|
8
|
+
message: "Either test_file_path or code_to_test must be provided."
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=test_contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test_contracts.js","sourceRoot":"","sources":["../../src/contracts/test_contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;IAC/F,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;IACrF,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC;IACtG,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,2CAA2C,CAAC;CACrH,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,YAAY,EAAE;IAC1D,OAAO,EAAE,yDAAyD;CACnE,CAAC,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const SearchGModWikiInputSchema: z.ZodObject<{
|
|
3
|
+
query: z.ZodString;
|
|
4
|
+
category: z.ZodDefault<z.ZodEnum<["functions", "hooks", "libraries", "panels", "enums", "all"]>>;
|
|
5
|
+
realm: z.ZodDefault<z.ZodEnum<["server", "client", "shared", "menu", "all"]>>;
|
|
6
|
+
max_results: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
query: string;
|
|
9
|
+
category: "functions" | "hooks" | "libraries" | "panels" | "enums" | "all";
|
|
10
|
+
realm: "all" | "server" | "client" | "shared" | "menu";
|
|
11
|
+
max_results: number;
|
|
12
|
+
}, {
|
|
13
|
+
query: string;
|
|
14
|
+
category?: "functions" | "hooks" | "libraries" | "panels" | "enums" | "all" | undefined;
|
|
15
|
+
realm?: "all" | "server" | "client" | "shared" | "menu" | undefined;
|
|
16
|
+
max_results?: number | undefined;
|
|
17
|
+
}>;
|
|
18
|
+
export type SearchGModWikiInput = z.infer<typeof SearchGModWikiInputSchema>;
|
|
19
|
+
export interface WikiSearchResultItem {
|
|
20
|
+
title: string;
|
|
21
|
+
url: string;
|
|
22
|
+
realm: "server" | "client" | "shared" | "menu";
|
|
23
|
+
summary: string;
|
|
24
|
+
signature: string;
|
|
25
|
+
category: string;
|
|
26
|
+
}
|
|
27
|
+
export interface SearchGModWikiOutput {
|
|
28
|
+
query: string;
|
|
29
|
+
category: string;
|
|
30
|
+
realm: string;
|
|
31
|
+
total_matches: number;
|
|
32
|
+
results: WikiSearchResultItem[];
|
|
33
|
+
}
|
|
34
|
+
export declare const GetGModSymbolInputSchema: z.ZodObject<{
|
|
35
|
+
symbol: z.ZodString;
|
|
36
|
+
include_examples: z.ZodDefault<z.ZodBoolean>;
|
|
37
|
+
}, "strip", z.ZodTypeAny, {
|
|
38
|
+
symbol: string;
|
|
39
|
+
include_examples: boolean;
|
|
40
|
+
}, {
|
|
41
|
+
symbol: string;
|
|
42
|
+
include_examples?: boolean | undefined;
|
|
43
|
+
}>;
|
|
44
|
+
export type GetGModSymbolInput = z.infer<typeof GetGModSymbolInputSchema>;
|
|
45
|
+
export interface SymbolArgument {
|
|
46
|
+
name: string;
|
|
47
|
+
type: string;
|
|
48
|
+
optional: boolean;
|
|
49
|
+
default?: string;
|
|
50
|
+
description: string;
|
|
51
|
+
}
|
|
52
|
+
export interface SymbolReturn {
|
|
53
|
+
name: string;
|
|
54
|
+
type: string;
|
|
55
|
+
description: string;
|
|
56
|
+
}
|
|
57
|
+
export interface SymbolExample {
|
|
58
|
+
title: string;
|
|
59
|
+
code: string;
|
|
60
|
+
}
|
|
61
|
+
export interface GetGModSymbolOutput {
|
|
62
|
+
symbol: string;
|
|
63
|
+
realm: "server" | "client" | "shared" | "menu";
|
|
64
|
+
description: string;
|
|
65
|
+
arguments: SymbolArgument[];
|
|
66
|
+
returns: SymbolReturn[];
|
|
67
|
+
examples: SymbolExample[];
|
|
68
|
+
notes: string[];
|
|
69
|
+
warnings: string[];
|
|
70
|
+
wiki_url: string;
|
|
71
|
+
}
|
|
72
|
+
export declare const WebSearchGLuaInputSchema: z.ZodObject<{
|
|
73
|
+
query: z.ZodString;
|
|
74
|
+
domain_filter: z.ZodDefault<z.ZodEnum<["github", "facepunch", "reddit", "steam", "all"]>>;
|
|
75
|
+
max_results: z.ZodDefault<z.ZodNumber>;
|
|
76
|
+
}, "strip", z.ZodTypeAny, {
|
|
77
|
+
query: string;
|
|
78
|
+
max_results: number;
|
|
79
|
+
domain_filter: "all" | "github" | "facepunch" | "reddit" | "steam";
|
|
80
|
+
}, {
|
|
81
|
+
query: string;
|
|
82
|
+
max_results?: number | undefined;
|
|
83
|
+
domain_filter?: "all" | "github" | "facepunch" | "reddit" | "steam" | undefined;
|
|
84
|
+
}>;
|
|
85
|
+
export type WebSearchGLuaInput = z.infer<typeof WebSearchGLuaInputSchema>;
|
|
86
|
+
export interface WebSearchResultItem {
|
|
87
|
+
title: string;
|
|
88
|
+
url: string;
|
|
89
|
+
snippet: string;
|
|
90
|
+
source: string;
|
|
91
|
+
}
|
|
92
|
+
export interface WebSearchGLuaOutput {
|
|
93
|
+
query: string;
|
|
94
|
+
results: WebSearchResultItem[];
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=wiki_contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki_contracts.d.ts","sourceRoot":"","sources":["../../src/contracts/wiki_contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;EAKpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC;AAED,eAAO,MAAM,wBAAwB;;;;;;;;;EAGnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,wBAAwB;;;;;;;;;;;;EAInC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const SearchGModWikiInputSchema = z.object({
|
|
3
|
+
query: z.string().min(1).describe("Search term (e.g. 'net.Receive', 'GM:PlayerInitialSpawn', 'DScrollPanel')"),
|
|
4
|
+
category: z.enum(["functions", "hooks", "libraries", "panels", "enums", "all"]).default("all").describe("Filter search by category"),
|
|
5
|
+
realm: z.enum(["server", "client", "shared", "menu", "all"]).default("all").describe("Filter by Garry's Mod execution realm"),
|
|
6
|
+
max_results: z.number().int().min(1).max(20).default(5).describe("Maximum number of results to return (1-20)")
|
|
7
|
+
});
|
|
8
|
+
export const GetGModSymbolInputSchema = z.object({
|
|
9
|
+
symbol: z.string().min(1).describe("Exact symbol name (e.g. 'surface.DrawPoly', 'Entity:TakeDamage', 'GM:CalcView')"),
|
|
10
|
+
include_examples: z.boolean().default(true).describe("Include official usage examples if available")
|
|
11
|
+
});
|
|
12
|
+
export const WebSearchGLuaInputSchema = z.object({
|
|
13
|
+
query: z.string().min(1).describe("Search query for community solutions, GitHub code, or GMod forums"),
|
|
14
|
+
domain_filter: z.enum(["github", "facepunch", "reddit", "steam", "all"]).default("all").describe("Target community platform"),
|
|
15
|
+
max_results: z.number().int().min(1).max(10).default(5).describe("Maximum number of search results (1-10)")
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=wiki_contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki_contracts.js","sourceRoot":"","sources":["../../src/contracts/wiki_contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,2EAA2E,CAAC;IAC9G,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IACpI,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,uCAAuC,CAAC;IAC7H,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,4CAA4C,CAAC;CAC/G,CAAC,CAAC;AAqBH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iFAAiF,CAAC;IACrH,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;CACrG,CAAC,CAAC;AAmCH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mEAAmE,CAAC;IACtG,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IAC7H,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,yCAAyC,CAAC;CAC5G,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class TTLCache {
|
|
2
|
+
private memoryCache;
|
|
3
|
+
private diskCacheDir?;
|
|
4
|
+
constructor(diskCacheDir?: string);
|
|
5
|
+
get<T>(key: string): Promise<T | null>;
|
|
6
|
+
set<T>(key: string, value: T, ttlMs: number): Promise<void>;
|
|
7
|
+
private sanitizeKey;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"AASA,qBAAa,QAAQ;IACnB,OAAO,CAAC,WAAW,CAA0C;IAC7D,OAAO,CAAC,YAAY,CAAC,CAAS;gBAElB,YAAY,CAAC,EAAE,MAAM;IAIpB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IA6BtC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBxE,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { logger } from "./logger.js";
|
|
4
|
+
export class TTLCache {
|
|
5
|
+
memoryCache = new Map();
|
|
6
|
+
diskCacheDir;
|
|
7
|
+
constructor(diskCacheDir) {
|
|
8
|
+
this.diskCacheDir = diskCacheDir;
|
|
9
|
+
}
|
|
10
|
+
async get(key) {
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
const mem = this.memoryCache.get(key);
|
|
13
|
+
if (mem) {
|
|
14
|
+
if (mem.expiresAt > now) {
|
|
15
|
+
return mem.value;
|
|
16
|
+
}
|
|
17
|
+
this.memoryCache.delete(key);
|
|
18
|
+
}
|
|
19
|
+
if (this.diskCacheDir) {
|
|
20
|
+
try {
|
|
21
|
+
const filePath = path.join(this.diskCacheDir, `${this.sanitizeKey(key)}.json`);
|
|
22
|
+
const data = await fs.readFile(filePath, "utf-8");
|
|
23
|
+
const entry = JSON.parse(data);
|
|
24
|
+
if (entry.expiresAt > now) {
|
|
25
|
+
// Re-populate memory
|
|
26
|
+
this.memoryCache.set(key, entry);
|
|
27
|
+
return entry.value;
|
|
28
|
+
}
|
|
29
|
+
await fs.unlink(filePath).catch(() => { });
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Disk cache miss or read error
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
async set(key, value, ttlMs) {
|
|
38
|
+
const expiresAt = Date.now() + ttlMs;
|
|
39
|
+
const entry = { value, expiresAt };
|
|
40
|
+
this.memoryCache.set(key, entry);
|
|
41
|
+
if (this.diskCacheDir) {
|
|
42
|
+
try {
|
|
43
|
+
await fs.mkdir(this.diskCacheDir, { recursive: true });
|
|
44
|
+
const filePath = path.join(this.diskCacheDir, `${this.sanitizeKey(key)}.json`);
|
|
45
|
+
await fs.writeFile(filePath, JSON.stringify(entry), "utf-8");
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
logger.warn(`Failed to write disk cache for key '${key}':`, { error: String(err) });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
sanitizeKey(key) {
|
|
53
|
+
return key.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standardized Error Codes and Error Hierarchy for mcp-garry-codes.
|
|
3
|
+
*/
|
|
4
|
+
export declare enum GModErrorCode {
|
|
5
|
+
INVALID_ARGUMENT = "INVALID_ARGUMENT",
|
|
6
|
+
SCHEMA_VALIDATION_FAILED = "SCHEMA_VALIDATION_FAILED",
|
|
7
|
+
PATH_JAIL_VIOLATION = "PATH_JAIL_VIOLATION",
|
|
8
|
+
COMMAND_INJECTION_DETECTED = "COMMAND_INJECTION_DETECTED",
|
|
9
|
+
UNSAFE_OPERATION = "UNSAFE_OPERATION",
|
|
10
|
+
CREDENTIAL_EXPOSURE_RISK = "CREDENTIAL_EXPOSURE_RISK",
|
|
11
|
+
REALM_MISMATCH = "REALM_MISMATCH",
|
|
12
|
+
NETWORK_STRING_UNREGISTERED = "NETWORK_STRING_UNREGISTERED",
|
|
13
|
+
NET_MESSAGE_OVERFLOW = "NET_MESSAGE_OVERFLOW",
|
|
14
|
+
SYNTAX_ERROR = "SYNTAX_ERROR",
|
|
15
|
+
PARSER_FAILURE = "PARSER_FAILURE",
|
|
16
|
+
PROCESS_TIMEOUT = "PROCESS_TIMEOUT",
|
|
17
|
+
PROCESS_EXECUTION_FAILED = "PROCESS_EXECUTION_FAILED",
|
|
18
|
+
TOOL_NOT_FOUND = "TOOL_NOT_FOUND",
|
|
19
|
+
WIKI_FETCH_ERROR = "WIKI_FETCH_ERROR",
|
|
20
|
+
SYMBOL_NOT_FOUND = "SYMBOL_NOT_FOUND",
|
|
21
|
+
CACHE_ERROR = "CACHE_ERROR",
|
|
22
|
+
INTERNAL_ERROR = "INTERNAL_ERROR"
|
|
23
|
+
}
|
|
24
|
+
export interface GModErrorDetails {
|
|
25
|
+
code: GModErrorCode;
|
|
26
|
+
message: string;
|
|
27
|
+
remediation?: string;
|
|
28
|
+
context?: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
export declare class GModMCPError extends Error {
|
|
31
|
+
readonly code: GModErrorCode;
|
|
32
|
+
readonly remediation?: string;
|
|
33
|
+
readonly context?: Record<string, unknown>;
|
|
34
|
+
constructor(details: GModErrorDetails);
|
|
35
|
+
toJSON(): GModErrorDetails;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,oBAAY,aAAa;IAEvB,gBAAgB,qBAAqB;IACrC,wBAAwB,6BAA6B;IAGrD,mBAAmB,wBAAwB;IAC3C,0BAA0B,+BAA+B;IACzD,gBAAgB,qBAAqB;IACrC,wBAAwB,6BAA6B;IAGrD,cAAc,mBAAmB;IACjC,2BAA2B,gCAAgC;IAC3D,oBAAoB,yBAAyB;IAC7C,YAAY,iBAAiB;IAC7B,cAAc,mBAAmB;IAGjC,eAAe,oBAAoB;IACnC,wBAAwB,6BAA6B;IACrD,cAAc,mBAAmB;IAGjC,gBAAgB,qBAAqB;IACrC,gBAAgB,qBAAqB;IACrC,WAAW,gBAAgB;IAG3B,cAAc,mBAAmB;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,qBAAa,YAAa,SAAQ,KAAK;IACrC,SAAgB,IAAI,EAAE,aAAa,CAAC;IACpC,SAAgB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrC,SAAgB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAEtC,OAAO,EAAE,gBAAgB;IAS9B,MAAM,IAAI,gBAAgB;CAQlC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standardized Error Codes and Error Hierarchy for mcp-garry-codes.
|
|
3
|
+
*/
|
|
4
|
+
export var GModErrorCode;
|
|
5
|
+
(function (GModErrorCode) {
|
|
6
|
+
// Input & Contract Errors
|
|
7
|
+
GModErrorCode["INVALID_ARGUMENT"] = "INVALID_ARGUMENT";
|
|
8
|
+
GModErrorCode["SCHEMA_VALIDATION_FAILED"] = "SCHEMA_VALIDATION_FAILED";
|
|
9
|
+
// Security & Boundary Errors
|
|
10
|
+
GModErrorCode["PATH_JAIL_VIOLATION"] = "PATH_JAIL_VIOLATION";
|
|
11
|
+
GModErrorCode["COMMAND_INJECTION_DETECTED"] = "COMMAND_INJECTION_DETECTED";
|
|
12
|
+
GModErrorCode["UNSAFE_OPERATION"] = "UNSAFE_OPERATION";
|
|
13
|
+
GModErrorCode["CREDENTIAL_EXPOSURE_RISK"] = "CREDENTIAL_EXPOSURE_RISK";
|
|
14
|
+
// Garry's Mod Domain Errors
|
|
15
|
+
GModErrorCode["REALM_MISMATCH"] = "REALM_MISMATCH";
|
|
16
|
+
GModErrorCode["NETWORK_STRING_UNREGISTERED"] = "NETWORK_STRING_UNREGISTERED";
|
|
17
|
+
GModErrorCode["NET_MESSAGE_OVERFLOW"] = "NET_MESSAGE_OVERFLOW";
|
|
18
|
+
GModErrorCode["SYNTAX_ERROR"] = "SYNTAX_ERROR";
|
|
19
|
+
GModErrorCode["PARSER_FAILURE"] = "PARSER_FAILURE";
|
|
20
|
+
// Process & Subsystem Execution
|
|
21
|
+
GModErrorCode["PROCESS_TIMEOUT"] = "PROCESS_TIMEOUT";
|
|
22
|
+
GModErrorCode["PROCESS_EXECUTION_FAILED"] = "PROCESS_EXECUTION_FAILED";
|
|
23
|
+
GModErrorCode["TOOL_NOT_FOUND"] = "TOOL_NOT_FOUND";
|
|
24
|
+
// Wiki & Search
|
|
25
|
+
GModErrorCode["WIKI_FETCH_ERROR"] = "WIKI_FETCH_ERROR";
|
|
26
|
+
GModErrorCode["SYMBOL_NOT_FOUND"] = "SYMBOL_NOT_FOUND";
|
|
27
|
+
GModErrorCode["CACHE_ERROR"] = "CACHE_ERROR";
|
|
28
|
+
// General Internal
|
|
29
|
+
GModErrorCode["INTERNAL_ERROR"] = "INTERNAL_ERROR";
|
|
30
|
+
})(GModErrorCode || (GModErrorCode = {}));
|
|
31
|
+
export class GModMCPError extends Error {
|
|
32
|
+
code;
|
|
33
|
+
remediation;
|
|
34
|
+
context;
|
|
35
|
+
constructor(details) {
|
|
36
|
+
super(`[${details.code}] ${details.message}`);
|
|
37
|
+
this.name = "GModMCPError";
|
|
38
|
+
this.code = details.code;
|
|
39
|
+
this.remediation = details.remediation;
|
|
40
|
+
this.context = details.context;
|
|
41
|
+
Object.setPrototypeOf(this, GModMCPError.prototype);
|
|
42
|
+
}
|
|
43
|
+
toJSON() {
|
|
44
|
+
return {
|
|
45
|
+
code: this.code,
|
|
46
|
+
message: this.message,
|
|
47
|
+
remediation: this.remediation,
|
|
48
|
+
context: this.context
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAN,IAAY,aA8BX;AA9BD,WAAY,aAAa;IACvB,0BAA0B;IAC1B,sDAAqC,CAAA;IACrC,sEAAqD,CAAA;IAErD,6BAA6B;IAC7B,4DAA2C,CAAA;IAC3C,0EAAyD,CAAA;IACzD,sDAAqC,CAAA;IACrC,sEAAqD,CAAA;IAErD,4BAA4B;IAC5B,kDAAiC,CAAA;IACjC,4EAA2D,CAAA;IAC3D,8DAA6C,CAAA;IAC7C,8CAA6B,CAAA;IAC7B,kDAAiC,CAAA;IAEjC,gCAAgC;IAChC,oDAAmC,CAAA;IACnC,sEAAqD,CAAA;IACrD,kDAAiC,CAAA;IAEjC,gBAAgB;IAChB,sDAAqC,CAAA;IACrC,sDAAqC,CAAA;IACrC,4CAA2B,CAAA;IAE3B,mBAAmB;IACnB,kDAAiC,CAAA;AACnC,CAAC,EA9BW,aAAa,KAAb,aAAa,QA8BxB;AASD,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrB,IAAI,CAAgB;IACpB,WAAW,CAAU;IACrB,OAAO,CAA2B;IAElD,YAAY,OAAyB;QACnC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;IAEM,MAAM;QACX,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface FileEntry {
|
|
2
|
+
path: string;
|
|
3
|
+
relativePath: string;
|
|
4
|
+
sizeBytes: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class FileUtils {
|
|
7
|
+
static readFile(filePath: string, workspaceRoot?: string): Promise<string>;
|
|
8
|
+
static writeFile(filePath: string, content: string, workspaceRoot?: string): Promise<string>;
|
|
9
|
+
static fileExists(filePath: string, workspaceRoot?: string): Promise<boolean>;
|
|
10
|
+
static listLuaFiles(dirPath: string, workspaceRoot?: string): Promise<FileEntry[]>;
|
|
11
|
+
static listAllFiles(dirPath: string, workspaceRoot?: string): Promise<FileEntry[]>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=file_utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file_utils.d.ts","sourceRoot":"","sources":["../../src/core/file_utils.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,SAAS;WACA,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAKnE,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAQrF,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;WAUtE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;WAkC3E,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;CAgChG"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { PathGuard } from "../security/path_guard.js";
|
|
4
|
+
export class FileUtils {
|
|
5
|
+
static async readFile(filePath, workspaceRoot) {
|
|
6
|
+
const safePath = PathGuard.resolveSafePath(filePath, workspaceRoot);
|
|
7
|
+
return await fs.readFile(safePath, "utf-8");
|
|
8
|
+
}
|
|
9
|
+
static async writeFile(filePath, content, workspaceRoot) {
|
|
10
|
+
const safePath = PathGuard.resolveSafePath(filePath, workspaceRoot);
|
|
11
|
+
const dir = path.dirname(safePath);
|
|
12
|
+
await fs.mkdir(dir, { recursive: true });
|
|
13
|
+
await fs.writeFile(safePath, content, "utf-8");
|
|
14
|
+
return safePath;
|
|
15
|
+
}
|
|
16
|
+
static async fileExists(filePath, workspaceRoot) {
|
|
17
|
+
try {
|
|
18
|
+
const safePath = PathGuard.resolveSafePath(filePath, workspaceRoot);
|
|
19
|
+
const stat = await fs.stat(safePath);
|
|
20
|
+
return stat.isFile();
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
static async listLuaFiles(dirPath, workspaceRoot) {
|
|
27
|
+
const safeDir = PathGuard.resolveSafePath(dirPath, workspaceRoot);
|
|
28
|
+
const results = [];
|
|
29
|
+
async function walk(currentDir) {
|
|
30
|
+
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
33
|
+
if (entry.isDirectory()) {
|
|
34
|
+
// Skip node_modules, .git, and common cache dirs
|
|
35
|
+
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === ".cache") {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
await walk(fullPath);
|
|
39
|
+
}
|
|
40
|
+
else if (entry.isFile() && entry.name.endsWith(".lua")) {
|
|
41
|
+
const stat = await fs.stat(fullPath);
|
|
42
|
+
results.push({
|
|
43
|
+
path: fullPath,
|
|
44
|
+
relativePath: path.relative(safeDir, fullPath).replace(/\\/g, "/"),
|
|
45
|
+
sizeBytes: stat.size
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
await walk(safeDir);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// directory might not exist yet
|
|
55
|
+
}
|
|
56
|
+
return results;
|
|
57
|
+
}
|
|
58
|
+
static async listAllFiles(dirPath, workspaceRoot) {
|
|
59
|
+
const safeDir = PathGuard.resolveSafePath(dirPath, workspaceRoot);
|
|
60
|
+
const results = [];
|
|
61
|
+
async function walk(currentDir) {
|
|
62
|
+
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
63
|
+
for (const entry of entries) {
|
|
64
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
65
|
+
if (entry.isDirectory()) {
|
|
66
|
+
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === ".cache") {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
await walk(fullPath);
|
|
70
|
+
}
|
|
71
|
+
else if (entry.isFile()) {
|
|
72
|
+
const stat = await fs.stat(fullPath);
|
|
73
|
+
results.push({
|
|
74
|
+
path: fullPath,
|
|
75
|
+
relativePath: path.relative(safeDir, fullPath).replace(/\\/g, "/"),
|
|
76
|
+
sizeBytes: stat.size
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
await walk(safeDir);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// ignore missing
|
|
86
|
+
}
|
|
87
|
+
return results;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=file_utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file_utils.js","sourceRoot":"","sources":["../../src/core/file_utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured Logger for mcp-garry-codes.
|
|
3
|
+
* CRITICAL: All logs MUST go to process.stderr. process.stdout is strictly reserved for MCP JSON-RPC messages.
|
|
4
|
+
*/
|
|
5
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
6
|
+
declare class Logger {
|
|
7
|
+
private level;
|
|
8
|
+
setLevel(level: LogLevel): void;
|
|
9
|
+
private shouldLog;
|
|
10
|
+
private formatMessage;
|
|
11
|
+
debug(message: string, meta?: Record<string, unknown>): void;
|
|
12
|
+
info(message: string, meta?: Record<string, unknown>): void;
|
|
13
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
14
|
+
error(message: string, meta?: Record<string, unknown>): void;
|
|
15
|
+
}
|
|
16
|
+
export declare const logger: Logger;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAS3D,cAAM,MAAM;IACV,OAAO,CAAC,KAAK,CAAoB;IAE1B,QAAQ,CAAC,KAAK,EAAE,QAAQ;IAI/B,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,aAAa;IAMd,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAMrD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAMpD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAMpD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAK7D;AAED,eAAO,MAAM,MAAM,QAAe,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured Logger for mcp-garry-codes.
|
|
3
|
+
* CRITICAL: All logs MUST go to process.stderr. process.stdout is strictly reserved for MCP JSON-RPC messages.
|
|
4
|
+
*/
|
|
5
|
+
const LEVEL_SEVERITY = {
|
|
6
|
+
debug: 0,
|
|
7
|
+
info: 1,
|
|
8
|
+
warn: 2,
|
|
9
|
+
error: 3
|
|
10
|
+
};
|
|
11
|
+
class Logger {
|
|
12
|
+
level = "info";
|
|
13
|
+
setLevel(level) {
|
|
14
|
+
this.level = level;
|
|
15
|
+
}
|
|
16
|
+
shouldLog(level) {
|
|
17
|
+
return LEVEL_SEVERITY[level] >= LEVEL_SEVERITY[this.level];
|
|
18
|
+
}
|
|
19
|
+
formatMessage(level, message, meta) {
|
|
20
|
+
const timestamp = new Date().toISOString();
|
|
21
|
+
const metaStr = meta && Object.keys(meta).length > 0 ? ` ${JSON.stringify(meta)}` : "";
|
|
22
|
+
return `[${timestamp}] [${level.toUpperCase()}] [mcp-garry-codes] ${message}${metaStr}\n`;
|
|
23
|
+
}
|
|
24
|
+
debug(message, meta) {
|
|
25
|
+
if (this.shouldLog("debug")) {
|
|
26
|
+
process.stderr.write(this.formatMessage("debug", message, meta));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
info(message, meta) {
|
|
30
|
+
if (this.shouldLog("info")) {
|
|
31
|
+
process.stderr.write(this.formatMessage("info", message, meta));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
warn(message, meta) {
|
|
35
|
+
if (this.shouldLog("warn")) {
|
|
36
|
+
process.stderr.write(this.formatMessage("warn", message, meta));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
error(message, meta) {
|
|
40
|
+
if (this.shouldLog("error")) {
|
|
41
|
+
process.stderr.write(this.formatMessage("error", message, meta));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export const logger = new Logger();
|
|
46
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,cAAc,GAA6B;IAC/C,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,MAAM,MAAM;IACF,KAAK,GAAa,MAAM,CAAC;IAE1B,QAAQ,CAAC,KAAe;QAC7B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAEO,SAAS,CAAC,KAAe;QAC/B,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC;IAEO,aAAa,CAAC,KAAe,EAAE,OAAe,EAAE,IAA8B;QACpF,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,OAAO,IAAI,SAAS,MAAM,KAAK,CAAC,WAAW,EAAE,uBAAuB,OAAO,GAAG,OAAO,IAAI,CAAC;IAC5F,CAAC;IAEM,KAAK,CAAC,OAAe,EAAE,IAA8B;QAC1D,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAEM,IAAI,CAAC,OAAe,EAAE,IAA8B;QACzD,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAEM,IAAI,CAAC,OAAe,EAAE,IAA8B;QACzD,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,OAAe,EAAE,IAA8B;QAC1D,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface ProcessRunOptions {
|
|
2
|
+
cwd?: string;
|
|
3
|
+
timeoutMs?: number;
|
|
4
|
+
env?: Record<string, string>;
|
|
5
|
+
maxBuffer?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface ProcessRunResult {
|
|
8
|
+
stdout: string;
|
|
9
|
+
stderr: string;
|
|
10
|
+
exitCode: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class ProcessRunner {
|
|
13
|
+
static execute(binary: string, args: string[], options?: ProcessRunOptions): Promise<ProcessRunResult>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=process_runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process_runner.d.ts","sourceRoot":"","sources":["../../src/core/process_runner.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,aAAa;WACJ,OAAO,CACzB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC;CAqE7B"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { ProcessGuard } from "../security/process_guard.js";
|
|
4
|
+
import { GModErrorCode, GModMCPError } from "./errors.js";
|
|
5
|
+
import { logger } from "./logger.js";
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
export class ProcessRunner {
|
|
8
|
+
static async execute(binary, args, options) {
|
|
9
|
+
ProcessGuard.validateArgs(args);
|
|
10
|
+
const timeout = options?.timeoutMs ?? 10000;
|
|
11
|
+
const maxBuffer = options?.maxBuffer ?? 10 * 1024 * 1024; // 10MB buffer
|
|
12
|
+
logger.debug(`Executing subprocess: ${binary} ${args.join(" ")}`, {
|
|
13
|
+
binary,
|
|
14
|
+
args,
|
|
15
|
+
cwd: options?.cwd,
|
|
16
|
+
timeout
|
|
17
|
+
});
|
|
18
|
+
try {
|
|
19
|
+
const { stdout, stderr } = await execFileAsync(binary, args, {
|
|
20
|
+
cwd: options?.cwd,
|
|
21
|
+
timeout,
|
|
22
|
+
maxBuffer,
|
|
23
|
+
shell: false,
|
|
24
|
+
env: {
|
|
25
|
+
...process.env,
|
|
26
|
+
...(options?.env ?? {})
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
stdout: stdout.toString(),
|
|
31
|
+
stderr: stderr.toString(),
|
|
32
|
+
exitCode: 0
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
const error = err;
|
|
37
|
+
const stdout = error.stdout?.toString() ?? "";
|
|
38
|
+
const stderr = error.stderr?.toString() ?? "";
|
|
39
|
+
if (error.killed || error.signal === "SIGTERM") {
|
|
40
|
+
throw new GModMCPError({
|
|
41
|
+
code: GModErrorCode.PROCESS_TIMEOUT,
|
|
42
|
+
message: `Process '${binary}' timed out after ${timeout}ms.`,
|
|
43
|
+
remediation: "Increase timeout_ms or inspect the target script for infinite loops.",
|
|
44
|
+
context: { binary, timeout, stdout, stderr }
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
// If it returned a non-zero exit code, return the result so caller can inspect linter/test errors
|
|
48
|
+
if (typeof error.code === "number") {
|
|
49
|
+
return {
|
|
50
|
+
stdout,
|
|
51
|
+
stderr,
|
|
52
|
+
exitCode: error.code
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
throw new GModMCPError({
|
|
56
|
+
code: GModErrorCode.PROCESS_EXECUTION_FAILED,
|
|
57
|
+
message: `Failed to execute binary '${binary}': ${error.message ?? String(err)}`,
|
|
58
|
+
remediation: `Verify that '${binary}' is installed and present in your system PATH or environment configuration.`,
|
|
59
|
+
context: { binary, args }
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=process_runner.js.map
|