feat(editor): built-in language features and deterministic formatting baseline (#1380)#1526
Merged
Conversation
… baseline (#1380) Make the explicit Format command + provider status reflect what is actually reachable in the browser, and register the syntax grammars every supported language needs, per ADR-0068 (Epic #1491). - D1: new strict contracts leaf `editor-builtin-capabilities.ts` — the single editor-tier source of truth for per-language browser built-in capabilities (syntaxHighlighting, bracketMatching, documentFormatting source), exhaustive over EDITOR_LANGUAGE_MODE_IDS and coherence-pinned by test. - D3/D5 (AC1/AC5): editorMonacoRuntime registers the css/scss/less/html basic-languages grammars so those buffers tokenise; EditorRuntimeWidget derives Format availability from the registry (monaco-builtin for json/css/scss/less/html; keiko-language-service for ts/js; none otherwise) so yaml/markdown no longer advertise a formatter the browser cannot reach. - D4 (AC5): a content-free `formatting` status field, fed the same degraded-aware value that gates the Format button + its dynamic aria-label, so command and status can never disagree. - D7: the Keiko formatting bridge selector stays ts/js only (no double-registration with Monaco's bundled json/css/html workers); pinned by a coherence test. - AC3/AC4: reuse the #1201 failure-safe bridge (EMPTY_EDITS on failure) — added tests, no behaviour change. - D4 deliverable: packaged-app Playwright browser evidence (editor-formatting-1380.spec.ts) for language mode, syntax highlighting, dark-theme/tokenisation after reload, per-source Format availability, and the no-formatter failure-safe path. Additive only; no server change, no contract-shape change, schema versions stay "1". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1f89ec5
into
feat/keiko-agent-native-editor-foundation-and-runtime
12 checks passed
72 tasks
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.
Summary
Resolves the Issue #1380 (Epic #1491) baseline for built-in editor language features and deterministic formatting, per ADR-0068. This is a wire-up-and-make-consistent change with one real correctness fix — not a new subsystem.
Refs #1380.The core defect fixed: the Format command/button was driven by the server language-service capability set, which advertises formatting for
yaml/markdowneven though the browser has no registered Monaco formatter for them — so the button appeared enabled and silently did nothing (the AC5 "command hidden inconsistently" problem). The product now has a single editor-tier source of truth for what formatting is actually reachable in the browser, and the command + status derive from it.What changed (by ADR-0068 decision)
editor-builtin-capabilities.ts— frozen per-language registry of browser built-in capabilities (syntaxHighlighting,bracketMatching,documentFormatting: "monaco-builtin" | "keiko-language-service" | "none"), exhaustive overEDITOR_LANGUAGE_MODE_IDS, coherence test-pinned.editorMonacoRuntime.tsimports thebasic-languages/{css,scss,less,html}grammars so those buffers actually tokenise and their bundled-worker formatters can attach.EditorRuntimeWidgetderives Format availability from the registry:monaco-builtin(json/css/scss/less/html) → reachable;keiko-language-service(ts/js) → reachable iff the server provider is up;none→ unavailable.formattingstatus field fed the same degraded-aware value that gates the Format button + its dynamicaria-label, so command and status can never disagree.EMPTY_EDITSon any error/cancel/stale) — added regression tests, no behaviour change.No server change, no contract-shape change, no
globals.csschange; additive only, schema versions stay"1".Acceptance Criteria → evidence
inferMonacoLanguageId+ D5 grammar registration; browser e2e asserts the status-bar language label for ts/json/css/scss/less/html/md/yaml andPlain Textfor an unknown file (6/6 green).data-theme, reloads, and asserts equality.EMPTY_EDITSfailure path (6 unit scenarios informatting-bridge.test.ts) + browser e2e asserts anone-source file's buffer is byte-identical after invoking Format.EditorRuntimeWidget.formatting.test.tsx) and browser e2e assert buttonaria-disabled+ status[data-field="formatting"]agree across all three sources.Deliverables
tests/e2e/editor-formatting-1380.spec.ts+playwright.issue-1380-formatting.config.ts.Verification
npm run typecheck— pass;npm run build:ui— pass.npm run test:e2e:formatting-1380: 6/6 passed against the real packaged app.ci— see checks below.Review disposition
Adversarial multi-lens review (correctness / architecture+ADR / a11y / tests / security+gates): SHIP (4 lenses SHIP, a11y SHIP-with-fixes). Two confirmed findings, both non-blocking:
aria-disabledrather than nativedisabled— intentional and pre-existing: all three editor-toolbar buttons (Save, Generate Tests, Format) use this focusable-but-disabled pattern so screen-reader users can discover the control and hear the reason viaaria-label; ADR-0068 D4 endorses it. Not introduced by this issue; left consistent.sourcefield — already documented in code; skipped.Out of scope (confirmed)
Format-on-save, model-based formatting, external LSP startup, deep semantic refactoring. yaml/markdown/python/… remain
"none"for browser formatting by design (the server may format some, but that is outside the explicit-browser-command scope).🤖 Generated with Claude Code