Skip to content

Commit fc1318c

Browse files
committed
fix: include plugin version in response, improve error messages, and validate captureAndContinue in singleShot mode
1 parent e219014 commit fc1318c

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

src/session.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,17 @@ export const startDebuggingAndWaitForStop = async (
11371137

11381138
logger.debug("startDebuggingAndWaitForStop params", params);
11391139

1140+
if (mode === "singleShot" && breakpointConfig?.breakpoints) {
1141+
const invalidBp = breakpointConfig.breakpoints.find(
1142+
(bp) => bp.onHit === "captureAndContinue"
1143+
);
1144+
if (invalidBp) {
1145+
throw new Error(
1146+
`'captureAndContinue' onHit action is not supported in singleShot mode. Use 'inspect' mode or 'break'/'stopDebugging' action.`
1147+
);
1148+
}
1149+
}
1150+
11401151
const serverReadyEnabled = config.serverReadyEnabled !== false;
11411152
if (serverReadyParam && !serverReadyEnabled) {
11421153
logger.info(
@@ -2089,7 +2100,7 @@ export const startDebuggingAndWaitForStop = async (
20892100
if (entryStop.reason === "terminated") {
20902101
throw new Error(
20912102
withRuntimeDiagnostics(
2092-
`Debug session '${effectiveSessionName}' terminated before hitting entry.`,
2103+
`Debug session '${effectiveSessionName}' terminated before hitting entry (unexpected: user cancelled or app exited).`,
20932104
entryStop.session.id
20942105
)
20952106
);
@@ -2152,7 +2163,7 @@ export const startDebuggingAndWaitForStop = async (
21522163
if (finalStop.reason === "terminated") {
21532164
throw new Error(
21542165
withRuntimeDiagnostics(
2155-
`Debug session '${effectiveSessionName}' terminated before hitting a user breakpoint.`,
2166+
`Debug session '${effectiveSessionName}' terminated before hitting a user breakpoint (unexpected: user cancelled or app exited).`,
21562167
finalStop.session.id
21572168
)
21582169
);
@@ -2194,7 +2205,7 @@ export const startDebuggingAndWaitForStop = async (
21942205
if (nextStop.reason === "terminated") {
21952206
throw new Error(
21962207
withRuntimeDiagnostics(
2197-
`Debug session '${effectiveSessionName}' terminated after serverReady processing before hitting a user breakpoint.`,
2208+
`Debug session '${effectiveSessionName}' terminated after serverReady processing before hitting a user breakpoint (unexpected: user cancelled or app exited).`,
21982209
finalStop.session.id
21992210
)
22002211
);

src/stopInfoMarkdown.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { BreakpointDefinition } from "./BreakpointDefinition";
22
import type { StartDebuggerStopInfo } from "./session";
33
import { markdownTable } from "markdown-table";
44
import { config } from "./config";
5+
import { version } from "./generated-meta";
56

67
// Keep rendering logic shared between StartDebuggerTool and ResumeDebugSessionTool.
78

@@ -256,6 +257,7 @@ export const renderStopInfoMarkdown = (params: {
256257
guidance.length > 0 ? guidance.map((item) => `- ${item}`).join("\n") : "";
257258

258259
const successLine = `Success: ${success}`;
260+
const versionLine = `Plugin Version: ${version}`;
259261

260262
const serverReadySection = (() => {
261263
const info = stopInfo.serverReadyInfo;
@@ -289,7 +291,7 @@ export const renderStopInfoMarkdown = (params: {
289291
const sections: Array<{ title: string; body: string }> = [
290292
{
291293
title: "Summary",
292-
body: [successLine, timestampLine, header]
294+
body: [successLine, versionLine, timestampLine, header]
293295
.filter((entry) => entry && entry.trim().length > 0)
294296
.join("\n"),
295297
},

src/test/autoCapture.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ describe("startDebuggingAndWaitForStop - capture-all (variableFilter empty)", ()
4545
const context = await startDebuggingAndWaitForStop(
4646
Object.assign({}, baseParams, {
4747
sessionName: "",
48+
mode: "inspect" as const,
4849
breakpointConfig: {
4950
breakpoints: [
5051
{

src/test/snippetBreakpoints.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,35 @@ describe("snippet-based breakpoints", function () {
9494
}
9595
);
9696
});
97+
98+
it("throws when 'code' snippet is missing (even if line is provided)", async () => {
99+
await activateCopilotDebugger();
100+
const extensionRoot = getExtensionRoot();
101+
const workspaceFolder = path.join(extensionRoot, "test-workspace");
102+
const scriptPath = path.join(workspaceFolder, "test.js");
103+
104+
await assert.rejects(
105+
() =>
106+
startDebuggingAndWaitForStop({
107+
sessionName: "",
108+
workspaceFolder,
109+
nameOrConfiguration: "Run test.js",
110+
breakpointConfig: {
111+
breakpoints: [
112+
{
113+
path: scriptPath,
114+
line: 10,
115+
onHit: "break",
116+
variableFilter: [],
117+
// eslint-disable-next-line ts/no-explicit-any
118+
} as any, // Cast to any to bypass TS check for missing 'code'
119+
],
120+
},
121+
}),
122+
(err: unknown) => {
123+
const msg = err instanceof Error ? err.message : String(err);
124+
return msg.includes("missing required 'code' snippet");
125+
}
126+
);
127+
});
97128
});

0 commit comments

Comments
 (0)