Skip to content

feat(editor): built-in language features and deterministic formatting baseline (#1380)#1526

Merged
oscharko merged 1 commit into
feat/keiko-agent-native-editor-foundation-and-runtimefrom
claude/issue-1380-editor-language-formatting
Jun 25, 2026
Merged

feat(editor): built-in language features and deterministic formatting baseline (#1380)#1526
oscharko merged 1 commit into
feat/keiko-agent-native-editor-foundation-and-runtimefrom
claude/issue-1380-editor-language-formatting

Conversation

@oscharko

Copy link
Copy Markdown
Contributor

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/markdown even 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)

Decision Change
D1/D6 New strict contracts leaf editor-builtin-capabilities.ts — frozen per-language registry of browser built-in capabilities (syntaxHighlighting, bracketMatching, documentFormatting: "monaco-builtin" | "keiko-language-service" | "none"), exhaustive over EDITOR_LANGUAGE_MODE_IDS, coherence test-pinned.
D5 (AC1/AC2) editorMonacoRuntime.ts imports the basic-languages/{css,scss,less,html} grammars so those buffers actually tokenise and their bundled-worker formatters can attach.
D3 (AC5) EditorRuntimeWidget derives 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.
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 Keiko formatting bridge selector stays ts/js only — no double-registration with Monaco's bundled json/css/html document formatters; pinned by a coherence test.
D8 (AC3/AC4) Reuse the #1201 failure-safe bridge (returns EMPTY_EDITS on any error/cancel/stale) — added regression tests, no behaviour change.

No server change, no contract-shape change, no globals.css change; additive only, schema versions stay "1".

Acceptance Criteria → evidence

  • AC1 Opening a supported file sets the correct language mode — inferMonacoLanguageId + D5 grammar registration; browser e2e asserts the status-bar language label for ts/json/css/scss/less/html/md/yaml and Plain Text for an unknown file (6/6 green).
  • AC2 Theme and tokenization remain correct after reload — on-mount theme re-registration; browser e2e captures editor background + a token colour + data-theme, reloads, and asserts equality.
  • AC3 Format applies only provider-returned deterministic edits — [Keiko Editor] Add diagnostics, symbols, hover, quick info, and formatting hooks #1201 bridge for ts/js (unit-tested) + Monaco's bundled JSON worker; browser e2e reflows valid JSON deterministically.
  • AC4 Formatting failure leaves editor content untouched — bridge EMPTY_EDITS failure path (6 unit scenarios in formatting-bridge.test.ts) + browser e2e asserts a none-source file's buffer is byte-identical after invoking Format.
  • AC5 Provider status reflects unavailable formatting instead of hiding the command inconsistently — D1+D3+D4; component tests (EditorRuntimeWidget.formatting.test.tsx) and browser e2e assert button aria-disabled + status [data-field="formatting"] agree across all three sources.

Deliverables

  • Built-in provider capability entries → the contracts registry (D1).
  • Explicit Format command pipeline for available built-in providers → registry-gated command (D3/D7).
  • Failure-safe edit application path → reused [Keiko Editor] Add diagnostics, symbols, hover, quick info, and formatting hooks #1201 bridge (D8).
  • Browser tests for language mode/theme stability → tests/e2e/editor-formatting-1380.spec.ts + playwright.issue-1380-formatting.config.ts.

Verification

  • npm run typecheck — pass; npm run build:ui — pass.
  • keiko-contracts + keiko-editor suites: 2334/2334; keiko-ui suite: 172 files / 2763 tests pass.
  • Targeted: contracts capability registry + status-bar + bridge coherence (59 new/updated), keiko-ui formatting gating (7), monaco runtime registration (4).
  • Browser e2e npm run test:e2e:formatting-1380: 6/6 passed against the real packaged app.
  • Required GitHub check 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:

  • Format button uses aria-disabled rather than native disabled — 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 via aria-label; ADR-0068 D4 endorses it. Not introduced by this issue; left consistent.
  • TSDoc nit on the status source field — 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

… 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>
@oscharko oscharko merged commit 1f89ec5 into feat/keiko-agent-native-editor-foundation-and-runtime Jun 25, 2026
12 checks passed
@oscharko oscharko deleted the claude/issue-1380-editor-language-formatting branch June 25, 2026 22:32
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.

1 participant