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.
Files changed (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +133 -0
  3. package/dist/config/env.d.ts +4 -0
  4. package/dist/config/env.d.ts.map +1 -0
  5. package/dist/config/env.js +27 -0
  6. package/dist/config/env.js.map +1 -0
  7. package/dist/config/schema.d.ts +28 -0
  8. package/dist/config/schema.d.ts.map +1 -0
  9. package/dist/config/schema.js +12 -0
  10. package/dist/config/schema.js.map +1 -0
  11. package/dist/contracts/common.d.ts +53 -0
  12. package/dist/contracts/common.d.ts.map +1 -0
  13. package/dist/contracts/common.js +30 -0
  14. package/dist/contracts/common.js.map +1 -0
  15. package/dist/contracts/linter_contracts.d.ts +79 -0
  16. package/dist/contracts/linter_contracts.d.ts.map +1 -0
  17. package/dist/contracts/linter_contracts.js +16 -0
  18. package/dist/contracts/linter_contracts.js.map +1 -0
  19. package/dist/contracts/scaffold_contracts.d.ts +84 -0
  20. package/dist/contracts/scaffold_contracts.d.ts.map +1 -0
  21. package/dist/contracts/scaffold_contracts.js +27 -0
  22. package/dist/contracts/scaffold_contracts.js.map +1 -0
  23. package/dist/contracts/security_contracts.d.ts +37 -0
  24. package/dist/contracts/security_contracts.d.ts.map +1 -0
  25. package/dist/contracts/security_contracts.js +6 -0
  26. package/dist/contracts/security_contracts.js.map +1 -0
  27. package/dist/contracts/test_contracts.d.ts +42 -0
  28. package/dist/contracts/test_contracts.d.ts.map +1 -0
  29. package/dist/contracts/test_contracts.js +10 -0
  30. package/dist/contracts/test_contracts.js.map +1 -0
  31. package/dist/contracts/wiki_contracts.d.ts +96 -0
  32. package/dist/contracts/wiki_contracts.d.ts.map +1 -0
  33. package/dist/contracts/wiki_contracts.js +17 -0
  34. package/dist/contracts/wiki_contracts.js.map +1 -0
  35. package/dist/core/cache.d.ts +9 -0
  36. package/dist/core/cache.d.ts.map +1 -0
  37. package/dist/core/cache.js +56 -0
  38. package/dist/core/cache.js.map +1 -0
  39. package/dist/core/errors.d.ts +37 -0
  40. package/dist/core/errors.d.ts.map +1 -0
  41. package/dist/core/errors.js +52 -0
  42. package/dist/core/errors.js.map +1 -0
  43. package/dist/core/file_utils.d.ts +13 -0
  44. package/dist/core/file_utils.d.ts.map +1 -0
  45. package/dist/core/file_utils.js +90 -0
  46. package/dist/core/file_utils.js.map +1 -0
  47. package/dist/core/logger.d.ts +18 -0
  48. package/dist/core/logger.d.ts.map +1 -0
  49. package/dist/core/logger.js +46 -0
  50. package/dist/core/logger.js.map +1 -0
  51. package/dist/core/process_runner.d.ts +15 -0
  52. package/dist/core/process_runner.d.ts.map +1 -0
  53. package/dist/core/process_runner.js +64 -0
  54. package/dist/core/process_runner.js.map +1 -0
  55. package/dist/domain/glua/ast.d.ts +12 -0
  56. package/dist/domain/glua/ast.d.ts.map +1 -0
  57. package/dist/domain/glua/ast.js +176 -0
  58. package/dist/domain/glua/ast.js.map +1 -0
  59. package/dist/domain/glua/lexer.d.ts +42 -0
  60. package/dist/domain/glua/lexer.d.ts.map +1 -0
  61. package/dist/domain/glua/lexer.js +232 -0
  62. package/dist/domain/glua/lexer.js.map +1 -0
  63. package/dist/domain/networking/net_auditor.d.ts +5 -0
  64. package/dist/domain/networking/net_auditor.d.ts.map +1 -0
  65. package/dist/domain/networking/net_auditor.js +188 -0
  66. package/dist/domain/networking/net_auditor.js.map +1 -0
  67. package/dist/domain/packaging/validator.d.ts +5 -0
  68. package/dist/domain/packaging/validator.d.ts.map +1 -0
  69. package/dist/domain/packaging/validator.js +121 -0
  70. package/dist/domain/packaging/validator.js.map +1 -0
  71. package/dist/domain/performance/hot_path_analyzer.d.ts +5 -0
  72. package/dist/domain/performance/hot_path_analyzer.d.ts.map +1 -0
  73. package/dist/domain/performance/hot_path_analyzer.js +127 -0
  74. package/dist/domain/performance/hot_path_analyzer.js.map +1 -0
  75. package/dist/domain/scaffolding/templates.d.ts +5 -0
  76. package/dist/domain/scaffolding/templates.d.ts.map +1 -0
  77. package/dist/domain/scaffolding/templates.js +219 -0
  78. package/dist/domain/scaffolding/templates.js.map +1 -0
  79. package/dist/domain/wiki/offline_db.d.ts +3 -0
  80. package/dist/domain/wiki/offline_db.d.ts.map +1 -0
  81. package/dist/domain/wiki/offline_db.js +534 -0
  82. package/dist/domain/wiki/offline_db.js.map +1 -0
  83. package/dist/domain/wiki/types.d.ts +29 -0
  84. package/dist/domain/wiki/types.d.ts.map +1 -0
  85. package/dist/domain/wiki/types.js +2 -0
  86. package/dist/domain/wiki/types.js.map +1 -0
  87. package/dist/index.d.ts +3 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +28 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/integrations/glualint_adapter.d.ts +6 -0
  92. package/dist/integrations/glualint_adapter.d.ts.map +1 -0
  93. package/dist/integrations/glualint_adapter.js +62 -0
  94. package/dist/integrations/glualint_adapter.js.map +1 -0
  95. package/dist/integrations/python_test_harness.d.ts +5 -0
  96. package/dist/integrations/python_test_harness.d.ts.map +1 -0
  97. package/dist/integrations/python_test_harness.js +67 -0
  98. package/dist/integrations/python_test_harness.js.map +1 -0
  99. package/dist/integrations/web_search_adapter.d.ts +6 -0
  100. package/dist/integrations/web_search_adapter.d.ts.map +1 -0
  101. package/dist/integrations/web_search_adapter.js +80 -0
  102. package/dist/integrations/web_search_adapter.js.map +1 -0
  103. package/dist/integrations/wiki_client.d.ts +13 -0
  104. package/dist/integrations/wiki_client.d.ts.map +1 -0
  105. package/dist/integrations/wiki_client.js +110 -0
  106. package/dist/integrations/wiki_client.js.map +1 -0
  107. package/dist/prompts/index.d.ts +73 -0
  108. package/dist/prompts/index.d.ts.map +1 -0
  109. package/dist/prompts/index.js +127 -0
  110. package/dist/prompts/index.js.map +1 -0
  111. package/dist/resources/realms_resources.d.ts +2 -0
  112. package/dist/resources/realms_resources.d.ts.map +1 -0
  113. package/dist/resources/realms_resources.js +30 -0
  114. package/dist/resources/realms_resources.js.map +1 -0
  115. package/dist/resources/schema_resources.d.ts +2 -0
  116. package/dist/resources/schema_resources.d.ts.map +1 -0
  117. package/dist/resources/schema_resources.js +43 -0
  118. package/dist/resources/schema_resources.js.map +1 -0
  119. package/dist/resources/wiki_resources.d.ts +3 -0
  120. package/dist/resources/wiki_resources.d.ts.map +1 -0
  121. package/dist/resources/wiki_resources.js +31 -0
  122. package/dist/resources/wiki_resources.js.map +1 -0
  123. package/dist/security/path_guard.d.ts +8 -0
  124. package/dist/security/path_guard.d.ts.map +1 -0
  125. package/dist/security/path_guard.js +37 -0
  126. package/dist/security/path_guard.js.map +1 -0
  127. package/dist/security/process_guard.d.ts +8 -0
  128. package/dist/security/process_guard.d.ts.map +1 -0
  129. package/dist/security/process_guard.js +26 -0
  130. package/dist/security/process_guard.js.map +1 -0
  131. package/dist/security/redaction.d.ts +6 -0
  132. package/dist/security/redaction.d.ts.map +1 -0
  133. package/dist/security/redaction.js +49 -0
  134. package/dist/security/redaction.js.map +1 -0
  135. package/dist/server.d.ts +3 -0
  136. package/dist/server.d.ts.map +1 -0
  137. package/dist/server.js +364 -0
  138. package/dist/server.js.map +1 -0
  139. package/dist/tools/analyze_performance.d.ts +4 -0
  140. package/dist/tools/analyze_performance.d.ts.map +1 -0
  141. package/dist/tools/analyze_performance.js +20 -0
  142. package/dist/tools/analyze_performance.js.map +1 -0
  143. package/dist/tools/audit_net_security.d.ts +4 -0
  144. package/dist/tools/audit_net_security.d.ts.map +1 -0
  145. package/dist/tools/audit_net_security.js +19 -0
  146. package/dist/tools/audit_net_security.js.map +1 -0
  147. package/dist/tools/get_gmod_symbol.d.ts +4 -0
  148. package/dist/tools/get_gmod_symbol.d.ts.map +1 -0
  149. package/dist/tools/get_gmod_symbol.js +30 -0
  150. package/dist/tools/get_gmod_symbol.js.map +1 -0
  151. package/dist/tools/lint_glua.d.ts +4 -0
  152. package/dist/tools/lint_glua.d.ts.map +1 -0
  153. package/dist/tools/lint_glua.js +24 -0
  154. package/dist/tools/lint_glua.js.map +1 -0
  155. package/dist/tools/package_and_validate.d.ts +4 -0
  156. package/dist/tools/package_and_validate.d.ts.map +1 -0
  157. package/dist/tools/package_and_validate.js +23 -0
  158. package/dist/tools/package_and_validate.js.map +1 -0
  159. package/dist/tools/run_glua_test.d.ts +4 -0
  160. package/dist/tools/run_glua_test.d.ts.map +1 -0
  161. package/dist/tools/run_glua_test.js +15 -0
  162. package/dist/tools/run_glua_test.js.map +1 -0
  163. package/dist/tools/scaffold_gmod_component.d.ts +4 -0
  164. package/dist/tools/scaffold_gmod_component.d.ts.map +1 -0
  165. package/dist/tools/scaffold_gmod_component.js +16 -0
  166. package/dist/tools/scaffold_gmod_component.js.map +1 -0
  167. package/dist/tools/search_gmod_wiki.d.ts +4 -0
  168. package/dist/tools/search_gmod_wiki.d.ts.map +1 -0
  169. package/dist/tools/search_gmod_wiki.js +30 -0
  170. package/dist/tools/search_gmod_wiki.js.map +1 -0
  171. package/dist/tools/web_search_glua.d.ts +4 -0
  172. package/dist/tools/web_search_glua.d.ts.map +1 -0
  173. package/dist/tools/web_search_glua.js +15 -0
  174. package/dist/tools/web_search_glua.js.map +1 -0
  175. package/package.json +58 -0
  176. package/src/test_harness/lua/glua_mock.lua +383 -0
  177. package/src/test_harness/python/gmod_tester.py +156 -0
@@ -0,0 +1,62 @@
1
+ import { getConfig } from "../config/env.js";
2
+ import { ProcessRunner } from "../core/process_runner.js";
3
+ import { GLuaAnalyzer } from "../domain/glua/ast.js";
4
+ import { logger } from "../core/logger.js";
5
+ import fs from "node:fs/promises";
6
+ import path from "node:path";
7
+ import os from "node:os";
8
+ export class GLuaLintAdapter {
9
+ static async lint(code, realm = "shared", fixFormatting = false) {
10
+ const config = getConfig();
11
+ const binary = config.GLUALINT_PATH;
12
+ let externalDiagnostics = [];
13
+ let formattedCode = undefined;
14
+ if (binary) {
15
+ try {
16
+ const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "gmod_lint_"));
17
+ const tempFile = path.join(tempDir, "temp.lua");
18
+ await fs.writeFile(tempFile, code, "utf-8");
19
+ const args = ["--lint", tempFile];
20
+ if (fixFormatting) {
21
+ args.push("--fix");
22
+ }
23
+ const result = await ProcessRunner.execute(binary, args, { timeoutMs: 5000 });
24
+ // Parse glualint output lines: [file]:[line]:[col]: [message]
25
+ const lines = (result.stdout + "\n" + result.stderr).split("\n");
26
+ for (const line of lines) {
27
+ const match = line.match(/:(\d+):(\d+):\s*(.*)$/);
28
+ if (match) {
29
+ externalDiagnostics.push({
30
+ line: parseInt(match[1], 10),
31
+ column: parseInt(match[2], 10),
32
+ severity: line.toLowerCase().includes("warning") ? "warning" : "error",
33
+ code: "GLUALINT",
34
+ message: match[3].trim()
35
+ });
36
+ }
37
+ }
38
+ if (fixFormatting) {
39
+ formattedCode = await fs.readFile(tempFile, "utf-8");
40
+ }
41
+ await fs.rm(tempDir, { recursive: true, force: true }).catch(() => { });
42
+ }
43
+ catch (err) {
44
+ logger.warn("glualint execution failed, using embedded AST analyzer fallback:", { error: String(err) });
45
+ }
46
+ }
47
+ // Run embedded AST analysis
48
+ const internalDiagnostics = GLuaAnalyzer.analyze(code, realm);
49
+ const combinedDiagnostics = [...externalDiagnostics, ...internalDiagnostics];
50
+ const errorCount = combinedDiagnostics.filter(d => d.severity === "error").length;
51
+ const warningCount = combinedDiagnostics.filter(d => d.severity === "warning").length;
52
+ return {
53
+ valid: errorCount === 0,
54
+ error_count: errorCount,
55
+ warning_count: warningCount,
56
+ realm_detected: realm,
57
+ diagnostics: combinedDiagnostics,
58
+ formatted_code: formattedCode
59
+ };
60
+ }
61
+ }
62
+ //# sourceMappingURL=glualint_adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glualint_adapter.js","sourceRoot":"","sources":["../../src/integrations/glualint_adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { RunGLuaTestInput, RunGLuaTestOutput } from "../contracts/test_contracts.js";
2
+ export declare class PythonTestHarness {
3
+ static runTest(input: RunGLuaTestInput): Promise<RunGLuaTestOutput>;
4
+ }
5
+ //# sourceMappingURL=python_test_harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"python_test_harness.d.ts","sourceRoot":"","sources":["../../src/integrations/python_test_harness.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAQrF,qBAAa,iBAAiB;WACR,OAAO,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA8DjF"}
@@ -0,0 +1,67 @@
1
+ import { getConfig } from "../config/env.js";
2
+ import { ProcessRunner } from "../core/process_runner.js";
3
+ import { PathGuard } from "../security/path_guard.js";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ export class PythonTestHarness {
9
+ static async runTest(input) {
10
+ const config = getConfig();
11
+ const pythonBin = config.PYTHON_PATH;
12
+ // Resolve script path
13
+ const testerScript = path.resolve(__dirname, "..", "test_harness", "python", "gmod_tester.py");
14
+ let testFile = "";
15
+ if (input.test_file_path) {
16
+ testFile = PathGuard.resolveSafePath(input.test_file_path);
17
+ }
18
+ const args = [testerScript];
19
+ if (testFile) {
20
+ args.push(testFile);
21
+ }
22
+ else {
23
+ args.push("");
24
+ }
25
+ args.push(input.mock_realm ?? "shared");
26
+ try {
27
+ const processResult = await ProcessRunner.execute(pythonBin, args, {
28
+ timeoutMs: input.timeout_ms ?? 5000,
29
+ env: input.code_to_test ? { INLINE_GLUA: input.code_to_test } : undefined
30
+ });
31
+ // gmod_tester.py prints a JSON line
32
+ const lines = processResult.stdout.trim().split("\n");
33
+ const jsonLine = lines.find(l => l.startsWith("{") && l.endsWith("}"));
34
+ if (jsonLine) {
35
+ return JSON.parse(jsonLine);
36
+ }
37
+ return {
38
+ passed: processResult.exitCode === 0,
39
+ tests_run: 1,
40
+ failures: processResult.exitCode === 0 ? 0 : 1,
41
+ errors: processResult.exitCode === 0 ? [] : [{
42
+ test_name: "Execution Error",
43
+ error_message: processResult.stderr || processResult.stdout,
44
+ stack_trace: ""
45
+ }],
46
+ output_log: processResult.stdout + "\n" + processResult.stderr,
47
+ execution_time_ms: 50
48
+ };
49
+ }
50
+ catch (err) {
51
+ const errorMsg = String(err);
52
+ return {
53
+ passed: false,
54
+ tests_run: 1,
55
+ failures: 1,
56
+ errors: [{
57
+ test_name: "Harness Failure",
58
+ error_message: errorMsg,
59
+ stack_trace: ""
60
+ }],
61
+ output_log: errorMsg,
62
+ execution_time_ms: 0
63
+ };
64
+ }
65
+ }
66
+ }
67
+ //# sourceMappingURL=python_test_harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"python_test_harness.js","sourceRoot":"","sources":["../../src/integrations/python_test_harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,OAAO,iBAAiB;IACrB,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAuB;QACjD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC;QAErC,sBAAsB;QACtB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAE/F,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;YACzB,QAAQ,GAAG,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;QAC5B,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC,CAAC;QAExC,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE;gBACjE,SAAS,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;gBACnC,GAAG,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS;aAC1E,CAAC,CAAC;YAEH,oCAAoC;YACpC,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAEvE,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAsB,CAAC;YACnD,CAAC;YAED,OAAO;gBACL,MAAM,EAAE,aAAa,CAAC,QAAQ,KAAK,CAAC;gBACpC,SAAS,EAAE,CAAC;gBACZ,QAAQ,EAAE,aAAa,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9C,MAAM,EAAE,aAAa,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;wBAC3C,SAAS,EAAE,iBAAiB;wBAC5B,aAAa,EAAE,aAAa,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM;wBAC3D,WAAW,EAAE,EAAE;qBAChB,CAAC;gBACF,UAAU,EAAE,aAAa,CAAC,MAAM,GAAG,IAAI,GAAG,aAAa,CAAC,MAAM;gBAC9D,iBAAiB,EAAE,EAAE;aACtB,CAAC;QACJ,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,CAAC;gBACZ,QAAQ,EAAE,CAAC;gBACX,MAAM,EAAE,CAAC;wBACP,SAAS,EAAE,iBAAiB;wBAC5B,aAAa,EAAE,QAAQ;wBACvB,WAAW,EAAE,EAAE;qBAChB,CAAC;gBACF,UAAU,EAAE,QAAQ;gBACpB,iBAAiB,EAAE,CAAC;aACrB,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import { WebSearchResultItem } from "../contracts/wiki_contracts.js";
2
+ export declare class WebSearchAdapter {
3
+ static search(query: string, domainFilter?: "github" | "facepunch" | "reddit" | "steam" | "all", maxResults?: number): Promise<WebSearchResultItem[]>;
4
+ private static getFallbackResults;
5
+ }
6
+ //# sourceMappingURL=web_search_adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web_search_adapter.d.ts","sourceRoot":"","sources":["../../src/integrations/web_search_adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAGrE,qBAAa,gBAAgB;WACP,MAAM,CACxB,KAAK,EAAE,MAAM,EACb,YAAY,GAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAa,EACzE,UAAU,GAAE,MAAU,GACrB,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAqEjC,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAmBlC"}
@@ -0,0 +1,80 @@
1
+ import { logger } from "../core/logger.js";
2
+ export class WebSearchAdapter {
3
+ static async search(query, domainFilter = "all", maxResults = 5) {
4
+ let siteFilter = "";
5
+ if (domainFilter === "github") {
6
+ siteFilter = "site:github.com ";
7
+ }
8
+ else if (domainFilter === "facepunch") {
9
+ siteFilter = "site:wiki.facepunch.com OR site:forum.facepunch.com ";
10
+ }
11
+ else if (domainFilter === "reddit") {
12
+ siteFilter = "site:reddit.com/r/gmod ";
13
+ }
14
+ else if (domainFilter === "steam") {
15
+ siteFilter = "site:steamcommunity.com ";
16
+ }
17
+ const fullQuery = `garrys mod ${siteFilter}${query}`;
18
+ const url = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(fullQuery)}`;
19
+ try {
20
+ const controller = new AbortController();
21
+ const timeout = setTimeout(() => controller.abort(), 5000);
22
+ const response = await fetch(url, {
23
+ headers: {
24
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
25
+ },
26
+ signal: controller.signal
27
+ });
28
+ clearTimeout(timeout);
29
+ if (!response.ok) {
30
+ return this.getFallbackResults(query, domainFilter);
31
+ }
32
+ const html = await response.text();
33
+ const results = [];
34
+ // Parse DuckDuckGo search result links and snippets
35
+ const resultRegex = /<a class="result__url" href="([^"]+)">[\s\S]*?<a class="result__snippet[^>]*>([\s\S]*?)<\/a>/g;
36
+ let match;
37
+ while ((match = resultRegex.exec(html)) !== null && results.length < maxResults) {
38
+ const rawUrl = match[1].trim();
39
+ const snippet = match[2].replace(/<[^>]+>/g, "").trim();
40
+ // Decode DDG uddg param if present
41
+ let actualUrl = rawUrl;
42
+ const uddgMatch = rawUrl.match(/uddg=([^&]+)/);
43
+ if (uddgMatch) {
44
+ actualUrl = decodeURIComponent(uddgMatch[1]);
45
+ }
46
+ results.push({
47
+ title: `GMod Resource: ${query}`,
48
+ url: actualUrl,
49
+ snippet,
50
+ source: domainFilter === "all" ? "community" : domainFilter
51
+ });
52
+ }
53
+ if (results.length === 0) {
54
+ return this.getFallbackResults(query, domainFilter);
55
+ }
56
+ return results;
57
+ }
58
+ catch (err) {
59
+ logger.warn(`Web search request failed: ${String(err)}`);
60
+ return this.getFallbackResults(query, domainFilter);
61
+ }
62
+ }
63
+ static getFallbackResults(query, domainFilter) {
64
+ return [
65
+ {
66
+ title: `Facepunch Wiki & Community for '${query}'`,
67
+ url: `https://wiki.facepunch.com/gmod/?q=${encodeURIComponent(query)}`,
68
+ snippet: `Facepunch official documentation and developer references matching '${query}'.`,
69
+ source: domainFilter
70
+ },
71
+ {
72
+ title: `GitHub GLua Repositories for '${query}'`,
73
+ url: `https://github.com/search?q=garrysmod+${encodeURIComponent(query)}+language%3ALua`,
74
+ snippet: `Open source Garry's Mod addons, SWEPs, and gamemodes containing '${query}'.`,
75
+ source: "github"
76
+ }
77
+ ];
78
+ }
79
+ }
80
+ //# sourceMappingURL=web_search_adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web_search_adapter.js","sourceRoot":"","sources":["../../src/integrations/web_search_adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { WikiDocEntry } from "../domain/wiki/types.js";
2
+ export declare class WikiClient {
3
+ private cache;
4
+ constructor();
5
+ search(query: string, options?: {
6
+ category?: string;
7
+ realm?: string;
8
+ maxResults?: number;
9
+ }): Promise<WikiDocEntry[]>;
10
+ getSymbol(symbol: string): Promise<WikiDocEntry | null>;
11
+ private fetchLiveWiki;
12
+ }
13
+ //# sourceMappingURL=wiki_client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wiki_client.d.ts","sourceRoot":"","sources":["../../src/integrations/wiki_client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKvD,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAW;;IAMX,MAAM,CACjB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GACA,OAAO,CAAC,YAAY,EAAE,CAAC;IAyCb,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;YAgCtD,aAAa;CA0C5B"}
@@ -0,0 +1,110 @@
1
+ import { GMOD_OFFLINE_DOCS } from "../domain/wiki/offline_db.js";
2
+ import { TTLCache } from "../core/cache.js";
3
+ import { getConfig } from "../config/env.js";
4
+ import { logger } from "../core/logger.js";
5
+ export class WikiClient {
6
+ cache;
7
+ constructor() {
8
+ this.cache = new TTLCache(getConfig().WIKI_CACHE_DIR);
9
+ }
10
+ async search(query, options) {
11
+ const qLower = query.toLowerCase().trim();
12
+ const category = options?.category ?? "all";
13
+ const realm = options?.realm ?? "all";
14
+ const maxResults = options?.maxResults ?? 5;
15
+ // Filter offline database
16
+ const matches = GMOD_OFFLINE_DOCS.filter(doc => {
17
+ // Category filter
18
+ if (category !== "all" && doc.category !== category) {
19
+ return false;
20
+ }
21
+ // Realm filter
22
+ if (realm !== "all" && doc.realm !== realm && doc.realm !== "shared") {
23
+ return false;
24
+ }
25
+ // Keyword match
26
+ const symbolMatch = doc.symbol.toLowerCase().includes(qLower);
27
+ const nameMatch = doc.name.toLowerCase().includes(qLower);
28
+ const descMatch = doc.description.toLowerCase().includes(qLower);
29
+ return symbolMatch || nameMatch || descMatch;
30
+ });
31
+ // Score relevance: exact symbol matches first, then prefix, then fuzzy
32
+ matches.sort((a, b) => {
33
+ const aExact = a.symbol.toLowerCase() === qLower ? 100 : 0;
34
+ const bExact = b.symbol.toLowerCase() === qLower ? 100 : 0;
35
+ if (aExact !== bExact)
36
+ return bExact - aExact;
37
+ const aPrefix = a.symbol.toLowerCase().startsWith(qLower) ? 50 : 0;
38
+ const bPrefix = b.symbol.toLowerCase().startsWith(qLower) ? 50 : 0;
39
+ if (aPrefix !== bPrefix)
40
+ return bPrefix - aPrefix;
41
+ return a.symbol.localeCompare(b.symbol);
42
+ });
43
+ return matches.slice(0, maxResults);
44
+ }
45
+ async getSymbol(symbol) {
46
+ const normalized = symbol.trim().toLowerCase();
47
+ // Check offline DB first
48
+ const offlineMatch = GMOD_OFFLINE_DOCS.find(doc => doc.symbol.toLowerCase() === normalized || doc.name.toLowerCase() === normalized);
49
+ if (offlineMatch) {
50
+ return offlineMatch;
51
+ }
52
+ // Check cache
53
+ const cached = await this.cache.get(`symbol_${normalized}`);
54
+ if (cached) {
55
+ return cached;
56
+ }
57
+ // Try live fetch from Facepunch Wiki
58
+ try {
59
+ const live = await this.fetchLiveWiki(symbol);
60
+ if (live) {
61
+ // Cache for 24 hours
62
+ await this.cache.set(`symbol_${normalized}`, live, 24 * 60 * 60 * 1000);
63
+ return live;
64
+ }
65
+ }
66
+ catch (err) {
67
+ logger.warn(`Failed live wiki lookup for '${symbol}':`, { error: String(err) });
68
+ }
69
+ return null;
70
+ }
71
+ async fetchLiveWiki(symbol) {
72
+ const url = `https://wiki.facepunch.com/gmod/${encodeURIComponent(symbol)}`;
73
+ const controller = new AbortController();
74
+ const timeout = setTimeout(() => controller.abort(), 4000);
75
+ try {
76
+ const response = await fetch(url, {
77
+ headers: { "User-Agent": "mcp-garry-codes/1.0" },
78
+ signal: controller.signal
79
+ });
80
+ if (!response.ok) {
81
+ return null;
82
+ }
83
+ const text = await response.text();
84
+ // Basic HTML extraction for wiki title & description
85
+ const titleMatch = text.match(/<h1[^>]*>([^<]+)<\/h1>/i);
86
+ const descMatch = text.match(/<div class="description"[^>]*>([\s\S]*?)<\/div>/i) ||
87
+ text.match(/<p>([\s\S]*?)<\/p>/i);
88
+ const title = titleMatch ? titleMatch[1].trim() : symbol;
89
+ const desc = descMatch ? descMatch[1].replace(/<[^>]+>/g, "").trim() : "Facepunch Wiki documentation.";
90
+ return {
91
+ symbol: title,
92
+ name: title.split(/[:.]/).pop() ?? title,
93
+ category: title.includes(":") ? "hooks" : "functions",
94
+ realm: text.includes("client") ? (text.includes("server") ? "shared" : "client") : "server",
95
+ description: desc,
96
+ signature: `${title}()`,
97
+ arguments: [],
98
+ returns: [],
99
+ examples: [],
100
+ notes: [],
101
+ warnings: [],
102
+ wiki_url: url
103
+ };
104
+ }
105
+ finally {
106
+ clearTimeout(timeout);
107
+ }
108
+ }
109
+ }
110
+ //# sourceMappingURL=wiki_client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wiki_client.js","sourceRoot":"","sources":["../../src/integrations/wiki_client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ export declare const AUDIT_ADDON_PROMPT: {
2
+ name: string;
3
+ description: string;
4
+ arguments: {
5
+ name: string;
6
+ description: string;
7
+ required: boolean;
8
+ }[];
9
+ handler: (args?: Record<string, string>) => {
10
+ messages: {
11
+ role: "user";
12
+ content: {
13
+ type: "text";
14
+ text: string;
15
+ };
16
+ }[];
17
+ };
18
+ };
19
+ export declare const FIX_NET_EXPLOIT_PROMPT: {
20
+ name: string;
21
+ description: string;
22
+ arguments: {
23
+ name: string;
24
+ description: string;
25
+ required: boolean;
26
+ }[];
27
+ handler: (args?: Record<string, string>) => {
28
+ messages: {
29
+ role: "user";
30
+ content: {
31
+ type: "text";
32
+ text: string;
33
+ };
34
+ }[];
35
+ };
36
+ };
37
+ export declare const SCAFFOLD_SWEP_PROMPT: {
38
+ name: string;
39
+ description: string;
40
+ arguments: {
41
+ name: string;
42
+ description: string;
43
+ required: boolean;
44
+ }[];
45
+ handler: (args?: Record<string, string>) => {
46
+ messages: {
47
+ role: "user";
48
+ content: {
49
+ type: "text";
50
+ text: string;
51
+ };
52
+ }[];
53
+ };
54
+ };
55
+ export declare const BUILD_DERMA_MENU_PROMPT: {
56
+ name: string;
57
+ description: string;
58
+ arguments: {
59
+ name: string;
60
+ description: string;
61
+ required: boolean;
62
+ }[];
63
+ handler: (args?: Record<string, string>) => {
64
+ messages: {
65
+ role: "user";
66
+ content: {
67
+ type: "text";
68
+ text: string;
69
+ };
70
+ }[];
71
+ };
72
+ };
73
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB;;;;;;;;qBAUZ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;;;;;CAmBxC,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;qBAehB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;;;;;CAmBxC,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;qBAed,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;;;;;CAiBxC,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;qBAUjB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;;;;;CAiBxC,CAAC"}
@@ -0,0 +1,127 @@
1
+ export const AUDIT_ADDON_PROMPT = {
2
+ name: "audit_addon",
3
+ description: "Comprehensive security and performance audit workflow for a Garry's Mod addon.",
4
+ arguments: [
5
+ {
6
+ name: "addon_dir",
7
+ description: "Path to addon directory to audit (defaults to workspace)",
8
+ required: false
9
+ }
10
+ ],
11
+ handler: (args) => {
12
+ const dir = args?.addon_dir ?? "the current workspace";
13
+ return {
14
+ messages: [
15
+ {
16
+ role: "user",
17
+ content: {
18
+ type: "text",
19
+ text: `Please perform a comprehensive audit of ${dir}:
20
+ 1. Run 'audit_net_security' to check for unauthenticated net.Receive messages, SQL injections, and missing util.AddNetworkString.
21
+ 2. Run 'package_and_validate' to inspect addon.json, Steam Workshop compliance, and illegal file extensions.
22
+ 3. For all client/shared rendering scripts, run 'analyze_performance' to identify Zero-GC hot-path violations (allocations in HUDPaint/RenderScreenspaceEffects).
23
+ 4. Run 'lint_glua' across all files to detect realm mismatches and syntax errors.
24
+ 5. Provide a prioritized report of critical vulnerabilities and immediate fixes.`
25
+ }
26
+ }
27
+ ]
28
+ };
29
+ }
30
+ };
31
+ export const FIX_NET_EXPLOIT_PROMPT = {
32
+ name: "fix_net_exploit",
33
+ description: "Guided repair workflow for net message vulnerabilities.",
34
+ arguments: [
35
+ {
36
+ name: "message_name",
37
+ description: "Vulnerable net message identifier to repair",
38
+ required: true
39
+ },
40
+ {
41
+ name: "file_path",
42
+ description: "File containing the vulnerable handler",
43
+ required: true
44
+ }
45
+ ],
46
+ handler: (args) => {
47
+ return {
48
+ messages: [
49
+ {
50
+ role: "user",
51
+ content: {
52
+ type: "text",
53
+ text: `Repair the vulnerable net message '${args?.message_name}' in '${args?.file_path}':
54
+ 1. Read the code using your file view tool.
55
+ 2. Add server-side caller validation: check 'if not IsValid(ply) or not ply:IsAdmin() then return end'.
56
+ 3. Validate all payload inputs (lengths of net.ReadString, bounds on net.ReadUInt).
57
+ 4. Escape any SQL parameters using sql.SQLStr().
58
+ 5. Verify util.AddNetworkString('${args?.message_name}') is registered on the server.
59
+ 6. Verify fix using 'audit_net_security'.`
60
+ }
61
+ }
62
+ ]
63
+ };
64
+ }
65
+ };
66
+ export const SCAFFOLD_SWEP_PROMPT = {
67
+ name: "scaffold_swep",
68
+ description: "Scaffold a production-grade, predicted Garry's Mod weapon.",
69
+ arguments: [
70
+ {
71
+ name: "name",
72
+ description: "Identifier for weapon (e.g. 'weapon_laser_smg')",
73
+ required: true
74
+ },
75
+ {
76
+ name: "category",
77
+ description: "Spawnmenu category",
78
+ required: false
79
+ }
80
+ ],
81
+ handler: (args) => {
82
+ return {
83
+ messages: [
84
+ {
85
+ role: "user",
86
+ content: {
87
+ type: "text",
88
+ text: `Scaffold a custom SWEP named '${args?.name}' (Category: '${args?.category ?? "Custom"}'):
89
+ 1. Run 'scaffold_gmod_component' with component_type 'swep'.
90
+ 2. Ensure AddCSLuaFile() is properly placed.
91
+ 3. Configure primary fire with client-side prediction (effects/sounds) and server-side hit verification.
92
+ 4. Run 'lint_glua' on the resulting file to ensure zero syntax or realm errors.`
93
+ }
94
+ }
95
+ ]
96
+ };
97
+ }
98
+ };
99
+ export const BUILD_DERMA_MENU_PROMPT = {
100
+ name: "build_derma_menu",
101
+ description: "Construct a responsive, DPI-scaled Garry's Mod Derma VGUI menu.",
102
+ arguments: [
103
+ {
104
+ name: "menu_name",
105
+ description: "Panel class name (e.g. 'DStoreMenu')",
106
+ required: true
107
+ }
108
+ ],
109
+ handler: (args) => {
110
+ return {
111
+ messages: [
112
+ {
113
+ role: "user",
114
+ content: {
115
+ type: "text",
116
+ text: `Construct a custom Derma menu '${args?.menu_name}':
117
+ 1. Use 'scaffold_gmod_component' with component_type 'vgui_panel'.
118
+ 2. Use ScrW() and ScrH() ratios for responsive sizing.
119
+ 3. Ensure Paint functions use pre-allocated Color tables (Zero-GC rule).
120
+ 4. Register the panel via vgui.Register.`
121
+ }
122
+ }
123
+ ]
124
+ };
125
+ }
126
+ };
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,gFAAgF;IAC7F,SAAS,EAAE;QACT;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,0DAA0D;YACvE,QAAQ,EAAE,KAAK;SAChB;KACF;IACD,OAAO,EAAE,CAAC,IAA6B,EAAE,EAAE;QACzC,MAAM,GAAG,GAAG,IAAI,EAAE,SAAS,IAAI,uBAAuB,CAAC;QACvD,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,2CAA2C,GAAG;;;;;iFAKiB;qBACtE;iBACF;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,yDAAyD;IACtE,SAAS,EAAE;QACT;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,6CAA6C;YAC1D,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,wCAAwC;YACrD,QAAQ,EAAE,IAAI;SACf;KACF;IACD,OAAO,EAAE,CAAC,IAA6B,EAAE,EAAE;QACzC,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,sCAAsC,IAAI,EAAE,YAAY,SAAS,IAAI,EAAE,SAAS;;;;;mCAK/D,IAAI,EAAE,YAAY;0CACX;qBAC/B;iBACF;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,4DAA4D;IACzE,SAAS,EAAE;QACT;YACE,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,iDAAiD;YAC9D,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,oBAAoB;YACjC,QAAQ,EAAE,KAAK;SAChB;KACF;IACD,OAAO,EAAE,CAAC,IAA6B,EAAE,EAAE;QACzC,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,iCAAiC,IAAI,EAAE,IAAI,iBAAiB,IAAI,EAAE,QAAQ,IAAI,QAAQ;;;;gFAIxB;qBACrE;iBACF;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE,iEAAiE;IAC9E,SAAS,EAAE;QACT;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,sCAAsC;YACnD,QAAQ,EAAE,IAAI;SACf;KACF;IACD,OAAO,EAAE,CAAC,IAA6B,EAAE,EAAE;QACzC,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,kCAAkC,IAAI,EAAE,SAAS;;;;yCAI1B;qBAC9B;iBACF;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function getRealmsMatrixContent(): string;
2
+ //# sourceMappingURL=realms_resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realms_resources.d.ts","sourceRoot":"","sources":["../../src/resources/realms_resources.ts"],"names":[],"mappings":"AAAA,wBAAgB,sBAAsB,IAAI,MAAM,CAgC/C"}
@@ -0,0 +1,30 @@
1
+ export function getRealmsMatrixContent() {
2
+ return JSON.stringify({
3
+ description: "Garry's Mod Three-Realm Matrix and Rules",
4
+ realms: {
5
+ SERVER: {
6
+ authority: "Dedicated or P2P Host Server",
7
+ powers: ["Physics simulation", "Entity lifecycle authority", "sql.Query / MySQL", "Damage calculation", "util.AddNetworkString"],
8
+ restrictions: ["No VGUI/UI", "No LocalPlayer()", "No surface/draw rendering calls", "No Cam3D2D"],
9
+ distribution_requirement: "Must call AddCSLuaFile() to transmit client files to joining players."
10
+ },
11
+ CLIENT: {
12
+ authority: "Local Player Instance",
13
+ powers: ["HUDPaint (2D HUD)", "RenderScreenspaceEffects (Shaders)", "VGUI / Derma Windows", "LocalPlayer()", "Viewmodel / Camera positioning"],
14
+ restrictions: ["Zero authority over health, inventory, or physics", "Cannot call util.AddNetworkString", "Cannot call ply:Ban() / ply:Kick() directly"],
15
+ performance_mandate: "ZERO GC allocations in HUDPaint and render hooks (pre-allocate Color and Vector tables)."
16
+ },
17
+ SHARED: {
18
+ authority: "Executes simultaneously on both Server and Client",
19
+ scope: ["Weapons (lua/weapons/)", "Entities (lua/entities/)", "Predicted movement (SetupMove / Move)"],
20
+ prediction_rules: "Client predicts tracers/sounds; server validates bullet hit and ammo."
21
+ },
22
+ MENU: {
23
+ authority: "Main Menu Sandbox",
24
+ scope: ["Server browser", "Options menu", "Addon manager"],
25
+ restrictions: ["Runs outside any active map or game session."]
26
+ }
27
+ }
28
+ }, null, 2);
29
+ }
30
+ //# sourceMappingURL=realms_resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realms_resources.js","sourceRoot":"","sources":["../../src/resources/realms_resources.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,CAAC,SAAS,CACnB;QACE,WAAW,EAAE,0CAA0C;QACvD,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,SAAS,EAAE,8BAA8B;gBACzC,MAAM,EAAE,CAAC,oBAAoB,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,uBAAuB,CAAC;gBAChI,YAAY,EAAE,CAAC,YAAY,EAAE,kBAAkB,EAAE,iCAAiC,EAAE,YAAY,CAAC;gBACjG,wBAAwB,EAAE,uEAAuE;aAClG;YACD,MAAM,EAAE;gBACN,SAAS,EAAE,uBAAuB;gBAClC,MAAM,EAAE,CAAC,mBAAmB,EAAE,oCAAoC,EAAE,sBAAsB,EAAE,eAAe,EAAE,gCAAgC,CAAC;gBAC9I,YAAY,EAAE,CAAC,mDAAmD,EAAE,mCAAmC,EAAE,6CAA6C,CAAC;gBACvJ,mBAAmB,EAAE,0FAA0F;aAChH;YACD,MAAM,EAAE;gBACN,SAAS,EAAE,mDAAmD;gBAC9D,KAAK,EAAE,CAAC,wBAAwB,EAAE,0BAA0B,EAAE,uCAAuC,CAAC;gBACtG,gBAAgB,EAAE,uEAAuE;aAC1F;YACD,IAAI,EAAE;gBACJ,SAAS,EAAE,mBAAmB;gBAC9B,KAAK,EAAE,CAAC,gBAAgB,EAAE,cAAc,EAAE,eAAe,CAAC;gBAC1D,YAAY,EAAE,CAAC,8CAA8C,CAAC;aAC/D;SACF;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;AACJ,CAAC"}