c64-debug-mcp 1.0.13 → 1.0.14

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.
package/dist/http.cjs CHANGED
@@ -66,7 +66,7 @@ var stopReasonSchema = import_zod.z.enum([
66
66
  ]);
67
67
  var sessionHealthSchema = import_zod.z.enum(["not_configured", "starting", "ready", "recovering", "stopped", "error"]);
68
68
  var breakpointKindSchema = import_zod.z.enum(["exec", "read", "write", "read_write"]);
69
- var resetModeSchema = import_zod.z.enum(["soft", "hard"]);
69
+ var resetModeSchema = import_zod.z.enum(["soft", "hard", "nuclear"]);
70
70
  var inputActionSchema = import_zod.z.enum(["press", "release", "tap"]);
71
71
  var joystickControlSchema = import_zod.z.enum(["up", "down", "left", "right", "fire"]);
72
72
  var joystickPortSchema = import_zod.z.union([import_zod.z.literal(1), import_zod.z.literal(2)]);
@@ -1728,7 +1728,17 @@ var ViceSession = class {
1728
1728
  }
1729
1729
  this.#syncMonitorRuntimeState();
1730
1730
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
1731
- void this.#scheduleRecovery();
1731
+ void this.#scheduleRecovery().catch((error) => {
1732
+ this.#writeProcessLogLine(`[recovery-error] ${error instanceof Error ? error.message : String(error)}`);
1733
+ });
1734
+ }
1735
+ });
1736
+ this.#client.on("transport-error", (error) => {
1737
+ this.#writeProcessLogLine(`[monitor-error] transport error: ${error.message}`);
1738
+ if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
1739
+ void this.#scheduleRecovery().catch((recoveryError) => {
1740
+ this.#writeProcessLogLine(`[recovery-error] ${recoveryError instanceof Error ? recoveryError.message : String(recoveryError)}`);
1741
+ });
1732
1742
  }
1733
1743
  });
1734
1744
  this.#client.on("event", (event) => {
@@ -2069,6 +2079,10 @@ var ViceSession = class {
2069
2079
  async resetMachine(mode) {
2070
2080
  return this.#withExecutionLock(async () => {
2071
2081
  await this.#ensureReady();
2082
+ this.#clearHeldInputState();
2083
+ if (mode === "nuclear") {
2084
+ return await this.#performNuclearReset();
2085
+ }
2072
2086
  const wasPaused = this.#explicitPauseActive;
2073
2087
  this.#lastExecutionIntent = "reset";
2074
2088
  this.#writeProcessLogLine(`[tx] execute reset mode=${mode}`);
@@ -2088,6 +2102,67 @@ var ViceSession = class {
2088
2102
  };
2089
2103
  });
2090
2104
  }
2105
+ async #performNuclearReset() {
2106
+ const savedBreakpoints = await this.#captureBreakpointState();
2107
+ const wasPaused = this.#explicitPauseActive;
2108
+ this.#writeProcessLogLine("[nuclear-reset] initiating full VICE process restart");
2109
+ await this.#scheduleRecovery();
2110
+ await this.#restoreBreakpointState(savedBreakpoints);
2111
+ this.#explicitPauseActive = wasPaused;
2112
+ if (wasPaused) {
2113
+ this.#writeProcessLogLine("[nuclear-reset] restoring paused state");
2114
+ await this.pauseExecution();
2115
+ }
2116
+ this.#writeProcessLogLine("[nuclear-reset] completed successfully");
2117
+ const debugState = await this.#readDebugState();
2118
+ return {
2119
+ executionState: debugState.executionState,
2120
+ lastStopReason: debugState.lastStopReason,
2121
+ programCounter: debugState.programCounter,
2122
+ registers: debugState.registers,
2123
+ warnings: []
2124
+ };
2125
+ }
2126
+ async #captureBreakpointState() {
2127
+ try {
2128
+ const result = await this.listBreakpoints(true);
2129
+ return result.breakpoints.map((bp) => ({
2130
+ kind: bp.kind,
2131
+ start: bp.start,
2132
+ end: bp.end,
2133
+ enabled: bp.enabled,
2134
+ temporary: bp.temporary,
2135
+ hasCondition: bp.hasCondition,
2136
+ label: this.#breakpointLabels.get(bp.id) ?? null
2137
+ }));
2138
+ } catch (error) {
2139
+ this.#writeProcessLogLine(`[nuclear-reset] failed to capture breakpoints: ${error instanceof Error ? error.message : String(error)}`);
2140
+ return [];
2141
+ }
2142
+ }
2143
+ async #restoreBreakpointState(savedBreakpoints) {
2144
+ if (savedBreakpoints.length === 0) {
2145
+ return;
2146
+ }
2147
+ this.#writeProcessLogLine(`[nuclear-reset] restoring ${savedBreakpoints.length} breakpoints`);
2148
+ for (const bp of savedBreakpoints) {
2149
+ try {
2150
+ await this.breakpointSet({
2151
+ kind: bp.kind,
2152
+ address: bp.start,
2153
+ length: bp.end - bp.start + 1,
2154
+ enabled: bp.enabled,
2155
+ temporary: bp.temporary,
2156
+ label: bp.label ?? void 0
2157
+ });
2158
+ this.#writeProcessLogLine(`[nuclear-reset] restored breakpoint at $${bp.start.toString(16).toUpperCase()}`);
2159
+ } catch (error) {
2160
+ this.#writeProcessLogLine(
2161
+ `[nuclear-reset] failed to restore breakpoint at $${bp.start.toString(16).toUpperCase()}: ${error instanceof Error ? error.message : String(error)}`
2162
+ );
2163
+ }
2164
+ }
2165
+ }
2091
2166
  async listBreakpoints(includeDisabled = true) {
2092
2167
  await this.#ensureReady();
2093
2168
  this.#writeProcessLogLine(`[tx] breakpoint_list includeDisabled=${includeDisabled}`);
@@ -2802,7 +2877,9 @@ var ViceSession = class {
2802
2877
  makeWarning(`C64 emulator process exited (${code ?? "null"} / ${signal ?? "null"})`, "process_exit")
2803
2878
  ];
2804
2879
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
2805
- void this.#scheduleRecovery();
2880
+ void this.#scheduleRecovery().catch((error) => {
2881
+ this.#writeProcessLogLine(`[recovery-error] ${error instanceof Error ? error.message : String(error)}`);
2882
+ });
2806
2883
  }
2807
2884
  });
2808
2885
  child.once("error", (error) => {
@@ -2815,12 +2892,16 @@ var ViceSession = class {
2815
2892
  this.#transportState = "faulted";
2816
2893
  this.#warnings = [...this.#warnings.filter((warning) => warning.code !== "process_error"), makeWarning(error.message, "process_error")];
2817
2894
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
2818
- void this.#scheduleRecovery();
2895
+ void this.#scheduleRecovery().catch((error2) => {
2896
+ this.#writeProcessLogLine(`[recovery-error] ${error2 instanceof Error ? error2.message : String(error2)}`);
2897
+ });
2819
2898
  }
2820
2899
  });
2821
2900
  }
2822
2901
  #attachProcessLogging(child, binary, args) {
2823
2902
  const logStream = (0, import_node_fs.createWriteStream)(VICE_PROCESS_LOG_PATH, { flags: "a" });
2903
+ logStream.on("error", () => {
2904
+ });
2824
2905
  this.#processLogStream = logStream;
2825
2906
  this.#stdoutMirrorBuffer = "";
2826
2907
  this.#stderrMirrorBuffer = "";
@@ -2854,7 +2935,10 @@ var ViceSession = class {
2854
2935
  logStream.write(`
2855
2936
  === Emulator stream closed ${nowIso()} (${reason}) ===
2856
2937
  `);
2857
- logStream.end();
2938
+ logStream.end(() => {
2939
+ });
2940
+ logStream.on("error", () => {
2941
+ });
2858
2942
  this.#processLogStream = null;
2859
2943
  }
2860
2944
  #mirrorViceOutputChunk(stream, chunk) {
@@ -3697,7 +3781,7 @@ var executeTool = createViceTool({
3697
3781
  inputSchema: import_zod4.z.object({
3698
3782
  action: import_zod4.z.enum(["pause", "resume", "step", "step_over", "step_out", "reset"]),
3699
3783
  count: import_zod4.z.number().int().positive().default(1).describe("Instruction count for step and step_over actions"),
3700
- resetMode: resetModeSchema.default("soft").describe("Reset mode when action is reset"),
3784
+ resetMode: resetModeSchema.default("soft").describe("Reset mode: soft (CPU reset), hard (full machine reset), or nuclear (complete VICE restart)"),
3701
3785
  waitUntilRunningStable: import_zod4.z.boolean().default(false).describe("When action is resume, wait until running becomes stable before returning")
3702
3786
  }),
3703
3787
  dataSchema: debugStateSchema.extend({
package/dist/http.js CHANGED
@@ -43,7 +43,7 @@ var stopReasonSchema = z.enum([
43
43
  ]);
44
44
  var sessionHealthSchema = z.enum(["not_configured", "starting", "ready", "recovering", "stopped", "error"]);
45
45
  var breakpointKindSchema = z.enum(["exec", "read", "write", "read_write"]);
46
- var resetModeSchema = z.enum(["soft", "hard"]);
46
+ var resetModeSchema = z.enum(["soft", "hard", "nuclear"]);
47
47
  var inputActionSchema = z.enum(["press", "release", "tap"]);
48
48
  var joystickControlSchema = z.enum(["up", "down", "left", "right", "fire"]);
49
49
  var joystickPortSchema = z.union([z.literal(1), z.literal(2)]);
@@ -1705,7 +1705,17 @@ var ViceSession = class {
1705
1705
  }
1706
1706
  this.#syncMonitorRuntimeState();
1707
1707
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
1708
- void this.#scheduleRecovery();
1708
+ void this.#scheduleRecovery().catch((error) => {
1709
+ this.#writeProcessLogLine(`[recovery-error] ${error instanceof Error ? error.message : String(error)}`);
1710
+ });
1711
+ }
1712
+ });
1713
+ this.#client.on("transport-error", (error) => {
1714
+ this.#writeProcessLogLine(`[monitor-error] transport error: ${error.message}`);
1715
+ if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
1716
+ void this.#scheduleRecovery().catch((recoveryError) => {
1717
+ this.#writeProcessLogLine(`[recovery-error] ${recoveryError instanceof Error ? recoveryError.message : String(recoveryError)}`);
1718
+ });
1709
1719
  }
1710
1720
  });
1711
1721
  this.#client.on("event", (event) => {
@@ -2046,6 +2056,10 @@ var ViceSession = class {
2046
2056
  async resetMachine(mode) {
2047
2057
  return this.#withExecutionLock(async () => {
2048
2058
  await this.#ensureReady();
2059
+ this.#clearHeldInputState();
2060
+ if (mode === "nuclear") {
2061
+ return await this.#performNuclearReset();
2062
+ }
2049
2063
  const wasPaused = this.#explicitPauseActive;
2050
2064
  this.#lastExecutionIntent = "reset";
2051
2065
  this.#writeProcessLogLine(`[tx] execute reset mode=${mode}`);
@@ -2065,6 +2079,67 @@ var ViceSession = class {
2065
2079
  };
2066
2080
  });
2067
2081
  }
2082
+ async #performNuclearReset() {
2083
+ const savedBreakpoints = await this.#captureBreakpointState();
2084
+ const wasPaused = this.#explicitPauseActive;
2085
+ this.#writeProcessLogLine("[nuclear-reset] initiating full VICE process restart");
2086
+ await this.#scheduleRecovery();
2087
+ await this.#restoreBreakpointState(savedBreakpoints);
2088
+ this.#explicitPauseActive = wasPaused;
2089
+ if (wasPaused) {
2090
+ this.#writeProcessLogLine("[nuclear-reset] restoring paused state");
2091
+ await this.pauseExecution();
2092
+ }
2093
+ this.#writeProcessLogLine("[nuclear-reset] completed successfully");
2094
+ const debugState = await this.#readDebugState();
2095
+ return {
2096
+ executionState: debugState.executionState,
2097
+ lastStopReason: debugState.lastStopReason,
2098
+ programCounter: debugState.programCounter,
2099
+ registers: debugState.registers,
2100
+ warnings: []
2101
+ };
2102
+ }
2103
+ async #captureBreakpointState() {
2104
+ try {
2105
+ const result = await this.listBreakpoints(true);
2106
+ return result.breakpoints.map((bp) => ({
2107
+ kind: bp.kind,
2108
+ start: bp.start,
2109
+ end: bp.end,
2110
+ enabled: bp.enabled,
2111
+ temporary: bp.temporary,
2112
+ hasCondition: bp.hasCondition,
2113
+ label: this.#breakpointLabels.get(bp.id) ?? null
2114
+ }));
2115
+ } catch (error) {
2116
+ this.#writeProcessLogLine(`[nuclear-reset] failed to capture breakpoints: ${error instanceof Error ? error.message : String(error)}`);
2117
+ return [];
2118
+ }
2119
+ }
2120
+ async #restoreBreakpointState(savedBreakpoints) {
2121
+ if (savedBreakpoints.length === 0) {
2122
+ return;
2123
+ }
2124
+ this.#writeProcessLogLine(`[nuclear-reset] restoring ${savedBreakpoints.length} breakpoints`);
2125
+ for (const bp of savedBreakpoints) {
2126
+ try {
2127
+ await this.breakpointSet({
2128
+ kind: bp.kind,
2129
+ address: bp.start,
2130
+ length: bp.end - bp.start + 1,
2131
+ enabled: bp.enabled,
2132
+ temporary: bp.temporary,
2133
+ label: bp.label ?? void 0
2134
+ });
2135
+ this.#writeProcessLogLine(`[nuclear-reset] restored breakpoint at $${bp.start.toString(16).toUpperCase()}`);
2136
+ } catch (error) {
2137
+ this.#writeProcessLogLine(
2138
+ `[nuclear-reset] failed to restore breakpoint at $${bp.start.toString(16).toUpperCase()}: ${error instanceof Error ? error.message : String(error)}`
2139
+ );
2140
+ }
2141
+ }
2142
+ }
2068
2143
  async listBreakpoints(includeDisabled = true) {
2069
2144
  await this.#ensureReady();
2070
2145
  this.#writeProcessLogLine(`[tx] breakpoint_list includeDisabled=${includeDisabled}`);
@@ -2779,7 +2854,9 @@ var ViceSession = class {
2779
2854
  makeWarning(`C64 emulator process exited (${code ?? "null"} / ${signal ?? "null"})`, "process_exit")
2780
2855
  ];
2781
2856
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
2782
- void this.#scheduleRecovery();
2857
+ void this.#scheduleRecovery().catch((error) => {
2858
+ this.#writeProcessLogLine(`[recovery-error] ${error instanceof Error ? error.message : String(error)}`);
2859
+ });
2783
2860
  }
2784
2861
  });
2785
2862
  child.once("error", (error) => {
@@ -2792,12 +2869,16 @@ var ViceSession = class {
2792
2869
  this.#transportState = "faulted";
2793
2870
  this.#warnings = [...this.#warnings.filter((warning) => warning.code !== "process_error"), makeWarning(error.message, "process_error")];
2794
2871
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
2795
- void this.#scheduleRecovery();
2872
+ void this.#scheduleRecovery().catch((error2) => {
2873
+ this.#writeProcessLogLine(`[recovery-error] ${error2 instanceof Error ? error2.message : String(error2)}`);
2874
+ });
2796
2875
  }
2797
2876
  });
2798
2877
  }
2799
2878
  #attachProcessLogging(child, binary, args) {
2800
2879
  const logStream = createWriteStream(VICE_PROCESS_LOG_PATH, { flags: "a" });
2880
+ logStream.on("error", () => {
2881
+ });
2801
2882
  this.#processLogStream = logStream;
2802
2883
  this.#stdoutMirrorBuffer = "";
2803
2884
  this.#stderrMirrorBuffer = "";
@@ -2831,7 +2912,10 @@ var ViceSession = class {
2831
2912
  logStream.write(`
2832
2913
  === Emulator stream closed ${nowIso()} (${reason}) ===
2833
2914
  `);
2834
- logStream.end();
2915
+ logStream.end(() => {
2916
+ });
2917
+ logStream.on("error", () => {
2918
+ });
2835
2919
  this.#processLogStream = null;
2836
2920
  }
2837
2921
  #mirrorViceOutputChunk(stream, chunk) {
@@ -3674,7 +3758,7 @@ var executeTool = createViceTool({
3674
3758
  inputSchema: z3.object({
3675
3759
  action: z3.enum(["pause", "resume", "step", "step_over", "step_out", "reset"]),
3676
3760
  count: z3.number().int().positive().default(1).describe("Instruction count for step and step_over actions"),
3677
- resetMode: resetModeSchema.default("soft").describe("Reset mode when action is reset"),
3761
+ resetMode: resetModeSchema.default("soft").describe("Reset mode: soft (CPU reset), hard (full machine reset), or nuclear (complete VICE restart)"),
3678
3762
  waitUntilRunningStable: z3.boolean().default(false).describe("When action is resume, wait until running becomes stable before returning")
3679
3763
  }),
3680
3764
  dataSchema: debugStateSchema.extend({
package/dist/stdio.cjs CHANGED
@@ -63,7 +63,7 @@ var stopReasonSchema = import_zod.z.enum([
63
63
  ]);
64
64
  var sessionHealthSchema = import_zod.z.enum(["not_configured", "starting", "ready", "recovering", "stopped", "error"]);
65
65
  var breakpointKindSchema = import_zod.z.enum(["exec", "read", "write", "read_write"]);
66
- var resetModeSchema = import_zod.z.enum(["soft", "hard"]);
66
+ var resetModeSchema = import_zod.z.enum(["soft", "hard", "nuclear"]);
67
67
  var inputActionSchema = import_zod.z.enum(["press", "release", "tap"]);
68
68
  var joystickControlSchema = import_zod.z.enum(["up", "down", "left", "right", "fire"]);
69
69
  var joystickPortSchema = import_zod.z.union([import_zod.z.literal(1), import_zod.z.literal(2)]);
@@ -1725,7 +1725,17 @@ var ViceSession = class {
1725
1725
  }
1726
1726
  this.#syncMonitorRuntimeState();
1727
1727
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
1728
- void this.#scheduleRecovery();
1728
+ void this.#scheduleRecovery().catch((error) => {
1729
+ this.#writeProcessLogLine(`[recovery-error] ${error instanceof Error ? error.message : String(error)}`);
1730
+ });
1731
+ }
1732
+ });
1733
+ this.#client.on("transport-error", (error) => {
1734
+ this.#writeProcessLogLine(`[monitor-error] transport error: ${error.message}`);
1735
+ if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
1736
+ void this.#scheduleRecovery().catch((recoveryError) => {
1737
+ this.#writeProcessLogLine(`[recovery-error] ${recoveryError instanceof Error ? recoveryError.message : String(recoveryError)}`);
1738
+ });
1729
1739
  }
1730
1740
  });
1731
1741
  this.#client.on("event", (event) => {
@@ -2066,6 +2076,10 @@ var ViceSession = class {
2066
2076
  async resetMachine(mode) {
2067
2077
  return this.#withExecutionLock(async () => {
2068
2078
  await this.#ensureReady();
2079
+ this.#clearHeldInputState();
2080
+ if (mode === "nuclear") {
2081
+ return await this.#performNuclearReset();
2082
+ }
2069
2083
  const wasPaused = this.#explicitPauseActive;
2070
2084
  this.#lastExecutionIntent = "reset";
2071
2085
  this.#writeProcessLogLine(`[tx] execute reset mode=${mode}`);
@@ -2085,6 +2099,67 @@ var ViceSession = class {
2085
2099
  };
2086
2100
  });
2087
2101
  }
2102
+ async #performNuclearReset() {
2103
+ const savedBreakpoints = await this.#captureBreakpointState();
2104
+ const wasPaused = this.#explicitPauseActive;
2105
+ this.#writeProcessLogLine("[nuclear-reset] initiating full VICE process restart");
2106
+ await this.#scheduleRecovery();
2107
+ await this.#restoreBreakpointState(savedBreakpoints);
2108
+ this.#explicitPauseActive = wasPaused;
2109
+ if (wasPaused) {
2110
+ this.#writeProcessLogLine("[nuclear-reset] restoring paused state");
2111
+ await this.pauseExecution();
2112
+ }
2113
+ this.#writeProcessLogLine("[nuclear-reset] completed successfully");
2114
+ const debugState = await this.#readDebugState();
2115
+ return {
2116
+ executionState: debugState.executionState,
2117
+ lastStopReason: debugState.lastStopReason,
2118
+ programCounter: debugState.programCounter,
2119
+ registers: debugState.registers,
2120
+ warnings: []
2121
+ };
2122
+ }
2123
+ async #captureBreakpointState() {
2124
+ try {
2125
+ const result = await this.listBreakpoints(true);
2126
+ return result.breakpoints.map((bp) => ({
2127
+ kind: bp.kind,
2128
+ start: bp.start,
2129
+ end: bp.end,
2130
+ enabled: bp.enabled,
2131
+ temporary: bp.temporary,
2132
+ hasCondition: bp.hasCondition,
2133
+ label: this.#breakpointLabels.get(bp.id) ?? null
2134
+ }));
2135
+ } catch (error) {
2136
+ this.#writeProcessLogLine(`[nuclear-reset] failed to capture breakpoints: ${error instanceof Error ? error.message : String(error)}`);
2137
+ return [];
2138
+ }
2139
+ }
2140
+ async #restoreBreakpointState(savedBreakpoints) {
2141
+ if (savedBreakpoints.length === 0) {
2142
+ return;
2143
+ }
2144
+ this.#writeProcessLogLine(`[nuclear-reset] restoring ${savedBreakpoints.length} breakpoints`);
2145
+ for (const bp of savedBreakpoints) {
2146
+ try {
2147
+ await this.breakpointSet({
2148
+ kind: bp.kind,
2149
+ address: bp.start,
2150
+ length: bp.end - bp.start + 1,
2151
+ enabled: bp.enabled,
2152
+ temporary: bp.temporary,
2153
+ label: bp.label ?? void 0
2154
+ });
2155
+ this.#writeProcessLogLine(`[nuclear-reset] restored breakpoint at $${bp.start.toString(16).toUpperCase()}`);
2156
+ } catch (error) {
2157
+ this.#writeProcessLogLine(
2158
+ `[nuclear-reset] failed to restore breakpoint at $${bp.start.toString(16).toUpperCase()}: ${error instanceof Error ? error.message : String(error)}`
2159
+ );
2160
+ }
2161
+ }
2162
+ }
2088
2163
  async listBreakpoints(includeDisabled = true) {
2089
2164
  await this.#ensureReady();
2090
2165
  this.#writeProcessLogLine(`[tx] breakpoint_list includeDisabled=${includeDisabled}`);
@@ -2799,7 +2874,9 @@ var ViceSession = class {
2799
2874
  makeWarning(`C64 emulator process exited (${code ?? "null"} / ${signal ?? "null"})`, "process_exit")
2800
2875
  ];
2801
2876
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
2802
- void this.#scheduleRecovery();
2877
+ void this.#scheduleRecovery().catch((error) => {
2878
+ this.#writeProcessLogLine(`[recovery-error] ${error instanceof Error ? error.message : String(error)}`);
2879
+ });
2803
2880
  }
2804
2881
  });
2805
2882
  child.once("error", (error) => {
@@ -2812,12 +2889,16 @@ var ViceSession = class {
2812
2889
  this.#transportState = "faulted";
2813
2890
  this.#warnings = [...this.#warnings.filter((warning) => warning.code !== "process_error"), makeWarning(error.message, "process_error")];
2814
2891
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
2815
- void this.#scheduleRecovery();
2892
+ void this.#scheduleRecovery().catch((error2) => {
2893
+ this.#writeProcessLogLine(`[recovery-error] ${error2 instanceof Error ? error2.message : String(error2)}`);
2894
+ });
2816
2895
  }
2817
2896
  });
2818
2897
  }
2819
2898
  #attachProcessLogging(child, binary, args) {
2820
2899
  const logStream = (0, import_node_fs.createWriteStream)(VICE_PROCESS_LOG_PATH, { flags: "a" });
2900
+ logStream.on("error", () => {
2901
+ });
2821
2902
  this.#processLogStream = logStream;
2822
2903
  this.#stdoutMirrorBuffer = "";
2823
2904
  this.#stderrMirrorBuffer = "";
@@ -2851,7 +2932,10 @@ var ViceSession = class {
2851
2932
  logStream.write(`
2852
2933
  === Emulator stream closed ${nowIso()} (${reason}) ===
2853
2934
  `);
2854
- logStream.end();
2935
+ logStream.end(() => {
2936
+ });
2937
+ logStream.on("error", () => {
2938
+ });
2855
2939
  this.#processLogStream = null;
2856
2940
  }
2857
2941
  #mirrorViceOutputChunk(stream, chunk) {
@@ -3694,7 +3778,7 @@ var executeTool = createViceTool({
3694
3778
  inputSchema: import_zod4.z.object({
3695
3779
  action: import_zod4.z.enum(["pause", "resume", "step", "step_over", "step_out", "reset"]),
3696
3780
  count: import_zod4.z.number().int().positive().default(1).describe("Instruction count for step and step_over actions"),
3697
- resetMode: resetModeSchema.default("soft").describe("Reset mode when action is reset"),
3781
+ resetMode: resetModeSchema.default("soft").describe("Reset mode: soft (CPU reset), hard (full machine reset), or nuclear (complete VICE restart)"),
3698
3782
  waitUntilRunningStable: import_zod4.z.boolean().default(false).describe("When action is resume, wait until running becomes stable before returning")
3699
3783
  }),
3700
3784
  dataSchema: debugStateSchema.extend({
package/dist/stdio.js CHANGED
@@ -40,7 +40,7 @@ var stopReasonSchema = z.enum([
40
40
  ]);
41
41
  var sessionHealthSchema = z.enum(["not_configured", "starting", "ready", "recovering", "stopped", "error"]);
42
42
  var breakpointKindSchema = z.enum(["exec", "read", "write", "read_write"]);
43
- var resetModeSchema = z.enum(["soft", "hard"]);
43
+ var resetModeSchema = z.enum(["soft", "hard", "nuclear"]);
44
44
  var inputActionSchema = z.enum(["press", "release", "tap"]);
45
45
  var joystickControlSchema = z.enum(["up", "down", "left", "right", "fire"]);
46
46
  var joystickPortSchema = z.union([z.literal(1), z.literal(2)]);
@@ -1702,7 +1702,17 @@ var ViceSession = class {
1702
1702
  }
1703
1703
  this.#syncMonitorRuntimeState();
1704
1704
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
1705
- void this.#scheduleRecovery();
1705
+ void this.#scheduleRecovery().catch((error) => {
1706
+ this.#writeProcessLogLine(`[recovery-error] ${error instanceof Error ? error.message : String(error)}`);
1707
+ });
1708
+ }
1709
+ });
1710
+ this.#client.on("transport-error", (error) => {
1711
+ this.#writeProcessLogLine(`[monitor-error] transport error: ${error.message}`);
1712
+ if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
1713
+ void this.#scheduleRecovery().catch((recoveryError) => {
1714
+ this.#writeProcessLogLine(`[recovery-error] ${recoveryError instanceof Error ? recoveryError.message : String(recoveryError)}`);
1715
+ });
1706
1716
  }
1707
1717
  });
1708
1718
  this.#client.on("event", (event) => {
@@ -2043,6 +2053,10 @@ var ViceSession = class {
2043
2053
  async resetMachine(mode) {
2044
2054
  return this.#withExecutionLock(async () => {
2045
2055
  await this.#ensureReady();
2056
+ this.#clearHeldInputState();
2057
+ if (mode === "nuclear") {
2058
+ return await this.#performNuclearReset();
2059
+ }
2046
2060
  const wasPaused = this.#explicitPauseActive;
2047
2061
  this.#lastExecutionIntent = "reset";
2048
2062
  this.#writeProcessLogLine(`[tx] execute reset mode=${mode}`);
@@ -2062,6 +2076,67 @@ var ViceSession = class {
2062
2076
  };
2063
2077
  });
2064
2078
  }
2079
+ async #performNuclearReset() {
2080
+ const savedBreakpoints = await this.#captureBreakpointState();
2081
+ const wasPaused = this.#explicitPauseActive;
2082
+ this.#writeProcessLogLine("[nuclear-reset] initiating full VICE process restart");
2083
+ await this.#scheduleRecovery();
2084
+ await this.#restoreBreakpointState(savedBreakpoints);
2085
+ this.#explicitPauseActive = wasPaused;
2086
+ if (wasPaused) {
2087
+ this.#writeProcessLogLine("[nuclear-reset] restoring paused state");
2088
+ await this.pauseExecution();
2089
+ }
2090
+ this.#writeProcessLogLine("[nuclear-reset] completed successfully");
2091
+ const debugState = await this.#readDebugState();
2092
+ return {
2093
+ executionState: debugState.executionState,
2094
+ lastStopReason: debugState.lastStopReason,
2095
+ programCounter: debugState.programCounter,
2096
+ registers: debugState.registers,
2097
+ warnings: []
2098
+ };
2099
+ }
2100
+ async #captureBreakpointState() {
2101
+ try {
2102
+ const result = await this.listBreakpoints(true);
2103
+ return result.breakpoints.map((bp) => ({
2104
+ kind: bp.kind,
2105
+ start: bp.start,
2106
+ end: bp.end,
2107
+ enabled: bp.enabled,
2108
+ temporary: bp.temporary,
2109
+ hasCondition: bp.hasCondition,
2110
+ label: this.#breakpointLabels.get(bp.id) ?? null
2111
+ }));
2112
+ } catch (error) {
2113
+ this.#writeProcessLogLine(`[nuclear-reset] failed to capture breakpoints: ${error instanceof Error ? error.message : String(error)}`);
2114
+ return [];
2115
+ }
2116
+ }
2117
+ async #restoreBreakpointState(savedBreakpoints) {
2118
+ if (savedBreakpoints.length === 0) {
2119
+ return;
2120
+ }
2121
+ this.#writeProcessLogLine(`[nuclear-reset] restoring ${savedBreakpoints.length} breakpoints`);
2122
+ for (const bp of savedBreakpoints) {
2123
+ try {
2124
+ await this.breakpointSet({
2125
+ kind: bp.kind,
2126
+ address: bp.start,
2127
+ length: bp.end - bp.start + 1,
2128
+ enabled: bp.enabled,
2129
+ temporary: bp.temporary,
2130
+ label: bp.label ?? void 0
2131
+ });
2132
+ this.#writeProcessLogLine(`[nuclear-reset] restored breakpoint at $${bp.start.toString(16).toUpperCase()}`);
2133
+ } catch (error) {
2134
+ this.#writeProcessLogLine(
2135
+ `[nuclear-reset] failed to restore breakpoint at $${bp.start.toString(16).toUpperCase()}: ${error instanceof Error ? error.message : String(error)}`
2136
+ );
2137
+ }
2138
+ }
2139
+ }
2065
2140
  async listBreakpoints(includeDisabled = true) {
2066
2141
  await this.#ensureReady();
2067
2142
  this.#writeProcessLogLine(`[tx] breakpoint_list includeDisabled=${includeDisabled}`);
@@ -2776,7 +2851,9 @@ var ViceSession = class {
2776
2851
  makeWarning(`C64 emulator process exited (${code ?? "null"} / ${signal ?? "null"})`, "process_exit")
2777
2852
  ];
2778
2853
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
2779
- void this.#scheduleRecovery();
2854
+ void this.#scheduleRecovery().catch((error) => {
2855
+ this.#writeProcessLogLine(`[recovery-error] ${error instanceof Error ? error.message : String(error)}`);
2856
+ });
2780
2857
  }
2781
2858
  });
2782
2859
  child.once("error", (error) => {
@@ -2789,12 +2866,16 @@ var ViceSession = class {
2789
2866
  this.#transportState = "faulted";
2790
2867
  this.#warnings = [...this.#warnings.filter((warning) => warning.code !== "process_error"), makeWarning(error.message, "process_error")];
2791
2868
  if (!this.#suppressRecovery && !this.#shuttingDown && this.#config) {
2792
- void this.#scheduleRecovery();
2869
+ void this.#scheduleRecovery().catch((error2) => {
2870
+ this.#writeProcessLogLine(`[recovery-error] ${error2 instanceof Error ? error2.message : String(error2)}`);
2871
+ });
2793
2872
  }
2794
2873
  });
2795
2874
  }
2796
2875
  #attachProcessLogging(child, binary, args) {
2797
2876
  const logStream = createWriteStream(VICE_PROCESS_LOG_PATH, { flags: "a" });
2877
+ logStream.on("error", () => {
2878
+ });
2798
2879
  this.#processLogStream = logStream;
2799
2880
  this.#stdoutMirrorBuffer = "";
2800
2881
  this.#stderrMirrorBuffer = "";
@@ -2828,7 +2909,10 @@ var ViceSession = class {
2828
2909
  logStream.write(`
2829
2910
  === Emulator stream closed ${nowIso()} (${reason}) ===
2830
2911
  `);
2831
- logStream.end();
2912
+ logStream.end(() => {
2913
+ });
2914
+ logStream.on("error", () => {
2915
+ });
2832
2916
  this.#processLogStream = null;
2833
2917
  }
2834
2918
  #mirrorViceOutputChunk(stream, chunk) {
@@ -3671,7 +3755,7 @@ var executeTool = createViceTool({
3671
3755
  inputSchema: z3.object({
3672
3756
  action: z3.enum(["pause", "resume", "step", "step_over", "step_out", "reset"]),
3673
3757
  count: z3.number().int().positive().default(1).describe("Instruction count for step and step_over actions"),
3674
- resetMode: resetModeSchema.default("soft").describe("Reset mode when action is reset"),
3758
+ resetMode: resetModeSchema.default("soft").describe("Reset mode: soft (CPU reset), hard (full machine reset), or nuclear (complete VICE restart)"),
3675
3759
  waitUntilRunningStable: z3.boolean().default(false).describe("When action is resume, wait until running becomes stable before returning")
3676
3760
  }),
3677
3761
  dataSchema: debugStateSchema.extend({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c64-debug-mcp",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "Model Context Protocol server for C64 debugging via VICE emulator",
5
5
  "type": "module",
6
6
  "keywords": [