@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,21 @@
1
+ import { type EditorMutationInput, type EditorMutationResult } from "@godot-mcp/protocol";
2
+ import type { MutationLedger } from "./mutationLedger.js";
3
+ export interface EditorMutationBridge {
4
+ request<T>(method: "editor.mutate", params: unknown, options: {
5
+ timeoutMs: number;
6
+ maxResponseBytes: number;
7
+ correlationId: string;
8
+ }): Promise<{
9
+ requestId: string;
10
+ data: T;
11
+ }>;
12
+ }
13
+ export declare function editorMutationRequestDigest(input: EditorMutationInput): string;
14
+ export declare class EditorMutationService {
15
+ private readonly bridge;
16
+ private readonly ledger;
17
+ constructor(bridge: () => EditorMutationBridge | null, ledger: MutationLedger);
18
+ execute(inputValue: EditorMutationInput, correlationId: string): Promise<EditorMutationResult>;
19
+ private validateTransition;
20
+ }
21
+ //# sourceMappingURL=editorMutationService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editorMutationService.d.ts","sourceRoot":"","sources":["../../src/editor/editorMutationService.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,CAAC,EACP,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,OAAO,EACf,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAC9E,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAC5C;AA6BD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAK9E;AAkBD,qBAAa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,MAAM,EAAE,MAAM,oBAAoB,GAAG,IAAI,EACzC,MAAM,EAAE,cAAc;IAGnC,OAAO,CAAC,UAAU,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA8CpG,OAAO,CAAC,kBAAkB;CA2B3B"}
@@ -0,0 +1,120 @@
1
+ import { createHash } from "node:crypto";
2
+ import { EditorMutationInputSchema, EditorMutationResultSchema, } from "@godot-mcp/protocol";
3
+ import { GodotMcpException } from "../errors.js";
4
+ function normalize(value, ancestors) {
5
+ if (value === null || typeof value === "boolean" || typeof value === "string")
6
+ return value;
7
+ if (typeof value === "number") {
8
+ if (!Number.isFinite(value))
9
+ throw new TypeError("Mutation digest accepts only finite numbers");
10
+ return Object.is(value, -0) ? 0 : value;
11
+ }
12
+ if (typeof value !== "object")
13
+ throw new TypeError(`Mutation digest does not support ${typeof value}`);
14
+ if (ancestors.has(value))
15
+ throw new TypeError("Mutation digest does not support cyclic values");
16
+ ancestors.add(value);
17
+ try {
18
+ if (Array.isArray(value))
19
+ return value.map((item) => normalize(item, ancestors));
20
+ const prototype = Object.getPrototypeOf(value);
21
+ if (prototype !== Object.prototype && prototype !== null) {
22
+ throw new TypeError("Mutation digest accepts only arrays and plain objects");
23
+ }
24
+ const output = {};
25
+ for (const key of Object.keys(value).sort()) {
26
+ output[key] = normalize(value[key], ancestors);
27
+ }
28
+ return output;
29
+ }
30
+ finally {
31
+ ancestors.delete(value);
32
+ }
33
+ }
34
+ export function editorMutationRequestDigest(input) {
35
+ const parsed = EditorMutationInputSchema.parse(input);
36
+ return createHash("sha256")
37
+ .update(JSON.stringify(normalize(parsed, new Set())))
38
+ .digest("hex");
39
+ }
40
+ function exception(code, message, correlationId, partialEffects = false) {
41
+ return new GodotMcpException({
42
+ code,
43
+ message,
44
+ retryable: code === "NOT_ATTACHED",
45
+ correlationId,
46
+ partialEffects,
47
+ rollback: partialEffects ? "not_attempted" : "not_needed",
48
+ });
49
+ }
50
+ export class EditorMutationService {
51
+ bridge;
52
+ ledger;
53
+ constructor(bridge, ledger) {
54
+ this.bridge = bridge;
55
+ this.ledger = ledger;
56
+ }
57
+ async execute(inputValue, correlationId) {
58
+ const input = EditorMutationInputSchema.parse(inputValue);
59
+ const bridge = this.bridge();
60
+ if (!bridge)
61
+ throw exception("NOT_ATTACHED", "Godot editor addon is not attached", correlationId);
62
+ if (input.operation === "preview") {
63
+ const response = await bridge.request("editor.mutate", input, {
64
+ timeoutMs: 10_000,
65
+ maxResponseBytes: 512 * 1024,
66
+ correlationId,
67
+ });
68
+ return this.validateTransition(input, response.data, correlationId);
69
+ }
70
+ const requestDigest = editorMutationRequestDigest(input);
71
+ const reconciliation = await this.ledger.reconcile(input.idempotencyKey, requestDigest);
72
+ if (reconciliation.state === "completed")
73
+ return reconciliation.result;
74
+ if (reconciliation.state === "unknown") {
75
+ throw exception("CONFLICT", "A prior mutation with this idempotency key has an unknown outcome; preview current targets and reconcile their revisions before retrying with a new key", correlationId, true);
76
+ }
77
+ await this.ledger.begin({
78
+ idempotencyKey: input.idempotencyKey,
79
+ requestDigest,
80
+ correlationId,
81
+ });
82
+ const response = await bridge.request("editor.mutate", input, {
83
+ timeoutMs: 30_000,
84
+ maxResponseBytes: 512 * 1024,
85
+ correlationId,
86
+ });
87
+ const result = this.validateTransition(input, response.data, correlationId);
88
+ await this.ledger.complete({
89
+ idempotencyKey: input.idempotencyKey,
90
+ requestDigest,
91
+ correlationId,
92
+ result,
93
+ });
94
+ return result;
95
+ }
96
+ validateTransition(input, value, correlationId) {
97
+ const parsed = EditorMutationResultSchema.safeParse(value);
98
+ if (!parsed.success) {
99
+ throw exception("INVALID_REQUEST", "Godot returned an invalid editor mutation result", correlationId);
100
+ }
101
+ const expectedState = input.operation === "preview"
102
+ ? "previewed"
103
+ : input.operation === "apply"
104
+ ? "applied"
105
+ : input.operation === "undo"
106
+ ? "undone"
107
+ : "redone";
108
+ if (parsed.data.state !== expectedState) {
109
+ throw exception("INVALID_REQUEST", `Godot returned ${parsed.data.state} for ${input.operation}`, correlationId);
110
+ }
111
+ if (input.operation === "apply" && parsed.data.planDigest !== input.expectedPlanDigest) {
112
+ throw exception("INVALID_REQUEST", "Godot apply result plan digest did not match the authorized preview", correlationId);
113
+ }
114
+ if ((input.operation === "undo" || input.operation === "redo") && parsed.data.actionId !== input.actionId) {
115
+ throw exception("INVALID_REQUEST", "Godot action result did not match the requested action", correlationId);
116
+ }
117
+ return parsed.data;
118
+ }
119
+ }
120
+ //# sourceMappingURL=editorMutationService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editorMutationService.js","sourceRoot":"","sources":["../../src/editor/editorMutationService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type EditorMutationResult } from "@godot-mcp/protocol";
2
+ export interface MutationLedgerKeyInput {
3
+ idempotencyKey: string;
4
+ requestDigest: string;
5
+ correlationId: string;
6
+ }
7
+ export interface MutationLedgerCompleteInput extends MutationLedgerKeyInput {
8
+ result: EditorMutationResult;
9
+ }
10
+ export type MutationReconciliation = {
11
+ state: "missing";
12
+ } | {
13
+ state: "unknown";
14
+ } | {
15
+ state: "completed";
16
+ result: EditorMutationResult;
17
+ };
18
+ export declare class MutationLedger {
19
+ private readonly path;
20
+ private readonly latest;
21
+ private tail;
22
+ static open(path: string): Promise<MutationLedger>;
23
+ private constructor();
24
+ reconcile(idempotencyKey: string, requestDigest: string): Promise<MutationReconciliation>;
25
+ begin(input: MutationLedgerKeyInput): Promise<void>;
26
+ complete(input: MutationLedgerCompleteInput): Promise<void>;
27
+ private append;
28
+ private remember;
29
+ }
30
+ //# sourceMappingURL=mutationLedger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutationLedger.d.ts","sourceRoot":"","sources":["../../src/editor/mutationLedger.ts"],"names":[],"mappings":"AAIA,OAAO,EAA8B,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AA+B5F,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,2BAA4B,SAAQ,sBAAsB;IACzE,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAiBzD,qBAAa,cAAc;IA4BL,OAAO,CAAC,QAAQ,CAAC,IAAI;IA3BzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,IAAI,CAAuC;WAEtC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAwBxD,OAAO;IAED,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAWzF,KAAK,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnD,QAAQ,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;YAYnD,MAAM;IAepB,OAAO,CAAC,QAAQ;CASjB"}
@@ -0,0 +1,133 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { mkdir, open, readFile, stat } from "node:fs/promises";
3
+ import { dirname } from "node:path";
4
+ import { EditorMutationResultSchema } from "@godot-mcp/protocol";
5
+ import { z } from "zod";
6
+ import { GodotMcpException } from "../errors.js";
7
+ const MAX_LEDGER_BYTES = 4 * 1024 * 1024;
8
+ const MAX_KEYS = 256;
9
+ const Sha256Schema = z.string().regex(/^[a-f0-9]{64}$/);
10
+ const StartedRecordSchema = z.object({
11
+ schemaVersion: z.literal(1),
12
+ state: z.literal("started"),
13
+ idempotencyKeySha256: Sha256Schema,
14
+ requestDigest: Sha256Schema,
15
+ correlationId: z.string().min(1).max(256),
16
+ recordedAt: z.string().datetime(),
17
+ }).strict();
18
+ const CompletedRecordSchema = z.object({
19
+ schemaVersion: z.literal(1),
20
+ state: z.literal("completed"),
21
+ idempotencyKeySha256: Sha256Schema,
22
+ requestDigest: Sha256Schema,
23
+ correlationId: z.string().min(1).max(256),
24
+ recordedAt: z.string().datetime(),
25
+ result: EditorMutationResultSchema,
26
+ }).strict();
27
+ const LedgerRecordSchema = z.discriminatedUnion("state", [StartedRecordSchema, CompletedRecordSchema]);
28
+ function sha256(value) {
29
+ return createHash("sha256").update(value).digest("hex");
30
+ }
31
+ function conflict(message) {
32
+ return new GodotMcpException({
33
+ code: "CONFLICT",
34
+ message,
35
+ retryable: false,
36
+ correlationId: randomUUID(),
37
+ partialEffects: false,
38
+ rollback: "not_attempted",
39
+ });
40
+ }
41
+ export class MutationLedger {
42
+ path;
43
+ latest = new Map();
44
+ tail = Promise.resolve();
45
+ static async open(path) {
46
+ const ledger = new MutationLedger(path);
47
+ let metadata;
48
+ try {
49
+ metadata = await stat(path);
50
+ }
51
+ catch (error) {
52
+ if (error.code === "ENOENT")
53
+ return ledger;
54
+ throw error;
55
+ }
56
+ if (metadata.size > MAX_LEDGER_BYTES) {
57
+ throw conflict("Mutation journal exceeds 4 MiB; inspect and archive it outside MCP before reconnecting");
58
+ }
59
+ const text = await readFile(path, "utf8");
60
+ for (const [index, line] of text.split("\n").entries()) {
61
+ if (line.length === 0)
62
+ continue;
63
+ try {
64
+ ledger.remember(LedgerRecordSchema.parse(JSON.parse(line)));
65
+ }
66
+ catch {
67
+ throw conflict(`Mutation journal record ${index + 1} is malformed; reconcile it outside MCP before reconnecting`);
68
+ }
69
+ }
70
+ return ledger;
71
+ }
72
+ constructor(path) {
73
+ this.path = path;
74
+ }
75
+ async reconcile(idempotencyKey, requestDigest) {
76
+ const record = this.latest.get(sha256(idempotencyKey));
77
+ if (!record)
78
+ return { state: "missing" };
79
+ if (record.requestDigest !== requestDigest) {
80
+ throw conflict("Idempotency key was already used for a different editor mutation request");
81
+ }
82
+ return record.state === "completed"
83
+ ? { state: "completed", result: record.result }
84
+ : { state: "unknown" };
85
+ }
86
+ async begin(input) {
87
+ await this.append({
88
+ schemaVersion: 1,
89
+ state: "started",
90
+ idempotencyKeySha256: sha256(input.idempotencyKey),
91
+ requestDigest: Sha256Schema.parse(input.requestDigest),
92
+ correlationId: input.correlationId,
93
+ recordedAt: new Date().toISOString(),
94
+ });
95
+ }
96
+ async complete(input) {
97
+ await this.append({
98
+ schemaVersion: 1,
99
+ state: "completed",
100
+ idempotencyKeySha256: sha256(input.idempotencyKey),
101
+ requestDigest: Sha256Schema.parse(input.requestDigest),
102
+ correlationId: input.correlationId,
103
+ recordedAt: new Date().toISOString(),
104
+ result: EditorMutationResultSchema.parse(input.result),
105
+ });
106
+ }
107
+ async append(record) {
108
+ const write = this.tail.then(async () => {
109
+ await mkdir(dirname(this.path), { recursive: true, mode: 0o700 });
110
+ const handle = await open(this.path, "a", 0o600);
111
+ try {
112
+ await handle.writeFile(`${JSON.stringify(record)}\n`, "utf8");
113
+ }
114
+ finally {
115
+ await handle.close();
116
+ }
117
+ this.remember(record);
118
+ });
119
+ this.tail = write.catch(() => undefined);
120
+ await write;
121
+ }
122
+ remember(record) {
123
+ this.latest.delete(record.idempotencyKeySha256);
124
+ this.latest.set(record.idempotencyKeySha256, record);
125
+ while (this.latest.size > MAX_KEYS) {
126
+ const oldest = this.latest.keys().next().value;
127
+ if (oldest === undefined)
128
+ break;
129
+ this.latest.delete(oldest);
130
+ }
131
+ }
132
+ }
133
+ //# sourceMappingURL=mutationLedger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutationLedger.js","sourceRoot":"","sources":["../../src/editor/mutationLedger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type GodotMcpError } from "@godot-mcp/protocol";
2
+ export declare class GodotMcpException extends Error {
3
+ readonly code: GodotMcpError["code"];
4
+ readonly retryable: boolean;
5
+ readonly correlationId: string;
6
+ readonly partialEffects: boolean;
7
+ readonly rollback: GodotMcpError["rollback"];
8
+ readonly failedPhase: string;
9
+ readonly safeRecovery: string;
10
+ constructor(input: Omit<GodotMcpError, "failedPhase" | "safeRecovery"> & Partial<Pick<GodotMcpError, "failedPhase" | "safeRecovery">>);
11
+ }
12
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE9E,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAElB,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,cAAc,CAAC,CAAC;CAYtI"}
package/dist/errors.js ADDED
@@ -0,0 +1,23 @@
1
+ import { GodotMcpErrorSchema } from "@godot-mcp/protocol";
2
+ export class GodotMcpException extends Error {
3
+ code;
4
+ retryable;
5
+ correlationId;
6
+ partialEffects;
7
+ rollback;
8
+ failedPhase;
9
+ safeRecovery;
10
+ constructor(input) {
11
+ const error = GodotMcpErrorSchema.parse(input);
12
+ super(error.message);
13
+ this.name = "GodotMcpException";
14
+ this.code = error.code;
15
+ this.retryable = error.retryable;
16
+ this.correlationId = error.correlationId;
17
+ this.partialEffects = error.partialEffects;
18
+ this.rollback = error.rollback;
19
+ this.failedPhase = error.failedPhase;
20
+ this.safeRecovery = error.safeRecovery;
21
+ }
22
+ }
23
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAsB,MAAM,qBAAqB,CAAC;AAE9E,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,IAAI,CAAwB;IAC5B,SAAS,CAAU;IACnB,aAAa,CAAS;IACtB,cAAc,CAAU;IACxB,QAAQ,CAA4B;IACpC,WAAW,CAAS;IACpB,YAAY,CAAS;IAE9B,YAAY,KAAyH;QACnI,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/C,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;QACzC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC;QAC3C,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QACrC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACzC,CAAC;CACF"}
@@ -0,0 +1,63 @@
1
+ export interface PngEvidenceMetadata {
2
+ viewport: "2d" | "3d" | "runtime";
3
+ width: number;
4
+ height: number;
5
+ viewportIndex?: number;
6
+ source?: "editor" | "runtime";
7
+ runId?: string;
8
+ generation?: number;
9
+ frameIndex?: number;
10
+ }
11
+ export interface EvidenceReference {
12
+ uri: `godot-mcp://evidence/${string}`;
13
+ observationUri: `godot-mcp://evidence/${string}`;
14
+ sha256: string;
15
+ mimeType: "image/png";
16
+ byteLength: number;
17
+ path: string;
18
+ observationPath: string;
19
+ }
20
+ export interface JsonEvidenceReference {
21
+ uri: `godot-mcp://evidence/${string}`;
22
+ observationUri: `godot-mcp://evidence/${string}`;
23
+ sha256: string;
24
+ mimeType: "application/json";
25
+ byteLength: number;
26
+ path: string;
27
+ observationPath: string;
28
+ }
29
+ export interface PngObservation {
30
+ data: Uint8Array;
31
+ sha256: string;
32
+ mimeType: "image/png";
33
+ byteLength: number;
34
+ width: number;
35
+ height: number;
36
+ observationUri: `godot-mcp://evidence/${string}`;
37
+ }
38
+ export interface PngBaselineManifest {
39
+ schemaVersion: 1;
40
+ comparisonContractVersion: 1;
41
+ name: string;
42
+ sha256: string;
43
+ mimeType: "image/png";
44
+ byteLength: number;
45
+ width: number;
46
+ height: number;
47
+ sourceObservationSha256: string;
48
+ createdAtUnixMs: number;
49
+ }
50
+ export declare class EvidenceStore {
51
+ private readonly projectRoot;
52
+ constructor(projectRoot: string);
53
+ putPng(sessionId: string, png: Uint8Array, metadata: PngEvidenceMetadata): Promise<EvidenceReference>;
54
+ readSessionPngObservation(sessionId: string, observationUri: string): Promise<PngObservation>;
55
+ putJson(sessionId: string, value: unknown, metadata: Record<string, unknown>): Promise<JsonEvidenceReference>;
56
+ createPngBaseline(sessionId: string, name: string, observationUri: string, createdAtUnixMs?: number): Promise<PngBaselineManifest>;
57
+ readPngBaseline(name: string): Promise<PngBaselineManifest>;
58
+ readPngBaselineData(name: string): Promise<{
59
+ manifest: PngBaselineManifest;
60
+ data: Uint8Array;
61
+ }>;
62
+ }
63
+ //# sourceMappingURL=evidenceStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidenceStore.d.ts","sourceRoot":"","sources":["../../src/evidence/evidenceStore.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,wBAAwB,MAAM,EAAE,CAAC;IACtC,cAAc,EAAE,wBAAwB,MAAM,EAAE,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,wBAAwB,MAAM,EAAE,CAAC;IACtC,cAAc,EAAE,wBAAwB,MAAM,EAAE,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,wBAAwB,MAAM,EAAE,CAAC;CAClD;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,CAAC,CAAC;IACjB,yBAAyB,EAAE,CAAC,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB,EAAE,MAAM,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;CACzB;AAkID,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAE1C,MAAM,CACV,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,mBAAmB,GAC5B,OAAO,CAAC,iBAAiB,CAAC;IAoDvB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAqD7F,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA+B7G,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,EACtB,eAAe,SAAa,GAC3B,OAAO,CAAC,mBAAmB,CAAC;IAwCzB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAI3D,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,mBAAmB,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,CAAC;CAkBtG"}