refactor(issue-bot): remove instructional comment for take/untake - #187
refactor(issue-bot): remove instructional comment for take/untake#187laxitajain wants to merge 11 commits into
Conversation
📝 WalkthroughWalkthroughUnifies issue claiming into a single GitHub Actions job that handles issue opened and Changes
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/workflows/issue-take-untake.ymldocs/docs/guidelines/CONTRIBUTING.md
💤 Files with no reviewable changes (1)
- .github/workflows/issue-take-untake.yml
Ryan-Millard
left a comment
There was a problem hiding this comment.
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>
---There was a problem hiding this comment.
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 unusedmembersfield from meta object.The
membersarray 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
memberswas 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
/takeor/untakecommands 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 (
+1orrocket) afterpersistMetacalls, orconfusedif the action wasn't allowed (e.g., trying to take an already-claimed issue).
43-70: Extract duplicatedbuildUntakenBodyfunction and evaluate the #99 issue reference.The
buildUntakenBodyfunction 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:
- Extracting
buildUntakenBodyto a shared workflow or external script to eliminate duplication.- Documenting whether issue #99 is still relevant, or updating the references to point to
CONTRIBUTING.mdinstead.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 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.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
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
/takeor/untakerather 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
/takehandler only checks ifmeta.owneris 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
buildUntakenBodyfunction (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
envvariables 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
updateIssueBodyfunction 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
📒 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
/takeand/untakecommands with appropriate case-insensitivity and boundaries. Early returns optimize execution.
168-172: LGTM: Proper ownership validation.The
/untakehandler correctly verifies that only the current owner can release their claim.
There was a problem hiding this comment.
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
buildUntakenBodyfunction (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
envvariables. 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
persistMetafunction (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
📒 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
indexOfwith 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.
|
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.
Two CodeRabbit suggestions were reviewed but intentionally not implemented:
Happy to revisit either of these if they seem concerning! |
Ryan-Millard
left a comment
There was a problem hiding this comment.
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.
After that, I'll happily merge this pull request. Thank you!🦔
…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>
There was a problem hiding this comment.
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 thejobs.<job_id>.usessyntax at the job level, not as a step.🔎 Proposed fix
If
commenter.ymlis a reusable workflow, the PR comment should be posted using a GitHub Action likeactions/github-scriptor 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.ymlis 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 --writeon 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_STARTandBODY_ENDcontain<!--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-inactiveor similar variable.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (108)
.editorconfig.editorconfig-checker.json.github/workflows/ci.yml.github/workflows/issue-take-untake.ymlCONTRIBUTING.mdREADME.mddocker-compose.ymldocs/changelogSidebarGenerator.jsdocs/docs/guidelines/_category_.jsondocs/docs/guidelines/coding-style.mddocs/docs/guidelines/commits.mddocs/docs/guidelines/issues.mddocs/docs/guidelines/pull-requests.mddocs/docs/index.mddocs/docs/introduction/getting-started.mddocs/docs/project-scripts/help-scripts/index.mddocs/docs/project-scripts/help-scripts/scripts-guide.mddocs/docs/reference/react/_category_.jsondocs/docs/reference/react/components/GlassCard/index.mddocs/docs/reference/react/components/GlassSwitch/_category_.jsondocs/docs/reference/react/components/GlassSwitch/index.mddocs/docs/reference/react/components/GlassSwitch/tests.mddocs/docs/reference/react/components/NavBar/index.mddocs/docs/reference/react/components/NavBar/testing.mddocs/docs/reference/react/components/ThemeSwitch/index.mddocs/docs/reference/react/components/ThemeSwitch/tests.mddocs/docs/reference/react/components/Tooltip/index.mddocs/docs/reference/react/components/Tooltip/tests.mddocs/docs/reference/react/css/global/variables/theme-independent.mddocs/docs/reference/react/css/global/variables/theme/best-practice.mddocs/docs/reference/react/css/global/variables/theme/dark.mddocs/docs/reference/react/css/global/variables/theme/extending.mddocs/docs/reference/react/css/global/variables/theme/light.mddocs/docs/reference/react/hooks/useTheme/index.mddocs/docs/reference/react/hooks/useTheme/tests.mddocs/docs/reference/tools/_category_.jsondocs/docs/reference/tools/ci-workflows.mddocs/docs/reference/wasm/_category_.jsondocs/docs/reference/wasm/development-workflow.mddocs/docs/reference/wasm/how-to-add-a-module.mddocs/docs/reference/wasm/modules/_category_.jsondocs/docs/reference/wasm/modules/image/_category_.jsondocs/docs/reference/wasm/modules/image/fft_iterative/_category_.jsondocs/docs/reference/wasm/modules/image/fft_iterative/api.mddocs/docs/reference/wasm/modules/image/fft_iterative/explained.mddocs/docs/reference/wasm/modules/image/fft_iterative/implementation.mddocs/docs/reference/wasm/modules/image/fft_iterative/overview.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/continuous-fourier-transform/index.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/discrete-time-signals-and-the-dft/index.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/fourier-series--the-bridge/index.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/how-fourier-transforms-work/index.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/index.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/introduction/index.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/keywords.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/why-img2num-uses-the-dft/index.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/complexity-and-memory.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/connected-components.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/faq.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/limitations-and-pitfalls.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/overview.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/testing-and-debugging-suggestions.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/variants-and-improvements.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/walkthrough-and-usage.mddocs/docs/reference/wasm/modules/image/overview.mddocs/docs/reference/wasm/overview.mddocs/docs/reference/wasm/setup-and-dependencies.mddocs/docs/reference/wasm/troubleshooting-and-optimizations.mddocs/docs/reference/wasm/using-wasm-in-react.mddocs/docusaurus.config.jsdocs/scripts/help.jsdocs/sidebars.jsdocs/src/components/ColorSwatch.jsxindex.htmlpackage.jsonscripts/build-wasm.jsscripts/format-wasm.jsscripts/handle-changelog.jsscripts/help.jsscripts/lib/cli-fuzzy.jsscripts/lib/colors.jsscripts/lib/read-packageJson-scripts.jsscripts/validate-scripts.jssrc/components/GlassSwitch.jsxsrc/components/GlassSwitch.module.csssrc/components/GlassSwitch.test.jsxsrc/components/NavBar.jsxsrc/components/NavBar.module.csssrc/components/NavBar.test.jsxsrc/components/ThemeSwitch.jsxsrc/components/ThemeSwitch.module.csssrc/components/ThemeSwitch.test.jsxsrc/components/Tooltip.jsxsrc/components/Tooltip.test.jsxsrc/components/WasmImageProcessor.jsxsrc/global-styles/variables.csssrc/hooks/useGoogleAnalytics.jssrc/hooks/useTheme.test.jsxsrc/pages/About/Author.jsxsrc/pages/About/CTA.jsxsrc/pages/About/Motivation.jsxsrc/pages/About/TechStack.jsxsrc/pages/About/WhatIsThis.jsxsrc/pages/Credits/ContributorsCreditsCard.jsxsrc/pages/Credits/DependencyCreditsCard.jsxsrc/pages/Credits/StaticCreditsCard.jsxsrc/test/setup.jsvite.config.jsvitest.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.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/faq.mddocs/docs/reference/wasm/modules/image/fft_iterative/explained.mddocs/docs/reference/tools/ci-workflows.mddocs/docs/reference/react/components/GlassSwitch/tests.mddocs/docs/reference/react/components/NavBar/testing.mddocs/docs/reference/react/components/Tooltip/tests.mddocs/docs/reference/react/components/GlassSwitch/index.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/complexity-and-memory.mddocs/docs/guidelines/commits.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/walkthrough-and-usage.mddocs/docs/reference/react/css/global/variables/theme/extending.mddocs/docs/project-scripts/help-scripts/index.mddocs/docs/reference/wasm/modules/image/mergeSmallRegionsInPlace/limitations-and-pitfalls.mddocs/docs/project-scripts/help-scripts/scripts-guide.mddocs/docs/reference/react/components/ThemeSwitch/index.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/fourier-series--the-bridge/index.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/keywords.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/why-img2num-uses-the-dft/index.mddocs/docs/reference/react/css/global/variables/theme/light.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/index.mddocs/docs/reference/wasm/modules/image/fft_iterative/prerequisite-theory/how-fourier-transforms-work/index.mddocs/docs/reference/react/css/global/variables/theme/best-practice.mddocs/docs/guidelines/pull-requests.mddocs/docs/reference/react/hooks/useTheme/index.mddocs/docs/reference/react/components/NavBar/index.mddocs/docs/reference/wasm/modules/image/fft_iterative/api.mddocs/docs/guidelines/issues.mddocs/docs/guidelines/coding-style.mddocs/docs/introduction/getting-started.mddocs/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.mdREADME.mddocs/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.mddocs/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.editorconfigdocs/docs/guidelines/commits.mddocs/docs/reference/react/_category_.jsondocs/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; thedocumentation-site-onlytab should either contain content and close beforebothopens, 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
noWrapKatexChildrenCSS 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
chunkfunction maintains correct chunking behavior usingArray.fromandslice. 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
--checkflag implementation correctly:
- Uses
--dry-run --Werrorfor 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
mergeSmallRegionsInPlacefunction, 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
afterEachimport 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.matchMediamock 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
.tsand.tsxfiles 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 addinginsert_final_newline = truealigns 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/changelogis missing. Therecursive: trueoption 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, andformat-wasm:checkscripts 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-typesis actively used inGlassSwitch.jsxandTooltip.jsxand works fine with React 19.2.3. Whileprop-typesis considered legacy, it remains a valid and functional choice for runtime type validation in JavaScript React projects. React 19 does not remove or breakprop-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.14does exist as a published version. The current constraint^5.90.12allows 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.ymlandpackage.json.
107-107: The link../../project-scripts/overview.mdis 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:
- Quick start: https://ryan-millard.github.io/Img2Num/info/docs/introduction/getting-started
- Guidelines: https://ryan-millard.github.io/Img2Num/info/docs/category/-guidelines
- Documentation: https://ryan-millard.github.io/Img2Num/info/docs/
- Reference: https://ryan-millard.github.io/Img2Num/info/docs/reference/
- Changelog: https://ryan-millard.github.io/Img2Num/info/changelog
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
scriptsInfoexample (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 + enterquit 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
GlassSwitchand wires up the theme toggle. TheisDarkderivation and aria label are appropriate.Note on icon convention: The
thumbContentshows<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
classNameprop, 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
toggleThemefunction 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 atsrc/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-checkedbased on theisOnprop.
39-62: LGTM! Interaction testing is thorough.The tests properly validate both mouse and keyboard interactions using the modern
userEventAPI 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/reactandvitest.
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.mdfor 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"andaria-checkedcorrectly 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-visiblewith a solid fallback for older browsers.
| trim_trailing_whitespace = true | ||
| insert_final_newline = true | ||
| max_line_length = 120 | ||
| max_line_length = 200 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# List potential configuration files
git ls-files | grep -E '(\.(eslintrc|prettierrc|editorconfig)|package\.json)' | head -20Repository: Ryan-Millard/Img2Num
Length of output: 187
🏁 Script executed:
# First, let's read the .editorconfig file to confirm the changes
cat -n .editorconfigRepository: 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.jsRepository: 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 -50Repository: Ryan-Millard/Img2Num
Length of output: 1308
🏁 Script executed:
# Check editorconfig-checker.json
cat -n .editorconfig-checker.jsonRepository: 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:
- Create a
.prettierrcfile with"printWidth": 200to match .editorconfig, or - Revert .editorconfig to 120 to match Prettier's default behavior
| - 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 |
There was a problem hiding this comment.
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: 22Note: 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.
| - 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.
| void exampleFunction(uint8_t x) | ||
| { | ||
| if (internalLibrary::isPrime(x)) | ||
| { | ||
| std::cout << "Prime" << std::endl; | ||
| return; | ||
| } | ||
|
|
||
| std::cout << "Non-prime" << std::endl; | ||
| } | ||
|
|
||
| } | ||
| ``` | ||
| } | ||
|
|
||
| ```` |
There was a problem hiding this comment.
🧩 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.
| ``` | ||
| src/components/GlassSwitch.test.jsx | ||
| ``` |
There was a problem hiding this comment.
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.
| - **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 |
There was a problem hiding this comment.
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.
| - **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; |
There was a problem hiding this comment.
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.
| {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> | ||
| ))} |
There was a problem hiding this comment.
🛠️ 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.
| {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> | ||
| ))} |
There was a problem hiding this comment.
🛠️ 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.
| {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.
There was a problem hiding this comment.
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: 100here versusper_page: 200earlier.🔎 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
catchblock 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
📒 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
indexOfto 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.
| const commentsResp = await github.rest.issues.listComments({ | ||
| owner, | ||
| repo, | ||
| issue_number: issueNumber, | ||
| per_page: 200 | ||
| }); |
There was a problem hiding this comment.
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.
| const issues = await github.rest.issues.listForRepo({ | ||
| owner, | ||
| repo, | ||
| labels: takenLabel, | ||
| state: 'open', | ||
| per_page: 100 | ||
| }); |
There was a problem hiding this comment.
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.
| const comments = await github.rest.issues.listComments({ | ||
| owner, | ||
| repo, | ||
| issue_number: issue.number, | ||
| per_page: 200 | ||
| }); |
There was a problem hiding this comment.
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.
|
Closing this PR in favor of a clean replacement: #200 This one picked up unrelated commits during rebasing. |
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:
🧪 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:
📸 Screenshots / Demo (if applicable)
Paste images, GIFs, or demo links here.
💬 Additional Context
Anything else relevant to the PR.
Summary by CodeRabbit
Documentation
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.