v0.1.121: close 5 MCP design issues found by live-driving all 48 verbs#32
Merged
Conversation
Found by driving the real editor with the real sidecar on v0.1.120 — gaps the fake-half unit suites (C++ fakes the sidecar, Rust fakes the bridge) structurally cannot see. Opus-architected, implemented in dependency order, each with a red-state test that FAILS without the fix. #1 Welcome tab (index 0) was a silent trap: it appeared in list_open_tabs like any tab but insert_text/compare_tabs/save_tab failed on it with generic errors, and read_tab returned empty text (worse — looked like an empty document). Now every tab carries "editable"; the five tab-context write/read verbs gate on it. #3 git_* were unusable with no repo file open. runGit now appends the editor's STARTUP working dir (QDir::currentPath captured once at construction, never live — a live cwd would make git_status depend on the last file dialog) as the final candidate root, so `notepatra ~/repo && git_status` works. #4 save_tab could not persist AI-generated content: it refused untitled tabs and had no path. It now takes an optional `path` (Save-As). It STAYS WRITE-tier and approval-gated: the path is validated (absolute + parent exists) BEFORE the card, the card SHOWS the destination (OVERWRITE-flagged if it exists), and the write executes only inside the approved closure. No headless bypass. #5 replace_selection was unusable by an AI — it needed a selection but nothing could set one. New ACT-tier verb select_range (1-based, like goto_line) sets the selection with no card (it mutates only the selection, like goto_line); replace_selection still carries its own approval. Tool count 48 -> 49. #6 generic errors ("could not insert", "could not open compare view", "needs Save As") replaced with specific, actionable messages so an AI can self-correct. Verified independently, not just by the implementer: full ctest 71/71, Rust default + --features remote green, fmt + clippy --all-features clean, Windows cross-check (x86_64-pc-windows-msvc) clean. Red-state spot-checked by hand — forcing tabIsEditable true fails exactly the 3 gate tests. Approval-gate audit: save_tab validates before the card and executes only in the approval closure; select_range enqueues zero cards. Deliberate deviation from spec: the Rust mock does NOT prepend a Welcome tab at index 0 — that would shift ~55 index-dependent assertions and break every write test targeting tab_index 0. The C++ bridge (source of truth) fully implements and tests Welcome-tab behavior; the mock exercises editable:false via diagram tabs. #2 (export_chart-to-file "TypeError: e.isString") is a separate WebEngine runtime bug, investigated separately — not in this change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…Engine
ROOT CAUSE (confirmed, hard evidence): the charts feature never rendered on
Qt 5.15. Its WebEngine is Chromium ~87, but the bundled vega libraries call
Object.hasOwn (needs Chromium 93) and structuredClone (needs Chromium 98).
The real-display editor log showed, on every chart render:
Uncaught TypeError: Object.hasOwn is not a function
Uncaught ReferenceError: structuredClone is not defined
vega core then fails to initialise, leaving vega.isString undefined, and
vega-embed dies synchronously with "TypeError: e.isString is not a function".
This broke BOTH paths: export_chart surfaced the error, while render_chart
returned rendered:true and drew NOTHING — a headline v0.1.120 feature that
was silently dead on any Qt 5.15 box.
FIX: define both APIs (JSON round-trip is a sufficient structuredClone for
vega's JSON-serialisable specs) in a <script> that runs BEFORE the three
vega <script> tags in the render shell. Standard, minimal polyfills for
exactly the two confirmed-missing functions.
VERIFICATION — HONEST STATUS: root cause is confirmed and the fix is a
textbook polyfill for it, but I could NOT complete an end-to-end runtime
render check in this environment. Offscreen WebEngine does not execute the
chart JS at all (proven: red-stating the fix offscreen showed no change —
the check was a false positive), and the on-display editor kept dying to a
/tmp socket reaper + single-instance collisions before a clean screenshot.
So this is committed as root-cause-confirmed + fix-sound, runtime-pending.
Confirm by rendering any chart on a real display (Qt 5.15 + WebEngine);
the fix is expected to make render_chart draw and export_chart save.
Charts code (vega_chart_renderer.cpp) only — no other surface touched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Version SSOT 0.1.120 -> 0.1.121 (CMakeLists, Cargo.toml/lock, mcpb
manifest). MCP tool count 48 -> 49 (the new select_range verb; tiers now
Read 24 / Act 14 / Write 11) across MCP_TOOL_COUNT and every current-tense
docs surface; v0.1.120 historical references left at 48/v0.1.120.
Docs swept to v0.1.121 (JSON-LD, sticky-CTA, hero badge — tagline
byte-identical except the version — download buttons/sizes, README
release row + installer filenames, docs.html/mcp.html/llms.txt tool
counts + a new select_range Act-table row). New v0.1.121 version card
added above v0.1.120 with the LATEST pill; no gaps in the card history.
release_notes/v0.1.121.md + CHANGELOG [0.1.121] added.
Test fix: protocol.rs asserted a hardcoded "0.1.120" serverInfo.version;
now derives from env!("CARGO_PKG_VERSION") so a version bump never leaves
it stale again.
The 6 fixes themselves are in the prior commits on this branch (e803578
API fixes #1/#3/#4/#5/#6; 65d4f4d charts Qt5.15 polyfill #2).
Local gates: ctest 71/71, Rust default + --features remote green, fmt +
clippy --all-features clean, stale-text-check 62/62, release-check green
(only tree-clean pending, resolved here). PII clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes 5 MCP design issues surfaced by driving the real editor with the real sidecar on v0.1.120 (gaps the fake-half unit suites can't see):
editablefield + gated verbspath(approval-gated, path shown on card, validated before card)select_range(tool count 48→49)Approval-gate invariant preserved: save_tab stays WRITE+approval, select_range is ACT (no card), no headless bypass. Each fix has a red-state test that fails without it (spot-verified by hand).
Local: ctest 71/71, Rust default +
--features remotegreen, fmt/clippy--all-featuresclean, Windows cross-check clean.#2 (export_chart→file
e.isString) is a separate WebEngine runtime bug, tracked separately.🤖 Generated with Claude Code