Skip to content

feat: logpoints — set_breakpoint logMessage logs without pausing (fixes #235) - #268

Merged
debugmcpdev merged 1 commit into
mainfrom
feat/logpoints-235
Aug 5, 2026
Merged

feat: logpoints — set_breakpoint logMessage logs without pausing (fixes #235)#268
debugmcpdev merged 1 commit into
mainfrom
feat/logpoints-235

Conversation

@debugmcpdev

Copy link
Copy Markdown
Collaborator

Closes #235. Builds on #267 (#236).

Logpoints are the prod-safe just-in-time diagnostics primitive: plant them at suspect lines, let the program run at full speed, and read interpolated values from get_output — no pauses, no pre-instrumented logging. This also closes the doc–reality gap where docs/javascript/README.md documented a logMessage parameter that never existed.

What's new

set_breakpoint accepts an optional logMessage (DAP SourceBreakpoint.logMessage, {expr} interpolation). The adapter logs instead of pausing; messages flow through the existing #218/#224 output-capture path into get_output and the debug://sessions/{id}/output resource. condition combines with logMessage per DAP semantics. Logpoints appear in list_breakpoints distinguished by their logMessage field.

Capability gating (hybrid, static-first). New AdapterPolicy.supportsLogPoints (python/js/go/rust/mock true, java/dotnet false, ruby unknown):

Pipeline fix underneath: one mapper, four construction sites

There were four independent places building setBreakpoints arrays, each mapping its own subset of fields (suspendPolicy already demonstrated the bug class — it silently vanished on every launch). A single shared toSourceBreakpoint in @debugmcp/shared now feeds all four (SessionManager live re-send, worker initial breakpoints, connection-manager helper, js-debug handshake), and initialBreakpoints carries logMessage/suspendPolicy end-to-end with message-parser validation.

⚠️ Intentional behavior change riding along: launch-time suspendPolicy is now honored for Java instead of silently dropped.

Mock adapter

Simulates logpoints for hermetic e2e: advertises supportsLogPoints, retains logMessage on stored breakpoints, and its run simulation emits output events (naive {expr} interpolation) instead of stopping at logpoint lines — shared walk for both launch and continue paths.

Tests

  • TDD units at every layer: shared mapper (key-omission semantics), session store/live-send/initialBreakpoints snapshot, message-parser accept/reject, connection-manager mapping, worker forwarding, js-debug handshake mapping, server gating (all four verdicts), and the launch-time capability drift annotation.
  • E2E: new tests/e2e/mcp-server-logpoints.test.ts, language-parameterized across all 8 adapters — python/javascript/go/rust/mock log without pausing (verified against the real adapters); java/dotnet fail fast; ruby warns. 8/8 pass locally. Python additionally asserts real interpolation (LP-MARK a=1).
  • Dogfooded live via the dev proxy: a logpoint on fibonacci.py's iteration line streamed LOGPOINT a=0 b=1a=21 b=34 into get_output while the program ran to completion, never pausing.

Docs

tool-reference (logpoints section + adapter support matrix), docs/javascript/README.md (the phantom example is now true), jit-diagnostics README (non-breaking inspection pattern), both skill copies + all per-language references, CHANGELOG.

🤖 Generated with Claude Code

…tput buffer

- set_breakpoint accepts logMessage: instead of pausing, the adapter logs
  the message ({expr} interpolated with live values) as DAP output, which
  lands in the per-session buffer readable via get_output and the output
  resource. condition may be combined with logMessage (DAP semantics).
- New shared toSourceBreakpoint mapper feeds ALL FOUR setBreakpoints
  construction sites (SessionManager live re-send, worker initial
  breakpoints, connection-manager helper, js-debug handshake), killing the
  field-drop bug class — this also fixes suspendPolicy being silently
  dropped on the launch path (Java behavior change: launch-time
  suspendPolicy is now honored).
- initialBreakpoints carry logMessage + suspendPolicy end-to-end
  (proxy-config, worker interfaces, message-parser validation).
- Hybrid capability gating: AdapterPolicy.supportsLogPoints (python/js/go/
  rust/mock true, java/dotnet false, ruby unknown). Known-unsupported
  adapters fail fast with UnsupportedFeatureError; unknown support is
  accepted with a warning and re-checked against live capabilities at
  launch (drift warning annotates the stored breakpoint).
- Mock adapter simulates logpoints: advertises supportsLogPoints, retains
  logMessage, and its run simulation emits output events (naive {expr}
  interpolation) instead of stopping at logpoint lines.
- E2E: new language-parameterized tests/e2e/mcp-server-logpoints.test.ts —
  python/javascript/go/rust/mock log without pausing (verified against real
  adapters), java/dotnet reject with a clear error, ruby warns. 8/8 pass
  locally. Dogfooded live: a logpoint on a Python hot loop streamed
  interpolated a/b values into get_output while the program ran to
  completion.
- Docs: tool-reference logpoints section + adapter support matrix,
  docs/javascript/README.md's previously-phantom logMessage example is now
  real, jit-diagnostics README teaches the non-breaking pattern, skill
  copies + per-language references updated, CHANGELOG.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.72727% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/server.ts 95.83% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@debugmcpdev
debugmcpdev merged commit 85cbe4c into main Aug 5, 2026
10 checks passed
@debugmcpdev
debugmcpdev deleted the feat/logpoints-235 branch August 5, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Logpoints: non-breaking breakpoints that emit a message into the output buffer

2 participants