@godot-mcp/control-plane 0.0.0 → 0.1.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 (156) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -2
  3. package/dist/audit/jsonlAuditSink.d.ts +33 -0
  4. package/dist/audit/jsonlAuditSink.d.ts.map +1 -0
  5. package/dist/audit/jsonlAuditSink.js +57 -0
  6. package/dist/audit/jsonlAuditSink.js.map +1 -0
  7. package/dist/audit/redact.d.ts +2 -0
  8. package/dist/audit/redact.d.ts.map +1 -0
  9. package/dist/audit/redact.js +44 -0
  10. package/dist/audit/redact.js.map +1 -0
  11. package/dist/auth/pairingDescriptor.d.ts +44 -0
  12. package/dist/auth/pairingDescriptor.d.ts.map +1 -0
  13. package/dist/auth/pairingDescriptor.js +91 -0
  14. package/dist/auth/pairingDescriptor.js.map +1 -0
  15. package/dist/auth/runtimeDirectory.d.ts +3 -0
  16. package/dist/auth/runtimeDirectory.d.ts.map +1 -0
  17. package/dist/auth/runtimeDirectory.js +30 -0
  18. package/dist/auth/runtimeDirectory.js.map +1 -0
  19. package/dist/auth/sessionCrypto.d.ts +18 -0
  20. package/dist/auth/sessionCrypto.d.ts.map +1 -0
  21. package/dist/auth/sessionCrypto.js +118 -0
  22. package/dist/auth/sessionCrypto.js.map +1 -0
  23. package/dist/editor/editorMutationService.d.ts +21 -0
  24. package/dist/editor/editorMutationService.d.ts.map +1 -0
  25. package/dist/editor/editorMutationService.js +120 -0
  26. package/dist/editor/editorMutationService.js.map +1 -0
  27. package/dist/editor/mutationLedger.d.ts +30 -0
  28. package/dist/editor/mutationLedger.d.ts.map +1 -0
  29. package/dist/editor/mutationLedger.js +133 -0
  30. package/dist/editor/mutationLedger.js.map +1 -0
  31. package/dist/errors.d.ts +12 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +23 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/evidence/evidenceStore.d.ts +63 -0
  36. package/dist/evidence/evidenceStore.d.ts.map +1 -0
  37. package/dist/evidence/evidenceStore.js +350 -0
  38. package/dist/evidence/evidenceStore.js.map +1 -0
  39. package/dist/extensions/extensionRegistry.d.ts +33 -0
  40. package/dist/extensions/extensionRegistry.d.ts.map +1 -0
  41. package/dist/extensions/extensionRegistry.js +37 -0
  42. package/dist/extensions/extensionRegistry.js.map +1 -0
  43. package/dist/help/coreHelp.d.ts +10 -0
  44. package/dist/help/coreHelp.d.ts.map +1 -0
  45. package/dist/help/coreHelp.js +82 -0
  46. package/dist/help/coreHelp.js.map +1 -0
  47. package/dist/index.d.ts +37 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +37 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/policy/authorize.d.ts +5 -0
  52. package/dist/policy/authorize.d.ts.map +1 -0
  53. package/dist/policy/authorize.js +19 -0
  54. package/dist/policy/authorize.js.map +1 -0
  55. package/dist/policy/capabilities.d.ts +36 -0
  56. package/dist/policy/capabilities.d.ts.map +1 -0
  57. package/dist/policy/capabilities.js +129 -0
  58. package/dist/policy/capabilities.js.map +1 -0
  59. package/dist/project/artifactStore.d.ts +32 -0
  60. package/dist/project/artifactStore.d.ts.map +1 -0
  61. package/dist/project/artifactStore.js +172 -0
  62. package/dist/project/artifactStore.js.map +1 -0
  63. package/dist/project/pathPolicy.d.ts +4 -0
  64. package/dist/project/pathPolicy.d.ts.map +1 -0
  65. package/dist/project/pathPolicy.js +74 -0
  66. package/dist/project/pathPolicy.js.map +1 -0
  67. package/dist/project/projectConfig.d.ts +10 -0
  68. package/dist/project/projectConfig.d.ts.map +1 -0
  69. package/dist/project/projectConfig.js +63 -0
  70. package/dist/project/projectConfig.js.map +1 -0
  71. package/dist/project/projectIdentity.d.ts +8 -0
  72. package/dist/project/projectIdentity.d.ts.map +1 -0
  73. package/dist/project/projectIdentity.js +58 -0
  74. package/dist/project/projectIdentity.js.map +1 -0
  75. package/dist/project/projectJobJournal.d.ts +49 -0
  76. package/dist/project/projectJobJournal.d.ts.map +1 -0
  77. package/dist/project/projectJobJournal.js +67 -0
  78. package/dist/project/projectJobJournal.js.map +1 -0
  79. package/dist/project/projectJobService.d.ts +52 -0
  80. package/dist/project/projectJobService.d.ts.map +1 -0
  81. package/dist/project/projectJobService.js +289 -0
  82. package/dist/project/projectJobService.js.map +1 -0
  83. package/dist/project/projectMutationService.d.ts +40 -0
  84. package/dist/project/projectMutationService.d.ts.map +1 -0
  85. package/dist/project/projectMutationService.js +145 -0
  86. package/dist/project/projectMutationService.js.map +1 -0
  87. package/dist/project/projectPreflight.d.ts +7 -0
  88. package/dist/project/projectPreflight.d.ts.map +1 -0
  89. package/dist/project/projectPreflight.js +50 -0
  90. package/dist/project/projectPreflight.js.map +1 -0
  91. package/dist/project/projectProcess.d.ts +40 -0
  92. package/dist/project/projectProcess.d.ts.map +1 -0
  93. package/dist/project/projectProcess.js +196 -0
  94. package/dist/project/projectProcess.js.map +1 -0
  95. package/dist/project/projectService.d.ts +20 -0
  96. package/dist/project/projectService.d.ts.map +1 -0
  97. package/dist/project/projectService.js +35 -0
  98. package/dist/project/projectService.js.map +1 -0
  99. package/dist/project/secureJournalFile.d.ts +3 -0
  100. package/dist/project/secureJournalFile.d.ts.map +1 -0
  101. package/dist/project/secureJournalFile.js +56 -0
  102. package/dist/project/secureJournalFile.js.map +1 -0
  103. package/dist/runtime/debugTokenStore.d.ts +41 -0
  104. package/dist/runtime/debugTokenStore.d.ts.map +1 -0
  105. package/dist/runtime/debugTokenStore.js +105 -0
  106. package/dist/runtime/debugTokenStore.js.map +1 -0
  107. package/dist/runtime/debuggerClient.d.ts +14 -0
  108. package/dist/runtime/debuggerClient.d.ts.map +1 -0
  109. package/dist/runtime/debuggerClient.js +21 -0
  110. package/dist/runtime/debuggerClient.js.map +1 -0
  111. package/dist/runtime/inputReceipt.d.ts +15 -0
  112. package/dist/runtime/inputReceipt.d.ts.map +1 -0
  113. package/dist/runtime/inputReceipt.js +36 -0
  114. package/dist/runtime/inputReceipt.js.map +1 -0
  115. package/dist/runtime/runtimeDescriptor.d.ts +50 -0
  116. package/dist/runtime/runtimeDescriptor.d.ts.map +1 -0
  117. package/dist/runtime/runtimeDescriptor.js +175 -0
  118. package/dist/runtime/runtimeDescriptor.js.map +1 -0
  119. package/dist/runtime/runtimeProcess.d.ts +39 -0
  120. package/dist/runtime/runtimeProcess.d.ts.map +1 -0
  121. package/dist/runtime/runtimeProcess.js +180 -0
  122. package/dist/runtime/runtimeProcess.js.map +1 -0
  123. package/dist/runtime/runtimeService.d.ts +130 -0
  124. package/dist/runtime/runtimeService.d.ts.map +1 -0
  125. package/dist/runtime/runtimeService.js +919 -0
  126. package/dist/runtime/runtimeService.js.map +1 -0
  127. package/dist/session/sessionService.d.ts +52 -0
  128. package/dist/session/sessionService.d.ts.map +1 -0
  129. package/dist/session/sessionService.js +72 -0
  130. package/dist/session/sessionService.js.map +1 -0
  131. package/dist/unsafe/unsafeFixtureAuthority.d.ts +27 -0
  132. package/dist/unsafe/unsafeFixtureAuthority.d.ts.map +1 -0
  133. package/dist/unsafe/unsafeFixtureAuthority.js +130 -0
  134. package/dist/unsafe/unsafeFixtureAuthority.js.map +1 -0
  135. package/dist/unsafe/unsafeFixtureProcess.d.ts +30 -0
  136. package/dist/unsafe/unsafeFixtureProcess.d.ts.map +1 -0
  137. package/dist/unsafe/unsafeFixtureProcess.js +119 -0
  138. package/dist/unsafe/unsafeFixtureProcess.js.map +1 -0
  139. package/dist/unsafe/unsafeFixtureService.d.ts +41 -0
  140. package/dist/unsafe/unsafeFixtureService.d.ts.map +1 -0
  141. package/dist/unsafe/unsafeFixtureService.js +162 -0
  142. package/dist/unsafe/unsafeFixtureService.js.map +1 -0
  143. package/dist/visual/pngComparison.d.ts +12 -0
  144. package/dist/visual/pngComparison.d.ts.map +1 -0
  145. package/dist/visual/pngComparison.js +136 -0
  146. package/dist/visual/pngComparison.js.map +1 -0
  147. package/dist/visual/scenarioService.d.ts +50 -0
  148. package/dist/visual/scenarioService.d.ts.map +1 -0
  149. package/dist/visual/scenarioService.js +421 -0
  150. package/dist/visual/scenarioService.js.map +1 -0
  151. package/dist/visual/visualService.d.ts +27 -0
  152. package/dist/visual/visualService.d.ts.map +1 -0
  153. package/dist/visual/visualService.js +70 -0
  154. package/dist/visual/visualService.js.map +1 -0
  155. package/package.json +26 -6
  156. package/index.js +0 -1
@@ -0,0 +1,56 @@
1
+ import { constants } from "node:fs";
2
+ import { lstat, mkdir, open, readFile, realpath } from "node:fs/promises";
3
+ import { dirname, join, sep } from "node:path";
4
+ async function assertSecureParent(path) {
5
+ const parent = dirname(path);
6
+ const marker = `${sep}.godot${sep}`;
7
+ const markerIndex = path.indexOf(marker);
8
+ if (markerIndex < 0) {
9
+ await mkdir(parent, { recursive: true, mode: 0o700 });
10
+ return;
11
+ }
12
+ let current = await realpath(path.slice(0, markerIndex));
13
+ const controlled = parent.slice(markerIndex + 1).split(sep).filter(Boolean);
14
+ for (const segment of controlled) {
15
+ current = join(current, segment);
16
+ let metadata = await lstat(current).catch(() => undefined);
17
+ if (!metadata) {
18
+ await mkdir(current, { mode: 0o700 });
19
+ metadata = await lstat(current);
20
+ }
21
+ if (metadata.isSymbolicLink() || !metadata.isDirectory())
22
+ throw new Error("Journal parent may not contain symbolic links");
23
+ }
24
+ }
25
+ export async function readSecureJournal(path, maxBytes) {
26
+ await assertSecureParent(path);
27
+ const metadata = await lstat(path).catch((error) => {
28
+ if (error.code === "ENOENT")
29
+ return undefined;
30
+ throw error;
31
+ });
32
+ if (!metadata)
33
+ return null;
34
+ if (metadata.isSymbolicLink() || !metadata.isFile())
35
+ throw new Error("Journal must be a regular non-symlink file");
36
+ if ((metadata.mode & 0o077) !== 0)
37
+ throw new Error("Journal permissions must be owner-only");
38
+ if (metadata.size > maxBytes)
39
+ throw new Error("Journal exceeds its byte limit");
40
+ return readFile(path, "utf8");
41
+ }
42
+ export async function appendSecureJournal(path, line) {
43
+ await assertSecureParent(path);
44
+ const existing = await lstat(path).catch(() => undefined);
45
+ if (existing && (existing.isSymbolicLink() || !existing.isFile() || (existing.mode & 0o077) !== 0)) {
46
+ throw new Error("Journal must remain an owner-only regular non-symlink file");
47
+ }
48
+ const handle = await open(path, constants.O_APPEND | constants.O_CREAT | constants.O_WRONLY | constants.O_NOFOLLOW, 0o600);
49
+ try {
50
+ await handle.writeFile(line, "utf8");
51
+ }
52
+ finally {
53
+ await handle.close();
54
+ }
55
+ }
56
+ //# sourceMappingURL=secureJournalFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secureJournalFile.js","sourceRoot":"","sources":["../../src/project/secureJournalFile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export interface DebugTokenIdentity {
2
+ runId: string;
3
+ generation: number;
4
+ debuggerGeneration: number;
5
+ stopSequence: number;
6
+ }
7
+ interface VariableRecord {
8
+ variablesReference: number;
9
+ depth: number;
10
+ }
11
+ export declare class DebugTokenStoreError extends Error {
12
+ readonly code = "STALE_HANDLE";
13
+ constructor(message: string);
14
+ }
15
+ export declare class DebugTokenStore {
16
+ private identity;
17
+ private readonly frames;
18
+ private readonly frameReferences;
19
+ private readonly variables;
20
+ private readonly maxFrames;
21
+ private readonly maxVariables;
22
+ private readonly maxDepth;
23
+ private variableEntries;
24
+ constructor(options?: {
25
+ maxFrames?: number;
26
+ maxVariables?: number;
27
+ maxDepth?: number;
28
+ });
29
+ bind(identity: DebugTokenIdentity): void;
30
+ issueFrame(frameId: number): string;
31
+ issueVariable(variablesReference: number, depth: number): string;
32
+ resolveFrame(token: string): number;
33
+ resolveVariable(token: string): VariableRecord;
34
+ consumeVariableEntries(count: number): void;
35
+ clear(): void;
36
+ private clearRecords;
37
+ private assertBound;
38
+ private createToken;
39
+ }
40
+ export {};
41
+ //# sourceMappingURL=debugTokenStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debugTokenStore.d.ts","sourceRoot":"","sources":["../../src/runtime/debugTokenStore.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,cAAc;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,kBAAkB;gBAEnB,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6B;IAC7D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqC;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,eAAe,CAAK;gBAEhB,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO;IAM1F,IAAI,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAMxC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAYnC,aAAa,CAAC,kBAAkB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAUhE,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAOnC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc;IAO9C,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAO3C,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;CAMpB"}
@@ -0,0 +1,105 @@
1
+ import { randomBytes } from "node:crypto";
2
+ export class DebugTokenStoreError extends Error {
3
+ code = "STALE_HANDLE";
4
+ constructor(message) {
5
+ super(message);
6
+ this.name = "DebugTokenStoreError";
7
+ }
8
+ }
9
+ export class DebugTokenStore {
10
+ identity = null;
11
+ frames = new Map();
12
+ frameReferences = new Map();
13
+ variables = new Map();
14
+ maxFrames;
15
+ maxVariables;
16
+ maxDepth;
17
+ variableEntries = 0;
18
+ constructor(options = {}) {
19
+ this.maxFrames = options.maxFrames ?? 64;
20
+ this.maxVariables = options.maxVariables ?? 2_048;
21
+ this.maxDepth = options.maxDepth ?? 8;
22
+ }
23
+ bind(identity) {
24
+ if (this.identity && sameIdentity(this.identity, identity))
25
+ return;
26
+ this.clearRecords();
27
+ this.identity = { ...identity };
28
+ }
29
+ issueFrame(frameId) {
30
+ this.assertBound();
31
+ if (!Number.isInteger(frameId) || frameId < 0)
32
+ throw new DebugTokenStoreError("Debugger frame identity is invalid");
33
+ const existing = this.frameReferences.get(frameId);
34
+ if (existing)
35
+ return existing;
36
+ if (this.frames.size >= this.maxFrames)
37
+ throw new DebugTokenStoreError("Debugger frame token limit exceeded");
38
+ const opaqueId = this.createToken("dft", this.frames, this.variables);
39
+ this.frames.set(opaqueId, frameId);
40
+ this.frameReferences.set(frameId, opaqueId);
41
+ return opaqueId;
42
+ }
43
+ issueVariable(variablesReference, depth) {
44
+ this.assertBound();
45
+ if (!Number.isInteger(variablesReference) || variablesReference < 1)
46
+ throw new DebugTokenStoreError("Debugger variable reference is invalid");
47
+ if (!Number.isInteger(depth) || depth < 1 || depth > this.maxDepth)
48
+ throw new DebugTokenStoreError("Debugger variable depth limit exceeded");
49
+ if (this.variables.size >= this.maxVariables)
50
+ throw new DebugTokenStoreError("Debugger variable token limit exceeded");
51
+ const token = this.createToken("dvt", this.frames, this.variables);
52
+ this.variables.set(token, { variablesReference, depth });
53
+ return token;
54
+ }
55
+ resolveFrame(token) {
56
+ this.assertBound();
57
+ const frameId = this.frames.get(token);
58
+ if (frameId === undefined)
59
+ throw new DebugTokenStoreError("Debugger frame token is stale or unknown");
60
+ return frameId;
61
+ }
62
+ resolveVariable(token) {
63
+ this.assertBound();
64
+ const record = this.variables.get(token);
65
+ if (!record)
66
+ throw new DebugTokenStoreError("Debugger variable token is stale or unknown");
67
+ return { ...record };
68
+ }
69
+ consumeVariableEntries(count) {
70
+ this.assertBound();
71
+ if (!Number.isInteger(count) || count < 0)
72
+ throw new DebugTokenStoreError("Debugger variable entry count is invalid");
73
+ if (this.variableEntries + count > this.maxVariables)
74
+ throw new DebugTokenStoreError("Debugger variable entry limit exceeded");
75
+ this.variableEntries += count;
76
+ }
77
+ clear() {
78
+ this.identity = null;
79
+ this.clearRecords();
80
+ }
81
+ clearRecords() {
82
+ this.frames.clear();
83
+ this.frameReferences.clear();
84
+ this.variables.clear();
85
+ this.variableEntries = 0;
86
+ }
87
+ assertBound() {
88
+ if (!this.identity)
89
+ throw new DebugTokenStoreError("Debugger tokens are not bound to a stopped runtime");
90
+ }
91
+ createToken(prefix, ...stores) {
92
+ for (;;) {
93
+ const opaqueId = `${prefix}_${randomBytes(32).toString("base64url")}`;
94
+ if (stores.every((store) => !store.has(opaqueId)))
95
+ return opaqueId;
96
+ }
97
+ }
98
+ }
99
+ function sameIdentity(left, right) {
100
+ return left.runId === right.runId &&
101
+ left.generation === right.generation &&
102
+ left.debuggerGeneration === right.debuggerGeneration &&
103
+ left.stopSequence === right.stopSequence;
104
+ }
105
+ //# sourceMappingURL=debugTokenStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debugTokenStore.js","sourceRoot":"","sources":["../../src/runtime/debugTokenStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export declare const AUTHENTICATED_DEBUGGER_COMMANDS: readonly ["disconnect", "setBreakpoints", "threads", "stackTrace", "scopes", "variables", "pause", "continue", "next", "stepIn"];
2
+ export type DebuggerCommand = (typeof AUTHENTICATED_DEBUGGER_COMMANDS)[number];
3
+ type DebuggerClientErrorCode = "INVALID_REQUEST" | "TIMEOUT" | "TRANSPORT_ERROR";
4
+ export declare class DebuggerClientError extends Error {
5
+ readonly code: DebuggerClientErrorCode;
6
+ constructor(code: DebuggerClientErrorCode, message: string);
7
+ }
8
+ export interface DebuggerStopEvent {
9
+ sequence: number;
10
+ reason: string;
11
+ body: Record<string, unknown>;
12
+ }
13
+ export {};
14
+ //# sourceMappingURL=debuggerClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debuggerClient.d.ts","sourceRoot":"","sources":["../../src/runtime/debuggerClient.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,+BAA+B,kIAWlC,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,+BAA+B,CAAC,CAAC,MAAM,CAAC,CAAC;AAC/E,KAAK,uBAAuB,GAAG,iBAAiB,GAAG,SAAS,GAAG,iBAAiB,CAAC;AAEjF,qBAAa,mBAAoB,SAAQ,KAAK;IAChC,QAAQ,CAAC,IAAI,EAAE,uBAAuB;gBAA7B,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,MAAM;CAIpE;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B"}
@@ -0,0 +1,21 @@
1
+ export const AUTHENTICATED_DEBUGGER_COMMANDS = [
2
+ "disconnect",
3
+ "setBreakpoints",
4
+ "threads",
5
+ "stackTrace",
6
+ "scopes",
7
+ "variables",
8
+ "pause",
9
+ "continue",
10
+ "next",
11
+ "stepIn",
12
+ ];
13
+ export class DebuggerClientError extends Error {
14
+ code;
15
+ constructor(code, message) {
16
+ super(message);
17
+ this.code = code;
18
+ this.name = "DebuggerClientError";
19
+ }
20
+ }
21
+ //# sourceMappingURL=debuggerClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debuggerClient.js","sourceRoot":"","sources":["../../src/runtime/debuggerClient.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC7C,YAAY;IACZ,gBAAgB;IAChB,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,WAAW;IACX,OAAO;IACP,UAAU;IACV,MAAM;IACN,QAAQ;CACA,CAAC;AAKX,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACvB;IAArB,YAAqB,IAA6B,EAAE,OAAe;QACjE,KAAK,CAAC,OAAO,CAAC,CAAC;QADI,SAAI,GAAJ,IAAI,CAAyB;QAEhD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import { type InputEvent, type InputOperationInput, type InputTrace, type InputTraceEvent, type RuntimeHandle } from "@godot-mcp/protocol";
2
+ export interface InputAuditSummary {
3
+ handle: RuntimeHandle;
4
+ operation: InputOperationInput["operation"];
5
+ mode?: "realtime" | "deterministic";
6
+ eventCount: number;
7
+ eventKinds: Partial<Record<InputEvent["type"], number>>;
8
+ firstFrameOffset: number | null;
9
+ lastFrameOffset: number | null;
10
+ traceSha256: string;
11
+ }
12
+ export declare function inputTraceEvents(input: InputOperationInput): InputTraceEvent[];
13
+ export declare function traceSha256(trace: InputTrace): string;
14
+ export declare function summarizeInputForAudit(input: InputOperationInput): InputAuditSummary;
15
+ //# sourceMappingURL=inputReceipt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputReceipt.d.ts","sourceRoot":"","sources":["../../src/runtime/inputReceipt.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,UAAU,GAAG,eAAe,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,eAAe,EAAE,CAY9E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAErD;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,GAAG,iBAAiB,CAepF"}
@@ -0,0 +1,36 @@
1
+ import { createHash } from "node:crypto";
2
+ import { canonicalJson, } from "@godot-mcp/protocol";
3
+ export function inputTraceEvents(input) {
4
+ switch (input.operation) {
5
+ case "send":
6
+ return [{ frameOffset: 0, event: input.event }];
7
+ case "sequence":
8
+ return input.events;
9
+ case "replay":
10
+ return input.trace.events;
11
+ case "record_start":
12
+ case "record_stop":
13
+ return [];
14
+ }
15
+ }
16
+ export function traceSha256(trace) {
17
+ return createHash("sha256").update(canonicalJson(trace)).digest("hex");
18
+ }
19
+ export function summarizeInputForAudit(input) {
20
+ const events = inputTraceEvents(input);
21
+ const eventKinds = {};
22
+ for (const { event } of events)
23
+ eventKinds[event.type] = (eventKinds[event.type] ?? 0) + 1;
24
+ const mode = input.operation === "sequence" || input.operation === "replay" ? input.mode : undefined;
25
+ return {
26
+ handle: input.handle,
27
+ operation: input.operation,
28
+ ...(mode === undefined ? {} : { mode }),
29
+ eventCount: events.length,
30
+ eventKinds,
31
+ firstFrameOffset: events[0]?.frameOffset ?? null,
32
+ lastFrameOffset: events.at(-1)?.frameOffset ?? null,
33
+ traceSha256: traceSha256({ schemaVersion: 1, events }),
34
+ };
35
+ }
36
+ //# sourceMappingURL=inputReceipt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputReceipt.js","sourceRoot":"","sources":["../../src/runtime/inputReceipt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EACL,aAAa,GAMd,MAAM,qBAAqB,CAAC;AAa7B,MAAM,UAAU,gBAAgB,CAAC,KAA0B;IACzD,QAAQ,KAAK,CAAC,SAAS,EAAE,CAAC;QACxB,KAAK,MAAM;YACT,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAClD,KAAK,UAAU;YACb,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;QAC5B,KAAK,cAAc,CAAC;QACpB,KAAK,aAAa;YAChB,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAA0B;IAC/D,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,UAAU,GAAoC,EAAE,CAAC;IACvD,KAAK,MAAM,EAAE,KAAK,EAAE,IAAI,MAAM;QAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3F,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,KAAK,UAAU,IAAI,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACrG,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACvC,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,UAAU;QACV,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,IAAI;QAChD,eAAe,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,IAAI;QACnD,WAAW,EAAE,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;KACvD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { type ProjectIdentity, type RuntimeLaunchPins } from "@godot-mcp/protocol";
2
+ import { z } from "zod";
3
+ export declare const RuntimeDescriptorSchema: z.ZodObject<{
4
+ project: z.ZodObject<{
5
+ projectId: z.ZodUUID;
6
+ rootRealPath: z.ZodString;
7
+ projectConfigSha256: z.ZodString;
8
+ godotVersion: z.ZodOptional<z.ZodString>;
9
+ }, z.core.$strip>;
10
+ sessionId: z.ZodString;
11
+ runId: z.ZodUUID;
12
+ generation: z.ZodNumber;
13
+ scenePath: z.ZodString;
14
+ pins: z.ZodOptional<z.ZodObject<{
15
+ width: z.ZodNumber;
16
+ height: z.ZodNumber;
17
+ renderer: z.ZodEnum<{
18
+ gl_compatibility: "gl_compatibility";
19
+ mobile: "mobile";
20
+ }>;
21
+ locale: z.ZodString;
22
+ seed: z.ZodNumber;
23
+ fixedFps: z.ZodUnion<readonly [z.ZodLiteral<30>, z.ZodLiteral<60>, z.ZodLiteral<120>]>;
24
+ }, z.core.$strict>>;
25
+ ownerLeasePath: z.ZodString;
26
+ secret: z.ZodString;
27
+ launchNonce: z.ZodString;
28
+ createdAtUnixMs: z.ZodNumber;
29
+ expiresAtUnixMs: z.ZodNumber;
30
+ }, z.core.$strict>;
31
+ export type RuntimeDescriptor = z.infer<typeof RuntimeDescriptorSchema>;
32
+ export interface RuntimeDescriptorInput {
33
+ project: ProjectIdentity;
34
+ sessionId: string;
35
+ runId: string;
36
+ generation: number;
37
+ scenePath: string;
38
+ pins?: RuntimeLaunchPins;
39
+ now?: number;
40
+ }
41
+ export interface RuntimeDescriptorMaterial {
42
+ path: string;
43
+ descriptor: RuntimeDescriptor;
44
+ secret: Uint8Array;
45
+ consume?(): Promise<void>;
46
+ cleanup(): Promise<void>;
47
+ }
48
+ export declare function createRuntimeDescriptor(input: RuntimeDescriptorInput): Promise<RuntimeDescriptorMaterial>;
49
+ export declare function consumeRuntimeDescriptor(path: string, expected: RuntimeDescriptorInput): Promise<RuntimeDescriptor>;
50
+ //# sourceMappingURL=runtimeDescriptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeDescriptor.d.ts","sourceRoot":"","sources":["../../src/runtime/runtimeDescriptor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsF,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACvK,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAczB,CAAC;AAEZ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,iBAAiB,CAAC;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAgED,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAsD/G;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA0BzH"}
@@ -0,0 +1,175 @@
1
+ import { randomBytes, randomUUID } from "node:crypto";
2
+ import { lstat, readFile, readdir, rename, rm, utimes, writeFile } from "node:fs/promises";
3
+ import { basename, dirname, join } from "node:path";
4
+ import { canonicalJson, ProjectIdentitySchema, RuntimeHandleSchema, RuntimeLaunchPinsSchema } from "@godot-mcp/protocol";
5
+ import { z } from "zod";
6
+ import { GodotMcpException } from "../errors.js";
7
+ import { ensureRuntimeDirectory } from "../auth/runtimeDirectory.js";
8
+ export const RuntimeDescriptorSchema = z
9
+ .object({
10
+ project: ProjectIdentitySchema,
11
+ sessionId: z.string().min(16).max(256),
12
+ runId: RuntimeHandleSchema.shape.runId,
13
+ generation: RuntimeHandleSchema.shape.generation,
14
+ scenePath: z.string().startsWith("res://").endsWith(".tscn").max(512),
15
+ pins: RuntimeLaunchPinsSchema.optional(),
16
+ ownerLeasePath: z.string().min(1).max(1024),
17
+ secret: z.string().regex(/^[A-Za-z0-9_-]{43}$/),
18
+ launchNonce: z.string().regex(/^[A-Za-z0-9_-]{43}$/),
19
+ createdAtUnixMs: z.number().int().nonnegative(),
20
+ expiresAtUnixMs: z.number().int().positive(),
21
+ })
22
+ .strict();
23
+ function authenticationFailed(message) {
24
+ return new GodotMcpException({
25
+ code: "AUTHENTICATION_FAILED",
26
+ message,
27
+ retryable: false,
28
+ correlationId: randomUUID(),
29
+ partialEffects: false,
30
+ rollback: "not_needed",
31
+ });
32
+ }
33
+ function assertExpected(descriptor, expected) {
34
+ if (descriptor.project.projectId !== expected.project.projectId ||
35
+ descriptor.project.projectConfigSha256 !== expected.project.projectConfigSha256 ||
36
+ descriptor.sessionId !== expected.sessionId ||
37
+ descriptor.runId !== expected.runId ||
38
+ descriptor.generation !== expected.generation ||
39
+ descriptor.scenePath !== expected.scenePath ||
40
+ canonicalJson(descriptor.pins ?? null) !== canonicalJson(expected.pins ?? null)) {
41
+ throw authenticationFailed("Runtime descriptor identity does not match the prepared run");
42
+ }
43
+ }
44
+ async function pruneOrphanedRuntimeFiles(directory, now) {
45
+ const names = (await readdir(directory).catch(() => []))
46
+ .filter((name) => name.startsWith("runtime-") || name.startsWith(".consuming-runtime-"))
47
+ .slice(0, 256);
48
+ const referencedLeases = new Set();
49
+ for (const name of names) {
50
+ if (!name.startsWith("runtime-") || !name.endsWith(".json"))
51
+ continue;
52
+ const path = join(directory, name);
53
+ let descriptor;
54
+ try {
55
+ descriptor = RuntimeDescriptorSchema.parse(JSON.parse(await readFile(path, "utf8")));
56
+ }
57
+ catch {
58
+ const metadata = await lstat(path).catch(() => undefined);
59
+ if (metadata && now - metadata.mtimeMs > 60_000)
60
+ await rm(path, { force: true });
61
+ continue;
62
+ }
63
+ const leaseName = basename(descriptor.ownerLeasePath);
64
+ const leasePath = join(directory, leaseName);
65
+ if (dirname(descriptor.ownerLeasePath) !== directory || !leaseName.startsWith("runtime-") || !leaseName.endsWith(".lease"))
66
+ continue;
67
+ referencedLeases.add(leaseName);
68
+ const lease = await lstat(leasePath).catch(() => undefined);
69
+ if (descriptor.expiresAtUnixMs < now || !lease || now - lease.mtimeMs > 4_000) {
70
+ await Promise.all([rm(path, { force: true }), rm(leasePath, { force: true })]);
71
+ }
72
+ }
73
+ for (const name of names) {
74
+ const path = join(directory, name);
75
+ if (name.startsWith("runtime-") && name.endsWith(".lease") && !referencedLeases.has(name)) {
76
+ const metadata = await lstat(path).catch(() => undefined);
77
+ if (metadata && now - metadata.mtimeMs > 4_000)
78
+ await rm(path, { force: true });
79
+ }
80
+ else if (name.startsWith(".consuming-runtime-")) {
81
+ const metadata = await lstat(path).catch(() => undefined);
82
+ if (metadata && now - metadata.mtimeMs > 60_000)
83
+ await rm(path, { force: true });
84
+ }
85
+ }
86
+ }
87
+ export async function createRuntimeDescriptor(input) {
88
+ const directory = await ensureRuntimeDirectory();
89
+ const now = input.now ?? Date.now();
90
+ await pruneOrphanedRuntimeFiles(directory, now);
91
+ const secret = randomBytes(32);
92
+ const descriptor = RuntimeDescriptorSchema.parse({
93
+ project: input.project,
94
+ sessionId: input.sessionId,
95
+ runId: input.runId,
96
+ generation: input.generation,
97
+ scenePath: input.scenePath,
98
+ ...(input.pins ? { pins: input.pins } : {}),
99
+ ownerLeasePath: join(directory, `runtime-${input.project.projectId}-${input.runId}.lease`),
100
+ secret: secret.toString("base64url"),
101
+ launchNonce: randomBytes(32).toString("base64url"),
102
+ createdAtUnixMs: now,
103
+ expiresAtUnixMs: now + 60_000,
104
+ });
105
+ const path = join(directory, `runtime-${input.project.projectId}-${input.runId}.json`);
106
+ const ownerLeasePath = descriptor.ownerLeasePath;
107
+ await writeFile(ownerLeasePath, "owner\n", { encoding: "utf8", flag: "wx", mode: 0o600 });
108
+ try {
109
+ await writeFile(path, `${JSON.stringify(descriptor)}\n`, { encoding: "utf8", flag: "wx", mode: 0o600 });
110
+ }
111
+ catch (error) {
112
+ await rm(ownerLeasePath, { force: true }).catch(() => undefined);
113
+ throw error;
114
+ }
115
+ const heartbeat = setInterval(() => {
116
+ const heartbeatAt = new Date();
117
+ void utimes(ownerLeasePath, heartbeatAt, heartbeatAt).catch(() => undefined);
118
+ }, 250);
119
+ heartbeat.unref();
120
+ let consumed = false;
121
+ let cleaned = false;
122
+ return {
123
+ path,
124
+ descriptor,
125
+ secret,
126
+ async consume() {
127
+ if (consumed || cleaned)
128
+ return;
129
+ secret.fill(0);
130
+ descriptor.secret = "";
131
+ await rm(path, { force: true });
132
+ consumed = true;
133
+ },
134
+ async cleanup() {
135
+ if (cleaned)
136
+ return;
137
+ clearInterval(heartbeat);
138
+ secret.fill(0);
139
+ descriptor.secret = "";
140
+ await Promise.all([rm(path, { force: true }), rm(ownerLeasePath, { force: true })]);
141
+ cleaned = true;
142
+ },
143
+ };
144
+ }
145
+ export async function consumeRuntimeDescriptor(path, expected) {
146
+ const consumingPath = join(dirname(path), `.consuming-${basename(path)}-${randomUUID()}`);
147
+ try {
148
+ await rename(path, consumingPath);
149
+ }
150
+ catch {
151
+ throw authenticationFailed("Runtime descriptor is missing or already consumed");
152
+ }
153
+ try {
154
+ const metadata = await lstat(consumingPath);
155
+ if (!metadata.isFile() || metadata.isSymbolicLink() || (metadata.mode & 0o077) !== 0) {
156
+ throw authenticationFailed("Runtime descriptor permissions are invalid");
157
+ }
158
+ let descriptor;
159
+ try {
160
+ descriptor = RuntimeDescriptorSchema.parse(JSON.parse(await readFile(consumingPath, "utf8")));
161
+ }
162
+ catch {
163
+ throw authenticationFailed("Runtime descriptor is malformed");
164
+ }
165
+ assertExpected(descriptor, expected);
166
+ if (descriptor.expiresAtUnixMs < (expected.now ?? Date.now())) {
167
+ throw authenticationFailed("Runtime descriptor has expired");
168
+ }
169
+ return descriptor;
170
+ }
171
+ finally {
172
+ await rm(consumingPath, { force: true });
173
+ }
174
+ }
175
+ //# sourceMappingURL=runtimeDescriptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeDescriptor.js","sourceRoot":"","sources":["../../src/runtime/runtimeDescriptor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ import type { RuntimeLaunchPins } from "@godot-mcp/protocol";
3
+ export interface RuntimeArgumentsInput {
4
+ projectRoot: string;
5
+ debugPort: number;
6
+ descriptorPath: string;
7
+ pins?: RuntimeLaunchPins;
8
+ }
9
+ export declare function godotRuntimeArguments(input: RuntimeArgumentsInput): string[];
10
+ export declare function scrubRuntimeEnvironment(environment: NodeJS.ProcessEnv): Record<string, string>;
11
+ export declare function lsofShowsLoopbackListener(output: string, pid: number, port: number): boolean;
12
+ export declare function listenerPortsAreDistinct(ports: readonly number[]): boolean;
13
+ export declare function assertLoopbackListenerOwnedByProcess(pid: number, port: number): Promise<void>;
14
+ export declare function assertLoopbackListenersOwnedByProcess(pid: number, ports: readonly number[], verify?: (pid: number, port: number) => Promise<void>): Promise<void>;
15
+ export declare function childHasExited(child: Pick<ChildProcess, "exitCode" | "signalCode">): boolean;
16
+ export declare function shouldRefuseProcessSignal(child: Pick<ChildProcess, "exitCode" | "signalCode">, currentFingerprint: string, ownedFingerprint: string): boolean;
17
+ export interface OwnedRuntimeProcess {
18
+ readonly pid: number;
19
+ readonly fingerprint: string;
20
+ stop(graceMs?: number): Promise<void>;
21
+ wait(): Promise<number>;
22
+ diagnostics?(): string;
23
+ }
24
+ export declare class OwnedGodotProcess implements OwnedRuntimeProcess {
25
+ private readonly child;
26
+ readonly pid: number;
27
+ readonly fingerprint: string;
28
+ private stopPromise;
29
+ private output;
30
+ private constructor();
31
+ static launch(input: RuntimeArgumentsInput & {
32
+ godotBin: string;
33
+ environment?: NodeJS.ProcessEnv;
34
+ }): Promise<OwnedGodotProcess>;
35
+ diagnostics(): string;
36
+ wait(): Promise<number>;
37
+ stop(graceMs?: number): Promise<void>;
38
+ }
39
+ //# sourceMappingURL=runtimeProcess.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeProcess.d.ts","sourceRoot":"","sources":["../../src/runtime/runtimeProcess.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAI9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAO7D,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,iBAAiB,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,EAAE,CAiB5E;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO9F;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK5F;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAE1E;AAED,wBAAsB,oCAAoC,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBnG;AAED,wBAAsB,qCAAqC,CACzD,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,GAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAwC,GAC1F,OAAO,CAAC,IAAI,CAAC,CAEf;AASD,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,YAAY,CAAC,GAAG,OAAO,CAE5F;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,YAAY,CAAC,EACpD,kBAAkB,EAAE,MAAM,EAC1B,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAET;AAUD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACxB,WAAW,CAAC,IAAI,MAAM,CAAC;CACxB;AAED,qBAAa,iBAAkB,YAAW,mBAAmB;IAKzD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM;IAN9B,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,MAAM,CAAM;IAEpB,OAAO;WAMM,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA+BrI,WAAW,IAAI,MAAM;IAIrB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAIvB,IAAI,CAAC,OAAO,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAsCrC"}