Skip to content

Add simulation gallery entries and computer links#1160

Merged
sbryngelson merged 7 commits intoMFlowCode:masterfrom
sbryngelson:read-improvements
Feb 18, 2026
Merged

Add simulation gallery entries and computer links#1160
sbryngelson merged 7 commits intoMFlowCode:masterfrom
sbryngelson:read-improvements

Conversation

@sbryngelson
Copy link
Member

@sbryngelson sbryngelson commented Feb 18, 2026

User description

Summary

  • Add 6 new simulation cards to docs landing page gallery (lithotripsy, kidney stone stress, pitching airfoil, Mach 10 triple jet, Mach 12 Starship, whale bubble nets)
  • Group gallery cards by topic (rockets, aerodynamics, shock-droplet, biomedical, bubbles, fundamentals)
  • Computer names in cards now link to their respective HPC center pages

Test plan

  • ./mfc.sh precheck passes (all 5 checks)
  • Verify gallery renders correctly with new thumbnails
  • Verify computer links open correct pages in new tab

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added structured metadata to the docs homepage for improved search visibility
    • Added "Page last updated" timestamps to documentation pages
    • Enhanced simulation examples with categorized groups and direct external links
  • Documentation

    • Converted sitemap to sitemap.xml and updated robots reference
    • Corrected meta keyword syntax and added meta description
  • Chores

    • Link checking now runs after publishing and is configured to fail on broken links

CodeAnt-AI Description

Add new simulation gallery entries, direct computer links, and per-page dates

What Changed

  • Added many new simulation cards to the docs landing gallery and grouped them by topic so similar examples appear together (rockets, aerodynamics, shock-droplet, biomedical, bubbles, fundamentals).
  • Computer names on each gallery card now link to the corresponding HPC center page and all card links open in a new browser tab; YouTube-linked cards show the YouTube icon.
  • Documentation pages now include machine-readable site metadata (JSON-LD) for the landing page, and markdown pages receive a visible "Page last updated: YYYY-MM-DD" footer during the build.
  • Sitemap generation switched to XML and robots.txt updated to reference sitemap.xml; CI now fetches full Git history so per-page dates reflect commits.

Impact

✅ Clearer external source links (open in new tab and YouTube icon)
✅ Better discoverability in search engines (JSON-LD + sitemap.xml + meta description)
✅ Visible "last updated" dates on documentation pages

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 18, 2026

Warning

Rate limit exceeded

@sbryngelson has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

CI docs workflow and link-check timing adjusted; sitemap format switched to XML; build now injects per-page "last updated" timestamps via a new Python script before Doxygen; header metadata and index content updated; robots.txt and lychee exclusions updated to reference sitemap.xml.

Changes

Cohort / File(s) Summary
CI / Link-check / Sitemap
.github/workflows/docs.yml, .lychee.toml, docs/robots.txt
Checkout now fetches full history (fetch-depth: 0); sitemap generation/output changed to sitemap.xml; lychee linkcheck step moved to run after publishing and set to fail=true; lychee exclude updated to omit sitemap.xml and its full URL; robots.txt now references sitemap.xml.
Build / Date injection
CMakeLists.txt, docs/inject-dates.py
Added custom command/target (inject-dates.stamp / inject_page_dates) and dependency so date-injection script runs before documentation_doxygen; new Python script appends "Page last updated" timestamps to docs Markdown.
HTML metadata & site content
docs/header.html, docs/index.html
Header: added meta description and fixed keyword quote characters. Index: added JSON‑LD SoftwareSourceCode, reorganized simulation entries into categories, adjusted link/icon rendering (YouTube vs external), added computerUrl linking and minor markup/typography tweaks.
Static asset
docs/robots.txt
Sitemap reference updated to https://mflowcode.github.io/sitemap.xml.

Sequence Diagram(s)

sequenceDiagram
    participant CMake as CMake (build)
    participant Script as inject-dates.py
    participant Git as Git repo
    participant Docs as docs/*.md
    participant Doxygen as Doxygen
    participant Publisher as GitHub Pages
    participant Lychee as Lychee linkcheck

    CMake->>Script: run inject_page_dates target
    Script->>Git: query last commit date (git log --date=short -- <file>)
    Git-->>Script: return last-commit-date (or none)
    Script->>Docs: append "Page last updated" HTML to files
    CMake->>Doxygen: run documentation_doxygen (depends on inject_page_dates)
    Doxygen->>Publisher: publish generated site
    Publisher->>Lychee: trigger lychee linkcheck after publish
    Lychee-->>Publisher: report results (fail=true)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

Review effort 2/5, size:M

Poem

🐰 I hop through docs at break of dawn,
I plant small dates on pages drawn,
Sitemap XML flutters bright,
Metadata twinkles in the site —
A nibble of joy for the build tonight! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add simulation gallery entries and computer links' accurately describes the primary changes (new gallery cards and computer linking) but omits significant secondary changes like JSON-LD metadata, per-page dates, and sitemap updates.
Description check ✅ Passed The PR description is comprehensive and includes both user-written and AI-generated summaries covering all major changes, but it lacks the structured format specified in the repository template (no explicit 'Type of change', minimal 'Testing' section, and incomplete checklist).
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
  • Post copyable unit tests in a comment

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.

New entries: burstwave lithotripsy, kidney stone stress waves,
pitching airfoil, Mach 10 triple jet, Mach 12 Starship, whale
bubble nets. Grouped cards by topic. Computer names now link
to their respective HPC center pages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sbryngelson and others added 2 commits February 18, 2026 19:16
- Add 3 new simulation gallery cards (earplug, orifice, particle cloud)
- Add JSON-LD structured data to landing page for rich search results
- Add per-page meta description to Doxygen header template
- Switch sitemap from txt to xml format for better SEO
- Add inject-dates.py build step for per-page last-updated dates
- Use full git history in docs CI for accurate file dates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cards linking to YouTube show the YouTube brand icon instead of a
generic external-link icon. DOI links keep the original icon.
All card links now open in a new tab.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sbryngelson sbryngelson marked this pull request as ready for review February 18, 2026 20:48
Copilot AI review requested due to automatic review settings February 18, 2026 20:48
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request enhances the documentation landing page and build system with new simulation showcase entries, interactive computer links, automated page dating, and improved SEO metadata.

Changes:

  • Expands the simulation gallery from 9 to 16+ entries, organized by topic (rockets, aerodynamics, shock-droplet, biomedical, bubbles, fundamentals), with one new thumbnail image (m.png for pitching airfoil)
  • Makes computer names in gallery cards clickable links to respective HPC center pages
  • Adds a Python script (inject-dates.py) to automatically inject "last updated" dates into documentation pages based on git history
  • Changes sitemap format from .txt to .xml across all configuration files for better SEO compliance
  • Adds schema.org structured data to the landing page for improved search engine indexing
  • Enhances meta descriptions for documentation pages

Reviewed changes

Copilot reviewed 7 out of 16 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
docs/index.html Reorganizes simulation gallery with 6+ new entries, adds computer URL links, includes schema.org structured data, updates icon display logic for YouTube vs external links
docs/inject-dates.py New Python script that reads git log to inject "Page last updated" footers into documentation markdown files
CMakeLists.txt Integrates inject-dates.py into the documentation build pipeline with custom command and stamp file
docs/robots.txt Updates sitemap reference from .txt to .xml format
.lychee.toml Updates sitemap exclusion path from .txt to .xml
.github/workflows/docs.yml Adds full git history fetch (fetch-depth: 0) for date injection, updates sitemap format to xml
docs/header.html Adds dynamic meta description for documentation pages
docs/res/simulations/m.png New binary image file for "Pitching airfoil (3D)" simulation thumbnail

Comment on lines +28 to +31
f"\n\n<div style='text-align:center; font-size:0.75rem; "
f"color:#888; padding:16px 0 0;'>"
f"Page last updated: {page_date}</div>\n"
)
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

The script uses f-strings spanning multiple lines (28-30) which may have readability issues. While this works, consider using parentheses to make the multi-line f-string more explicit, or breaking it into smaller parts for better maintainability.

Suggested change
f"\n\n<div style='text-align:center; font-size:0.75rem; "
f"color:#888; padding:16px 0 0;'>"
f"Page last updated: {page_date}</div>\n"
)
f"\n\n<div style='text-align:center; font-size:0.75rem; color:#888; padding:16px 0 0;'>Page last updated: {page_date}</div>\n"
)

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +31
for md_file in sorted(docs_dir.glob("*.md")):
if "Page last updated:" in md_file.read_text():
continue

result = subprocess.run(
["git", "log", "-1", "--format=%as", "--", str(md_file)],
capture_output=True, text=True,
cwd=str(src_dir),
)
page_date = result.stdout.strip() or str(date.today())

with open(md_file, "a") as f:
f.write(
f"\n\n<div style='text-align:center; font-size:0.75rem; "
f"color:#888; padding:16px 0 0;'>"
f"Page last updated: {page_date}</div>\n"
)
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

The script does not specify encoding when reading/writing files. While Python 3 defaults to UTF-8 on most platforms, it's better to be explicit about encoding to avoid issues on Windows or other platforms. Add encoding='utf-8' to both read_text() and the open() calls.

Copilot uses AI. Check for mistakes.
docs_dir = src_dir / "docs" / "documentation"

for md_file in sorted(docs_dir.glob("*.md")):
if "Page last updated:" in md_file.read_text():
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

The inject-dates.py script reads each markdown file in its entirety into memory on line 16, then modifies it by appending content. This can cause issues if the script is run multiple times on the same files, as the check "Page last updated:" only verifies presence anywhere in the file, not whether it's already been appended at the end. This could lead to duplicate date footers being appended on subsequent builds.

Consider checking if the footer has already been added at the end of the file, or tracking which files have been processed using a more robust mechanism (e.g., a separate state file).

Suggested change
if "Page last updated:" in md_file.read_text():
content = md_file.read_text()
stripped = content.rstrip()
# Check if a "Page last updated" footer already exists at the end of the file.
tail = stripped[-1024:]
if "Page last updated:" in tail and stripped.endswith("</div>"):

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +24
result = subprocess.run(
["git", "log", "-1", "--format=%as", "--", str(md_file)],
capture_output=True, text=True,
cwd=str(src_dir),
)
page_date = result.stdout.strip() or str(date.today())
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

The subprocess.run call does not check the return code of the git command. If git fails (e.g., file not in git history, git not available, not in a git repository), the script silently falls back to today's date. Consider adding error handling or logging to make debugging easier if the git command fails unexpectedly.

Suggested change
result = subprocess.run(
["git", "log", "-1", "--format=%as", "--", str(md_file)],
capture_output=True, text=True,
cwd=str(src_dir),
)
page_date = result.stdout.strip() or str(date.today())
try:
result = subprocess.run(
["git", "log", "-1", "--format=%as", "--", str(md_file)],
capture_output=True,
text=True,
cwd=str(src_dir),
check=True,
)
git_date = result.stdout.strip()
if git_date:
page_date = git_date
else:
raise ValueError(f"Empty git log output for {md_file}")
except (subprocess.CalledProcessError, OSError, ValueError) as exc:
print(
f"Warning: could not determine last-updated date from git for {md_file}: {exc}",
file=sys.stderr,
)
page_date = str(date.today())

Copilot uses AI. Check for mistakes.
Comment on lines +814 to +818
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/examples.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/case_constraints.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/physics_constraints.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/cli-reference.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/parameters.md"
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

The custom command dependency list in CMakeLists.txt includes the generated markdown files that the script is supposed to modify. This creates a circular dependency issue: the script modifies these files, which are listed as dependencies, which would trigger the script to run again. The stamp file approach helps, but the dependencies should be the script itself and the files it reads from, not the files it writes to.

Suggested change
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/examples.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/case_constraints.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/physics_constraints.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/cli-reference.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/parameters.md"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/inject-dates.py"

Copilot uses AI. Check for mistakes.
Comment on lines +824 to +825
add_custom_target(inject_page_dates DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/inject-dates.stamp")
add_dependencies(documentation_doxygen inject_page_dates)
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

The inject_page_dates target is added as a dependency of documentation_doxygen, but the correct ordering might need verification. The script should run after the markdown files are generated (which happens as part of documentation_doxygen's dependencies) but before Doxygen processes them. The current setup may not guarantee this ordering. Consider making inject_page_dates depend on the commands that generate the markdown files, and having documentation_doxygen depend on inject_page_dates.

Copilot uses AI. Check for mistakes.
docs/index.html Outdated
Comment on lines 26 to 35
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

The schema.org structured data added to the page claims "operatingSystem": "Linux, macOS", but this should be verified against the actual supported platforms. If Windows is also supported (even via WSL), this metadata may be incomplete. Similarly, if other Unix-like systems are supported, they should be listed.

Copilot uses AI. Check for mistakes.
Copy link
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: 3

🧹 Nitpick comments (3)
docs/inject-dates.py (1)

15-17: Idempotency guard permanently prevents date updates after first injection

The continue on line 17 means a date is written exactly once per source file and never refreshed. In CI (clean checkout), this works correctly. However, during local development:

  • The .md source files are mutated in-place, immediately showing as git diff noise.
  • If a developer subsequently edits and commits a page, the stale date from the prior build remains locked in until they manually strip the injected <div>.

The stamp-file DEPENDS in CMakeLists.txt only lists the 5 auto-generated .md files, so edits to manually-maintained pages (e.g. getting-started.md, contributing.md) don't invalidate the stamp either, compounding this.

A cleaner approach is to work on build-directory copies instead of source files, or to always overwrite (replace rather than append) the <div> so re-runs refresh the date.

♻️ Always-overwrite variant (replaces the stale-date guard)
-for md_file in sorted(docs_dir.glob("*.md")):
-    if "Page last updated:" in md_file.read_text():
-        continue
-
+DATE_MARKER = "<!-- inject-dates-start -->"
+
+for md_file in sorted(docs_dir.glob("*.md")):
     result = subprocess.run(
         ["git", "log", "-1", "--format=%as", "--", str(md_file)],
         capture_output=True, text=True,
         cwd=str(src_dir),
     )
     page_date = result.stdout.strip() or str(date.today())
 
-    with open(md_file, "a") as f:
-        f.write(
-            f"\n\n<div style='text-align:center; font-size:0.75rem; "
-            f"color:`#888`; padding:16px 0 0;'>"
-            f"Page last updated: {page_date}</div>\n"
-        )
+    new_block = (
+        f"\n\n{DATE_MARKER}\n"
+        f"<div style='text-align:center; font-size:0.75rem; "
+        f"color:`#888`; padding:16px 0 0;'>"
+        f"Page last updated: {page_date}</div>\n"
+    )
+    text = md_file.read_text(encoding="utf-8")
+    if DATE_MARKER in text:
+        text = text[:text.index(DATE_MARKER)] + new_block
+    else:
+        text = text + new_block
+    md_file.write_text(text, encoding="utf-8")
docs/index.html (1)

26-46: JSON-LD: programmingLanguage and codeRepository are SoftwareSourceCode properties, not SoftwareApplication

Per Schema.org, both programmingLanguage and codeRepository are defined on SoftwareSourceCode, which is a subtype of SoftwareApplication — not the other way round. Using them on an @type: "SoftwareApplication" node is technically non-conformant (validators will flag them as unrecognised properties for this type). Either change the type to "SoftwareSourceCode" (which inherits everything in SoftwareApplication) or drop those two fields.

♻️ Option A — change type to SoftwareSourceCode
-      "@type": "SoftwareApplication",
+      "@type": "SoftwareSourceCode",
♻️ Option B — drop the non-conformant properties
       "operatingSystem": "Linux, macOS",
       "license": "https://opensource.org/licenses/MIT",
-      "programmingLanguage": ["Fortran", "Python"],
-      "codeRepository": "https://github.com/MFlowCode/MFC",
       "author": {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/index.html` around lines 26 - 46, The JSON-LD block uses "@type":
"SoftwareApplication" but includes properties "programmingLanguage" and
"codeRepository" which are defined on "SoftwareSourceCode"; fix by either
changing "@type" from "SoftwareApplication" to "SoftwareSourceCode" (so the
existing fields remain valid) or by removing the "programmingLanguage" and
"codeRepository" fields and keeping "@type": "SoftwareApplication"; update the
"@type" value and/or remove the two properties in the script accordingly to
ensure Schema.org conformance.
CMakeLists.txt (1)

812-825: Stamp DEPENDS list omits manually-maintained .md files, so edits to them won't retrigger date injection

The five paths in DEPENDS are all auto-generated files. If a developer updates a hand-authored page (e.g. contributing.md, getting-started.md) and the stamp already exists, CMake will not re-run inject-dates.py, and the stale date will remain in the source file — a consequence of the idempotency design described in the inject-dates.py comment above.

If the always-overwrite approach suggested there is adopted, adding file(GLOB doc_md_files ...) and listing all .md files in DEPENDS would make the stamp properly track any source change:

+    file(GLOB_RECURSE all_doc_mds CONFIGURE_DEPENDS
+        "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/*.md")
     add_custom_command(
         OUTPUT  "${CMAKE_CURRENT_BINARY_DIR}/inject-dates.stamp"
         DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/examples.md"
                 "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/case_constraints.md"
                 "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/physics_constraints.md"
                 "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/cli-reference.md"
                 "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/parameters.md"
+                ${all_doc_mds}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CMakeLists.txt` around lines 812 - 825, The DEPENDS list for the
add_custom_command that produces
"${CMAKE_CURRENT_BINARY_DIR}/inject-dates.stamp" only lists auto-generated .md
files, so edits to hand-authored pages won't retrigger inject-dates.py; define a
file(GLOB doc_md_files "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/*.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/*.md") (or an explicit list) and update the
add_custom_command for inject-dates.stamp to DEPENDS the ${doc_md_files} so
inject-dates.py (referenced by
"${CMAKE_CURRENT_SOURCE_DIR}/docs/inject-dates.py") runs whenever any .md source
changes; keep the touch stamp and the add_custom_target(inject_page_dates) /
add_dependencies(documentation_doxygen inject_page_dates) behavior unchanged.
🤖 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/index.html`:
- Around line 93-94: The anchor element rendering the source icon (the <a
class="w-10 text-center text-xl" href="${s.source}" target="_blank"> element)
and any other anchors that open new tabs should include rel="noopener
noreferrer"; update the JSX/HTML that generates this link (and the computer URL
link) to add rel="noopener noreferrer" whenever target="_blank" is used so
window.opener is not exposed and the referrer is not leaked.
- Line 64: Update the inconsistent walltime string for the simulation entry with
name "Cavitation fragments kidney stone" in docs/index.html: change the walltime
value from "30 min" to the abbreviated form "30m" to match the other entries'
format (look for the object containing name: "Cavitation fragments kidney stone"
and modify its walltime property).

In `@docs/inject-dates.py`:
- Line 26: The open() call that appends to markdown files uses the system
default encoding; update the with open(md_file, "a") as f: usage to explicitly
specify encoding='utf-8' so all .md files are written in UTF-8. Locate the open
call where md_file is used (the with open(md_file, "a") context) and add the
encoding parameter; ensure any other similar open(...) usages in this script
follow the same pattern.

---

Nitpick comments:
In `@CMakeLists.txt`:
- Around line 812-825: The DEPENDS list for the add_custom_command that produces
"${CMAKE_CURRENT_BINARY_DIR}/inject-dates.stamp" only lists auto-generated .md
files, so edits to hand-authored pages won't retrigger inject-dates.py; define a
file(GLOB doc_md_files "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/*.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/*.md") (or an explicit list) and update the
add_custom_command for inject-dates.stamp to DEPENDS the ${doc_md_files} so
inject-dates.py (referenced by
"${CMAKE_CURRENT_SOURCE_DIR}/docs/inject-dates.py") runs whenever any .md source
changes; keep the touch stamp and the add_custom_target(inject_page_dates) /
add_dependencies(documentation_doxygen inject_page_dates) behavior unchanged.

In `@docs/index.html`:
- Around line 26-46: The JSON-LD block uses "@type": "SoftwareApplication" but
includes properties "programmingLanguage" and "codeRepository" which are defined
on "SoftwareSourceCode"; fix by either changing "@type" from
"SoftwareApplication" to "SoftwareSourceCode" (so the existing fields remain
valid) or by removing the "programmingLanguage" and "codeRepository" fields and
keeping "@type": "SoftwareApplication"; update the "@type" value and/or remove
the two properties in the script accordingly to ensure Schema.org conformance.

Comment on lines +93 to +94
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
<i class="${s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}"></i>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add rel="noopener noreferrer" to all target="_blank" links

Both the source icon link (line 93) and the computer URL link (line 100) open a new tab without rel="noopener noreferrer". This leaves window.opener accessible in the opened tab and leaks the Referer header. These are straightforward to fix:

🔒 Proposed fix
-                        <a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
+                        <a class="w-10 text-center text-xl" href="${s.source}" target="_blank" rel="noopener noreferrer">
-                            <div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank">${s.computer}</a>` : s.computer}</div>
+                            <div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank" rel="noopener noreferrer">${s.computer}</a>` : s.computer}</div>

Also applies to: 100-100

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

In `@docs/index.html` around lines 93 - 94, The anchor element rendering the
source icon (the <a class="w-10 text-center text-xl" href="${s.source}"
target="_blank"> element) and any other anchors that open new tabs should
include rel="noopener noreferrer"; update the JSX/HTML that generates this link
(and the computer URL link) to add rel="noopener noreferrer" whenever
target="_blank" is used so window.opener is not exposed and the referrer is not
leaked.

)
page_date = result.stdout.strip() or str(date.today())

with open(md_file, "a") as f:
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing encoding='utf-8' in open()

Without an explicit encoding, the file is opened using the platform default, which is not utf-8 on some Windows and POSIX locales. All the documentation .md files use UTF-8.

🐛 Proposed fix
-    with open(md_file, "a") as f:
+    with open(md_file, "a", encoding="utf-8") as f:
📝 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
with open(md_file, "a") as f:
with open(md_file, "a", encoding="utf-8") as f:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/inject-dates.py` at line 26, The open() call that appends to markdown
files uses the system default encoding; update the with open(md_file, "a") as f:
usage to explicitly specify encoding='utf-8' so all .md files are written in
UTF-8. Locate the open call where md_file is used (the with open(md_file, "a")
context) and add the encoding parameter; ensure any other similar open(...)
usages in this script follow the same pattern.

Copy link
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.

5 issues found across 16 files

Confidence score: 4/5

  • Minor security hardening needed in docs/index.html where target="_blank" links lack rel="noopener noreferrer", but impact is limited to documentation pages
  • Build/doc freshness could lag because CMakeLists.txt doesn’t depend on docs/inject-dates.py, and docs/inject-dates.py should specify UTF-8 to avoid cross-platform encoding hiccups; these are low-to-moderate risk documentation issues
  • Pay close attention to docs/index.html, CMakeLists.txt, docs/inject-dates.py - link safety, stale doc regeneration, and encoding consistency.
Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docs/index.html">

<violation number="1" location="docs/index.html:64">
P3: Inconsistent walltime format. This entry uses `"30 min"` while all other entries use the abbreviated form (e.g., `"30m"`, `"20m"`, `"5h"`). Use `"30m"` for consistency.</violation>

<violation number="2" location="docs/index.html:93">
P2: Add rel="noopener noreferrer" to the external link opened with target="_blank" to prevent window.opener security risks.</violation>

<violation number="3" location="docs/index.html:100">
P2: Add rel="noopener noreferrer" to the computer link opened with target="_blank" to avoid window.opener vulnerabilities.</violation>
</file>

<file name="CMakeLists.txt">

<violation number="1" location="CMakeLists.txt:814">
P2: The inject-dates custom command runs docs/inject-dates.py but doesn’t list that script in DEPENDS, so updates to the script won’t retrigger the stamp and documentation can go stale without a clean build.</violation>
</file>

<file name="docs/inject-dates.py">

<violation number="1" location="docs/inject-dates.py:26">
P2: Add `encoding='utf-8'` to `open()`. Without explicit encoding, the file uses the platform default which isn't UTF-8 on all systems. This can cause encoding errors when the documentation files contain non-ASCII characters.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

<div class="flex flex-row items-center">
<div class="pr-2"><i class="fa-solid fa-server"></i></div>
<div class="flex-1 text-center">${s.computer}</div>
<div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank">${s.computer}</a>` : s.computer}</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

P2: Add rel="noopener noreferrer" to the computer link opened with target="_blank" to avoid window.opener vulnerabilities.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/index.html, line 100:

<comment>Add rel="noopener noreferrer" to the computer link opened with target="_blank" to avoid window.opener vulnerabilities.</comment>

<file context>
@@ -54,14 +90,14 @@
                         <div class="flex flex-row items-center">
                             <div class="pr-2"><i class="fa-solid fa-server"></i></div>
-                            <div class="flex-1 text-center">${s.computer}</div>
+                            <div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank">${s.computer}</a>` : s.computer}</div>
                         </div>
                         <div class="flex flex-row items-center">
</file context>
Suggested change
<div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank">${s.computer}</a>` : s.computer}</div>
<div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank" rel="noopener noreferrer">${s.computer}</a>` : s.computer}</div>

<div class="flex-1 p-2 font-semibold text-center">${s.name}</div>
<a class="w-10 text-center" href="${s.source}">
<i class="fa-solid fa-arrow-up-right-from-square"></i>
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
Copy link
Contributor

Choose a reason for hiding this comment

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

P2: Add rel="noopener noreferrer" to the external link opened with target="_blank" to prevent window.opener security risks.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/index.html, line 93:

<comment>Add rel="noopener noreferrer" to the external link opened with target="_blank" to prevent window.opener security risks.</comment>

<file context>
@@ -54,14 +90,14 @@
                         <div class="flex-1 p-2 font-semibold text-center">${s.name}</div>
-                        <a class="w-10 text-center" href="${s.source}">
-                            <i class="fa-solid fa-arrow-up-right-from-square"></i>
+                        <a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
+                            <i class="${s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}"></i>
                         </a>
</file context>
Suggested change
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank" rel="noopener noreferrer">

Comment on lines +814 to +818
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/examples.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/case_constraints.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/physics_constraints.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/cli-reference.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/parameters.md"
Copy link
Contributor

Choose a reason for hiding this comment

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

P2: The inject-dates custom command runs docs/inject-dates.py but doesn’t list that script in DEPENDS, so updates to the script won’t retrigger the stamp and documentation can go stale without a clean build.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At CMakeLists.txt, line 814:

<comment>The inject-dates custom command runs docs/inject-dates.py but doesn’t list that script in DEPENDS, so updates to the script won’t retrigger the stamp and documentation can go stale without a clean build.</comment>

<file context>
@@ -806,6 +806,24 @@ if (MFC_DOCUMENTATION)
+    # Uses a stamp file so it only runs once per build.
+    add_custom_command(
+        OUTPUT  "${CMAKE_CURRENT_BINARY_DIR}/inject-dates.stamp"
+        DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/examples.md"
+                "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/case_constraints.md"
+                "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/physics_constraints.md"
</file context>
Suggested change
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/examples.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/case_constraints.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/physics_constraints.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/cli-reference.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/parameters.md"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/examples.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/case_constraints.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/physics_constraints.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/cli-reference.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/parameters.md"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/inject-dates.py"

)
page_date = result.stdout.strip() or str(date.today())

with open(md_file, "a") as f:
Copy link
Contributor

Choose a reason for hiding this comment

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

P2: Add encoding='utf-8' to open(). Without explicit encoding, the file uses the platform default which isn't UTF-8 on all systems. This can cause encoding errors when the documentation files contain non-ASCII characters.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/inject-dates.py, line 26:

<comment>Add `encoding='utf-8'` to `open()`. Without explicit encoding, the file uses the platform default which isn't UTF-8 on all systems. This can cause encoding errors when the documentation files contain non-ASCII characters.</comment>

<file context>
@@ -0,0 +1,31 @@
+    )
+    page_date = result.stdout.strip() or str(date.today())
+
+    with open(md_file, "a") as f:
+        f.write(
+            f"\n\n<div style='text-align:center; font-size:0.75rem; "
</file context>

- Change @type from SoftwareApplication to SoftwareSourceCode so
  programmingLanguage and codeRepository are conformant properties
- Normalize "30 min" to "30m" to match other gallery entries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@codeant-ai
Copy link
Contributor

codeant-ai bot commented Feb 18, 2026

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai bot added the size:L This PR changes 100-499 lines, ignoring generated files label Feb 18, 2026
@codeant-ai
Copy link
Contributor

codeant-ai bot commented Feb 18, 2026

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Reverse tabnabbing
    Several anchors for external links are opened with target="_blank" but do not include rel="noopener" or "noreferrer". This allows a newly opened page to access the originating window via window.opener (reverse tabnabbing). Update generated anchors to include rel attributes when target="_blank".

  • Template injection
    The $title variable is inserted directly into the meta description (and could be used in other meta attributes). If $title contains quotes or HTML, it may break attributes or allow unintended markup. Ensure $title is HTML-escaped/sanitized before being emitted into attribute values.

  • Unescaped template insertion
    The gallery HTML is built by injecting properties (e.g., s.source, s.computerUrl, s.computer) directly into template strings. If these strings ever come from external input, they could introduce HTML/attribute injection. Consider sanitizing or ensuring these values are hard-coded and trusted.

  • Missing social metadata
    The new description meta improves search snippets but social previews (Twitter/OG) are not present. Adding Open Graph and Twitter card tags will give better previews when links are shared.

<div class="flex-1 p-2 font-semibold text-center">${s.name}</div>
<a class="w-10 text-center" href="${s.source}">
<i class="fa-solid fa-arrow-up-right-from-square"></i>
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Using target="_blank" on external links without rel="noopener noreferrer" allows the opened page to access window.opener and potentially redirect the original page (reverse tabnabbing), so the link to simulation sources should include rel attributes to prevent this. [security]

Severity Level: Major ⚠️
- CRITICAL Docs homepage simulation links expose window.opener reference.
- WARN Original docs tab can be navigated by external site.
- WARN Security hardening for primary marketing page is reduced.
Suggested change
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank" rel="noopener noreferrer">
Steps of Reproduction ✅
1. Open `docs/index.html` in a browser (homepage entry point).

2. On DOMContentLoaded, script block at `docs/index.html:82-99` populates `#ft-sim` with
cards, rendering anchor at `docs/index.html:93` as `<a ... href="${s.source}"
target="_blank">` without `rel`.

3. Click any simulation source link (e.g., a YouTube or DOI URL) so it opens in a new tab
due to `target="_blank"`.

4. In the DevTools console of the newly opened tab, execute `window.opener.location =
'https://example.com'` and observe the original `docs/index.html` tab is navigated away,
demonstrating the reverse‑tabnabbing risk caused by missing `rel="noopener noreferrer"`.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** docs/index.html
**Line:** 93:93
**Comment:**
	*Security: Using target="_blank" on external links without rel="noopener noreferrer" allows the opened page to access window.opener and potentially redirect the original page (reverse tabnabbing), so the link to simulation sources should include rel attributes to prevent this.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

<div class="flex flex-row items-center">
<div class="pr-2"><i class="fa-solid fa-server"></i></div>
<div class="flex-1 text-center">${s.computer}</div>
<div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank">${s.computer}</a>` : s.computer}</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: The dynamically generated external links to HPC center pages also use target="_blank" without rel="noopener noreferrer", which can be abused by the new tab to manipulate the originating page, so the anchor should include rel attributes. [security]

Severity Level: Major ⚠️
- CRITICAL Docs homepage HPC links expose window.opener reference.
- WARN External HPC pages can navigate original documentation tab.
- WARN Security posture of external-resource links is weakened.
Suggested change
<div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank">${s.computer}</a>` : s.computer}</div>
<div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank" rel="noopener noreferrer">${s.computer}</a>` : s.computer}</div>
Steps of Reproduction ✅
1. Open `docs/index.html` in a browser (homepage).

2. DOMContentLoaded handler at `docs/index.html:82-107` renders the server row, producing
the template at `docs/index.html:100` with `<a href="${s.computerUrl}" ...
target="_blank">` and no `rel`.

3. Click any HPC center link (e.g., CSCS Alps, OLCF Frontier) so it opens in a new tab due
to `target="_blank"`.

4. In the DevTools console of that new HPC tab, run `window.opener.location =
'https://example.com'` and see the original docs tab navigated, confirming the
reverse‑tabnabbing condition from missing `rel="noopener noreferrer"`.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** docs/index.html
**Line:** 100:100
**Comment:**
	*Security: The dynamically generated external links to HPC center pages also use target="_blank" without rel="noopener noreferrer", which can be abused by the new tab to manipulate the originating page, so the anchor should include rel attributes.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

"${CMAKE_CURRENT_SOURCE_DIR}"
COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/inject-dates.stamp"
COMMENT "Injecting page dates into documentation"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Add VERBATIM to the new custom command so that the Python invocation and paths are safely quoted across platforms, matching the other custom commands in this file. [custom_rule]

Severity Level: Minor ⚠️

Suggested change
)
VERBATIM
Why it matters? ⭐

Adding VERBATIM matches the pattern used elsewhere in this CMakeLists (other add_custom_command invocations include VERBATIM) and ensures CMake does not perform platform-specific tokenization/escaping on the Python command and its arguments. This improves robustness/portability of the custom command and directly addresses a portability/consistency concern in the diff. The change is syntactically valid CMake and fixes a real potential issue rather than being purely cosmetic.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** CMakeLists.txt
**Line:** 823:823
**Comment:**
	*Custom Rule: Add VERBATIM to the new custom command so that the Python invocation and paths are safely quoted across platforms, matching the other custom commands in this file.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

<div class="flex-1 p-2 font-semibold text-center">${s.name}</div>
<a class="w-10 text-center" href="${s.source}">
<i class="fa-solid fa-arrow-up-right-from-square"></i>
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Add a rel attribute to the external link opened in a new tab to prevent the new page from accessing the opener context. [custom_rule]

Severity Level: Minor ⚠️

Suggested change
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank" rel="noopener noreferrer">
Why it matters? ⭐

Adding rel="noopener noreferrer" mitigates reverse tabnabbing and prevents the opened page from accessing window.opener. This is a security best-practice for links using target="_blank" and directly improves the code's safety without changing behavior for legitimate destinations.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** docs/index.html
**Line:** 93:93
**Comment:**
	*Custom Rule: Add a rel attribute to the external link opened in a new tab to prevent the new page from accessing the opener context.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

<a class="w-10 text-center" href="${s.source}">
<i class="fa-solid fa-arrow-up-right-from-square"></i>
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
<i class="${s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}"></i>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Guard the use of the includes method on the source URL to avoid runtime errors if the field is ever missing or null. [custom_rule]

Severity Level: Minor ⚠️

Suggested change
<i class="${s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}"></i>
<i class="${s.source && s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}"></i>
Why it matters? ⭐

The proposed change (s.source && s.source.includes(...)) guards against a potential runtime TypeError if a future sims entry omitted source or set it to null/undefined. This is a correctness improvement (runtime-safety) rather than cosmetic, and the improved code is a small, syntactically valid defensive check that directly resolves that issue.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** docs/index.html
**Line:** 94:94
**Comment:**
	*Custom Rule: Guard the use of the `includes` method on the source URL to avoid runtime errors if the field is ever missing or null.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

<div class="flex flex-row items-center">
<div class="pr-2"><i class="fa-solid fa-server"></i></div>
<div class="flex-1 text-center">${s.computer}</div>
<div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank">${s.computer}</a>` : s.computer}</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Ensure that dynamically generated external computer links opened in a new tab also include a rel attribute for security. [custom_rule]

Severity Level: Minor ⚠️

Suggested change
<div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank">${s.computer}</a>` : s.computer}</div>
<div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank" rel="noopener noreferrer">${s.computer}</a>` : s.computer}</div>
Why it matters? ⭐

Same as above: adding rel="noopener noreferrer" to programmatically-generated external links prevents window.opener access and improves security. The improved code is a minimal, correct fix that addresses a real security concern and is applicable to this PR hunk.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** docs/index.html
**Line:** 100:100
**Comment:**
	*Custom Rule: Ensure that dynamically generated external computer links opened in a new tab also include a rel attribute for security.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

@codeant-ai
Copy link
Contributor

codeant-ai bot commented Feb 18, 2026

CodeAnt AI finished reviewing your PR.

- Make weak scaling card clickable (links to expectedPerformance.html)
- Fix lychee exclude_path: glob to regex syntax for CLI compatibility
- Add URL exclude for sitemap referenced in robots.txt
- Move publish step before lychee so deploys are not blocked by link errors
- Set lychee fail: true so broken links fail CI
- Add VERBATIM to inject-dates CMake custom command

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/docs.yml:
- Around line 80-84: The Linkcheck step ("Linkcheck - Lychee" using
lycheeverse/lychee-action@v2 with fail: true) is placed after the Publish step
so broken links won't prevent deployment on schedule/workflow_dispatch runs;
move the Lychee step earlier in the job sequence so it runs (and can fail)
before the Publish step, or alternatively ensure the Publish step is conditional
on the Linkcheck step succeeding (e.g., make Publish depend on the Linkcheck
job/result) so that fail: true actually blocks deployment for non-PR runs.

In `@docs/index.html`:
- Around line 26-46: The JSON-LD block uses "@type": "SoftwareSourceCode" but
includes two invalid properties for that type: "applicationCategory" and
"operatingSystem"; remove those two properties from the object so the schema
validates as SoftwareSourceCode (keep valid fields like "codeRepository" and
"programmingLanguage"), or if you prefer representing an application instead,
change "@type" to "SoftwareApplication" and then remove/adjust
source-code-specific fields ("codeRepository", "programmingLanguage") to match
the chosen type consistently.
- Around line 93-95: The anchor that renders the source icon (the <a> that uses
s.source and contains the <i> element) lacks an accessible label; update its
markup to include an accessible name by adding an aria-label (and optionally a
title or visually-hidden text) that describes the destination (e.g., "Open
source on YouTube" when s.source includes 'youtube.com', otherwise "Open source
link"); ensure the label text is generated from s.source or context so screen
readers receive a meaningful description and keep the existing icon for visual
users.

---

Duplicate comments:
In `@docs/index.html`:
- Around line 93-95: Add rel="noopener noreferrer" to any anchor that opens a
new tab to prevent window.opener access and referer leakage; specifically update
the anchor with href="${s.source}" (the source-icon link) and the computer-URL
anchor (the link that opens the computer URL in a new tab) to include
rel="noopener noreferrer" alongside target="_blank". Ensure both anchors include
the attribute exactly as shown and keep existing class/href attributes intact.

Comment on lines +80 to +84
- name: Linkcheck - Lychee
uses: lycheeverse/lychee-action@v2
with:
args: -c .lychee.toml build/install/docs/mfc/
fail: true
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Lychee now runs after publish — broken links won't block deployment on scheduled/dispatch runs.

Moving Lychee after the Publish step (with fail: true) means that on schedule / workflow_dispatch triggers, documentation is deployed to GitHub Pages before link checking occurs. A link-check failure will mark the workflow as failed but won't roll back the published content.

On PRs this is not an issue (the publish step is skipped), so Lychee correctly gates PR merges. For production runs, this trade-off appears intentional per the PR description ("move publish step before lychee"), but it's worth confirming that alerting-on-failure (e.g., via GitHub notification or branch protection) is sufficient to catch post-deploy regressions.

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

In @.github/workflows/docs.yml around lines 80 - 84, The Linkcheck step
("Linkcheck - Lychee" using lycheeverse/lychee-action@v2 with fail: true) is
placed after the Publish step so broken links won't prevent deployment on
schedule/workflow_dispatch runs; move the Lychee step earlier in the job
sequence so it runs (and can fail) before the Publish step, or alternatively
ensure the Publish step is conditional on the Linkcheck step succeeding (e.g.,
make Publish depend on the Linkcheck job/result) so that fail: true actually
blocks deployment for non-PR runs.

Comment on lines +93 to 95
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
<i class="${s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}"></i>
</a>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Source-link icon has no accessible label — screen readers cannot identify the link.

The <a> contains only a FontAwesome <i> icon with no visible text, aria-label, or title. Screen-reader users will hear an unlabelled link.

♿ Proposed fix
-                        <a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
-                            <i class="${s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}"></i>
+                        <a class="w-10 text-center text-xl" href="${s.source}" target="_blank" rel="noopener noreferrer"
+                           aria-label="${s.source.includes('youtube.com') ? 'Watch on YouTube' : 'View source'}">
+                            <i class="${s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}" aria-hidden="true"></i>
📝 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
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
<i class="${s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}"></i>
</a>
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank" rel="noopener noreferrer"
aria-label="${s.source.includes('youtube.com') ? 'Watch on YouTube' : 'View source'}">
<i class="${s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}" aria-hidden="true"></i>
</a>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/index.html` around lines 93 - 95, The anchor that renders the source
icon (the <a> that uses s.source and contains the <i> element) lacks an
accessible label; update its markup to include an accessible name by adding an
aria-label (and optionally a title or visually-hidden text) that describes the
destination (e.g., "Open source on YouTube" when s.source includes
'youtube.com', otherwise "Open source link"); ensure the label text is generated
from s.source or context so screen readers receive a meaningful description and
keep the existing icon for visual users.

…eratingSystem)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
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.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@docs/index.html`:
- Around line 91-93: The anchor rendering the source link (the <a> with classes
"w-10 text-center text-xl" linking to ${s.source}) lacks an accessible label and
its icon <i> has no aria-hidden attribute; update the anchor to include a
descriptive aria-label (constructed from s.source, e.g., "Open source on
YouTube" when s.source.includes('youtube.com') else "Open source in new tab")
and set aria-hidden="true" on the <i> element so screen readers get the anchor
label rather than the decorative icon.
- Around line 91-92: The anchor that renders external links (the <a> with class
"w-10 text-center text-xl" and href="${s.source}" target="_blank") — and its
twin around line 98 — are missing rel attributes; update both anchor elements to
include rel="noopener noreferrer" so opened tabs cannot access window.opener and
the Referer header is not leaked, ensuring you add this attribute to the same
anchor(s) that use target="_blank".

@sbryngelson
Copy link
Member Author

/improve

@qodo-code-review
Copy link
Contributor

ⓘ Your monthly quota for Qodo has expired. Upgrade your plan
ⓘ Paying users. Check that your Qodo account is linked with this Git user account

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sbryngelson sbryngelson merged commit df22a69 into MFlowCode:master Feb 18, 2026
34 of 54 checks passed
@codecov
Copy link

codecov bot commented Feb 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 44.07%. Comparing base (c5493c1) to head (f76ad55).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1160   +/-   ##
=======================================
  Coverage   44.07%   44.07%           
=======================================
  Files          70       70           
  Lines       20431    20431           
  Branches     1974     1974           
=======================================
  Hits         9004     9004           
  Misses      10291    10291           
  Partials     1136     1136           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Development

Successfully merging this pull request may close these issues.

1 participant

Comments