Skip to content

Commit eb6546e

Browse files
Merge pull request #47 from Mermaid-Chart/PLUG-78-vscode-pre-commit-diagram-sync-auto-regenerate-mermaid-diagrams-when-referenced-source-files-are-staged
PLUG-78 Regenerate Diagram Integration
2 parents 1b9db16 + eda87b4 commit eb6546e

5 files changed

Lines changed: 107 additions & 0 deletions

File tree

.changeset/smart-nails-mix.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@mermaidchart/sdk': patch
3+
---
4+
5+
Add a regenerate method to the SDK that complements our Mermaid Diagram Sync GitHub App functionality. This method should accept the existing Mermaid diagram content along with source file changes, and regenerate the diagram based on those updates while preserving the overall diagram structure and intent.

packages/sdk/src/index.e2e.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,46 @@ describe('suggestPrSummary', () => {
267267
}
268268
}, 60000); // 60 seconds timeout for AI operations
269269
});
270+
271+
describe('regenerateDiagram', () => {
272+
it('should regenerate a diagram from updated source files', async () => {
273+
const code = `flowchart TD\n A[Start] --> B[Process]\n B --> C[End]`;
274+
const sourceFiles = [
275+
'function processOrder(order) {\n validateOrder(order);\n shipOrder(order);\n}',
276+
];
277+
278+
try {
279+
const creditsBefore = await client.getAICredits();
280+
281+
const result = await client.regenerateDiagram({
282+
code,
283+
sourceFiles,
284+
});
285+
286+
// Verify response structure
287+
expect(result).toHaveProperty('result');
288+
expect(result).toHaveProperty('code');
289+
expect(['ok', 'fail']).toContain(result.result);
290+
291+
// When the AI successfully regenerates the diagram, creditUsage should be present
292+
// and credits should have been deducted
293+
if (result.result === 'ok' && result.solved === true) {
294+
expect(result.creditUsage).toMatchObject({
295+
creditsToDeduct: expect.any(Number),
296+
baseCost: expect.any(Number),
297+
reason: expect.any(String),
298+
});
299+
300+
const creditsAfter = await client.getAICredits();
301+
expect(creditsAfter.aiCredits.remaining).toBe(
302+
creditsBefore.aiCredits.remaining - result.creditUsage!.creditsToDeduct,
303+
);
304+
}
305+
} catch (error) {
306+
if (error instanceof AICreditsLimitExceededError) {
307+
return; // Credits exceeded is acceptable for E2E test
308+
}
309+
throw error;
310+
}
311+
}, 60000); // 60 seconds timeout for AI operations
312+
});

packages/sdk/src/index.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import type {
2121
RepairDiagramResponse,
2222
PrSummaryRequest,
2323
PrSummaryResponse,
24+
RegenerateDiagramRequest,
25+
RegenerateDiagramResponse,
2426
AICreditsUsage,
2527
} from './types.js';
2628
import { URLS } from './urls.js';
@@ -351,6 +353,26 @@ export class MermaidChart {
351353
}
352354
}
353355

356+
/**
357+
* Regenerates a Mermaid diagram based on updated source files using AI.
358+
*
359+
* @param request - `code` (current diagram source) and `sourceFiles` (full contents of related source files)
360+
* @throws {@link AICreditsLimitExceededError} if credits limit exceeded (HTTP 402)
361+
*/
362+
public async regenerateDiagram(
363+
request: RegenerateDiagramRequest,
364+
): Promise<RegenerateDiagramResponse> {
365+
try {
366+
const response = await this.axios.post<RegenerateDiagramResponse>(
367+
URLS.rest.openai.regenerate,
368+
request,
369+
);
370+
return response.data;
371+
} catch (error: unknown) {
372+
throwIfAICreditsExceeded(error);
373+
}
374+
}
375+
354376
/**
355377
* Chat with Mermaid AI about a diagram.
356378
*

packages/sdk/src/types.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,42 @@ export interface PrSummaryResponse {
114114
commitMessage: string;
115115
}
116116

117+
/**
118+
* Request parameters for regenerating a Mermaid diagram from updated source files.
119+
*/
120+
export interface RegenerateDiagramRequest {
121+
/** The current Mermaid diagram source to be regenerated. */
122+
code: string;
123+
/** Ordered full contents of the source files that the diagram is based on. */
124+
sourceFiles: string[];
125+
}
126+
127+
/**
128+
* Response from regenerating a Mermaid diagram.
129+
*/
130+
export interface RegenerateDiagramResponse {
131+
/**
132+
* The status of the regeneration: 'ok' if a valid mermaid code block was generated, 'fail' otherwise.
133+
*/
134+
result: 'ok' | 'fail';
135+
/**
136+
* Markdown message that may contain a valid mermaid code block.
137+
*/
138+
code: string;
139+
/**
140+
* Whether the diagram regeneration was successful.
141+
*/
142+
solved?: boolean;
143+
/**
144+
* Credit usage for client-side deduction (only present when solved).
145+
*/
146+
creditUsage?: {
147+
creditsToDeduct: number;
148+
baseCost: number;
149+
reason: string;
150+
};
151+
}
152+
117153
/**
118154
* Request parameters for chatting with the Mermaid AI about a diagram.
119155
*/

packages/sdk/src/urls.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export const URLS = {
4242
openai: {
4343
repair: `/rest-api/openai/repair`,
4444
prSummary: `/rest-api/openai/pr-summary`,
45+
regenerate: `/rest-api/openai/regenerate`,
4546
chat: `/rest-api/openai/chat`,
4647
},
4748
},

0 commit comments

Comments
 (0)