Skip to content

feat: per-block direction detection in Auto mode - #2

Merged
BenKalsky merged 8 commits into
masterfrom
feat/per-block-direction
Aug 4, 2026
Merged

feat: per-block direction detection in Auto mode#2
BenKalsky merged 8 commits into
masterfrom
feat/per-block-direction

Conversation

@BenKalsky

Copy link
Copy Markdown
Member

Summary

Auto mode previously used unicode-bidi: plaintext on response paragraphs, which picks direction from the first strong character. In Hebrew conversations this caused: English-first mixed lines drifting left, list bullets on the wrong side, and hard-to-read mixed Hebrew/English text.

This PR switches Auto mode to per-block direction detection: a JS walker sets dir="rtl"/dir="ltr" on each block element (p, li, h1h6, blockquote) inside .YBYrtl bubbles by presence of Hebrew/Arabic/Persian characters, and the CSS keys off the dir attribute instead of plaintext.

  • Mixed lines (even English-first) → right-aligned, bullets on the right, readable
  • Pure-English blocks (headings like delta sound) → stay naturally left-aligned
  • Code blocks, tool output, thinking blocks → untouched (skip selector)
  • Streaming-safe: debounced MutationObserver re-tags as text arrives (same pattern as the BiDi stripper); observer filters attribute mutations to class only so its own dir writes can't self-trigger

Spec: docs/superpowers/specs/2026-08-04-auto-mode-per-block-direction-design.md

Testing

  • npm run build clean, npm test (concurrency, 8 simulated windows) passes
  • Manually verified in Antigravity IDE (v0.5.1 VSIX): mixed Hebrew/English replies align right and read correctly, bullets on the right, pure-English headings stay left, code blocks LTR, streaming settles correctly

Round 0 local pre-review skipped (Codex plugin slash commands unavailable in this session); cloud loop is the gate.

🤖 Generated with Claude Code

Response blocks now get dir=rtl/ltr by presence of RTL characters instead
of first-strong-character plaintext heuristic. Fixes English-first mixed
lines drifting left, bullets on the wrong side, and hard-to-read mixed
Hebrew/English text. Pure-English blocks stay naturally left-aligned.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 23:44
@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: edb0c90575

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/content.ts Outdated
var SKIP_SEL = '[class*="codeBlockWrapper_"],pre,code,[class*="toolUse_"],[class*="toolResult_"],[class*="thinkingContent_"]';

function tagBlocks(bubble) {
var els = bubble.querySelectorAll(BLOCK_SEL);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict the walker to markdown containers

When an RTL timeline bubble contains non-markdown UI with matching tags—such as a <p> or <li> inside a tool summary/body—this bubble-wide query assigns that element a native dir attribute even though tool UI is intended to remain LTR. The skip selector only covers toolUse_ and toolResult_, while the existing LTR overrides identify additional tool containers such as toolSummary_, toolBody_, and toolBodyRow_; a direction specified on their child is not neutralized by an inherited direction on the container. Query blocks only beneath the eligible markdown root_ elements (while preserving the exclusions), or skip every protected tool/UI container.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves Auto mode RTL handling by moving from unicode-bidi: plaintext (first-strong-character direction) to per-block direction tagging, so mixed Hebrew/English blocks render with more consistent alignment and list marker placement while keeping pure-LTR blocks naturally LTR.

Changes:

  • Update Auto-mode CSS to style markdown blocks based on dir="rtl" / dir="ltr" attributes instead of relying on unicode-bidi: plaintext.
  • Add Auto-mode webview JS that walks block elements inside .YBYrtl bubbles and sets dir per block based on presence of RTL characters, with a debounced MutationObserver for streaming updates.
  • Bump extension version to 0.5.1 and document the change via a new spec and changelog entry.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/content.ts Switch Auto-mode styling to dir-based per-block direction and add a JS block walker + observer to tag blocks during streaming.
package.json Bump extension version to 0.5.1.
docs/superpowers/specs/2026-08-04-auto-mode-per-block-direction-design.md Add design/spec documentation for the per-block direction approach.
CHANGELOG.md Add v0.5.1 entry describing the Auto-mode per-block direction change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/content.ts Outdated
Comment thread src/content.ts Outdated
Comment on lines +944 to +948
new MutationObserver(function() {
if (dirTimer) return;
dirTimer = setTimeout(function() {
dirTimer = null;
scanAll();
Comment thread src/content.ts Outdated
…rs (Codex round-1 P2)

The walker tagged block elements bubble-wide, so a <p>/<li> inside tool
UI (toolSummary_/toolBody_ etc.) could receive a native dir attribute,
which is not neutralized by the container's LTR direction rules. Blocks
are now queried only under [class*="root_"] markdown containers, and
the skip selector covers every container the LTR overrides protect.

Adds a regression guard test (test/dir-walker-scope.test.cjs) wired
into npm test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 23:48
@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ee95d9be83

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread package.json
"displayName": "RTL Support",
"description": "Adds RTL (Right-to-Left) text support for Hebrew, Arabic and Persian to Claude Code in VS Code, Cursor, Antigravity and Kiro",
"version": "0.5.0",
"version": "0.5.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the lockfile version synchronized

Bumping the extension to 0.5.1 here leaves both version fields in package-lock.json at 0.5.0. This makes the committed package metadata inconsistent and causes tooling that reads the lockfile to report the previous release; regenerate or update the lockfile so its top-level and packages[""] versions are also 0.5.1.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/content.ts:923

  • SKIP_SEL is documented as covering every container the LTR overrides protect, but it currently omits several protected tool/thinking/todo containers (e.g. toolBodyGrid_, toolBodyRow_, toolNameText_, thinkingContainer_, todoItem_). If any of those contain block tags (p, li, headings, etc.), the walker can still write dir attributes there, which the LTR override container rules cannot neutralize.
    var SKIP_SEL = '[class*="codeBlockWrapper_"],pre,code,[class*="thinkingContent_"],[class*="thinking_"],[class*="toolUse_"],[class*="toolSummary_"],[class*="toolBody_"],[class*="toolResult_"],[class*="toolReference_"],[class*="todoList_"],[class*="todoListContainer_"]';

test/dir-walker-scope.test.cjs:33

  • The regression test claims SKIP_SEL covers every protected container, but the asserted class list is missing several containers that are already forced LTR in ltrOverrideRules() (e.g. toolBodyGrid_, toolBodyRow*, toolNameText_, thinkingContainer_, todoItem_). This makes the guard incomplete and could allow future regressions to slip through.
for (const cls of [
    'codeBlockWrapper_', 'thinkingContent_', 'thinking_',
    'toolUse_', 'toolSummary_', 'toolBody_', 'toolResult_', 'toolReference_',
    'todoList_', 'todoListContainer_',
]) {

BenKalsky and others added 2 commits August 4, 2026 02:58
Both [dir=rtl]/[dir=ltr] block rules now carry the same
:not(thinkingContent_) scoping as the sibling markdown rule, so a stray
dir attribute under thinking content can never restyle it. Regression
guard extended to assert the guard on both rules.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 23:58
@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b406945533

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/content.ts
Comment on lines +304 to +307
.YBYrtl [class*="root_"]:not([class*="thinkingContent_"] [class*="root_"]) :is(p, li, h1, h2, h3, h4, h5, h6, blockquote)[dir="rtl"] {
direction: rtl;
text-align: right;
unicode-bidi: isolate;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore inline bidi isolation for links

When an RTL-tagged paragraph contains an English link or URL surrounded by Hebrew/Arabic text, isolating only the entire block does not isolate the anchor because unicode-bidi is not inherited. This change also removes the previous anchor-specific unicode-bidi: plaintext rule, so URL punctuation and adjacent text can be reordered by the surrounding RTL bidi context. Preserve an inline isolation rule for anchors while using the new per-block direction rules.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/content.ts:922

  • The comment above SKIP_SEL says it includes “every container the LTR overrides protect”, but ltrOverrideRules() protects additional containers (e.g. toolBodyGrid_, toolNameText_, todoItem_, etc.). This makes the comment misleading and weakens the value of the regression test, since it’s not clear whether SKIP_SEL is intended to be exhaustive vs “top-level/ancestor” containers only. Reword the comment to reflect the actual intent (top-level/ancestor skip regions) or explicitly reference which set it’s meant to cover.
    /* Every container the LTR overrides protect — a native dir attribute on a
       child is NOT neutralized by direction rules on the container, so the
       walker must never tag inside these */

…nd-3 P2)

The CSS rewrite dropped the anchor-specific unicode-bidi rule; since
unicode-bidi is not inherited, block-level isolation left URL punctuation
reorderable by the surrounding RTL context. Anchors inside markdown
blocks get unicode-bidi: plaintext again. Regression guard added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

Copilot AI review requested due to automatic review settings August 4, 2026 00:02

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e3610997a9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/content.ts Outdated
for (var i = 0; i < els.length; i++) {
var el = els[i];
if (el.closest && el.closest(SKIP_SEL)) continue;
var want = RTL.test(el.textContent || '') ? 'rtl' : 'ltr';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude skipped descendants from direction detection

When an otherwise-English list item contains a fenced code block with Hebrew/Arabic text, the li itself is not inside SKIP_SEL, but its textContent includes the skipped code and therefore makes want become rtl. This moves the list marker and can right-align the item's prose even though the only RTL text is in a code block that is supposed to remain untouched. Compute the direction from text nodes outside skipped containers (and nested blocks) rather than from the entire subtree.

Useful? React with 👍 / 👎.

…ound-4 P2)

A code block quoting Hebrew inside an English list item made the item's
textContent test RTL and flipped it. Direction now comes only from text
nodes outside SKIP_SEL containers (TreeWalker with a fast path when the
subtree has no RTL characters at all). Regression guard added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (2)

docs/superpowers/specs/2026-08-04-auto-mode-per-block-direction-design.md:5

  • The spec says the scope is src/content.ts only, but this PR also adds a regression test and bumps version/changelog. Consider clarifying that this is the runtime/code scope so the doc stays accurate when other supporting files change.
**Scope:** `src/content.ts` only (Auto mode CSS + JS)

test/dir-walker-scope.test.cjs:28

  • The SKIP_SEL extraction only matches single-quoted assignments. If the injected JS ever switches to double quotes, this test will fail even though behavior is unchanged; matching both quote styles makes the regression guard less brittle.
const skipSel = (w.match(/var SKIP_SEL = '([^']+)'/) || [])[1] || '';

Copilot AI review requested due to automatic review settings August 4, 2026 00:08

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88be133024

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/content.ts Outdated
Comment on lines +940 to +941
if (p && p.closest && p.closest(SKIP_SEL)) continue;
return true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude nested blocks from the parent direction test

When an English outer list item contains a nested Hebrew/Arabic item, hasOwnRtl walks into the nested li and this check excludes only skipped UI containers, so the outer item also receives dir="rtl" and moves its English text and marker to the wrong side. Fresh evidence in the updated walker is that the new TreeWalker filters SKIP_SEL ancestors but still accepts RTL text whose nearest BLOCK_SEL ancestor is a descendant of el; exclude text owned by nested blocks when determining the parent block's direction.

Useful? React with 👍 / 👎.

Comment thread src/content.ts Outdated
Comment on lines +984 to +985
var bubble = el && el.closest ? el.closest('.YBYrtl') : null;
if (!bubble) { pendingFull = true; return; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid full-history scans for unrelated mutations

When a pure-English response streams after a long RTL conversation, each character-data mutation has no .YBYrtl ancestor, so this branch sets pendingFull and the timer repeatedly calls scanAll(), traversing every block in every prior RTL bubble about once per debounce interval. This makes unrelated LTR streaming increasingly expensive as chat history grows; inspect added or newly classed RTL bubbles directly and ignore other non-RTL targets instead of falling back to a full scan.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/content.ts:944

  • hasOwnRtl builds el.textContent as a fast-path, but for blocks that contain RTL text this forces a full subtree traversal + string allocation and then immediately does a second traversal via TreeWalker. In large bubbles (especially with big code/tool chunks), this double-walk can add noticeable overhead during streaming.

Consider removing the textContent fast-path and doing a single TreeWalker pass with early-exit when an RTL text node outside SKIP_SEL is found.

    function hasOwnRtl(el) {
        if (!RTL.test(el.textContent || '')) return false; /* fast path */
        var walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false);
        var n;
        while ((n = walker.nextNode())) {
            if (!RTL.test(n.nodeValue)) continue;
            var p = n.parentElement;
            if (p && p.closest && p.closest(SKIP_SEL)) continue;

…dex round-5 P2s)

1) hasOwnRtl now only accepts RTL text whose nearest block ancestor is
   the judged element, so a Hebrew sub-item no longer flips its English
   parent item (the nested block gets its own dir).
2) The mutation observer never falls back to a full-history scan:
   mutations outside bubbles are ignored, and new bubbles are detected
   directly from addedNodes and class changes — unrelated LTR streaming
   no longer re-walks every prior RTL bubble per debounce tick.

Regression guards added for both.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 4, 2026 00:11
@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7941df48ba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/content.ts Outdated
var p = n.parentElement;
if (!p) continue;
if (p.closest && p.closest(SKIP_SEL)) continue;
if (p.closest && p.closest(BLOCK_SEL) !== el) continue; /* owned by a nested block */

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include loose-list paragraphs in the item direction test

When Markdown renders a loose or multi-paragraph list item as <li><p>…Hebrew…</p></li>, the paragraph is the text node's nearest BLOCK_SEL ancestor, so this check rejects all of the item's RTL text and the li is assigned dir="ltr". Although the child paragraph becomes RTL, the list marker belongs to the li and therefore remains on the left. Exclude independently nested list items while still counting paragraph content owned by the current li.

Useful? React with 👍 / 👎.

…ound-6 P2)

The round-5 ownership rule rejected any text whose nearest block ancestor
wasn't the judged element, so <li><p>Hebrew</p></li> left the li LTR with
its marker on the wrong side. Ownership now stops only at independently
rendered nested blocks (li, blockquote) — p and headings inside a loose
list item count toward the item, whose marker they visually belong to.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/content.ts:928

  • The comment above SKIP_SEL says it includes every container the LTR override rules protect, but ltrOverrideRules() also forces LTR for additional tool/thinking/todo containers (e.g. toolBodyGrid_/toolBodyRow_/thinkingContainer_/thinkingHeader_/spinnerRow_/timelineMessage_/todoItem_) that are not listed in SKIP_SEL. Either expand SKIP_SEL to truly mirror the protected containers, or soften the comment to avoid implying completeness.
    /* Every container the LTR overrides protect — a native dir attribute on a
       child is NOT neutralized by direction rules on the container, so the
       walker must never tag inside these */

test/dir-walker-scope.test.cjs:6

  • This header comment says the walker skip selector must cover every container the LTR overrides protect, but the test only asserts a subset of the LTR-protected containers (and ltrOverrideRules() lists more). Consider rewording this comment (or expanding the asserted list) so the test’s intent matches what it actually verifies.
 * Regression guard for the Auto-mode per-block direction walker
 * (Codex round-1 P2, PR #2): the walker must only tag blocks inside
 * markdown containers, and its skip selector must cover every container
 * the LTR overrides protect — a native dir attribute on a child is not
 * neutralized by direction rules on its container.

Copilot AI review requested due to automatic review settings August 4, 2026 00:15
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Unknown error
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 916de9c01b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated no new comments.

@BenKalsky
BenKalsky merged commit a2ac55c into master Aug 4, 2026
4 checks passed
@BenKalsky
BenKalsky deleted the feat/per-block-direction branch August 4, 2026 00: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.

2 participants