Skip to content

fix(docs): sync claude-structure accessibility improvements#1342

Open
Tenormusica2024 wants to merge 4 commits intoaffaan-m:mainfrom
Tenormusica2024:fix/docs-accessibility-robustness-accuracy
Open

fix(docs): sync claude-structure accessibility improvements#1342
Tenormusica2024 wants to merge 4 commits intoaffaan-m:mainfrom
Tenormusica2024:fix/docs-accessibility-robustness-accuracy

Conversation

@Tenormusica2024
Copy link
Copy Markdown

@Tenormusica2024 Tenormusica2024 commented Apr 10, 2026

Summary

  • claude-code-hooksリポジトリの修正をclaude-structure.htmlに同期
  • SRI, CDNフォールバック, aria-label, classDef適用, エージェント数修正

Test plan

  • GitHub Pages URLで正常表示確認

🤖 Generated with Claude Code


Summary by cubic

Syncs docs/claude-structure.html with accessibility and robustness fixes from claude-code-hooks, plus a small config refactor for easier maintenance. Also adds .nojekyll so GitHub Pages serves static files without Jekyll.

  • Bug Fixes

    • Add SRI to mermaid CDN and a graceful fallback if the CDN fails.
    • Make zoom toolbar accessible with aria-labels; ignore toolbar when panning.
    • Apply classDef styles consistently across all panels.
    • Correct agents count in legends/details.
    • Make diagram init idempotent and add retry-based SVG fit to avoid race conditions.
    • Add docs/.nojekyll to disable Jekyll on GitHub Pages.
  • Refactors

    • Centralize zoom/pan/fit/timing constants in a CFG object, synced with claude-code-hooks.

Written for commit 3f913ef. Summary will update on new commits.

Summary by CodeRabbit

  • Documentation
    • Added an interactive documentation page showing the directory layout as tabbed flowchart diagrams.
    • Each tab has its own viewport with toolbar controls for zoom in/out, fit-to-view, reset, and drag-to-pan.
    • Diagrams render in dark theme; tab switching re-centers views automatically.
    • Displays a friendly error message if diagram rendering fails.

tenormusica2025 and others added 3 commits April 10, 2026 01:38
Add interactive ~/.claude directory structure visualization with Mermaid diagrams.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Jekyll was failing on Liquid syntax in markdown files. Static deployment doesn't need Jekyll.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ss improvements

Mirrors fixes from claude-code-hooks: SRI, CDN fallback, aria-labels,
classDef application, agent count correction, idempotent init.

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 10, 2026

📝 Walkthrough

Walkthrough

Adds docs/claude-structure.html, a new multi-tab static documentation page that renders Mermaid flowcharts of the ~/.claude directory with client-side zoom/pan controls, tabbed navigation, Mermaid init/error handling, and per-panel viewport controls.

Changes

Cohort / File(s) Summary
Interactive Documentation UI
docs/claude-structure.html
New multi-tab HTML doc rendering ~/.claude as Mermaid flowcharts (tabs: 全体概要, Hooks 詳細, Commands 詳細, Rules / Scripts, Skills 一覧, Channels / Agents). Implements Mermaid dark-mode init with CDN fallback, SVG render polling, per-panel viewport controls (zoom in/out, fit, reset), lazy panel init, and tab switching via showPanel(). Introduces global helpers zpCall(id, method, arg), initAllPanels(), showPanel(name, btn), and a ZoomPan class with zoomAt(), zoomBy(), fit(), reset().

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • affaan-m

Poem

🐰 I hopped through tabs in the moonlit code,
Charts unfurled where directories stowed,
Zoomed and fitted with a gentle spin,
Dark-theme diagrams glowing within,
A tiny rabbit cheers — hooray, go! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title mentions 'sync claude-structure accessibility improvements' which aligns with the PR objective of syncing fixes to improve accessibility, robustness, and accuracy. However, the actual changeset adds a new 656-line HTML file with interactive diagram functionality, which is more substantial than just accessibility improvements. Clarify whether the title should reflect the primary change (new interactive documentation page) or if it should be more specific about what accessibility improvements are included.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 10, 2026

Greptile Summary

This PR adds docs/claude-structure.html, an interactive GitHub Pages visualization of the ~/.claude directory structure with six Mermaid flowchart panels, a custom zoom/pan controller, SRI on the Mermaid CDN script, and a graceful CDN-failure fallback. docs/.nojekyll is also added to disable Jekyll so GitHub Pages serves the file directly.

All previously raised concerns (touch/mobile support, window-level listener accumulation, and the global SVG retry check) remain open; no new P0/P1 issues were found in this iteration.

Confidence Score: 5/5

Safe to merge; all remaining findings are P2 suggestions that do not block correct rendering for the intended desktop audience.

No P0 or P1 defects were found. The two new comments are P2: a reminder to verify the SRI hash and a defensive try/catch for getBBox(). The previously flagged concerns around touch support and window listeners are also P2 quality improvements, not correctness blockers.

docs/claude-structure.html — confirm SRI hash matches the CDN file before the page goes live.

Important Files Changed

Filename Overview
docs/claude-structure.html New interactive visualization page with zoom/pan controls, Mermaid diagrams, SRI for CDN, and graceful CDN-failure fallback; minor concern around SRI hash correctness and getBBox() safety
docs/.nojekyll Empty file added to disable Jekyll processing on GitHub Pages — correct and expected practice

Reviews (2): Last reviewed commit: "refactor(docs): sync CFG config object e..." | Re-trigger Greptile

Comment on lines +574 to +592
this.vp.addEventListener('mousedown', e => {
if (e.button !== 0 || e.target.closest('.ztb')) return;
this.drag = true;
this.ox = e.clientX; this.oy = e.clientY;
this.sx = this.x; this.sy = this.y;
this.vp.classList.add('panning');
e.preventDefault();
});
window.addEventListener('mousemove', e => {
if (!this.drag) return;
this.x = this.sx + (e.clientX - this.ox);
this.y = this.sy + (e.clientY - this.oy);
this._apply();
});
window.addEventListener('mouseup', () => {
if (!this.drag) return;
this.drag = false;
this.vp.classList.remove('panning');
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Window event listeners accumulate across panel instances

_bind() attaches mousemove and mouseup listeners directly to window for each ZoomPan instance. With 6 panels all initialised, 12 window-level handlers fire on every single mouse move across the page. Each one only short-circuits via if (!this.drag) return, but the overhead compounds on lower-end devices.

Consider attaching these once at the class level, or moving them onto this.vp with setPointerCapture (which also solves the mobile gap above) so the listeners are scoped to the active viewport instead of the global window.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
docs/claude-structure.html (1)

627-636: Add guards in showPanel to prevent runtime crashes on invalid inputs.

document.getElementById('panel-' + name) and btn are dereferenced without checks; one bad call can break tab switching.

Defensive guard
 function showPanel(name, btn) {
+  const panel = document.getElementById('panel-' + name);
+  if (!panel || !btn) return;
   document.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
   document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
-  document.getElementById('panel-' + name).classList.add('active');
+  panel.classList.add('active');
   btn.classList.add('active');
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/claude-structure.html` around lines 627 - 636, The showPanel function
dereferences document.getElementById('panel-'+name) and btn without checks which
can throw; add defensive guards at the start of showPanel to validate that name
is a non-empty string, that document.getElementById('panel-'+name) returns a
non-null element, and that btn is a DOM element before proceeding; if any check
fails, return early (no-op) to avoid runtime crashes, and only instantiate
zp[name] = new ZoomPan(name) and call zp[name].fit() after confirming the panel
element exists.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/claude-structure.html`:
- Line 483: Replace the direct assignment to document.body.innerHTML
(document.body.innerHTML = '...') with safe DOM APIs: create the container
element via document.createElement, set its text via textContent (not
innerHTML), apply styles via element.style or classList, and append it to
document.body with appendChild; ensure any dynamic parts are escaped or
sanitized before setting textContent and remove usage of innerHTML to satisfy
XSS prevention requirements.
- Around line 7-10: The mermaid <script> currently sets
window.__mermaidFailed=true onerror but lacks a fallback and also uses innerHTML
to show the error; update the loader to attempt a secondary CDN (or local)
script when window.__mermaidFailed is true and only show the error banner if
both loads fail, and replace any use of innerHTML for that banner (the code that
writes the banner when window.__mermaidFailed is set) with safe DOM APIs (e.g.,
createElement/appendChild and setting textContent) so the failure is recoverable
and not vulnerable to XSS.

---

Nitpick comments:
In `@docs/claude-structure.html`:
- Around line 627-636: The showPanel function dereferences
document.getElementById('panel-'+name) and btn without checks which can throw;
add defensive guards at the start of showPanel to validate that name is a
non-empty string, that document.getElementById('panel-'+name) returns a non-null
element, and that btn is a DOM element before proceeding; if any check fails,
return early (no-op) to avoid runtime crashes, and only instantiate zp[name] =
new ZoomPan(name) and call zp[name].fit() after confirming the panel element
exists.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d4bde6cf-5df6-48b6-82a6-58c05bd07cf2

📥 Commits

Reviewing files that changed from the base of the PR and between e48468a and 42fc213.

📒 Files selected for processing (2)
  • docs/.nojekyll
  • docs/claude-structure.html

Comment on lines +7 to +10
<script src="https://cdn.jsdelivr.net/npm/mermaid@10.9.3/dist/mermaid.min.js"
integrity="sha384-R63zfMfSwJF4xCR11wXii+QUsbiBIdiDzDbtxia72oGWfkT7WHJfmD/I/eeHPJyT"
crossorigin="anonymous"
onerror="window.__mermaidFailed=true"></script>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
file="docs/claude-structure.html"

echo "[Check 1] Mermaid include and fail branch:"
rg -n "mermaid.min.js|__mermaidFailed|onerror=" "$file"

echo "[Check 2] Fallback loader indicators (expected if fallback exists):"
rg -n "createElement\\(['\"]script['\"]\\)|appendChild\\(|unpkg|cdnjs|fallback" "$file" || true

Repository: affaan-m/everything-claude-code

Length of output: 468


🏁 Script executed:

cat -n docs/claude-structure.html | sed -n '480,490p'

Repository: affaan-m/everything-claude-code

Length of output: 542


Mermaid fallback is not implemented; current path is hard failure.

Line 10 only sets a failure flag, and lines 481–485 render an error banner via innerHTML. There is no secondary CDN or local script load. Additionally, using innerHTML at line 483 violates XSS prevention guidelines; use textContent or DOM APIs instead.

Suggested fix (add secondary source and use safe DOM methods)
-if (window.__mermaidFailed || typeof mermaid === 'undefined') {
-  document.addEventListener('DOMContentLoaded', () => {
-    document.body.innerHTML = '<p style="color:`#f85149`;padding:2rem;font-family:sans-serif">Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。</p>';
-  });
-} else {
-mermaid.initialize({
+function showMermaidLoadError() {
+  document.addEventListener('DOMContentLoaded', () => {
+    const p = document.createElement('p');
+    p.style.color = '#f85149';
+    p.style.padding = '2rem';
+    p.style.fontFamily = 'sans-serif';
+    p.textContent = 'Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。';
+    document.body.replaceChildren(p);
+  });
+}
+
+function initMermaid() {
+  mermaid.initialize({
   startOnLoad: true,
   theme: 'dark',
   themeVariables: {
@@
   flowchart: {
@@
   }
-});
-} // end mermaid guard
+  });
+}
+
+if (window.__mermaidFailed || typeof mermaid === 'undefined') {
+  const fallback = document.createElement('script');
+  fallback.src = 'https://unpkg.com/mermaid@10.9.3/dist/mermaid.min.js';
+  fallback.crossOrigin = 'anonymous';
+  fallback.onload = () => (typeof mermaid !== 'undefined' ? initMermaid() : showMermaidLoadError());
+  fallback.onerror = showMermaidLoadError;
+  document.head.appendChild(fallback);
+} else {
+  initMermaid();
+} // end mermaid guard
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/claude-structure.html` around lines 7 - 10, The mermaid <script>
currently sets window.__mermaidFailed=true onerror but lacks a fallback and also
uses innerHTML to show the error; update the loader to attempt a secondary CDN
(or local) script when window.__mermaidFailed is true and only show the error
banner if both loads fail, and replace any use of innerHTML for that banner (the
code that writes the banner when window.__mermaidFailed is set) with safe DOM
APIs (e.g., createElement/appendChild and setting textContent) so the failure is
recoverable and not vulnerable to XSS.

<script>
if (window.__mermaidFailed || typeof mermaid === 'undefined') {
document.addEventListener('DOMContentLoaded', () => {
document.body.innerHTML = '<p style="color:#f85149;padding:2rem;font-family:sans-serif">Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。</p>';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid innerHTML for error rendering; use safe DOM APIs.

Even with static content, this introduces an unsafe output pattern and bypasses sanitization discipline.

Safe replacement
-    document.body.innerHTML = '<p style="color:`#f85149`;padding:2rem;font-family:sans-serif">Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。</p>';
+    const p = document.createElement('p');
+    p.style.color = '#f85149';
+    p.style.padding = '2rem';
+    p.style.fontFamily = 'sans-serif';
+    p.textContent = 'Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。';
+    document.body.replaceChildren(p);

As per coding guidelines: "Implement XSS prevention by sanitizing HTML output".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
document.body.innerHTML = '<p style="color:#f85149;padding:2rem;font-family:sans-serif">Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。</p>';
const p = document.createElement('p');
p.style.color = '#f85149';
p.style.padding = '2rem';
p.style.fontFamily = 'sans-serif';
p.textContent = 'Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。';
document.body.replaceChildren(p);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/claude-structure.html` at line 483, Replace the direct assignment to
document.body.innerHTML (document.body.innerHTML = '...') with safe DOM APIs:
create the container element via document.createElement, set its text via
textContent (not innerHTML), apply styles via element.style or classList, and
append it to document.body with appendChild; ensure any dynamic parts are
escaped or sanitized before setting textContent and remove usage of innerHTML to
satisfy XSS prevention requirements.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 2 files

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
docs/claude-structure.html (1)

7-10: ⚠️ Potential issue | 🟠 Major

Mermaid fallback CDN and safe error rendering remain unaddressed.

Both issues from the previous review are still present:

  1. No secondary CDN is attempted when the primary CDN fails at line 10
  2. Line 483 uses innerHTML for the error message instead of safe DOM APIs

As per coding guidelines: "Implement XSS prevention by sanitizing HTML output".

Also applies to: 481-511

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/claude-structure.html` around lines 7 - 10, Add a resilient Mermaid
loader: update the script onerror handler (where window.__mermaidFailed is set)
to attempt loading a secondary CDN URL (and optionally a local copy) before
giving up, and expose/consume that retry state in the existing Mermaid init
logic so the page still initializes if a fallback succeeds. Replace any use of
element.innerHTML in the error/display path (the block around lines 481–511 that
currently writes the error message) with safe DOM APIs—use textContent or
createTextNode for plain text and, if HTML markup is required, sanitize it with
a trusted sanitizer (e.g., DOMPurify) before inserting via DOM methods; ensure
you reference the same element/id the current code mutates and remove direct
innerHTML assignments.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/claude-structure.html`:
- Around line 569-570: The code incorrectly reads non-existent SVG properties
scrollWidth/scrollHeight from the svg variable; replace those checks with valid
SVG measurements (e.g., use svg.clientWidth/clientHeight for rendered sizes, or
for an <svg> element read svg.width.baseVal.value and svg.height.baseVal.value,
and fall back to svg.getBBox().width / svg.getBBox().height if needed) so that
the width/height calculations use actual SVG properties instead of always
falling back to getBBox().

---

Duplicate comments:
In `@docs/claude-structure.html`:
- Around line 7-10: Add a resilient Mermaid loader: update the script onerror
handler (where window.__mermaidFailed is set) to attempt loading a secondary CDN
URL (and optionally a local copy) before giving up, and expose/consume that
retry state in the existing Mermaid init logic so the page still initializes if
a fallback succeeds. Replace any use of element.innerHTML in the error/display
path (the block around lines 481–511 that currently writes the error message)
with safe DOM APIs—use textContent or createTextNode for plain text and, if HTML
markup is required, sanitize it with a trusted sanitizer (e.g., DOMPurify)
before inserting via DOM methods; ensure you reference the same element/id the
current code mutates and remove direct innerHTML assignments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e469a7dd-721e-462f-b159-cff2d0fb4f8e

📥 Commits

Reviewing files that changed from the base of the PR and between 42fc213 and 3f913ef.

📒 Files selected for processing (1)
  • docs/claude-structure.html

Comment on lines +569 to +570
const sw = svg.scrollWidth || svg.getBBox().width;
const sh = svg.scrollHeight || svg.getBBox().height;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

SVG elements don't have scrollWidth/scrollHeight properties.

Lines 569-570 attempt to read scrollWidth and scrollHeight from an SVG element, but these properties only exist on HTML elements with scrollable overflow. The values will always be undefined, causing the fallback to getBBox() to always be used.

🔧 Clearer measurement approach

Use properties that actually exist on SVG elements:

-      const sw = svg.scrollWidth  || svg.getBBox().width;
-      const sh = svg.scrollHeight || svg.getBBox().height;
+      const bbox = svg.getBBox();
+      const sw = bbox.width;
+      const sh = bbox.height;

Or if you want to try clientWidth/clientHeight first:

-      const sw = svg.scrollWidth  || svg.getBBox().width;
-      const sh = svg.scrollHeight || svg.getBBox().height;
+      const bbox = svg.getBBox();
+      const sw = svg.clientWidth  || bbox.width;
+      const sh = svg.clientHeight || bbox.height;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const sw = svg.scrollWidth || svg.getBBox().width;
const sh = svg.scrollHeight || svg.getBBox().height;
const bbox = svg.getBBox();
const sw = bbox.width;
const sh = bbox.height;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/claude-structure.html` around lines 569 - 570, The code incorrectly
reads non-existent SVG properties scrollWidth/scrollHeight from the svg
variable; replace those checks with valid SVG measurements (e.g., use
svg.clientWidth/clientHeight for rendered sizes, or for an <svg> element read
svg.width.baseVal.value and svg.height.baseVal.value, and fall back to
svg.getBBox().width / svg.getBBox().height if needed) so that the width/height
calculations use actual SVG properties instead of always falling back to
getBBox().

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 10, 2026

Tip:

Greploop — Automatically fix all review issues by running /greploops in Claude Code. It iterates: fix, push, re-review, repeat until 5/5 confidence.

Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal.

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