Skip to content

Commit 88929cb

Browse files
committed
feat: Enhance debugger robustness by adding session cleanup and pre-enablement checks, along with relocating breakpoint debugging skill documentation.
1 parent 3720bc4 commit 88929cb

3 files changed

Lines changed: 47 additions & 1 deletion

File tree

File renamed without changes.

src/tools/debugger.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ async function getSession(page: Page): Promise<CDPSession> {
3838
pausedState.delete(session);
3939
});
4040

41+
session.on('closed', () => {
42+
sessions.delete(page);
43+
scriptMap.delete(session);
44+
pausedState.delete(session);
45+
});
46+
4147
// We intentionally do NOT auto-enable here to give users control,
4248
// but many tools will check or imply functionality that requires it.
4349
return session;
@@ -217,6 +223,10 @@ export const getPausedState = definePageTool({
217223
},
218224
schema: {},
219225
handler: async (request, response) => {
226+
if (!sessions.has(request.page.pptrPage)) {
227+
response.appendResponseLine('Debugger is not enabled (or no active session).');
228+
return;
229+
}
220230
const session = await getSession(request.page.pptrPage);
221231
const state = pausedState.get(session);
222232

@@ -254,6 +264,9 @@ export const getScopeVariables = definePageTool({
254264
scopeIndex: zod.number().default(0).describe('The scope index (0 is typically local)'),
255265
},
256266
handler: async (request, response) => {
267+
if (!sessions.has(request.page.pptrPage)) {
268+
throw new Error('Debugger is not enabled.');
269+
}
257270
const session = await getSession(request.page.pptrPage);
258271
const {callFrameId, scopeIndex} = request.params;
259272

@@ -305,6 +318,9 @@ export const evaluateOnCallFrame = definePageTool({
305318
expression: zod.string().describe('The expression to evaluate'),
306319
},
307320
handler: async (request, response) => {
321+
if (!sessions.has(request.page.pptrPage)) {
322+
throw new Error('Debugger is not enabled.');
323+
}
308324
const session = await getSession(request.page.pptrPage);
309325
const {callFrameId, expression} = request.params;
310326

@@ -334,6 +350,9 @@ export const getScriptSource = definePageTool({
334350
scriptId: zod.string().describe('The script ID'),
335351
},
336352
handler: async (request, response) => {
353+
if (!sessions.has(request.page.pptrPage)) {
354+
throw new Error('Debugger is not enabled.');
355+
}
337356
const session = await getSession(request.page.pptrPage);
338357
const {scriptId} = request.params;
339358

@@ -355,6 +374,9 @@ export const getCodeLines = definePageTool({
355374
count: zod.number().default(10).describe('Number of lines to retrieve (default 10)'),
356375
},
357376
handler: async (request, response) => {
377+
if (!sessions.has(request.page.pptrPage)) {
378+
throw new Error('Debugger is not enabled.');
379+
}
358380
const session = await getSession(request.page.pptrPage);
359381
const {scriptId, lineNumber, count} = request.params;
360382

tests/tools/debugger.test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,31 @@ describe('debugger', () => {
144144
}
145145
});
146146
});
147-
147+
148+
it('reports not enabled when calling getPausedState without enabling', async () => {
149+
await withMcpContext(async (response, context) => {
150+
const page = context.getSelectedMcpPage();
151+
await getPausedState.handler({ params: {}, page }, response, context);
152+
assert.ok(response.responseLines[0].includes('Debugger is not enabled'));
153+
});
154+
});
155+
156+
it('throws when calling getScopeVariables without enabling', async () => {
157+
await withMcpContext(async (response, context) => {
158+
const page = context.getSelectedMcpPage();
159+
try {
160+
await getScopeVariables.handler({ params: { callFrameId: '1', scopeIndex: 0 }, page }, response, context);
161+
assert.fail('Should have thrown');
162+
} catch (e: any) {
163+
if (!e.message.includes('Debugger is not enabled')) {
164+
console.error('Unexpected error:', e);
165+
assert.fail(`Expected "Debugger is not enabled", got: ${e.message}`);
166+
}
167+
assert.ok(true);
168+
}
169+
});
170+
});
171+
148172
it('evaluates on call frame (mock check)', async () => {
149173
// This is hard to test e2e without actually being paused.
150174
// We verified "not paused" error in getPausedState.

0 commit comments

Comments
 (0)