Skip to content

refactor(issue-bot): remove instructional comment for take/untake - #187

Closed
laxitajain wants to merge 11 commits into
Ryan-Millard:mainfrom
laxitajain:fix/remove-bot-instruction
Closed

refactor(issue-bot): remove instructional comment for take/untake#187
laxitajain wants to merge 11 commits into
Ryan-Millard:mainfrom
laxitajain:fix/remove-bot-instruction

Conversation

@laxitajain

@laxitajain laxitajain commented Jan 2, 2026

Copy link
Copy Markdown
Contributor

⚠️ Are you using the correct pull request template?
Please choose one of the following:

If none of these fit, you may use this default to describe your change manually.

If this is the right template, go ahead and complete it below 👇


📌 Description

Fixes #129

✅ Type of Change

Place an "x" in the brackets below:

  • Bug fix 🐛
  • New feature ✨
  • Refactor 🔧
  • Documentation 📚
  • Build/dependency update 🧱
  • Other (describe):

🧪 How Has This Been Tested?

Please describe how you tested your changes (e.g., unit tests, manual testing, screenshots, etc.)

🧩 Checklist

Place an "x" in the brackets below:

  • I’ve followed the contribution guidelines.
  • My code follows the code style of this project.
  • I’ve added tests where necessary.
  • I’ve updated the documentation where applicable.
  • I’ve linked related issues or discussions (if any).
  • I’ve checked for breaking changes and backwards compatibility.

📸 Screenshots / Demo (if applicable)

Paste images, GIFs, or demo links here.

💬 Additional Context

Anything else relevant to the PR.

Summary by CodeRabbit

  • Documentation

    • Added “Claiming Issues” guidance for /take and /untake and updated many docs for clarity and formatting.
  • New Features

    • Unified issue-claiming flow: taken/untaken banners and labels reflect claim state persisted by the bot.
    • New GlassSwitch UI component used for theme toggling (replaces previous button control).
  • Chores

    • Automated claim expiry (21 days) and weekly cleanup to clear stale claims and keep banners/labels in sync.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 2, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Unifies issue claiming into a single GitHub Actions job that handles issue opened and /take//untake comments, persists claim metadata in bot comments, updates issue body banners and the taken label, and adds expiry detection plus a weekly cleanup. (33 words)

Changes

Cohort / File(s) Summary
Workflow: unified take/untake logic
**/.github/workflows/issue-take-untake.yml
Replaced split workflows with one take_untake job handling issue opened and comment events; introduced banner markers (MARKER_PREFIX, BODY_START, BODY_END), unified /take & /untake handling, and centralized label/body updates.
Persistence, expiry & cleanup
**/.github/workflows/issue-take-untake.yml
Persist claim meta as JSON in bot comments, read latest bot meta to reconstruct state, delete stale meta comments, expire claims after 21 days on interaction and via weekly scan, remove taken label and rewrite body banners on expiry.
Docs: claiming & CI docs
docs/docs/guidelines/CONTRIBUTING.md, CONTRIBUTING.md, docs/docs/reference/tools/ci-workflows.md
Added "Claiming Issues" guidance for /take and /untake; documented CI workflow behavior and script-validation conditions; removed reliance on posting instructional bot comments.
New UI component & integration
src/components/GlassSwitch.jsx, src/components/GlassSwitch.module.css, src/components/GlassSwitch.test.jsx, src/components/ThemeSwitch.jsx, src/components/ThemeSwitch.test.jsx
Added accessible GlassSwitch component (styles + tests); refactored ThemeSwitch to use GlassSwitch and updated tests/mocks.
CI / lint / script validation
**/.github/workflows/ci.yml, scripts/format-wasm.js, scripts/validate-scripts.js, `package.json``
Added lint job, conditional validate-scripts execution, non-mutating format-check scripts, and format-wasm --check mode; updated package.json scripts and deps.
Editor config & tooling
.editorconfig, .editorconfig-checker.json
Broadened file patterns, increased max_line_length, added editorconfig-checker config and exclusions.
Wide docs & formatting edits
docs/**
Large set of editorial/formatting changes, new docs pages (ci-workflows), and many localized content/formatting updates across documentation.
Misc: stylistic & small tooling edits
src/**, scripts/**, vite.config.js, vitest.config.js, docs/**
Numerous non-functional string-quote, whitespace, and formatting changes; a few small behavior-preserving guards (e.g., mkdir in scripts/handle-changelog.js).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant GH as GitHub (Events/API)
  participant Actions as GitHub Actions Runner
  participant Issue as Issue (body/labels)
  participant BotC as Bot Comments (meta)

  rect rgb(240,249,255)
    Note over User,GH: Claim flow: user posts "/take" comment
  end

  User->>GH: POST comment "/take"
  GH->>Actions: webhook -> run take_untake job
  Actions->>GH: GET issue, comments, labels
  GH->>Actions: return issue data + comments
  Actions->>BotC: DELETE stale meta comments (if any)
  Actions->>BotC: CREATE new meta comment with JSON marker (owner, expiry)
  Actions->>Issue: UPDATE body banner (replace marker region or prepend)
  Actions->>Issue: ADD `taken` label (create label if missing)
  GH->>User: label/body updated

  rect rgb(255,243,240)
    Note over Actions,GH: Periodic expiry scan (weekly cleanup or on-interaction expiry)
  end

  Actions->>GH: LIST open issues with `taken` label
  loop per issue
    Actions->>GH: GET comments -> latest bot meta
    GH->>Actions: returns latest meta
    alt meta expired
      Actions->>Issue: REMOVE `taken` label
      Actions->>Issue: UPDATE body banner to untaken
      Actions->>BotC: CREATE meta comment noting expiry
    else still valid
      Note right of Actions: no-op
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #129 — Fix: Stop posting bot instruction comment on new issues — PR removes posting instructional bot comments and documents claiming in CONTRIBUTING.
  • Ryan-Millard/Img2Num#120 — Similar changes to the issue-take-untake workflow; both modify claim handling/meta comment format.

Possibly related PRs

  • Ryan-Millard/Img2Num#170 — Adds GlassSwitch and updates ThemeSwitch; closely matches the UI/component changes here.
  • Ryan-Millard/Img2Num#146 — Modifies CI lint/validate-scripts workflows; related to the CI changes in this PR.
  • Ryan-Millard/Img2Num#135 — Related to script-validation CI flow; touches validate-scripts logic.

Suggested labels

refactor, docs

Suggested reviewers

  • Ryan-Millard

Poem

🐇
I hopped the issue garden, soft and light,
Pushed a tidy banner, held it tight.
/take for a while, /untake when I’m through,
A labeled burrow, neat and true.
Small paws, big help — hooray and chew!

Pre-merge checks

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Most changes are in-scope (issue-bot workflow, contributing guide, tests), but extensive documentation reformatting, styling updates, new components (GlassSwitch), and package.json modifications for unrelated features appear out-of-scope for the stated objective. Isolate changes to issue-bot workflow, contributing documentation, and related tests; move unrelated refactoring (GlassSwitch, ThemeSwitch, editor config, styling) and documentation reformatting to separate PRs.
Docstring Coverage ⚠️ Warning Docstring coverage is 77.27% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'refactor(issue-bot): remove instructional comment for take/untake' accurately describes the main change: removing the bot's instructional comment while keeping the take/untake functionality.
Linked Issues check ✅ Passed The PR addresses all coding requirements from issue #129: removes instructional comment posting, preserves /take and /untake handling, updates contribution guide with claim/release documentation, and ensures the 'taken' label indicates ownership.

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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b7ea93 and 89f5ee2.

📒 Files selected for processing (2)
  • .github/workflows/issue-take-untake.yml
  • docs/docs/guidelines/CONTRIBUTING.md
💤 Files with no reviewable changes (1)
  • .github/workflows/issue-take-untake.yml

Comment thread docs/docs/guidelines/CONTRIBUTING.md

@Ryan-Millard Ryan-Millard left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This is great. Thank you!

I've realized that it's still important to display the status of the issue to potential contributors, so please will you get the action to update the body (description) of the issue instead of commenting on it . It should show something like the below at the top of the body of the issue:

Untaken

Tip

This issue hasn't been claimed yet. Comment /take if you'd like to work on it!

For more information on how Img2Num's claim system works, please see #99.

This edit was made by the issue-take-untake GitHub workflow


> [!TIP]
> This issue hasn't been claimed yet. Comment `/take` if you'd like to work on it!
>
> > For more information on how Img2Num's claim system works, please see #99.
> 
> <sub>This edit was made by the [`issue-take-untake`](https://github.com/Ryan-Millard/Img2Num/blob/main/.github/workflows/issue-take-untake.yml) GitHub workflow</sub>
---

Taken

Caution

This issue has been claimed, so it is not recommended that you work on it.

For more information on how Img2Num's claim system works, please see #99.

For the owner of the claim:
If you would like to revoke your claim, comment /untake

This edit was made by the issue-take-untake GitHub workflow


> [!CAUTION]
> This issue has been claimed, so it is not recommended that you work on it.
>
> > For more information on how Img2Num's claim system works, please see #99.
> 
> > **For the owner of the claim:**
> > If you would like to revoke your claim, comment `/untake`
> 
> <sub>This edit was made by the [`issue-take-untake`](https://github.com/Ryan-Millard/Img2Num/blob/main/.github/workflows/issue-take-untake.yml) GitHub workflow</sub>
---

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 6

🧹 Nitpick comments (5)
.github/workflows/issue-take-untake.yml (5)

72-92: Consider adding error handling for API failures.

The function performs two API calls without error handling. While GitHub Actions will fail the workflow on unhandled errors, adding try-catch would allow for more graceful degradation or retry logic.

🔎 Optional: Add error handling
 async function updateIssueBody(newBanner) {
+  try {
     const issue = await github.rest.issues.get({ owner, repo, issue_number: issueNumber });
     const body = issue.data.body || '';

     let updated;
     if (body.includes(BODY_START)) {
       updated = body.replace(
         new RegExp(`${BODY_START}[\\s\\S]*?${BODY_END}`),
         newBanner
       );
     } else {
       updated = `${newBanner}\n\n---\n\n${body}`;
     }

     await github.rest.issues.update({
       owner,
       repo,
       issue_number: issueNumber,
       body: updated
     });
+  } catch (error) {
+    console.error('Failed to update issue body:', error.message);
+    throw error; // Re-throw to fail the workflow
+  }
 }

168-172: Consider allowing maintainers to force-untake claims.

Currently, only the claim owner can /untake. In some cases, maintainers may need to release a stale claim or resolve disputes. Consider checking for write permissions and allowing maintainers to override.

🔎 Optional: Allow maintainer override
+// Check if commenter has write permission
+const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({
+  owner,
+  repo,
+  username: commenter
+});
+const isMaintainer = ['admin', 'write'].includes(permission.permission);
+
-if (isUntake && meta.owner === commenter) {
+if (isUntake && (meta.owner === commenter || isMaintainer)) {
   meta = { owner: null, members: [], ts: 0 };
   await persistMeta(meta, false);
   return;
 }

126-126: Remove unused members field from meta object.

The members array is initialized but never populated or read anywhere in the workflow. This suggests incomplete implementation or technical debt.

🔎 Cleanup suggestion
-let meta = { owner: null, members: [], ts: 0 };
+let meta = { owner: null, ts: 0 };

Also remove from line 169:

-  meta = { owner: null, members: [], ts: 0 };
+  meta = { owner: null, ts: 0 };

If members was intended for future co-ownership features, consider documenting that plan or creating a TODO comment.


115-117: Consider adding user feedback for claim commands.

Users issuing /take or /untake commands receive no immediate confirmation. Adding reactions or replies would improve the user experience and make the workflow behavior more transparent.

💡 Example: Add reaction feedback
 const isTake = /^\/take(\s|$)/i.test(bodyText);
 const isUntake = /^\/untake(\s|$)/i.test(bodyText);
 if (!isTake && !isUntake) return;
+
+// Add eyes reaction to show we're processing
+await github.rest.reactions.createForIssueComment({
+  owner,
+  repo,
+  comment_id: comment.id,
+  content: 'eyes'
+});

Then add success reactions (+1 or rocket) after persistMeta calls, or confused if the action wasn't allowed (e.g., trying to take an already-claimed issue).


43-70: Extract duplicated buildUntakenBody function and evaluate the #99 issue reference.

The buildUntakenBody function is duplicated at lines 43–54 and lines 191–202 with identical logic. Both banners and a third reference (line 197) point to issue #99 for claim system documentation.

However, the actual claim system is documented in docs/docs/guidelines/CONTRIBUTING.md. The hard-coded #99 reference is repeated three times in the workflow. Consider:

  1. Extracting buildUntakenBody to a shared workflow or external script to eliminate duplication.
  2. Documenting whether issue #99 is still relevant, or updating the references to point to CONTRIBUTING.md instead.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 900ede1 and 1e4b4f8.

📒 Files selected for processing (1)
  • .github/workflows/issue-take-untake.yml
🔇 Additional comments (2)
.github/workflows/issue-take-untake.yml (2)

17-20: LGTM: Bot loop prevention.

The condition correctly prevents the bot from triggering itself while allowing both issue open events and user comments.


94-107: LGTM: Clean handling of label creation and initial banner.

The idempotent label creation with an empty catch block is appropriate here, as the label may already exist. The early return and banner update logic are correct.

Comment thread .github/workflows/issue-take-untake.yml Outdated
Comment thread .github/workflows/issue-take-untake.yml Outdated
Comment thread .github/workflows/issue-take-untake.yml
Comment thread .github/workflows/issue-take-untake.yml
Comment thread .github/workflows/issue-take-untake.yml
Comment thread .github/workflows/issue-take-untake.yml
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

♻️ Duplicate comments (7)
.github/workflows/issue-take-untake.yml (7)

127-137: Fragile JSON parsing remains unaddressed.

The JSON parsing still uses simple string splitting on --> (line 134), which will fail if the JSON payload contains that sequence (e.g., in a username or error message).

🔎 More robust parsing approach
 if (latestMeta) {
   try {
-    const json = latestMeta.body.split(MARKER_PREFIX)[1].split('-->')[0].trim();
+    const match = latestMeta.body.match(/<!-- take-meta:(.+?)-->/);
+    const json = match ? match[1].trim() : '';
     meta = JSON.parse(json);
   } catch {}
 }

Based on past review comments, this parsing vulnerability should be addressed to prevent runtime failures.


141-158: Meta comments still accumulate indefinitely.

The function continues to create a new bot comment on every /take or /untake rather than editing or deleting existing meta comments. Active issues will accumulate many hidden meta comments over time.

Consider either editing the latest meta comment or deleting old ones before creating new ones. Based on past review comments, this accumulation should be addressed.


161-166: Critical: Expired claims still cannot be taken until weekly cleanup.

The /take handler only checks if meta.owner is null but doesn't verify whether an existing claim has expired. Users attempting to claim an expired issue will be blocked until the weekly cleanup job runs.

🔎 Proposed fix: Check expiry in real-time
-if (isTake && !meta.owner) {
+const isExpired = meta.ts && (now - meta.ts > EXPIRE_MS);
+if (isTake && (!meta.owner || isExpired)) {
   meta.owner = commenter;
   meta.ts = now;
   await persistMeta(meta, true);
   return;
 }

Based on past review comments, this prevents users from claiming expired issues and creates a poor experience.


185-202: Significant code duplication between jobs.

Constants (lines 185-189) and the buildUntakenBody function (lines 191-202) are duplicated from the main job. This creates a maintenance burden where changes must be synchronized across both locations.

Based on past review comments, consider extracting to workflow-level env variables or a reusable composite action to maintain a single source of truth.


220-228: Missing sort could select incorrect meta comment.

Unlike the main job (line 129), the cleanup job doesn't sort meta comments before using .pop() (line 222). If the GitHub API doesn't guarantee chronological order, this could select the wrong meta comment.

🔎 Proposed fix: Add explicit sorting
 const metaComment = comments.data
   .filter(c => c.body?.includes(MARKER_PREFIX))
+  .sort((a, b) => new Date(a.created_at) - new Date(b.created_at))
   .pop();

Based on past review comments, this should match the sorting used in the main job to ensure correct meta selection.


227-227: Same fragile JSON parsing in cleanup job.

Line 227 uses the same vulnerable string splitting approach on --> as the main job (line 134), which will fail if the JSON contains that sequence.

🔎 More robust parsing
-const meta = JSON.parse(metaComment.body.split(MARKER_PREFIX)[1].split('-->')[0].trim());
+const match = metaComment.body.match(/<!-- take-meta:(.+?)-->/);
+const meta = match ? JSON.parse(match[1].trim()) : null;
+if (!meta) continue;

Based on past review comments, use regex matching instead of string splitting for robust parsing.


231-247: Duplicated body update logic.

The body replacement logic (lines 231-247) duplicates the updateIssueBody function from the main job (lines 72-92), requiring updates in multiple places when the logic changes.

Based on past review comments, this duplication creates maintenance overhead and should be consolidated.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e4b4f8 and 66f94b3.

📒 Files selected for processing (1)
  • .github/workflows/issue-take-untake.yml
🔇 Additional comments (6)
.github/workflows/issue-take-untake.yml (6)

16-21: LGTM: Clean event filtering.

The combined conditional correctly handles both issue opens and comments while preventing bot self-triggering.


43-70: LGTM: Clear banner generation with proper documentation links.

The functions correctly generate untaken and taken banners with helpful references to issue #99 for centralized documentation, aligning with PR objectives.


72-92: LGTM: Robust body update logic.

The function correctly handles both updating existing banners and adding new ones, with proper regex-based replacement.


94-107: LGTM: Correctly implements PR objective.

This replaces the previous instructional comment mechanism with an in-body banner, reducing noise while providing clear claiming instructions. The best-effort label creation is appropriate.


109-117: LGTM: Efficient command parsing.

The regex patterns correctly match /take and /untake commands with appropriate case-insensitivity and boundaries. Early returns optimize execution.


168-172: LGTM: Proper ownership validation.

The /untake handler correctly verifies that only the current owner can release their claim.

Comment thread .github/workflows/issue-take-untake.yml

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 0

♻️ Duplicate comments (2)
.github/workflows/issue-take-untake.yml (2)

224-241: Code duplication persists between jobs.

The constants (lines 224-228) and buildUntakenBody function (lines 230-241) are duplicated from the main job (lines 31-36, 43-54). This creates a maintenance burden where changes must be synchronized across both jobs.

As noted in previous reviews, consider extracting shared constants to workflow-level env variables. For the function duplication, GitHub Actions doesn't support sharing JavaScript functions between jobs natively—you would need to move to a reusable composite action or accept the duplication with clear documentation.

Based on past review comments, this duplication was previously flagged but remains unresolved.


252-257: Performance note: fetching all comments may be slow for active issues.

The cleanup job fetches up to 200 comments for each taken issue. For issues with many comments, this could be slow. Previous reviews noted this concern.

Consider optimizing if this becomes a bottleneck:

  • Use GraphQL to fetch only bot comments
  • Add pagination handling beyond 200 comments

Since this runs weekly and most issues likely have fewer than 200 comments, this is an optional optimization rather than a blocking concern.

Based on past review comments, this performance concern was previously noted.

🧹 Nitpick comments (1)
.github/workflows/issue-take-untake.yml (1)

277-300: Consider deleting stale meta comments for consistency.

The cleanup job removes the label and updates the issue body when expiring a claim but doesn't delete the stale meta comment. This differs from the main job's persistMeta function (lines 154-163), which deletes old meta comments.

For consistency and to prevent stale metadata from accumulating, consider deleting the meta comment when expiring a claim.

🔎 Suggested enhancement
                if (meta.ts && Date.now() - meta.ts > EXPIRE_MS) {
+                 // Delete the stale meta comment
+                 try {
+                   await github.rest.issues.deleteComment({
+                     owner,
+                     repo,
+                     comment_id: metaComment.id
+                   });
+                 } catch {}
+
                  await github.rest.issues.removeLabel({
                    owner,
                    repo,
                    issue_number: issue.number,
                    name: takenLabel
                  });
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66f94b3 and 904bae0.

📒 Files selected for processing (1)
  • .github/workflows/issue-take-untake.yml
🔇 Additional comments (3)
.github/workflows/issue-take-untake.yml (3)

194-197: Excellent fix for real-time expiry handling!

The expiry normalization before command processing successfully addresses the critical issue flagged in previous reviews. Expired claims are now immediately treated as unclaimed, allowing users to take expired issues without waiting for the weekly cleanup job.


141-163: Good improvement: meta comments no longer accumulate.

The function now deletes all previous meta comments before creating a new one, successfully addressing the accumulation concern raised in previous reviews. This keeps the comment section clean while maintaining claim state.


126-136: Improved JSON parsing is more robust.

The use of indexOf with proper bounds checking is a significant improvement over the fragile string splitting approach flagged in previous reviews. This correctly handles cases where --> might appear in the JSON payload.

@laxitajain

Copy link
Copy Markdown
Contributor Author

Hello, this PR now updates the issue claim workflow to render the claim status directly as a banner in the issue description instead of the comments. The banner updates automatically when an issue is opened, when /take or /untake is used, and when a stale claim expires. Older issues are automatically upgraded when the workflow runs, without overwriting existing content.
I’ve implemented all functional and safety-related changes suggested by CodeRabbit, including:

  • Robust meta parsing using explicit marker boundaries instead of fragile string splits
  • Sorting meta comments before selection to guarantee the latest state is used
  • Normalizing expired claims in real time so users can claim immediately without waiting for the weekly cleanup
  • Preventing unbounded meta comment growth by deleting older meta comments before writing the new state

Two CodeRabbit suggestions were reviewed but intentionally not implemented:

  • Code duplication between the main job and cleanup job
    While there is some duplication (constants, banner generation, and replacement logic), keeping the cleanup job self-contained avoids cross-job coupling and makes the workflow easier to reason about and modify independently. Given the relatively small surface area and low change frequency, this felt like a reasonable tradeoff for clarity and maintainability.

  • Optimizing comment fetching performance
    The cleanup job fetches up to 200 comments per issue to locate the latest meta marker. This runs only once per week and only on issues with the taken label, so the performance impact is expected to be minimal in practice.

Happy to revisit either of these if they seem concerning!

@Ryan-Millard Ryan-Millard left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This is wonderful! I unfortunately just realized that I forgot something: it would be helpful to show who has taken the issue.

Please will you update the notice to use the @ of the claimer so others can understand that a specific person has claimed it.

Image

After that, I'll happily merge this pull request. Thank you!🦔

laxitajain and others added 4 commits January 5, 2026 11:56
…d#186)

* refactor(vite): ignore docs in dev and preview folders

* refactor(vite): ignore docs in dev and preview folders

* fix(.gitignore): don't ignore docs/ files, docs/.gitignore does that

---------

Co-authored-by: Ryan-Millard <millardryandevon@gmail.com>
…yan-Millard#146)

* feat(ci): add linting job to CI workflow and update contributing docs

- Add lint job to ci.yml that runs ESLint and editorconfig-checker
- Configure lint job to run on pull_request and push to main
- Update CONTRIBUTING.md with comprehensive linting documentation
- Include instructions for running lints locally and fixing issues
- Document current linting status and CI integration

Resolves Ryan-Millard#141

* docs: move linting documentation to Docusaurus and address review feedback

- Simplify root CONTRIBUTING.md and link to detailed docs
- Add comprehensive linting section to coding-style.md
- Create new ci-workflows.md documenting GitHub Actions workflows
- Update Questions section to link to discussions/issues instead of draft PRs

Addresses review feedback from @Ryan-Millard in Ryan-Millard#146

* fix: resolve linting errors in PR files and add sidebar position

- Fix line endings (CRLF -> LF) in all modified files
- Add final newlines to ci.yml, CONTRIBUTING.md, and docs files
- Fix indentation in markdown numbered lists
- Add sidebar_position: 2 to ci-workflows.md

Addresses feedback from @Ryan-Millard in Ryan-Millard#146

* chore: remove accidentally created files

* fix(docs): correct code block indentation in ci-workflows.md

* chore: remove accidentally created file from working tree

* feat(config): add editorconfig-checker exclusions

- Exclude build directories (dist, build, docs/build)
- Exclude node_modules and lock files
- Exclude all CMake build directories in wasm modules
- Exclude binary files (.ase, .min.js, .min.css)

* style: apply Prettier and clang-format to entire codebase

- Format 66 files with npm run format
- Prettier formatted all JS/React/Markdown files
- clang-format formatted all C++ files
- This establishes consistent formatting baseline for lint checks

* fix(config): correct editorconfig-checker regex patterns

- Remove ** glob patterns (not supported in regex)
- Use explicit paths for build directories

* fix: align editorconfig with Prettier output to resolve lint conflicts

- Increase max_line_length to 150 for HTML files
- Add LICENSE* pattern to catch all LICENSE files
- Add .tsx to JavaScript/React file patterns
- Configure editorconfig-checker to skip markdown detailed validation
- Resolves conflicts between Prettier's 3-space nested lists and 2-space rule

This allows formatters and linters to coexist without conflicts.

* style: run Prettier to fix trailing whitespace

- Fixed trailing whitespace in CSS and test files
- Formatted markdown documentation files
- Reduced lint errors from 258 to 178

* fix: exclude formatters' domains and increase line length limits

- Exclude Python (.py), Windows scripts (.bat, .ps1), bash (img2num), C++ (.cpp, .h)
- These files are handled by their respective formatters (Python, clang-format)
- Increase max_line_length to 200 for JS/JSX/HTML (allows long import/meta tags)
- Keep strict checking for JSON, YAML, and core project files

This allows each formatter to handle its domain without conflicts.

* fix: correct JSDoc formatting in sidebars.js

- Add missing asterisk prefix to JSDoc comment lines
- Resolves final 3 linting errors
- All linting checks now pass! ✅

* fix(linting & formatting): resolve errors & improve config

* feat(format scripts): add check scripts to avoid altering files in CI

* fix(README.md): close HTML tags

* feat(ci): add format:check to lint workflow and address review feedback

- Add npm run format:check to CI lint job
- Add TypeScript (.ts) to .editorconfig patterns
- Restore npm ci step in CI workflow
- Simplify root CONTRIBUTING.md to link to docs
- Fix admonition closing syntax in why-img2num-uses-the-dft
- Run Prettier on modified markdown files
- Resolve merge conflicts from maintainer's commits

Addresses feedback from @Ryan-Millard

* fix(file formatting): address CodeRabbit remarks

---------

Co-authored-by: Ryan-Millard <millardryandevon@gmail.com>
* added a sliding ui effect for theme switcher button

* refactor(theme-switch): address review feedback

* fix(theme-switch): render both icons to enable sliding animation

* refactor(glass-switch): apply DRY styles and finalize reusable switch

* fix(glass-switch): restore icon animation after merge

* fixed some issues & added sliding effect

* feat(glass-switch): finalize reusable switch with tests and accessibility

* docs: add GlassSwitch component documentation

* fixed changes suggested by coderabbit

* refactor(theme-switch): move theme logic back into ThemeSwitch to follow SRP

* removed unused code & rendered themeswitch only

* added isRequired to isOn

* Update @tanstack/react-query to the latest stable version (5.90.12).

* added size , disabled props that are optional

* improved documentation for GlassSwitch resuable component

* Added documentation for GlassSwitch component including it's tests

* Improved documentation as per it's usage & also modified it's test documentation accordingly

* Added a fallback Content when no thumbContent is given to component

* Improved the tests for GlassSwitch component to address changes

* Added useful comments back

* Improved tests for ThemeSwitch component & Adresed the required changes as per it's new usage

* modified documentation to ease the usage

* Fixed missing focus indicator in GlassSwitch component.

* Fixed extra space issue

* feat(GlassSwitch): improve styles

* removed size props as is not being used

* fixed table formating issue

* Fixed react node issue in classname

* style(react: GlassSwitch, ThemeSwitch): format GlassSwitch and ThemeSwitch components, tests, and docs

* docs(react: GlassSwitch): fix wording

* fix(docs: broken links): fix links in GlassSwitch documentation

---------

Co-authored-by: Ryan-Millard <millardryandevon@gmail.com>
Co-authored-by: Ryan Millard <142347829+Ryan-Millard@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 8

Fix all issues with AI Agents 🤖
In @.github/workflows/ci.yml:
- Around line 39-49: The lint job uses actions/checkout@v4 and
actions/setup-node@v4 while the validate-scripts job uses @v6; update the lint
job to use actions/checkout@v6 and actions/setup-node@v6 so both jobs are
consistent. Locate the lint job in the CI workflow and replace the checkout and
setup-node steps to match the validate-scripts job (actions/checkout and
actions/setup-node -> @v6) ensuring fetch-depth or node-version settings remain
intact.

In @docs/docs/guidelines/coding-style.md:
- Around line 74-87: The code block in the docs has mismatched fencing and
inconsistent indentation; fix by replacing the closing four-backtick fence with
a three-backtick fence and normalize indentation inside the example so the
function exampleFunction, its body, and the if block (including the call to
internalLibrary::isPrime and the std::cout lines) are consistently indented
(e.g., two spaces per block level) and ensure the namespace closing braces align
with the function indentation before the corrected closing ``` fence.

In @docs/docs/reference/react/components/GlassSwitch/tests.md:
- Around line 9-11: Update the fenced code block that contains the line
"src/components/GlassSwitch.test.jsx" in tests.md so the opening fence includes
a language identifier (change the opening "```" to "```bash") to enable proper
syntax highlighting; locate the block around the
"src/components/GlassSwitch.test.jsx" text and only modify the opening fence.
- Around line 51-56: The sentence "Can be disabled via `disabled` prop" is
missing a subject; update it to a complete sentence such as "The GlassSwitch
component can be disabled via the `disabled` prop" (or "This component can be
disabled via the `disabled` prop") so it reads properly under the "Component
props" section and references the `disabled` prop.

In @src/components/GlassSwitch.module.css:
- Line 36: Change the CSS rule that currently reads "bottom: 1;" to include a
unit (e.g., "bottom: 1px;" or use centering like "bottom: 50%;") and then update
the corresponding thumb transform to preserve vertical centering: if you use
"bottom: 50%" change the transform to include "translateY(50%)", or if you use
"bottom: 1px" keep vertical centering by ensuring the thumb's transform still
offsets vertically (e.g., "translateY(-50%)"); update the same selector that
contains the thumb positioning so horizontal translateX behavior is preserved.

In @src/components/NavBar.jsx:
- Around line 75-86: Replace the non-idiomatic React.createElement(icon, { size:
16 }) in the EXTERNAL_LINKS mapping with idiomatic JSX by assigning the icon
variable to a capitalized component identifier (e.g., const Icon = icon) and
rendering it as <Icon size={16} /> inside the map; remove the "Supress eslint"
comment and ensure you still render the icon component, label, and
SquareArrowOutUpRight as before so ARIA/role attributes and external link props
(target, rel) remain unchanged.
- Around line 59-73: The list rendering uses React.createElement(icon, { size:
16 }) which is non-idiomatic; change the map destructuring to rename icon to a
capitalized component (e.g., .map(({ path, label, icon: Icon, tooltip }) =>
...)) and render it with JSX (<Icon size={16} />) inside the Link, removing the
suppress comment; keep the rest of the props (key, role, className, onClick)
unchanged so behavior and styling remain identical.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/workflows/ci.yml (1)

89-100: Incorrect workflow reference syntax.

Line 91 uses uses: ./.github/workflows/commenter.yml, but this syntax is invalid for reusable workflows. Reusable workflows must be called using the jobs.<job_id>.uses syntax at the job level, not as a step.

🔎 Proposed fix

If commenter.yml is a reusable workflow, the PR comment should be posted using a GitHub Action like actions/github-script or a dedicated commenting action:

      - name: Comment on PR if validation fails
        if: steps.validate.outputs.validation_exit_code != '0' && github.event_name == 'pull_request'
-        uses: ./.github/workflows/commenter.yml
-        with:
-          issue_number: ${{ github.event.pull_request.number }}
-          message: |
-            ⚠️ **Script validation failed!**
-            The following issues were found with your PR (latest 100 lines):
-            ```
-            $(tail -n 100 validation.log)
-            ```
-          is_pr: true
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const fs = require('fs');
+            const log = fs.readFileSync('validation.log', 'utf8').split('\n').slice(-100).join('\n');
+            await github.rest.issues.createComment({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              issue_number: context.issue.number,
+              body: `⚠️ **Script validation failed!**\nThe following issues were found with your PR (latest 100 lines):\n\`\`\`\n${log}\n\`\`\``
+            });

Alternatively, if .github/workflows/commenter.yml is intended as a composite action, it should be moved to .github/actions/commenter/action.yml.

.github/workflows/issue-take-untake.yml (1)

1-301: Address Prettier formatting issues flagged by CI.

The pipeline reports code style issues found by Prettier. Run prettier --write on this file to fix formatting.

#!/bin/bash
# Check current prettier formatting status
npx prettier --check ".github/workflows/issue-take-untake.yml" 2>&1 || true
🧹 Nitpick comments (9)
docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/introduction/index.md (1)

41-41: Consider optional style refinements.

Static analysis flagged a few style patterns that could be polished:

  • Line 41: "exact same" might be wordy → consider "same" or "identical"
  • Line 119: "is just" appears twice in nearby sentences → consider varying the phrasing
  • Line 120: "The only reason...is because" → "The only reason...is that" (avoids redundancy)

These are minor polishing opportunities that don't affect clarity.

Also applies to: 119-120

docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/testing-and-debugging-suggestions.md (1)

13-13: Consider hyphenating the compound adjective (optional).

"Single pixel islands" could be written as "Single-pixel islands" to follow standard English compound adjective rules. However, this is a minor style preference.

src/components/WasmImageProcessor.jsx (1)

104-104: Consider refactoring nested ternary for readability.

The four-level nested ternary on a single line is harder to parse. Consider using a more readable format:

🔎 Proposed refactor
-const minimumAllowedMinArea = area > 100_000_000 ? 25 : area > 10_000_000 ? 20 : area > 1_000_000 ? 15 : 10;
+const minimumAllowedMinArea =
+  area > 100_000_000 ? 25
+  : area > 10_000_000 ? 20
+  : area > 1_000_000 ? 15
+  : 10;

Alternatively, use an early-return pattern or lookup approach if thresholds grow:

-const minimumAllowedMinArea = area > 100_000_000 ? 25 : area > 10_000_000 ? 20 : area > 1_000_000 ? 15 : 10;
+const getMinimumAllowedMinArea = (area) => {
+  if (area > 100_000_000) return 25;
+  if (area > 10_000_000) return 20;
+  if (area > 1_000_000) return 15;
+  return 10;
+};
+const minimumAllowedMinArea = getMinimumAllowedMinArea(area);
docs/docs/guidelines/coding-style.md (1)

172-173: Consider more formal wording for the tip.

The phrase "Don't feel obligated" uses informal language in a documentation context. A more formal alternative would be: "Focus on keeping your changes lint-clean. You are not required to fix unrelated pre-existing lint issues."

README.md (1)

73-73: Replace empty self-closing divs with markdown list formatting.

Self-closing empty divs (lines 73, 84) used for alignment are not semantically meaningful. Consider using standard markdown list formatting or heading structure for badge sections instead.

Also applies to: 84-84

.github/workflows/issue-take-untake.yml (2)

76-78: Regex special characters in markers are not escaped.

BODY_START and BODY_END contain <!-- and --> which include regex special characters (- in character class context is safe, but if markers ever change to include ., *, ?, etc., this would break). The current markers work, but consider escaping for robustness.

🔎 Optional: Escape regex special characters
+            function escapeRegex(str) {
+              return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+            }
+
             const updated = body.includes(BODY_START)
-              ? body.replace(new RegExp(`${BODY_START}[\\s\\S]*?${BODY_END}`), newBanner)
+              ? body.replace(new RegExp(`${escapeRegex(BODY_START)}[\\s\\S]*?${escapeRegex(BODY_END)}`), newBanner)
               : `${newBanner}\n\n---\n\n${body}`;

267-300: Silent error handling may hide issues during weekly cleanup.

The empty catch {} at line 300 swallows all errors, including potential API failures or rate limiting issues. Consider logging errors for observability during the weekly cleanup run.

🔎 Proposed improvement
-              } catch {}
+              } catch (err) {
+                console.error(`Failed to expire claim for issue #${issue.number}:`, err.message);
+              }
src/components/GlassSwitch.jsx (1)

1-31: Consider separating unrelated changes into a dedicated PR.

The GlassSwitch component appears unrelated to the stated PR objective of refactoring the issue-bot to remove instructional comments. Bundling unrelated changes in a single PR makes reviews harder, obscures the intent of each change, and complicates selective rollback if needed.

src/components/GlassSwitch.module.css (1)

48-50: Consider using a CSS variable for consistency.

Line 49 uses a hard-coded rgb(110, 110, 110) while other colors reference CSS variables. For consistency and theming flexibility, consider defining a --color-inactive or similar variable.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 904bae0 and 6ffd245.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (108)
  • .editorconfig
  • .editorconfig-checker.json
  • .github/workflows/ci.yml
  • .github/workflows/issue-take-untake.yml
  • CONTRIBUTING.md
  • README.md
  • docker-compose.yml
  • docs/changelogSidebarGenerator.js
  • docs/docs/guidelines/_category_.json
  • docs/docs/guidelines/coding-style.md
  • docs/docs/guidelines/commits.md
  • docs/docs/guidelines/issues.md
  • docs/docs/guidelines/pull-requests.md
  • docs/docs/index.md
  • docs/docs/introduction/getting-started.md
  • docs/docs/project-scripts/help-scripts/index.md
  • docs/docs/project-scripts/help-scripts/scripts-guide.md
  • docs/docs/reference/react/_category_.json
  • docs/docs/reference/react/components/GlassCard/index.md
  • docs/docs/reference/react/components/GlassSwitch/_category_.json
  • docs/docs/reference/react/components/GlassSwitch/index.md
  • docs/docs/reference/react/components/GlassSwitch/tests.md
  • docs/docs/reference/react/components/NavBar/index.md
  • docs/docs/reference/react/components/NavBar/testing.md
  • docs/docs/reference/react/components/ThemeSwitch/index.md
  • docs/docs/reference/react/components/ThemeSwitch/tests.md
  • docs/docs/reference/react/components/Tooltip/index.md
  • docs/docs/reference/react/components/Tooltip/tests.md
  • docs/docs/reference/react/css/global/variables/theme-independent.md
  • docs/docs/reference/react/css/global/variables/theme/best-practice.md
  • docs/docs/reference/react/css/global/variables/theme/dark.md
  • docs/docs/reference/react/css/global/variables/theme/extending.md
  • docs/docs/reference/react/css/global/variables/theme/light.md
  • docs/docs/reference/react/hooks/useTheme/index.md
  • docs/docs/reference/react/hooks/useTheme/tests.md
  • docs/docs/reference/tools/_category_.json
  • docs/docs/reference/tools/ci-workflows.md
  • docs/docs/reference/wasm/_category_.json
  • docs/docs/reference/wasm/development-workflow.md
  • docs/docs/reference/wasm/how-to-add-a-module.md
  • docs/docs/reference/wasm/modules/_category_.json
  • docs/docs/reference/wasm/modules/image/_category_.json
  • docs/docs/reference/wasm/modules/image/fft_iterative/_category_.json
  • docs/docs/reference/wasm/modules/image/fft_iterative/api.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/explained.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/implementation.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/overview.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/continuous-fourier-transform/index.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/discrete-time-signals-and-the-dft/index.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/fourier-series--the-bridge/index.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/how-fourier-transforms-work/index.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/index.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/introduction/index.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/keywords.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/why-img2num-uses-the-dft/index.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/complexity-and-memory.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/connected-components.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/faq.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/limitations-and-pitfalls.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/overview.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/testing-and-debugging-suggestions.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/variants-and-improvements.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/walkthrough-and-usage.md
  • docs/docs/reference/wasm/modules/image/overview.md
  • docs/docs/reference/wasm/overview.md
  • docs/docs/reference/wasm/setup-and-dependencies.md
  • docs/docs/reference/wasm/troubleshooting-and-optimizations.md
  • docs/docs/reference/wasm/using-wasm-in-react.md
  • docs/docusaurus.config.js
  • docs/scripts/help.js
  • docs/sidebars.js
  • docs/src/components/ColorSwatch.jsx
  • index.html
  • package.json
  • scripts/build-wasm.js
  • scripts/format-wasm.js
  • scripts/handle-changelog.js
  • scripts/help.js
  • scripts/lib/cli-fuzzy.js
  • scripts/lib/colors.js
  • scripts/lib/read-packageJson-scripts.js
  • scripts/validate-scripts.js
  • src/components/GlassSwitch.jsx
  • src/components/GlassSwitch.module.css
  • src/components/GlassSwitch.test.jsx
  • src/components/NavBar.jsx
  • src/components/NavBar.module.css
  • src/components/NavBar.test.jsx
  • src/components/ThemeSwitch.jsx
  • src/components/ThemeSwitch.module.css
  • src/components/ThemeSwitch.test.jsx
  • src/components/Tooltip.jsx
  • src/components/Tooltip.test.jsx
  • src/components/WasmImageProcessor.jsx
  • src/global-styles/variables.css
  • src/hooks/useGoogleAnalytics.js
  • src/hooks/useTheme.test.jsx
  • src/pages/About/Author.jsx
  • src/pages/About/CTA.jsx
  • src/pages/About/Motivation.jsx
  • src/pages/About/TechStack.jsx
  • src/pages/About/WhatIsThis.jsx
  • src/pages/Credits/ContributorsCreditsCard.jsx
  • src/pages/Credits/DependencyCreditsCard.jsx
  • src/pages/Credits/StaticCreditsCard.jsx
  • src/test/setup.js
  • vite.config.js
  • vitest.config.js
💤 Files with no reviewable changes (4)
  • src/pages/About/Author.jsx
  • docs/src/components/ColorSwatch.jsx
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/variants-and-improvements.md
  • src/components/ThemeSwitch.module.css
✅ Files skipped from review due to trivial changes (46)
  • vitest.config.js
  • index.html
  • docs/docs/reference/react/css/global/variables/theme-independent.md
  • docs/docs/index.md
  • src/components/NavBar.module.css
  • src/pages/About/WhatIsThis.jsx
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/connected-components.md
  • docs/docs/reference/react/hooks/useTheme/tests.md
  • docker-compose.yml
  • docs/sidebars.js
  • docs/docs/reference/react/components/GlassSwitch/category.json
  • src/pages/Credits/StaticCreditsCard.jsx
  • docs/docs/reference/wasm/development-workflow.md
  • docs/docusaurus.config.js
  • src/pages/About/CTA.jsx
  • src/pages/Credits/DependencyCreditsCard.jsx
  • docs/docs/guidelines/category.json
  • docs/docs/reference/wasm/overview.md
  • .editorconfig-checker.json
  • src/test/setup.js
  • docs/docs/reference/wasm/modules/image/category.json
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/overview.md
  • scripts/build-wasm.js
  • docs/docs/reference/wasm/setup-and-dependencies.md
  • docs/docs/reference/wasm/modules/category.json
  • docs/docs/reference/wasm/how-to-add-a-module.md
  • src/hooks/useGoogleAnalytics.js
  • docs/docs/reference/wasm/modules/image/fft_iterative/implementation.md
  • src/pages/About/Motivation.jsx
  • src/global-styles/variables.css
  • docs/docs/reference/react/components/Tooltip/index.md
  • scripts/validate-scripts.js
  • scripts/lib/read-packageJson-scripts.js
  • docs/docs/reference/react/components/ThemeSwitch/tests.md
  • docs/docs/reference/wasm/modules/image/overview.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/continuous-fourier-transform/index.md
  • docs/docs/reference/react/components/GlassCard/index.md
  • docs/docs/reference/wasm/troubleshooting-and-optimizations.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/discrete-time-signals-and-the-dft/index.md
  • docs/changelogSidebarGenerator.js
  • docs/docs/reference/react/css/global/variables/theme/dark.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/overview.md
  • docs/docs/reference/wasm/category.json
  • docs/docs/reference/tools/category.json
  • docs/docs/reference/wasm/using-wasm-in-react.md
  • CONTRIBUTING.md
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2026-01-04T15:34:04.654Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 146
File: docs/docs/reference/react/components/ThemeSwitch/tests.md:123-124
Timestamp: 2026-01-04T15:34:04.654Z
Learning: In Docusaurus documentation, relative directory links (e.g., ../ or ../../../hooks/useTheme) resolve to index.md within the target directory. Do not require or force linking to index.md explicitly; such relative links remain valid and should not be changed when reviewing docs under the docs directory.

Applied to files:

  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/testing-and-debugging-suggestions.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/faq.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/explained.md
  • docs/docs/reference/tools/ci-workflows.md
  • docs/docs/reference/react/components/GlassSwitch/tests.md
  • docs/docs/reference/react/components/NavBar/testing.md
  • docs/docs/reference/react/components/Tooltip/tests.md
  • docs/docs/reference/react/components/GlassSwitch/index.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/complexity-and-memory.md
  • docs/docs/guidelines/commits.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/walkthrough-and-usage.md
  • docs/docs/reference/react/css/global/variables/theme/extending.md
  • docs/docs/project-scripts/help-scripts/index.md
  • docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/limitations-and-pitfalls.md
  • docs/docs/project-scripts/help-scripts/scripts-guide.md
  • docs/docs/reference/react/components/ThemeSwitch/index.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/fourier-series--the-bridge/index.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/keywords.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/why-img2num-uses-the-dft/index.md
  • docs/docs/reference/react/css/global/variables/theme/light.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/index.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/how-fourier-transforms-work/index.md
  • docs/docs/reference/react/css/global/variables/theme/best-practice.md
  • docs/docs/guidelines/pull-requests.md
  • docs/docs/reference/react/hooks/useTheme/index.md
  • docs/docs/reference/react/components/NavBar/index.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/api.md
  • docs/docs/guidelines/issues.md
  • docs/docs/guidelines/coding-style.md
  • docs/docs/introduction/getting-started.md
  • docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/introduction/index.md
📚 Learning: 2025-12-20T20:11:28.422Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 0
File: :0-0
Timestamp: 2025-12-20T20:11:28.422Z
Learning: In the Img2Num repository, all documentation should be properly organized in the docs/docs/ folder structure following the Docusaurus conventions, either as a dedicated category or integrated into existing categories like project-scripts.

Applied to files:

  • docs/docs/reference/tools/ci-workflows.md
  • README.md
  • docs/docs/introduction/getting-started.md
📚 Learning: 2025-12-17T22:39:25.711Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 0
File: :0-0
Timestamp: 2025-12-17T22:39:25.711Z
Learning: In the Img2Num repository, do not create multiple markdown files at the repository root. The README.md at root should remain brief and point to the Docusaurus site.

Applied to files:

  • README.md
  • docs/docs/guidelines/commits.md
📚 Learning: 2025-12-17T22:39:25.711Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 0
File: :0-0
Timestamp: 2025-12-17T22:39:25.711Z
Learning: In the Img2Num repository, all documentation must be placed in the docs/docs/ folder following the Docusaurus structure, not at the repository root.

Applied to files:

  • README.md
📚 Learning: 2025-12-17T21:35:30.143Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 0
File: :0-0
Timestamp: 2025-12-17T21:35:30.143Z
Learning: In the Img2Num project, files that import React hooks must use the `.jsx` extension (not `.js`), as `npm run dev` fails otherwise. This is a build configuration requirement.

Applied to files:

  • README.md
  • .editorconfig
  • docs/docs/guidelines/commits.md
  • docs/docs/reference/react/_category_.json
  • docs/docs/guidelines/coding-style.md
📚 Learning: 2025-12-17T22:39:25.711Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 0
File: :0-0
Timestamp: 2025-12-17T22:39:25.711Z
Learning: In the Img2Num repository, avoid creating strangely-named markdown files (like COMPREHENSIVE_TEST_REPORT.md, DELIVERABLES.md, etc.) at the root level.

Applied to files:

  • README.md
🧬 Code graph analysis (12)
src/components/ThemeSwitch.test.jsx (1)
src/components/ThemeSwitch.jsx (1)
  • ThemeSwitch (14-27)
src/components/NavBar.test.jsx (1)
src/components/NavBar.jsx (1)
  • NavBar (25-96)
scripts/format-wasm.js (1)
vite.config.js (1)
  • files (108-108)
src/components/ThemeSwitch.jsx (2)
src/hooks/useTheme.js (2)
  • theme (4-17)
  • toggleTheme (37-39)
src/components/GlassSwitch.jsx (1)
  • GlassSwitch (5-21)
src/components/Tooltip.test.jsx (1)
src/components/Tooltip.jsx (1)
  • Tooltip (5-35)
src/hooks/useTheme.test.jsx (1)
src/hooks/useTheme.js (2)
  • theme (4-17)
  • toggleTheme (37-39)
src/components/GlassSwitch.jsx (1)
src/components/Tooltip.jsx (1)
  • Tooltip (5-35)
src/components/NavBar.jsx (3)
src/components/Tooltip.jsx (1)
  • Tooltip (5-35)
src/components/ThemeSwitch.jsx (1)
  • ThemeSwitch (14-27)
src/components/GlassCard.jsx (1)
  • GlassCard (4-8)
src/components/GlassSwitch.test.jsx (1)
src/components/GlassSwitch.jsx (1)
  • GlassSwitch (5-21)
src/components/WasmImageProcessor.jsx (2)
src/components/Tooltip.jsx (1)
  • Tooltip (5-35)
src/components/LoadingHedgehog.jsx (1)
  • LoadingHedgehog (16-214)
scripts/help.js (1)
scripts/lib/read-packageJson-scripts.js (1)
  • readPackageJsonScripts (13-34)
docs/scripts/help.js (2)
scripts/help.js (2)
  • title (4-6)
  • items (9-9)
scripts/lib/read-packageJson-scripts.js (1)
  • readPackageJsonScripts (13-34)
🪛 GitHub Actions: CI
.github/workflows/issue-take-untake.yml

[warning] 1-1: Code style issues found by Prettier. Run 'prettier --write' to fix.

🪛 LanguageTool
docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/testing-and-debugging-suggestions.md

[grammar] ~13-~13: Use a hyphen to join words.
Context: ...es that exercise corner cases: - Single pixel islands - Long 1-pixel-wide arms (...

(QB_NEW_EN_HYPHEN)

docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/faq.md

[style] ~31-~31: ‘exactly the same’ might be wordy. Consider a shorter alternative.
Context: ...n, left, or right** - All pixels have exactly the same RGBA values Diagonal adjacency **doe...

(EN_WORDINESS_PREMIUM_EXACTLY_THE_SAME)

docs/docs/reference/tools/ci-workflows.md

[uncategorized] ~16-~16: The official name of this software platform is spelled with a capital “H”.
Context: ... Overview ### Lint Workflow File: .github/workflows/ci.yml (lint job) **Trigger...

(GITHUB)


[uncategorized] ~45-~45: The official name of this software platform is spelled with a capital “H”.
Context: ...# Script Validation Workflow File: .github/workflows/ci.yml (validate-scripts job...

(GITHUB)

README.md

[style] ~133-~133: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...thub.io/Img2Num/info/docs/reference)) - Very large images or heavy explanations — use the ...

(EN_WEAK_ADJECTIVE)

docs/docs/reference/react/components/GlassSwitch/tests.md

[style] ~56-~56: To form a complete sentence, be sure to include a subject.
Context: ...ded and isOn ### 6. Component props - Can be disabled via disabled prop - Sets ...

(MISSING_IT_THERE)

docs/docs/project-scripts/help-scripts/scripts-guide.md

[uncategorized] ~99-~99: The official name of this software platform is spelled with a capital “H”.
Context: ...integration A GitHub Actions workflow (.github/workflows/ci.yml) was added to: - Det...

(GITHUB)

docs/docs/guidelines/coding-style.md

[style] ~173-~173: Consider using a different verb for a more formal wording.
Context: ...ges lint-clean. Don't feel obligated to fix unrelated issues! :::

(FIX_RESOLVE)

docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/introduction/index.md

[style] ~41-~41: ‘exact same’ might be wordy. Consider a shorter alternative.
Context: ...n-time-and-frequency-domains) shows the exact same sinusoid plotted in both the time and f...

(EN_WORDINESS_PREMIUM_EXACT_SAME)


[style] ~119-~119: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...s practical implementation" The FFT is just a fast algorithm for computing the DFT:...

(REP_BE_JUST)


[style] ~120-~120: The word “because” means “for the reason that” and thus introduces redundancy.
Context: ... The only reason FFTs appear everywhere is because they are essentially just fast DFTs...

(REASON_IS_BECAUSE)

🪛 markdownlint-cli2 (0.18.1)
docs/docs/reference/react/components/GlassSwitch/tests.md

9-9: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/walkthrough-and-usage.md

71-71: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

docs/docs/guidelines/coding-style.md

82-82: Code block style
Expected: fenced; Actual: indented

(MD046, code-block-style)


87-87: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

docs/docs/introduction/getting-started.md

136-136: Code block style
Expected: indented; Actual: fenced

(MD046, code-block-style)


149-149: Code block style
Expected: indented; Actual: fenced

(MD046, code-block-style)


159-159: Code block style
Expected: indented; Actual: fenced

(MD046, code-block-style)

🔇 Additional comments (97)
docs/docs/reference/react/css/global/variables/theme/extending.md (2)

11-21: Documentation formatting looks good.

The reindentation of the CSS code block improves readability and aligns with markdown best practices. The example correctly demonstrates adding custom variables to both light and dark theme roots.


24-28: Code block example is clear and correct.

The usage example concisely demonstrates how to consume the custom CSS variable in a component. The formatting is consistent with the preceding code block.

docs/docs/reference/react/css/global/variables/theme/best-practice.md (1)

7-7: Verify the Markdown admonition syntax after formatting changes.

The closing delimiters were changed from -::: to ::: (with leading spaces). This formatting may violate Docusaurus/Markdown admonition block syntax and could break documentation rendering. Confirm that the closing delimiters are valid and that the admonition blocks render correctly in the published documentation.

Additionally, this file (CSS theme best practices) appears unrelated to the PR objective (issue-bot refactor). Please confirm this file is intentionally included in this pull request.

Also applies to: 12-12, 15-15, 20-20

docs/docs/introduction/getting-started.md (3)

366-367: Potential TabItem structure error — two opening tags without proper nesting.

Lines 366–367 contain two consecutive <TabItem> opening tags without the first being closed. Verify the JSX structure is correct; the documentation-site-only tab should either contain content and close before both opens, or one of these should be removed/refactored.

// Current (lines 366–367):
<TabItem value="documentation-site-only" label="Docs Site Only" default>
<TabItem value="both" label="Both" default>

136-136: Code-block-style linting warnings are likely false positives.

Markdownlint flagged three code blocks (lines 136, 149, 159) for using fenced syntax (```bash) instead of indented style. Fenced code blocks are standard in modern Markdown and offer better readability and language hints. These warnings reflect a linting configuration preference, not a correctness issue. Either update the markdownlint config to allow fenced blocks, or ignore these particular violations if your project standard favors fenced blocks.

Also applies to: 149-149, 159-159


10-12: Documentation improvements are well-structured and clear.

The formatting, headings, and new macOS/Linux installation sections are well-organized, improve readability, and provide comprehensive setup guidance. Image import normalization and link updates follow documentation conventions. The changes align with Docusaurus best practices.

Also applies to: 36-124, 129-162, 564-564

scripts/lib/colors.js (1)

7-24: LGTM! Consistent quote normalization.

The quote style changes from double to single quotes are purely cosmetic with no functional impact. The addition of a newline at EOF follows common linting conventions.

Also applies to: 28-45, 67-67

docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/index.md (1)

10-10: LGTM! Formatting improvement.

The blank line improves readability by visually separating the introductory sentence from the list.

docs/docs/reference/wasm/modules/image/fft_iterative/_category_.json (1)

9-9: LGTM! JSON syntax correction.

Removing the trailing comma ensures strict JSON compliance per RFC 8259.

docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/why-img2num-uses-the-dft/index.md (1)

14-19: LGTM! Admonition formatting improvements.

The blank line after the note opening and the indented closing delimiter improve readability and align with Docusaurus admonition formatting conventions.

docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/introduction/index.md (1)

15-177: LGTM! Formatting improvements throughout.

The blank lines added throughout the document improve readability by creating clearer visual separation between sections and concepts.

docs/docs/reference/wasm/modules/image/fft_iterative/api.md (1)

24-42: LGTM! Documentation formatting improvements.

The changes improve document structure and consistency:

  • Emphasis on "same-size in / same-size out" text improves readability of the warning
  • Table alignment enhances clarity
  • Info block formatting matches Docusaurus admonition conventions
docs/docs/reference/wasm/modules/image/fft_iterative/explained.md (1)

44-44: ✓ Formatting improvements enhance readability.

The blank line additions after headings (line 44) and before the Mermaid diagram (line 96), combined with consistent table spacing (lines 50–59), improve the visual hierarchy and flow of the documentation. No content concerns.

Also applies to: 50-59, 96-96

docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/keywords.md (2)

12-12: ✓ Aliasing keyword addition is well-placed and complete.

The new entry fills a natural gap in the signal processing keywords and the definition is accurate and concise. Positioning before "Angular frequency" maintains alphabetical order.


51-56: ✓ Formatting and emphasis adjustments improve clarity.

The blank lines added before subsections and equation blocks (lines 67–87, 104, 115) enhance readability by creating visual separation. The emphasis change in line 135 from italic to regular text preserves the warning intent while improving focus.

Also applies to: 67-87, 104-104, 115-115, 135-135

docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/fourier-series--the-bridge/index.md (5)

25-31: ✓ Figure blocks with images and collapsible code enhance learning.

The three figure sections (1–3) with embedded images and code examples provide excellent visual support for understanding Fourier series decomposition. The collapsible code structure keeps the documentation clean while remaining accessible.

Also applies to: 39-45, 47-53


66-90: ✓ Expanded Block Equation section with clearer structure and detailed k-indexing explanation.

The reorganization clarifies the role of k, explicitly addresses the DC component (k=0) and negative frequencies (k<0), and provides clear magnitude/phase interpretation formulas. The pedagogical flow is significantly improved.


92-134: ✓ "Understanding Magnitude and Phase" section adds valuable geometric intuition.

The detailed explanation with Euler's formula, complex plane visualization (fourier_coefficient_triangle image), and SOH-CAH-TOA trigonometric mapping makes the abstract concept concrete. Mathematical formulas are correct and the pedagogical narrative is clear.


142-157: ✓ Real Fourier Series Form section completes the picture.

Introducing the equivalent real-valued representation (cosines and sines) alongside the complex exponential form, with the conversion relationship shown explicitly, addresses a key conceptual gap. Both forms are correct and the explanation is appropriately positioned.


176-186: ✓ Conversion formulas A_k and φ_k provide practical bridge.

The tip connecting a_k/b_k to amplitude/phase via standard formulas is mathematically correct and helps readers transition between the two representations.

docs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/how-fourier-transforms-work/index.md (3)

28-86: Formatting improvements to section headers enhance readability.

The addition of blank lines after markdown headers (### Definition, ### Domain of Input, etc.) follows standard markdown formatting conventions and improves visual hierarchy. The mathematical definitions for CFT and DFT are accurate and well-explained.


91-101: Table format provides effective side-by-side comparison.

The new table view (complementing the list format) offers readers a compact way to compare CFT and DFT across key dimensions. The use of noWrapKatexChildren CSS class shows awareness of LaTeX rendering constraints in table cells. Ensure this renders correctly in the live Docusaurus build.


107-203: Mathematical rigor and pedagogical clarity are well-maintained.

The derivation of the relationship between CFT and DFT kernels (lines 117–147) is mathematically sound and clearly explained. The justification for using complex exponentials (lines 149–193) connects theory to practical applications. All formatting changes enhance readability without altering substance.

src/pages/About/TechStack.jsx (1)

7-7: LGTM! Clean formatting change.

The anchor element props are correctly collapsed onto a single line with no semantic or behavioral changes.

src/pages/Credits/ContributorsCreditsCard.jsx (1)

9-10: LGTM! Array chunking logic is correct.

The reformatted chunk function maintains correct chunking behavior using Array.from and slice. The single-line format is appropriate for this concise helper.

scripts/format-wasm.js (1)

12-29: LGTM! Clean implementation of format-check mode.

The --check flag implementation correctly:

  • Uses --dry-run --Werror for non-mutating validation
  • Returns early to prevent in-place formatting when checking
  • Exits with code 1 on errors for CI integration
  • Updates the completion message to reflect the mode
docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/testing-and-debugging-suggestions.md (1)

9-28: LGTM! Comprehensive testing guidance.

The added documentation sections provide valuable testing and debugging strategies for the mergeSmallRegionsInPlace function, including synthetic test cases, visualization techniques, unit testing suggestions, and instrumentation approaches.

vite.config.js (1)

44-49: LGTM! Appropriate exclusion of docs from file watching.

Adding '**/docs/**' to the watcher's ignored patterns prevents unnecessary rebuilds when documentation changes, improving development experience. The formatting improvements also enhance readability.

src/components/NavBar.test.jsx (3)

1-1: LGTM! Correct removal of unused import.

The afterEach import was not used in this test file, so removing it is appropriate cleanup.


20-21: LGTM! Improved helper function conciseness.

The simplified inline rendering is more concise while maintaining the same functionality.


33-376: LGTM! Consistent whitespace formatting.

The removal of extraneous empty lines throughout the test file makes it more compact and easier to read without affecting test functionality.

src/components/Tooltip.jsx (1)

10-19: LGTM! Improved readability of conditional rendering.

The reformatted ternary operator with explicit parentheses around each branch makes the conditional logic clearer while maintaining identical behavior.

docs/scripts/help.js (1)

1-21: LGTM! Consistent quote style formatting.

The conversion to single quotes throughout the file improves code style consistency without any functional changes.

src/hooks/useTheme.test.jsx (2)

11-14: LGTM! Improved JSX formatting.

The reformatted TestComponent JSX layout is clearer without changing any functionality.


30-85: LGTM! Enhanced mock readability.

The expanded multi-line format for window.matchMedia mock implementations improves readability while maintaining identical functionality.

docs/docs/reference/react/css/global/variables/theme/light.md (2)

13-24: LGTM! Improved table formatting.

The reformatted Colors table maintains all CSS variable definitions and ColorSwatch previews while improving presentation consistency.


28-36: LGTM! Consistent glass effect table formatting.

The reformatted glass effect variables table maintains all definitions and preview swatches while aligning with the Colors table formatting style.

scripts/help.js (1)

1-21: LGTM! Consistent quote style and improved documentation.

The migration to single quotes and the addition of the documentation URL improve consistency and discoverability.

.editorconfig (3)

51-51: Good addition of TypeScript file support.

Extending the pattern to include .ts and .tsx files prepares the codebase for TypeScript adoption.


148-151: Good improvement to LICENSE file pattern.

The glob pattern change from [LICENSE] to [LICENSE*] allows matching LICENSE variants (e.g., LICENSE.txt, LICENSE.md), and adding insert_final_newline = true aligns with Git best practices.


100-102: Helpful clarification for Markdown formatting.

The note about Prettier's 3-space nested list indentation vs. the 2-space file-level setting improves maintainer understanding.

scripts/handle-changelog.js (2)

59-60: Excellent defensive programming addition.

The directory existence check ensures the script doesn't fail when docs/changelog is missing. The recursive: true option safely creates parent directories if needed.


2-4: LGTM! Consistent quote style throughout.

The migration to single quotes aligns with the codebase-wide formatting standards visible across the PR.

Also applies to: 9-13, 17-18, 21-34, 49-55, 72-73, 80-86

docs/docs/guidelines/commits.md (1)

8-100: LGTM! Improved documentation formatting.

The table alignment and blank line adjustments enhance readability without changing the content or semantics of the commit guidelines.

scripts/lib/cli-fuzzy.js (1)

1-195: LGTM! Consistent quote style throughout.

The comprehensive migration to single quotes for imports, string literals, and template strings maintains consistency with the broader codebase formatting standards without affecting functionality.

src/components/WasmImageProcessor.jsx (1)

65-65: LGTM! Clean inline formatting.

The JSX formatting consolidations improve compactness without affecting readability or functionality.

Also applies to: 149-149, 162-162, 169-171, 176-176, 190-190, 193-193

docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/walkthrough-and-usage.md (1)

20-83: LGTM! Documentation formatting improved.

The markdown restructuring enhances readability without changing technical content. The static analysis hint about line 71 is a false positive (it's closing the mermaid flowchart block, not a standalone fenced block).

Also applies to: 86-103

.github/workflows/ci.yml (1)

10-34: LGTM! Well-structured lint job.

The lint job correctly runs ESLint, format checks, and editorconfig validation.

package.json (3)

71-73: LGTM! Format check scripts align with CI workflow.

The new format:check, format-js:check, and format-wasm:check scripts provide non-mutating validation, which is essential for CI enforcement introduced in .github/workflows/ci.yml.

Also applies to: 77-79, 83-85, 149-149, 151-151, 153-153


166-166: No action needed. prop-types is actively used in GlassSwitch.jsx and Tooltip.jsx and works fine with React 19.2.3. While prop-types is considered legacy, it remains a valid and functional choice for runtime type validation in JavaScript React projects. React 19 does not remove or break prop-types—it has been a separate package since React 16. Migrating to TypeScript would require a broader project refactor beyond this dependency and is outside the scope of this change.


175-175: Cannot verify this downgrade claim. The repository's git history shows only one commit for package.json, making it impossible to confirm the previous version was ^5.90.14. Additionally, @tanstack/react-query@5.90.14 does exist as a published version. The current constraint ^5.90.12 allows versions from 5.90.12 to <5.91.0, which still includes 5.90.14, and the package-lock.json is currently locked to 5.90.14, not 5.90.12. Without access to previous package.json versions or a clear commit message explaining the change, the intentionality and risk of this constraint adjustment cannot be determined.

docs/docs/reference/tools/ci-workflows.md (2)

1-148: Excellent documentation for new CI workflows!

The documentation clearly explains the lint and script validation workflows, including triggers, steps, troubleshooting, and configuration details. This aligns well with the changes in .github/workflows/ci.yml and package.json.


107-107: The link ../../project-scripts/overview.md is valid and correctly references an existing file. No changes needed.

docs/docs/guidelines/coding-style.md (1)

108-171: Excellent new linting guidance section.

The "Linting and Style Checks" section is well-structured and provides clear, actionable guidance for contributors on running lints locally, understanding what linters validate, and integrating with CI. The subsections are logical and the tip about existing lint violations is helpful and sets realistic expectations.

README.md (2)

1-2: Action required: TODO comment should be addressed.

The TODO comment indicates the breaking change notice should be removed after January 5, 2026. Since today's date is January 5, 2026, this notice and TODO should be removed or updated now.

If the notice is still needed, update the target date in the TODO; otherwise, remove both the TODO and the caution block (lines 1-9).


105-109: Verify updated documentation links are correct.

The documentation links have been updated to a new URL pattern. Please verify these URLs resolve correctly:

docs/docs/project-scripts/help-scripts/scripts-guide.md (3)

17-22: Approve bullet list reformatting.

The reformatting of the "What's in this page" section improves readability by using single-line bullets, consistent with modern documentation style and easier to scan.


30-49: Approve JSON schema example formatting.

The reformatting of the scriptsInfo example (especially the "help" script desc field being collapsed to a single-line array) improves visual clarity while preserving the schema documentation. The formatting aligns with JSON best practices.


113-116: Approve refactored help CLI section formatting.

The condensed formatting of the refactored help CLI info block improves readability without losing content. The bullet points are now more concise and scannable.

docs/docs/project-scripts/help-scripts/index.md (1)

29-34: LGTM!

Good addition documenting the q + enter quit shortcut. The formatting adjustments are appropriate.

.github/workflows/issue-take-untake.yml (2)

88-101: LGTM!

The issue open handling correctly ensures the label exists and applies the untaken banner. The empty catch for label creation is appropriate since the label may already exist.


194-211: LGTM!

The expiry normalization (lines 194-197) correctly runs before command handling, allowing users to claim expired issues immediately. The take/untake logic is sound.

docs/docs/reference/react/components/Tooltip/tests.md (1)

1-47: LGTM!

Minor formatting improvements throughout the documentation. No issues.

src/components/Tooltip.test.jsx (1)

1-80: LGTM!

Formatting-only changes (semicolons, indentation). Test logic is unchanged and provides good coverage for tooltip visibility behavior including keyboard accessibility.

docs/docs/reference/react/_category_.json (1)

1-10: LGTM!

Good fix removing the trailing comma for valid JSON syntax.

src/components/ThemeSwitch.jsx (1)

14-26: Clean refactor to GlassSwitch.

The implementation correctly delegates to GlassSwitch and wires up the theme toggle. The isDark derivation and aria label are appropriate.

Note on icon convention: The thumbContent shows <Sun /> when in dark mode and <Moon /> when in light mode. This follows the "show what you'll switch to" pattern. If the intent was "show current state," the icons would be swapped. Either convention is valid—just verify this matches the project's UX intent.

docs/docs/guidelines/issues.md (1)

10-30: LGTM!

Good improvements to the issues documentation:

  • Table formatting is cleaner and more readable.
  • New guidelines bullets provide clear, actionable guidance.
  • The tip block reinforces template usage importance.
src/components/ThemeSwitch.test.jsx (4)

10-28: LGTM! Mock structure is well-designed.

The icon mocks correctly accept and pass through the className prop, and the Tooltip mock properly exports a default component with ESM interop. The multiline JSX formatting improves readability.


41-93: LGTM! Accessibility testing is comprehensive.

The tests properly validate the switch role, aria-checked attributes, and keyboard accessibility. The lowercase aria-labels follow conventional patterns and align with the GlassSwitch implementation.


95-101: LGTM! Good defensive testing.

This test ensures graceful handling of unexpected theme values, verifying the component defaults to displaying the Moon icon when the theme is falsy or unrecognized.


103-112: LGTM! Hook integration properly tested.

This test validates that the component correctly uses the toggleTheme function provided by the hook, ensuring proper integration and flexibility.

docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/complexity-and-memory.md (1)

14-25: LGTM! Formatting improvement.

The additional blank lines after section headers improve readability and create consistent visual separation between sections.

docs/docs/reference/react/hooks/useTheme/index.md (3)

8-13: LGTM! Documentation formatting improvement.

The additional blank lines improve visual separation and readability within the info block.


41-44: LGTM! Table formatting is consistent.

The table header alignment adjustment is a cosmetic change that improves consistency with markdown formatting conventions.


70-86: The color values in the documentation are already consistent with the source CSS file at src/global-styles/variables.css. All values match exactly, including the lowercase hex format.

src/components/GlassSwitch.test.jsx (5)

6-21: LGTM! Mock setup is comprehensive.

The mocks appropriately isolate the component's behavior by providing simple stubs for the Tooltip component and CSS module classes.


24-37: LGTM! ARIA attributes properly validated.

The tests correctly verify that the component renders with the switch role and properly sets aria-checked based on the isOn prop.


39-62: LGTM! Interaction testing is thorough.

The tests properly validate both mouse and keyboard interactions using the modern userEvent API with async/await. This ensures the component is fully accessible to all users.


64-78: LGTM! CSS class logic properly tested.

The tests validate that CSS classes are applied correctly in both checked and unchecked states, ensuring proper styling behavior.


80-115: LGTM! Comprehensive feature coverage.

The tests validate thumbContent rendering, fallback styling, disabled state, and aria-label association. This ensures all component features work correctly across different configurations.

docs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/faq.md (3)

16-154: LGTM! Documentation formatting improvements.

The additional blank lines, emphasis formatting (italics/bold), and clarified SVG text improve readability and help highlight key concepts. The LaTeX-style escaping in the SVG text (line 145) is appropriate for the technical context.


28-32: LGTM! Technical definition is precise and appropriate.

The phrase "exactly the same" (line 31) correctly emphasizes byte-level equality of RGBA values, which is important in this technical context. The static analysis suggestion to shorten it can be safely ignored as the precision is intentional.


195-383: LGTM! Consistent documentation improvements throughout.

The formatting changes maintain consistency across all sections, with appropriate emphasis on key concepts and improved visual separation between sections.

docs/docs/reference/react/components/GlassSwitch/tests.md (2)

65-152: Comprehensive test examples are well-structured.

The example test snippets cover the key testing scenarios (checked state, user interaction, keyboard accessibility, CSS classes, custom content, disabled state, and aria-label). Code examples are syntactically correct and follow best practices using @testing-library/react and vitest.


1-160: Documentation provides clear, thorough coverage of the test suite.

The test documentation is well-organized with clear sections, practical examples, and a logical flow from basics to advanced testing patterns. The mocking strategy and test utilities sections provide helpful context.

docs/docs/guidelines/pull-requests.md (1)

1-51: Well-structured PR guidelines with clear workflow steps.

The documentation clearly outlines the PR workflow from branch creation through review feedback. The new sections (danger admonition for merge conflicts and tip block for PR best practices) add valuable guidance. Code examples are proper and easy to follow.

docs/docs/reference/react/components/GlassSwitch/index.md (8)

1-28: Excellent component overview with clear feature highlights.

The introduction section effectively conveys the purpose of GlassSwitch with emoji-enhanced feature callouts and a tip block that establishes appropriate use cases. The overview is concise yet comprehensive.


40-62: Clear and minimal basic usage example.

The quick start section effectively demonstrates the simplest implementation with the three required props. The example is easy to follow and immediately actionable for new users.


87-142: Props documentation is thorough and well-structured.

The props table with required indicators and defaults is followed by individual sections for each prop with practical code examples. This layered approach serves both quick reference and detailed guidance effectively.


168-193: Accessibility section properly implements WCAG switch pattern.

Clear enumeration of semantic HTML, ARIA attributes, keyboard navigation, and additional features demonstrates compliance with accessibility best practices. Checkmarks aid visual scanning.


214-311: Practical examples cover real-world use cases.

Three examples (dark mode, settings panel, conditional disable) are well-commented and cover distinct scenarios. Code is syntactically correct and follows React best practices.


313-342: Testing section appropriately links to comprehensive test documentation.

The section correctly references ./tests.md for detailed test suite documentation and provides clear commands for running tests. The bullet-point coverage summary supports the linked documentation well.


344-388: Troubleshooting and best practices provide actionable guidance.

The troubleshooting section anticipates common issues with concrete solutions. The best practices do's and don'ts reinforce accessibility and usability principles established earlier in the documentation.


1-398: Comprehensive component documentation meets professional standards.

This documentation provides a complete reference covering overview, API, accessibility, examples, testing, and best practices. The structure supports both novice and experienced users seeking quick reference or deep dives. Cross-references are properly linked and follow Docusaurus conventions. The content aligns well with the supporting test documentation file.

src/components/GlassSwitch.jsx (2)

5-21: LGTM!

The component implementation is solid with proper accessibility semantics:

  • role="switch" and aria-checked correctly implement switch behavior
  • Both visual tooltips and screen reader labels are provided
  • Disabled state is properly handled

23-29: LGTM!

PropTypes are complete and appropriate for the component's API.

src/components/GlassSwitch.module.css (1)

14-31: LGTM! Excellent accessibility implementation.

The focus indicators properly implement WCAG 2.4.7 with progressive enhancement—using :focus-visible with a solid fallback for older browsers.

Comment thread .editorconfig
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 120
max_line_length = 200

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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# List potential configuration files
git ls-files | grep -E '(\.(eslintrc|prettierrc|editorconfig)|package\.json)' | head -20

Repository: Ryan-Millard/Img2Num

Length of output: 187


🏁 Script executed:

# First, let's read the .editorconfig file to confirm the changes
cat -n .editorconfig

Repository: Ryan-Millard/Img2Num

Length of output: 5510


🏁 Script executed:

# Search for ESLint configuration in the repository
fd -E node_modules -t f -E '.git' 'eslintrc|eslint\.config' .

Repository: Ryan-Millard/Img2Num

Length of output: 82


🏁 Script executed:

# Search for Prettier configuration
fd -E node_modules -t f -E '.git' 'prettierrc|prettier\.config' .

Repository: Ryan-Millard/Img2Num

Length of output: 46


🏁 Script executed:

# Check package.json for inline eslintConfig and prettier config
cat package.json | jq '.eslintConfig, .prettier' 2>/dev/null || echo "No inline config found or jq not available"

Repository: Ryan-Millard/Img2Num

Length of output: 73


🏁 Script executed:

# Read the eslint config file
cat -n eslint.config.js

Repository: Ryan-Millard/Img2Num

Length of output: 1257


🏁 Script executed:

# Explicitly look for .prettierrc with various extensions
fd -E node_modules '.prettierrc*' .

Repository: Ryan-Millard/Img2Num

Length of output: 46


🏁 Script executed:

# Check if prettier config is in package.json at root
cat package.json | head -50

Repository: Ryan-Millard/Img2Num

Length of output: 1308


🏁 Script executed:

# Check editorconfig-checker.json
cat -n .editorconfig-checker.json

Repository: Ryan-Millard/Img2Num

Length of output: 1121


🏁 Script executed:

# Check if Prettier is installed and what its default printWidth is
cat package.json | grep -A 5 -B 5 prettier || echo "Prettier not found in package.json"

Repository: Ryan-Millard/Img2Num

Length of output: 962


Resolve the line length configuration mismatch between Prettier and .editorconfig.

The change to max_line_length = 200 for JavaScript/TypeScript (line 58) and HTML (line 93) is misaligned with actual formatting tools:

  • Prettier (v3.7.4, installed and used for formatting) has NO custom configuration and defaults to printWidth: 80
  • ESLint (eslint.config.js) has NO max-len rules configured
  • .editorconfig allows 200 characters for these file types
  • editorconfig-checker enforces the 200-character limit

This creates an inconsistency: Prettier will format code to 80 characters, but .editorconfig permits 200. Either:

  1. Create a .prettierrc file with "printWidth": 200 to match .editorconfig, or
  2. Revert .editorconfig to 120 to match Prettier's default behavior

Comment thread .github/workflows/ci.yml
Comment on lines 39 to 49
- uses: actions/checkout@v6
with:
fetch-depth: 0

# Node.js setup
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22

# Install dependencies
- name: Install dependencies
run: npm ci

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

Action version inconsistency with lint job.

The validate-scripts job uses actions/checkout@v6 and actions/setup-node@v6, while the lint job uses @v4 for both. This inconsistency should be resolved.

🔎 Recommended fix: Standardize action versions
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      # Node.js setup
      - name: Setup Node.js
-        uses: actions/setup-node@v6
+        uses: actions/setup-node@v4
        with:
          node-version: 22

Note: If v6 is preferred, update the lint job to match. GitHub Actions v4 is currently stable for both checkout and setup-node.

📝 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
- uses: actions/checkout@v6
with:
fetch-depth: 0
# Node.js setup
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22
# Install dependencies
- name: Install dependencies
run: npm ci
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Node.js setup
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
# Install dependencies
- name: Install dependencies
run: npm ci
🤖 Prompt for AI Agents
In @.github/workflows/ci.yml around lines 39-49, The lint job uses
actions/checkout@v4 and actions/setup-node@v4 while the validate-scripts job
uses @v6; update the lint job to use actions/checkout@v6 and
actions/setup-node@v6 so both jobs are consistent. Locate the lint job in the CI
workflow and replace the checkout and setup-node steps to match the
validate-scripts job (actions/checkout and actions/setup-node -> @v6) ensuring
fetch-depth or node-version settings remain intact.

Comment on lines +74 to +87
void exampleFunction(uint8_t x)
{
if (internalLibrary::isPrime(x))
{
std::cout << "Prime" << std::endl;
return;
}

std::cout << "Non-prime" << std::endl;
}

}
```
}

````

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

🧩 Analysis chain

🏁 Script executed:

cat -n docs/docs/guidelines/coding-style.md | sed -n '70,90p'

Repository: Ryan-Millard/Img2Num

Length of output: 480


🏁 Script executed:

cat -n docs/docs/guidelines/coding-style.md | sed -n '60,90p'

Repository: Ryan-Millard/Img2Num

Length of output: 717


Fix code block formatting issues.

The closing code fence uses 4 backticks instead of 3 (mismatched with opening), and the C++ code example has inconsistent indentation—line 82 is indented while lines 74-81 are not.

🔎 Proposed fix
 ```cpp title="exampleFunction.cpp"
 #include "exampleFunction.h"
 #include "internalLibrary.h"
 
 #include <iostream>
 
 namespace exampleNamespace
 {
-void exampleFunction(uint8_t x)
-{
-if (internalLibrary::isPrime(x))
-{
-std::cout << "Prime" << std::endl;
-return;
-}
+  void exampleFunction(uint8_t x)
+  {
+    if (internalLibrary::isPrime(x))
+    {
+      std::cout << "Prime" << std::endl;
+      return;
+    }
 
     std::cout << "Non-prime" << std::endl;
 
-}
-}
-````
+  }
+}
+```
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

82-82: Code block style
Expected: fenced; Actual: indented

(MD046, code-block-style)


87-87: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In @docs/docs/guidelines/coding-style.md around lines 74-87, The code block in
the docs has mismatched fencing and inconsistent indentation; fix by replacing
the closing four-backtick fence with a three-backtick fence and normalize
indentation inside the example so the function exampleFunction, its body, and
the if block (including the call to internalLibrary::isPrime and the std::cout
lines) are consistently indented (e.g., two spaces per block level) and ensure
the namespace closing braces align with the function indentation before the
corrected closing ``` fence.

Comment on lines +9 to +11
```
src/components/GlassSwitch.test.jsx
```

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

Add language specifier to fenced code block.

Line 9 code block should specify a language identifier for proper syntax highlighting.

-```
+```bash
 src/components/GlassSwitch.test.jsx
-```
+```bash
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

9-9: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In @docs/docs/reference/react/components/GlassSwitch/tests.md around lines 9-11,
Update the fenced code block that contains the line
"src/components/GlassSwitch.test.jsx" in tests.md so the opening fence includes
a language identifier (change the opening "```" to "```bash") to enable proper
syntax highlighting; locate the block around the
"src/components/GlassSwitch.test.jsx" text and only modify the opening fence.

Comment on lines +51 to +56
- **Off styling:** when `thumbContent` is not provided and isOff
- **On styling:** when `thumbContent` is not provided and isOn

### 6. Component props

- Can be disabled via `disabled` prop

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

Fix incomplete sentence structure.

Line 56 is missing a subject. Restructure or add a subject pronoun.

🔎 Proposed fix
 ### 5. Thumb content
 
 - Renders custom `thumbContent` when provided
 - Renders fallback thumb content
   - **Off styling:** when `thumbContent` is not provided and isOff
   - **On styling:** when `thumbContent` is not provided and isOn
 
 ### 6. Component props
 
-- Can be disabled via `disabled` prop
+- It can be disabled via the `disabled` prop
📝 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
- **Off styling:** when `thumbContent` is not provided and isOff
- **On styling:** when `thumbContent` is not provided and isOn
### 6. Component props
- Can be disabled via `disabled` prop
- **Off styling:** when `thumbContent` is not provided and isOff
- **On styling:** when `thumbContent` is not provided and isOn
### 6. Component props
- It can be disabled via the `disabled` prop
🧰 Tools
🪛 LanguageTool

[style] ~56-~56: To form a complete sentence, be sure to include a subject.
Context: ...ded and isOn ### 6. Component props - Can be disabled via disabled prop - Sets ...

(MISSING_IT_THERE)

🤖 Prompt for AI Agents
In @docs/docs/reference/react/components/GlassSwitch/tests.md around lines
51-56, The sentence "Can be disabled via `disabled` prop" is missing a subject;
update it to a complete sentence such as "The GlassSwitch component can be
disabled via the `disabled` prop" (or "This component can be disabled via the
`disabled` prop") so it reads properly under the "Component props" section and
references the `disabled` prop.

.thumb {
position: absolute;
left: 0;
bottom: 1;

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 | 🔴 Critical

Fix missing CSS unit.

Line 36 has bottom: 1; without a unit, which browsers will ignore. Numeric CSS values (except 0) require units.

🔎 Proposed fix

For proper vertical centering of the thumb:

 .thumb {
   position: absolute;
   left: 0;
-  bottom: 1;
+  top: 50%;
+  transform: translateY(-50%);
   width: calc(var(--size) - 4px);

Or if bottom: 1px; was intended:

-  bottom: 1;
+  bottom: 1px;

Note: You'll also need to adjust line 42 to preserve the horizontal transform:

-  transition: transform 0.3s ease;
+  transition: transform 0.3s ease, top 0s;

And update line 46:

 .checked .thumb {
-  transform: translateX(var(--size));
+  transform: translateX(var(--size)) translateY(-50%);
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @src/components/GlassSwitch.module.css around line 36, Change the CSS rule
that currently reads "bottom: 1;" to include a unit (e.g., "bottom: 1px;" or use
centering like "bottom: 50%;") and then update the corresponding thumb transform
to preserve vertical centering: if you use "bottom: 50%" change the transform to
include "translateY(50%)", or if you use "bottom: 1px" keep vertical centering
by ensuring the thumb's transform still offsets vertically (e.g.,
"translateY(-50%)"); update the same selector that contains the thumb
positioning so horizontal translateX behavior is preserved.

Comment thread src/components/NavBar.jsx
Comment on lines +59 to +73
{INTERNAL_LINKS.map(({ path, label, icon, tooltip }) => (
<li key={path} role="none">
<Tooltip content={tooltip}>
<Link
to={path}
role="menuitem"
className={`${styles.navLink} ${pathname === path ? styles.active : ''}`}
onClick={closeMenu}>
{/* Supress eslint "no-unused-vars" rule */}
{React.createElement(icon, { size: 16 })}
<span>{label}</span>
</Link>
</Tooltip>
</li>
))}

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.

🛠️ Refactor suggestion | 🟠 Major

Refactor to use idiomatic JSX instead of React.createElement.

The current approach using React.createElement(icon, { size: 16 }) to suppress eslint warnings is non-idiomatic. This pattern makes the code less readable and suggests a linting configuration issue rather than a code problem.

🔎 Recommended refactor using capital-case variable
-          {INTERNAL_LINKS.map(({ path, label, icon, tooltip }) => (
+          {INTERNAL_LINKS.map(({ path, label, icon: Icon, tooltip }) => (
             <li key={path} role="none">
               <Tooltip content={tooltip}>
                 <Link
                   to={path}
                   role="menuitem"
                   className={`${styles.navLink} ${pathname === path ? styles.active : ''}`}
                   onClick={closeMenu}>
-                  {/* Supress eslint "no-unused-vars" rule */}
-                  {React.createElement(icon, { size: 16 })}
+                  <Icon size={16} />
                   <span>{label}</span>
                 </Link>
               </Tooltip>
             </li>
           ))}

Note: The comment also has a typo ("Supress" → "Suppress"), but this refactor removes the need for it entirely.

🤖 Prompt for AI Agents
In @src/components/NavBar.jsx around lines 59-73, The list rendering uses
React.createElement(icon, { size: 16 }) which is non-idiomatic; change the map
destructuring to rename icon to a capitalized component (e.g., .map(({ path,
label, icon: Icon, tooltip }) => ...)) and render it with JSX (<Icon size={16}
/>) inside the Link, removing the suppress comment; keep the rest of the props
(key, role, className, onClick) unchanged so behavior and styling remain
identical.

Comment thread src/components/NavBar.jsx
Comment on lines +75 to +86
{EXTERNAL_LINKS.map(({ href, label, icon, tooltip }) => (
<li key={href} role="none">
<Tooltip content={`${tooltip} (opens in a new tab)`}>
<a href={href} target="_blank" rel="noopener noreferrer" role="menuitem" className={styles.navLink}>
{/* Supress eslint "no-unused-vars" rule */}
{React.createElement(icon, { size: 16 })}
<span>{label}</span>
<SquareArrowOutUpRight size={12} className={styles.externalIcon} />
</a>
</Tooltip>
</li>
))}

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.

🛠️ Refactor suggestion | 🟠 Major

Refactor to use idiomatic JSX instead of React.createElement.

Same issue as the internal links: using React.createElement(icon, { size: 16 }) is non-idiomatic and suggests a linting configuration issue.

🔎 Recommended refactor using capital-case variable
-          {EXTERNAL_LINKS.map(({ href, label, icon, tooltip }) => (
+          {EXTERNAL_LINKS.map(({ href, label, icon: Icon, tooltip }) => (
             <li key={href} role="none">
               <Tooltip content={`${tooltip} (opens in a new tab)`}>
                 <a href={href} target="_blank" rel="noopener noreferrer" role="menuitem" className={styles.navLink}>
-                  {/* Supress eslint "no-unused-vars" rule */}
-                  {React.createElement(icon, { size: 16 })}
+                  <Icon size={16} />
                   <span>{label}</span>
                   <SquareArrowOutUpRight size={12} className={styles.externalIcon} />
                 </a>
               </Tooltip>
             </li>
           ))}
📝 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
{EXTERNAL_LINKS.map(({ href, label, icon, tooltip }) => (
<li key={href} role="none">
<Tooltip content={`${tooltip} (opens in a new tab)`}>
<a href={href} target="_blank" rel="noopener noreferrer" role="menuitem" className={styles.navLink}>
{/* Supress eslint "no-unused-vars" rule */}
{React.createElement(icon, { size: 16 })}
<span>{label}</span>
<SquareArrowOutUpRight size={12} className={styles.externalIcon} />
</a>
</Tooltip>
</li>
))}
{EXTERNAL_LINKS.map(({ href, label, icon: Icon, tooltip }) => (
<li key={href} role="none">
<Tooltip content={`${tooltip} (opens in a new tab)`}>
<a href={href} target="_blank" rel="noopener noreferrer" role="menuitem" className={styles.navLink}>
<Icon size={16} />
<span>{label}</span>
<SquareArrowOutUpRight size={12} className={styles.externalIcon} />
</a>
</Tooltip>
</li>
))}
🤖 Prompt for AI Agents
In @src/components/NavBar.jsx around lines 75-86, Replace the non-idiomatic
React.createElement(icon, { size: 16 }) in the EXTERNAL_LINKS mapping with
idiomatic JSX by assigning the icon variable to a capitalized component
identifier (e.g., const Icon = icon) and rendering it as <Icon size={16} />
inside the map; remove the "Supress eslint" comment and ensure you still render
the icon component, label, and SquareArrowOutUpRight as before so ARIA/role
attributes and external link props (target, rel) remain unchanged.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

Fix all issues with AI Agents 🤖
In @.github/workflows/issue-take-untake.yml:
- Around line 252-257: The current call to github.rest.issues.listComments when
building "comments" may miss results beyond 200; replace it with
github.paginate(github.rest.issues.listComments, { owner, repo, issue_number:
issue.number, per_page: 100 }) (or similar per_page) to collect all pages and
assign the concatenated array to the comments variable; update any downstream
usage expecting the old shape accordingly.
- Around line 243-249: The listing call uses github.rest.issues.listForRepo and
only fetches a single page (per_page:100), so add pagination and accumulate all
pages; use GitHub's pagination helper (github.paginate) or loop with page param
to retrieve all issues with labels: takenLabel and state:'open', then update any
code that referenced issues.data to use the aggregated issues array (e.g.,
rename variable or replace issues.data references with issues) so stale claims
beyond the first 100 are processed.
- Around line 113-118: The current call to github.rest.issues.listComments
(assigned to commentsResp) only requests per_page: 200 and can miss comments on
very active issues; change this to paginate through all comment pages by using
Octokit pagination (github.paginate) or a loop that calls
github.rest.issues.listComments with an incremental page parameter until no more
results, aggregating all items into a single comments array before further
processing; ensure you replace usages of commentsResp.data with the combined
array and preserve the same owner, repo, and issue_number parameters.
🧹 Nitpick comments (2)
.github/workflows/issue-take-untake.yml (2)

141-192: Optional: Reuse comment fetch and standardize per_page.

The function refetches comments even though they were just retrieved (lines 113-118). Additionally, it uses per_page: 100 here versus per_page: 200 earlier.

🔎 Minor optimization: Pass comments as parameter

You could modify the function signature to accept comments as a parameter to avoid the extra API call:

-            async function persistMeta(metaObj, claimed) {
+            async function persistMeta(metaObj, claimed, existingComments = null) {
               // Find existing meta comments
-              const commentsResp = await github.rest.issues.listComments({
-                owner,
-                repo,
-                issue_number: issueNumber,
-                per_page: 100
-              });
+              const commentsResp = existingComments 
+                ? { data: existingComments }
+                : await github.rest.issues.listComments({
+                    owner,
+                    repo,
+                    issue_number: issueNumber,
+                    per_page: 200
+                  });

Then update the calls:

-              await persistMeta(meta, true);
+              await persistMeta(meta, true, commentsResp.data);

267-300: Consider logging errors in the cleanup job.

The empty catch block silently swallows all exceptions, which could hide parsing errors, API failures, or other issues that might warrant investigation.

🔎 Optional: Add error logging
               } catch (err) {
+                console.log(`Failed to process issue #${issue.number}:`, err.message);
               }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6ffd245 and 35be5c8.

📒 Files selected for processing (1)
  • .github/workflows/issue-take-untake.yml
🔇 Additional comments (7)
.github/workflows/issue-take-untake.yml (7)

16-21: LGTM! Bot loop prevention is properly implemented.

The condition correctly filters out the bot's own comments while allowing human-triggered events, preventing infinite loops.


56-70: Good addition of owner name in the claim banner.

The taken banner now clearly identifies the claim owner, improving transparency and making it easy for collaborators to see who's working on the issue.


72-86: LGTM! Banner update logic is robust.

The function correctly handles both upgrading existing banners (via regex replacement) and adding new banners (via prepending), ensuring older issues are upgraded without data loss.


88-101: LGTM! Issue opened handler is clean and idempotent.

Label creation gracefully handles the already-exists case, and the untaken banner is properly added to new issues.


121-139: LGTM! Meta parsing is now robust.

The use of indexOf to locate marker boundaries makes the parsing resilient to edge cases like --> appearing in JSON values, and the fallback ensures graceful degradation.


194-197: LGTM! Expired claims are normalized in real-time.

The immediate normalization of expired claims ensures users can claim stale issues without waiting for the weekly cleanup job.


200-211: LGTM! Take/untake logic is correct.

The conditions properly enforce that only unclaimed/expired issues can be taken and only the current owner can untake.

Comment on lines +113 to +118
const commentsResp = await github.rest.issues.listComments({
owner,
repo,
issue_number: issueNumber,
per_page: 200
});

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

Consider pagination for very active issues.

Fetching only 200 comments could miss meta comments on issues with hundreds of comments. While this is rare, it could cause state loss on extremely active issues.

🔎 Optional enhancement: Add pagination
-            const commentsResp = await github.rest.issues.listComments({
-              owner,
-              repo,
-              issue_number: issueNumber,
-              per_page: 200
-            });
+            // Fetch all comments with pagination
+            const comments = await github.paginate(
+              github.rest.issues.listComments,
+              {
+                owner,
+                repo,
+                issue_number: issueNumber,
+                per_page: 100
+              }
+            );
+            const commentsResp = { data: comments };
🤖 Prompt for AI Agents
In @.github/workflows/issue-take-untake.yml around lines 113-118, The current
call to github.rest.issues.listComments (assigned to commentsResp) only requests
per_page: 200 and can miss comments on very active issues; change this to
paginate through all comment pages by using Octokit pagination (github.paginate)
or a loop that calls github.rest.issues.listComments with an incremental page
parameter until no more results, aggregating all items into a single comments
array before further processing; ensure you replace usages of commentsResp.data
with the combined array and preserve the same owner, repo, and issue_number
parameters.

Comment on lines +243 to 249
const issues = await github.rest.issues.listForRepo({
owner,
repo,
labels: takenLabel,
state: 'open',
per_page: 100
});

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

Pagination not handled for issue listing.

The cleanup job fetches up to 100 issues with the taken label. If your repository grows to have more than 100 simultaneously claimed issues, some stale claims won't be cleaned up.

🔎 Optional enhancement: Add pagination
-            const issues = await github.rest.issues.listForRepo({
+            const issues = await github.paginate(
+              github.rest.issues.listForRepo,
+              {
-              owner,
-              repo,
-              labels: takenLabel,
-              state: 'open',
-              per_page: 100
-            });
+                owner,
+                repo,
+                labels: takenLabel,
+                state: 'open',
+                per_page: 100
+              }
+            );

Then update references from issues.data to issues.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @.github/workflows/issue-take-untake.yml around lines 243-249, The listing
call uses github.rest.issues.listForRepo and only fetches a single page
(per_page:100), so add pagination and accumulate all pages; use GitHub's
pagination helper (github.paginate) or loop with page param to retrieve all
issues with labels: takenLabel and state:'open', then update any code that
referenced issues.data to use the aggregated issues array (e.g., rename variable
or replace issues.data references with issues) so stale claims beyond the first
100 are processed.

Comment on lines +252 to +257
const comments = await github.rest.issues.listComments({
owner,
repo,
issue_number: issue.number,
per_page: 200
});

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

Consider pagination for comment fetching (same issue as main job).

Similar to the main job, fetching only 200 comments could miss meta comments on very active issues during cleanup.

See the earlier comment on lines 113-118 for the suggested pagination approach using github.paginate.

🤖 Prompt for AI Agents
In @.github/workflows/issue-take-untake.yml around lines 252-257, The current
call to github.rest.issues.listComments when building "comments" may miss
results beyond 200; replace it with
github.paginate(github.rest.issues.listComments, { owner, repo, issue_number:
issue.number, per_page: 100 }) (or similar per_page) to collect all pages and
assign the concatenated array to the comments variable; update any downstream
usage expecting the old shape accordingly.

@laxitajain

laxitajain commented Jan 5, 2026

Copy link
Copy Markdown
Contributor Author

Closing this PR in favor of a clean replacement: #200
@Ryan-Millard please review #200

This one picked up unrelated commits during rebasing.
The new PR contains only the intended changes.

@laxitajain laxitajain closed this Jan 5, 2026
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.

Fix: Stop posting bot instruction comment on new issues

4 participants