Skip to content

Feat/veashi scanner#461

Open
mani99brar wants to merge 14 commits into
devfrom
feat/veashi-scanner
Open

Feat/veashi scanner#461
mani99brar wants to merge 14 commits into
devfrom
feat/veashi-scanner

Conversation

@mani99brar

@mani99brar mani99brar commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

PR-Codex overview

This PR introduces significant updates to the veashi-scanner and veashi-envio-yaho projects, including new components, hooks, and TypeScript configurations to enhance functionality and improve user experience in handling cross-chain messages.

Detailed summary

  • Added Layout component for application structure.
  • Introduced Pagination, AddressesCard, ChainRouteCard, and BridgeSummaryCard components for better UI.
  • Implemented useDebounce and useExecutionStatus hooks for improved state management.
  • Updated TypeScript configurations in tsconfig.json and related files.
  • Enhanced MessagesTable and SearchBar for better transaction searching.
  • Added GraphQL schema for MessageDispatched events in veashi-envio-yaho.
  • Improved styling and structure in globals.css and various components.
  • Updated package.json dependencies for compatibility and new features.

The following files were skipped due to too many changes: veashi-scanner/hooks/useTransaction.ts, veashi-scanner/README.md, veashi-scanner/components/tx/cards/AdaptersCard.tsx, veashi-envio-yaho/test/EventHandlers.test.ts, veashi-scanner/lib/envioClient.ts, veashi-scanner/pages/Home.tsx, veashi-scanner/components/ChainFilterPanel.tsx, veashi-scanner/lib/scannerCache.ts, veashi-envio-yaho/abis/Yaho.json, veashi-scanner/hooks/useMessageScanner.ts, yarn.lock

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features
    • Added a cross-chain message explorer with source/destination and block filters, transaction search, a paginated message list, and transaction detail pages.
    • Shows per-message progress and live adapter/bridge confirmation status, including threshold and execution state indicators.
    • Added an Envio-based indexer for MessageDispatched data to support message discovery.
  • Chores
    • Added new workspace packages for the scanner UI and the Yaho indexer.
    • Expanded local ignore rules for Envio artifacts/config.

@netlify

netlify Bot commented Jun 15, 2026

Copy link
Copy Markdown

Deploy Preview for veascan ready!

Name Link
🔨 Latest commit 9b08d69
🔍 Latest deploy log https://app.netlify.com/projects/veascan/deploys/6a4514584ca180000813e43e
😎 Deploy Preview https://deploy-preview-461--veascan.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Jun 15, 2026

Copy link
Copy Markdown

Deploy Preview for veashi-scan ready!

Name Link
🔨 Latest commit 9b08d69
🔍 Latest deploy log https://app.netlify.com/projects/veashi-scan/deploys/6a451458e96c4a000742413d
😎 Deploy Preview https://deploy-preview-461--veashi-scan.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b19b4036-114f-497f-9160-2ae6ac8dd839

📥 Commits

Reviewing files that changed from the base of the PR and between fb50b65 and 9b08d69.

📒 Files selected for processing (1)
  • veashi-scanner/lib/utils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • veashi-scanner/lib/utils.ts

Walkthrough

Adds two monorepo packages: veashi-envio-yaho, which indexes Yaho MessageDispatched events into a GraphQL store, and veashi-scanner, which scans, caches, and displays cross-chain messages with transaction detail views and fallback RPC lookup.

Changes

veashi-envio-yaho Envio Indexer

Layer / File(s) Summary
Indexer schema and network config
veashi-envio-yaho/schema.graphql, veashi-envio-yaho/abis/Yaho.json, veashi-envio-yaho/config.yaml
Adds the MessageDispatched GraphQL type, the Yaho ABI, and Envio mappings for three chains and contract addresses.
Indexer handler and tests
veashi-envio-yaho/src/EventHandlers.ts, veashi-envio-yaho/test/EventHandlers.test.ts
Persists normalized MessageDispatched records and verifies field mapping, unique IDs, same-block handling, and array serialization.
Indexer package setup
veashi-envio-yaho/package.json, veashi-envio-yaho/tsconfig.json, veashi-envio-yaho/jest.config.ts, veashi-envio-yaho/envio-env.d.ts, veashi-envio-yaho/.env.example, veashi-envio-yaho/README.md, .gitignore, package.json
Adds package metadata, config, env sample, docs, ignore rules, and workspace wiring.

veashi-scanner Cross-Chain Message Explorer

Layer / File(s) Summary
Shared scanner types and data access
veashi-scanner/lib/types.ts, veashi-scanner/lib/chains.ts, veashi-scanner/lib/envioClient.ts, veashi-scanner/lib/hashi.ts, veashi-scanner/lib/scannerCache.ts, veashi-scanner/lib/veashiHelpers.ts, veashi-scanner/lib/utils.ts
Adds shared message and status types, chain/bridge helpers, Envio and RPC fetchers, cache management, and utility functions for search, status labels, and block parsing.
Scanner hooks
veashi-scanner/hooks/useMessageScanner.ts, veashi-scanner/hooks/useTransaction.ts, veashi-scanner/hooks/useAdapters.ts, veashi-scanner/hooks/useExecutionStatus.ts, veashi-scanner/hooks/useDebounce.ts
Implements message scanning, transaction resolution, adapter status polling, execution status reads, and debounced input parsing.
Scanner UI components and transaction cards
veashi-scanner/components/*, veashi-scanner/components/tx/*
Adds the badges, header, search, table, pagination, filter panel, status indicator, and transaction detail card set used by the explorer.
Scanner pages
veashi-scanner/pages/Home.tsx, veashi-scanner/pages/TxPage.tsx
Adds the paginated message list page and the transaction detail route with loading, error, and fallback states.
App shell and tooling
veashi-scanner/main.tsx, veashi-scanner/Layout.tsx, veashi-scanner/globals.css, veashi-scanner/index.html, veashi-scanner/package.json, veashi-scanner/vite.config.ts, veashi-scanner/tsconfig*.json, veashi-scanner/eslint.config.mjs, veashi-scanner/README.md
Adds the app entrypoint, routing, layout, global styles, HTML shell, build/lint/config files, and scanner documentation.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Home
  participant useMessageScanner
  participant scannerCache
  participant fetchMessagesFromEnvio
  participant getMessageDispatchedLogs

  User->>Home: set filters and block range
  Home->>useMessageScanner: sourceChain, destChain, fromBlock, toBlock
  useMessageScanner->>scannerCache: getCachedMessages
  useMessageScanner->>fetchMessagesFromEnvio: fetchMessagesFromEnvio
  alt Envio unavailable
    useMessageScanner->>scannerCache: getUncachedSubranges
    useMessageScanner->>getMessageDispatchedLogs: getMessageDispatchedLogs
    useMessageScanner->>scannerCache: updateCache
  end
  useMessageScanner->>Home: messages, isScanning, blockRange, error
Loading

Estimated code review effort: 5 (Critical) | ~120 minutes

Suggested reviewers: jaybuidl

Poem

Hop hop, the indexers start to hum,
Through cache and chain the messages come.
A badge, a card, a tx path bright,
The scanner glows in rabbit light.
I nibble logs, then bound along —
Cross-chain trails now sing this song.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is related to the PR, but it is too generic to convey the main change. Use a more specific title that names the primary change, such as adding the veashi scanner and Envio indexer support.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/veashi-scanner

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 19

🧹 Nitpick comments (7)
veashi-scanner/app/globals.css (2)

1-1: Replace CSS @import with next/font/google for better performance and privacy.

The project uses Next.js 14 with App Router, which provides built-in font optimization via next/font/google. This eliminates external requests to Google's servers, automatically self-hosts fonts at build time, prevents layout shift with optimized fallbacks, and removes the rendering-blocking behavior of CSS @import.

Move the DM Sans and JetBrains Mono font declarations from globals.css to a dedicated font configuration file (e.g., app/fonts.ts) using next/font/google, then import and use them in layout.tsx.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@veashi-scanner/app/globals.css` at line 1, Replace the CSS `@import` statement
in globals.css that loads DM Sans and JetBrains Mono fonts from Google Fonts
with Next.js font optimization. Create a new font configuration file (such as
app/fonts.ts) that uses the localFont or google function from next/font/google
to declare the DM Sans and JetBrains Mono font families with their respective
weights (400, 500, 600, 700 for DM Sans and 400, 500, 600 for JetBrains Mono).
Export these font objects from the configuration file, then import them in
app/layout.tsx and apply them using their className property in the appropriate
elements (typically DM Sans for body/general content and JetBrains Mono for
code). Finally, remove the `@import` url() line from globals.css entirely.

2-3: Use bare import paths instead of relative node_modules paths.

The current relative paths (../node_modules/@kleros/ui-components-library/...) are safe since the repository explicitly uses nodeLinker: node-modules in .yarnrc.yml. However, bare imports are more idiomatic for Tailwind CSS v4 and would remain compatible if the linker configuration ever changes.

Suggested improvement
-@import "../node_modules/@kleros/ui-components-library/dist/assets/theme.css";
-@source "../node_modules/@kleros/ui-components-library";
+@import "`@kleros/ui-components-library/dist/assets/theme.css`";
+@source "`@kleros/ui-components-library`";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@veashi-scanner/app/globals.css` around lines 2 - 3, Replace the relative
node_modules paths in the import and source statements with bare import paths.
Change `../node_modules/@kleros/ui-components-library/dist/assets/theme.css` to
`@kleros/ui-components-library/dist/assets/theme.css` in the `@import` statement
and change `../node_modules/@kleros/ui-components-library` to
`@kleros/ui-components-library` in the `@source` statement to follow the more
idiomatic Tailwind CSS v4 convention and ensure compatibility if the node linker
configuration changes in the future.
veashi-scanner/README.md (1)

1-61: 💤 Low value

Consider adding a "Quick Start" or "How to Use" section explaining the scanner's features.

The README covers installation and configuration, but doesn't document what users will see or do once the app is running (e.g., browsing message list, searching by transaction hash, viewing bridge confirmations, filtering by chain/threshold). Adding a brief "Features" or "Usage" section would improve discoverability and set expectations for first-time users.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@veashi-scanner/README.md` around lines 1 - 61, Add a new "Features" or
"Usage" section to the README after the "Running locally" section that documents
what users can do with the Veashi Scanner once it is running. The section should
explain key features such as browsing the message list dispatched through
Hashi's Yaho contract, searching or filtering messages by transaction hash,
viewing bridge confirmation status and progress toward the required threshold,
inspecting execution status across multiple bridge providers, and filtering
results by source/destination chains. This will help first-time users understand
the scanner's capabilities and how to navigate the interface without requiring
them to discover features through trial and error.
veashi-envio-yaho/test/EventHandlers.test.ts (1)

49-61: ⚡ Quick win

Add an explicit txHash assertion in the main mapping test.

Line 49 onward validates nearly all persisted fields, but txHash is currently unverified even though the handler depends on transaction_fields.hash. Adding this catches config/handler/schema drift early.

Suggested test addition
     expect(entity.messageId).toBe("1");
+    expect(entity.txHash).toMatch(/^0x[a-fA-F0-9]{64}$/);
     expect(entity.sourceChainId).toBe(42161n);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@veashi-envio-yaho/test/EventHandlers.test.ts` around lines 49 - 61, The test
assertions in EventHandlers.test.ts are missing a verification for the txHash
field, even though the handler code depends on transaction_fields.hash. Add an
explicit expect statement that asserts the txHash property of the entity to
match the expected transaction hash value, placing it among the other field
assertions in the sequence that validates the entity's persisted fields.
veashi-scanner/components/BridgeStatusCard.tsx (1)

33-35: ⚡ Quick win

Remove the duplicated BridgeStatusCardProps declaration.

Line 33 re-declares the same interface already declared at Line 6. This can drift over time due to interface merging and makes the type contract harder to maintain.

Suggested cleanup
-interface BridgeStatusCardProps {
-  status: BridgeStatus;
-}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@veashi-scanner/components/BridgeStatusCard.tsx` around lines 33 - 35, The
BridgeStatusCardProps interface is declared twice in the file, creating a
duplicate that can cause type drift and maintenance issues. Remove the duplicate
BridgeStatusCardProps interface declaration and retain only the original one to
maintain a single source of truth for the interface contract.
veashi-scanner/components/tx/cards/DetailsCard.tsx (1)

33-50: ⚡ Quick win

Extract execution status mapping to a single derived object.

The nested ternaries duplicate branching for both dot color and label, which is harder to maintain and easy to desync.

Suggested refactor
+  const executionMeta = execLoading
+    ? { dotClass: "bg-purple-400 animate-pulse", text: "Checking…" }
+    : execStatus === "executed"
+      ? { dotClass: "bg-green-400", text: "Executed" }
+      : execStatus === "failed"
+        ? { dotClass: "bg-red-400", text: "Failed" }
+        : { dotClass: "bg-amber-400 animate-pulse", text: "Pending" };
...
         <MetaRow label="Execution">
           <div className="flex items-center gap-1.5">
-            {execLoading ? (
-              <span className="w-1.5 h-1.5 rounded-full bg-purple-400 animate-pulse inline-block" />
-            ) : execStatus === "executed" ? (
-              <span className="w-1.5 h-1.5 rounded-full bg-green-400 inline-block" />
-            ) : execStatus === "failed" ? (
-              <span className="w-1.5 h-1.5 rounded-full bg-red-400 inline-block" />
-            ) : (
-              <span className="w-1.5 h-1.5 rounded-full bg-amber-400 animate-pulse inline-block" />
-            )}
-            <span className="text-sm font-mono">
-              {execLoading
-                ? "Checking…"
-                : execStatus === "executed"
-                ? "Executed"
-                : execStatus === "failed"
-                ? "Failed"
-                : "Pending"}
-            </span>
+            <span className={`w-1.5 h-1.5 rounded-full inline-block ${executionMeta.dotClass}`} />
+            <span className="text-sm font-mono">{executionMeta.text}</span>
           </div>
         </MetaRow>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@veashi-scanner/components/tx/cards/DetailsCard.tsx` around lines 33 - 50, The
execution status display in the DetailsCard component contains duplicated nested
ternaries for both the indicator dot color and status label text, which makes it
difficult to maintain and easy to desync. Create a single derived object that
maps the execution state (determined by execLoading and execStatus variables) to
an object containing both the className for the indicator dot and the label
text. Then replace both sets of nested ternaries with references to the
properties of this single status mapping object, so the branching logic only
exists in one place.

Source: Linters/SAST tools

veashi-scanner/hooks/useMessageScanner.ts (1)

125-291: 🏗️ Heavy lift

Extract route scanning into smaller units to reduce failure-prone complexity.

This block is heavily nested and already flagged for cognitive complexity/nesting thresholds. Splitting into helpers (resolveScanRange, scanViaEnvio, scanViaRpcChunks, applyRouteResult) will make cancellation, cache invariants, and error handling safer to maintain.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@veashi-scanner/hooks/useMessageScanner.ts` around lines 125 - 291, The scan
function contains deeply nested logic that makes it difficult to maintain and
prone to errors in cancellation handling and cache management. Extract the route
scanning logic within the outer loop (where targetDestIds are processed) into
smaller helper functions: create resolveScanRange to handle determining
startBlock and endBlock based on input parameters and current block number,
create scanViaEnvio to handle the Envio indexer fetch and filtering logic,
create scanViaRpcChunks to handle the RPC fallback logic with chunked scanning
and the nested loops, and create applyRouteResult to handle updating cache and
setting messages from results. Each helper should accept necessary parameters
(srcId, dstId, chainConfig, publicClient, displayRange, scanRange, signal, etc.)
and return results to be processed by the main loop. This refactoring will
reduce nesting depth, improve error handling clarity, and make cancellation
logic easier to follow.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@veashi-scanner/app/tx/`[...params]/page.tsx:
- Around line 13-15: The chainId derivation from segments[0] can result in NaN
when Number() fails to convert the value, which then gets passed to TxDetail and
useTransaction causing invalid behavior. Add validation to ensure that
Number(segments[0]) produces a valid number before assigning it to chainId; if
the conversion results in NaN, treat chainId as null instead. This validation
should be applied wherever chainId is parsed from the segments array (including
the location at line 50 referenced in the comment).

In `@veashi-scanner/components/BridgeStatusCard.tsx`:
- Around line 40-55: The getTimeAgo function assumes timestamps are in
milliseconds (dividing by 1000), but blockchain event timestamps are in seconds,
causing a ~1000x overstatement of elapsed time when blockchain data is used. Add
JSDoc documentation to the BridgeStatus type clarifying that timestamp should be
in milliseconds, and when populating bridgeStatuses from blockchain data in the
TODO section, ensure you multiply blockchain timestamps (which are in seconds)
by 1000 before assigning to status.timestamp so the getTimeAgo function receives
the correct unit.

In `@veashi-scanner/components/MessagesTable.tsx`:
- Around line 73-76: The table row element (the `<tr>` with the `onClick`
handler and hover-lift class) is only accessible via mouse clicks, preventing
keyboard users from navigating to transaction details. To fix this, add keyboard
accessibility to the row by: adding a tabIndex attribute to make it focusable in
the keyboard navigation order, adding an onKeyDown handler that triggers the
same onClick action when Enter or Space keys are pressed, and adding
role="button" to semantically indicate the row is interactive. Make sure the
keyboard event handler checks for the appropriate key codes and calls the same
onClick callback function.
- Around line 54-57: The key for the MessageRow component in the messages.map
function uses only message.txHash, which creates collisions when different
chains have the same transaction hash, causing React to reuse incorrect row
state. Modify the key prop to include both the chain identifier and the
transaction hash (for example, by combining message.chainId or similar chain
property with message.txHash using a delimiter like a colon or underscore) to
ensure each row has a globally unique key across all chains.

In `@veashi-scanner/components/StatusIndicator.tsx`:
- Around line 29-31: The StatusIndicator function computes the percentage by
dividing current by required without checking if required is zero, which would
result in Infinity or NaN and break the progress display. Add a guard check
before the percentage calculation on line 30 to handle the case when required
equals zero. If required is zero, you should either return a default percentage
value (such as 0) or handle it appropriately for the status computation. This
guard should be placed before the Math.min calculation for the percentage
variable to ensure valid numeric values are used downstream.

In `@veashi-scanner/components/tx/cards/AdaptersCard.tsx`:
- Around line 53-61: The map function iterating over pairedData uses array index
idx as the key, which is unstable and can cause React to render stale UI/state
if the group ordering changes. Replace key={idx} with a stable identifier
derived from the pair object itself, such as a unique id, bridge name, or other
property that uniquely identifies each adapter group independent of its position
in the array.

In `@veashi-scanner/components/tx/cards/BridgeSummaryCard.tsx`:
- Around line 11-23: The `getBridgeName()` function returns lowercase enum
values like "ccip", "lz", "vea", but these are being compared against the
uppercase `Bridge` type literals in the `knownBridges` array ("CCIP",
"LayerZero", "Vea", "DeBridge"), causing all comparisons to fail. Fix this by
normalizing the enum output to match the uppercase format before adding to the
`bridgeNames` Set. Specifically, when processing the results from
`getBridgeName()` calls in both the adapters and reporters loops, transform the
returned values to uppercase or map them to their corresponding `Bridge` type
literal equivalents before calling `bridgeNames.add()`. Additionally, note that
`getBridgeName()` does not currently support DeBridge detection, making the
"DeBridge" entry in the `knownBridges` array unreachable unless that function is
also updated to handle DeBridge cases.

In `@veashi-scanner/components/tx/cards/TxHeaderCard.tsx`:
- Around line 44-47: The messageId display in TxHeaderCard always appends an
ellipsis even when the messageId is shorter than 18 characters, which is
misleading. Modify the rendering logic to conditionally display the ellipsis
only when message.messageId.length is greater than 18 characters. Keep the
slice(0, 18) operation but wrap the ellipsis character in a conditional
expression that checks the actual length of message.messageId before appending
it.

In `@veashi-scanner/hooks/useAdapters.ts`:
- Line 17: The guard clause on line 17 of the useAdapters hook is checking
`message.nonce === undefined` but the actual code usage at line 36 calls
`getHash(domain, id)` which depends on `messageId`. Change the guard condition
to check `message.messageId === undefined` instead of `message.nonce ===
undefined` so that the early return prevents execution when the property that's
actually needed is missing, avoiding errors in the adapter polling logic.

In `@veashi-scanner/hooks/useExecutionStatus.ts`:
- Around line 31-36: In the useExecutionStatus hook's readContract call to the
executed function, the args array currently passes message.messageId as a
string, but the executed function expects a uint256 argument. Cast
message.messageId to BigInt by wrapping it with the BigInt() constructor in the
args property to ensure type compatibility.

In `@veashi-scanner/hooks/useMessageScanner.ts`:
- Around line 199-214: The issue is that when fetchMessagesFromEnvio returns
results with a limit of 10, the code calls updateCache with the full scanRange,
incorrectly marking the entire range as scanned even though only a partial
result was returned. This prevents RPC fallback from discovering older messages.
Fix this by not marking scanRange as covered when only a partial Envio query
result is obtained. Either remove the updateCache call for partial results, or
modify it to only cache the range that was actually covered by the returned
messages. Also ensure the continue statement does not skip RPC fallback for
uncovered portions of scanRange.
- Around line 97-105: In the useMessageScanner hook, the abort logic for
aborting `abortRef.current` and creating a new AbortController is placed after
the early return condition that checks if sourceChain equals destinationChain.
Move the abort logic (the if statement checking abortRef.current and the
AbortController instantiation) to execute before the early return condition, so
that any in-progress scan is properly aborted before returning early when chains
match, preventing stale async results from repopulating after filter changes.

In `@veashi-scanner/hooks/useTransaction.ts`:
- Around line 47-53: The fetchMessageByTxHash call in the useTransaction hook is
not wrapped in error handling, causing the hook to exit prematurely if an error
is thrown, preventing the RPC fallback branch from executing. Wrap the
fetchMessageByTxHash call and the conditional block that checks the result (the
if statement checking envioMsg and !cancelled) in a try-catch block, allowing
any errors to be caught so that execution can continue to the fallback branch
instead of leaving the request in a stuck state.

In `@veashi-scanner/lib/envioClient.ts`:
- Around line 15-21: The TX_HASH_QUERY constant uses the _ilike operator for
filtering by txHash, but _ilike is a pattern-matching operator that supports SQL
wildcards and is inappropriate for exact transaction hash lookups. Replace the
_ilike operator with _eq in the MessageDispatched where clause to ensure
exact-match filtering for the transaction hash, which is semantically correct
and more efficient for this use case.

In `@veashi-scanner/lib/utils.ts`:
- Around line 32-41: Add per-request timeouts to the RPC fetch call in the
eth_getTransactionByHash request to prevent indefinite hangs that can leave
transaction search stuck in loading state. Implement an AbortController with a
timeout (e.g., 5-10 seconds) and pass the abort signal to the fetch options,
ensuring the request is automatically aborted if it exceeds the timeout
duration. This will allow the system to fail fast and move on rather than
waiting indefinitely for unresponsive RPC endpoints.
- Around line 49-50: The hash equality check in the condition comparing
data.result.hash === hash is case-sensitive, but RPC responses are typically
lowercase while the input hash parameter may be mixed-case, causing valid hashes
to fail the equality check. Normalize both the data.result.hash and the hash
variable to lowercase by using the toLowerCase() method before performing the
=== comparison to ensure case-insensitive matching.

In `@veashi-scanner/lib/veashiHelpers.ts`:
- Around line 24-39: The getBridgeName helper function is incomplete and does
not check for DeBridge routes despite DeBridge being defined in the Bridges enum
and scanner types. Add a DeBridge check in the getBridgeName function following
the same pattern as the existing CCIP, LayerZero (LZ), and Vea checks. Insert a
new conditional block that uses isMatch to compare adapterAddress and
reporterAddress against route.debridgeAdapter and route.debridgeReporter, and
return Bridges.DEBRIDGE when matched, placing this check before the final return
null statement to maintain consistency with the other bridge checks.

In `@veashi-scanner/package.json`:
- Around line 15-17: The eslint-config-next dependency version is misaligned
with the next package version. Update the eslint-config-next version to major
version 14 to match next@14. Check the package.json file at line range 15-17
(where next is declared at version 14) and at line range 27-27 (where
eslint-config-next is declared), and ensure eslint-config-next version is set to
14.x to maintain compatibility and prevent linting configuration issues.

In `@veashi-scanner/README.md`:
- Around line 51-59: Remove the table row for the
`NEXT_PUBLIC_HASURA_ADMIN_SECRET` environment variable from the README
environment variables section. This variable is not actually used anywhere in
the codebase, and as noted in the envioClient.ts file, no Hasura admin secret is
required or should ever be sent to the browser. Removing this entry will prevent
misleading users during setup. The NEXT_PUBLIC_ENVIO_URL entry should remain as
it is correctly implemented and documented.

---

Nitpick comments:
In `@veashi-envio-yaho/test/EventHandlers.test.ts`:
- Around line 49-61: The test assertions in EventHandlers.test.ts are missing a
verification for the txHash field, even though the handler code depends on
transaction_fields.hash. Add an explicit expect statement that asserts the
txHash property of the entity to match the expected transaction hash value,
placing it among the other field assertions in the sequence that validates the
entity's persisted fields.

In `@veashi-scanner/app/globals.css`:
- Line 1: Replace the CSS `@import` statement in globals.css that loads DM Sans
and JetBrains Mono fonts from Google Fonts with Next.js font optimization.
Create a new font configuration file (such as app/fonts.ts) that uses the
localFont or google function from next/font/google to declare the DM Sans and
JetBrains Mono font families with their respective weights (400, 500, 600, 700
for DM Sans and 400, 500, 600 for JetBrains Mono). Export these font objects
from the configuration file, then import them in app/layout.tsx and apply them
using their className property in the appropriate elements (typically DM Sans
for body/general content and JetBrains Mono for code). Finally, remove the
`@import` url() line from globals.css entirely.
- Around line 2-3: Replace the relative node_modules paths in the import and
source statements with bare import paths. Change
`../node_modules/@kleros/ui-components-library/dist/assets/theme.css` to
`@kleros/ui-components-library/dist/assets/theme.css` in the `@import` statement
and change `../node_modules/@kleros/ui-components-library` to
`@kleros/ui-components-library` in the `@source` statement to follow the more
idiomatic Tailwind CSS v4 convention and ensure compatibility if the node linker
configuration changes in the future.

In `@veashi-scanner/components/BridgeStatusCard.tsx`:
- Around line 33-35: The BridgeStatusCardProps interface is declared twice in
the file, creating a duplicate that can cause type drift and maintenance issues.
Remove the duplicate BridgeStatusCardProps interface declaration and retain only
the original one to maintain a single source of truth for the interface
contract.

In `@veashi-scanner/components/tx/cards/DetailsCard.tsx`:
- Around line 33-50: The execution status display in the DetailsCard component
contains duplicated nested ternaries for both the indicator dot color and status
label text, which makes it difficult to maintain and easy to desync. Create a
single derived object that maps the execution state (determined by execLoading
and execStatus variables) to an object containing both the className for the
indicator dot and the label text. Then replace both sets of nested ternaries
with references to the properties of this single status mapping object, so the
branching logic only exists in one place.

In `@veashi-scanner/hooks/useMessageScanner.ts`:
- Around line 125-291: The scan function contains deeply nested logic that makes
it difficult to maintain and prone to errors in cancellation handling and cache
management. Extract the route scanning logic within the outer loop (where
targetDestIds are processed) into smaller helper functions: create
resolveScanRange to handle determining startBlock and endBlock based on input
parameters and current block number, create scanViaEnvio to handle the Envio
indexer fetch and filtering logic, create scanViaRpcChunks to handle the RPC
fallback logic with chunked scanning and the nested loops, and create
applyRouteResult to handle updating cache and setting messages from results.
Each helper should accept necessary parameters (srcId, dstId, chainConfig,
publicClient, displayRange, scanRange, signal, etc.) and return results to be
processed by the main loop. This refactoring will reduce nesting depth, improve
error handling clarity, and make cancellation logic easier to follow.

In `@veashi-scanner/README.md`:
- Around line 1-61: Add a new "Features" or "Usage" section to the README after
the "Running locally" section that documents what users can do with the Veashi
Scanner once it is running. The section should explain key features such as
browsing the message list dispatched through Hashi's Yaho contract, searching or
filtering messages by transaction hash, viewing bridge confirmation status and
progress toward the required threshold, inspecting execution status across
multiple bridge providers, and filtering results by source/destination chains.
This will help first-time users understand the scanner's capabilities and how to
navigate the interface without requiring them to discover features through trial
and error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 04a016ef-de24-484c-9398-1e59984422cf

📥 Commits

Reviewing files that changed from the base of the PR and between 8911800 and d986dc7.

⛔ Files ignored due to path filters (9)
  • veashi-scanner/app/favicon.ico is excluded by !**/*.ico
  • veashi-scanner/public/file.svg is excluded by !**/*.svg
  • veashi-scanner/public/globe.svg is excluded by !**/*.svg
  • veashi-scanner/public/image.png is excluded by !**/*.png
  • veashi-scanner/public/logo.png is excluded by !**/*.png
  • veashi-scanner/public/next.svg is excluded by !**/*.svg
  • veashi-scanner/public/vercel.svg is excluded by !**/*.svg
  • veashi-scanner/public/window.svg is excluded by !**/*.svg
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (56)
  • .gitignore
  • package.json
  • veashi-envio-yaho/.env.example
  • veashi-envio-yaho/README.md
  • veashi-envio-yaho/abis/Yaho.json
  • veashi-envio-yaho/config.yaml
  • veashi-envio-yaho/envio-env.d.ts
  • veashi-envio-yaho/jest.config.ts
  • veashi-envio-yaho/package.json
  • veashi-envio-yaho/schema.graphql
  • veashi-envio-yaho/src/EventHandlers.ts
  • veashi-envio-yaho/test/EventHandlers.test.ts
  • veashi-envio-yaho/tsconfig.json
  • veashi-scanner/README.md
  • veashi-scanner/app/globals.css
  • veashi-scanner/app/layout.tsx
  • veashi-scanner/app/page.tsx
  • veashi-scanner/app/tx/[...params]/page.tsx
  • veashi-scanner/components/BridgeBadge.tsx
  • veashi-scanner/components/BridgeStatusCard.tsx
  • veashi-scanner/components/ChainBadge.tsx
  • veashi-scanner/components/ChainFilterPanel.tsx
  • veashi-scanner/components/Header.tsx
  • veashi-scanner/components/MessagesTable.tsx
  • veashi-scanner/components/Pagination.tsx
  • veashi-scanner/components/SearchBar.tsx
  • veashi-scanner/components/StatusIndicator.tsx
  • veashi-scanner/components/tx/SectionLabel.tsx
  • veashi-scanner/components/tx/TxDetailContent.tsx
  • veashi-scanner/components/tx/cards/AdaptersCard.tsx
  • veashi-scanner/components/tx/cards/AddressCard.tsx
  • veashi-scanner/components/tx/cards/BridgeSummaryCard.tsx
  • veashi-scanner/components/tx/cards/ChainRouteCard.tsx
  • veashi-scanner/components/tx/cards/DetailsCard.tsx
  • veashi-scanner/components/tx/cards/SectionCard.tsx
  • veashi-scanner/components/tx/cards/ThresholdCard.tsx
  • veashi-scanner/components/tx/cards/TxHeaderCard.tsx
  • veashi-scanner/eslint.config.mjs
  • veashi-scanner/hooks/useAdapters.ts
  • veashi-scanner/hooks/useDebounce.ts
  • veashi-scanner/hooks/useExecutionStatus.ts
  • veashi-scanner/hooks/useMessageScanner.ts
  • veashi-scanner/hooks/useTransaction.ts
  • veashi-scanner/lib/chains.ts
  • veashi-scanner/lib/envioClient.ts
  • veashi-scanner/lib/hashi.ts
  • veashi-scanner/lib/mock-data.ts
  • veashi-scanner/lib/scannerCache.ts
  • veashi-scanner/lib/types.ts
  • veashi-scanner/lib/utils.ts
  • veashi-scanner/lib/veashiHelpers.ts
  • veashi-scanner/next-env.d.ts
  • veashi-scanner/next.config.mjs
  • veashi-scanner/package.json
  • veashi-scanner/postcss.config.mjs
  • veashi-scanner/tsconfig.json

Comment thread veashi-scanner/pages/TxPage.tsx
Comment thread veashi-scanner/components/BridgeStatusCard.tsx
Comment thread veashi-scanner/components/MessagesTable.tsx
Comment thread veashi-scanner/components/MessagesTable.tsx
Comment thread veashi-scanner/components/StatusIndicator.tsx
Comment thread veashi-scanner/lib/utils.ts Outdated
Comment thread veashi-scanner/lib/utils.ts Outdated
Comment thread veashi-scanner/lib/veashiHelpers.ts
Comment thread veashi-scanner/package.json Outdated
Comment thread veashi-scanner/README.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
veashi-scanner/pages/TxPage.tsx (1)

13-15: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate parsed chainId before calling TxDetail.

Number(segments[0]) can be NaN. In that case hasChainId is still true, so TxDetail runs with an invalid chainId, and useTransaction exits early without clearing loading state (infinite loading UI).

Suggested change
-  const hasChainId = segments.length >= 2;
-  const chainId = hasChainId ? Number(segments[0]) : null;
+  const hasChainId = segments.length >= 2;
+  const parsedChainId = hasChainId ? Number(segments[0]) : null;
+  const chainId =
+    parsedChainId !== null && Number.isInteger(parsedChainId) && parsedChainId > 0 ? parsedChainId : null;
   const txHash = hasChainId ? segments[1] : segments[0];
@@
-        ) : (
-          <TxDetail chainId={chainId!} txHash={txHash} />
+        ) : chainId === null ? (
+          <NoChainIdCard />
+        ) : (
+          <TxDetail chainId={chainId} txHash={txHash} />
         )}

Also applies to: 50-50

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@veashi-scanner/pages/TxPage.tsx` around lines 13 - 15, The chainId parsing in
TxPage.tsx has a validation issue where Number(segments[0]) can return NaN, but
hasChainId remains true based only on the segments length check. This causes
TxDetail to be called with an invalid chainId (NaN), which makes useTransaction
exit early without clearing the loading state. Fix this by validating that the
parsed chainId is actually a valid number (not NaN) before setting hasChainId to
true. The validation should check both that segments.length >= 2 AND that
Number(segments[0]) is not NaN. Apply this same fix at the second occurrence
around line 50.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@veashi-scanner/globals.css`:
- Line 3: The Tailwind v4 at-rules (`@source`, `@theme`, and `@custom-variant`) used
in globals.css are not recognized by the stylelint-config-standard-scss
configuration, causing linting failures. Configure the stylelint rule for
at-rule-no-unknown by adding an ignoreAtRules array in .stylelintrc.json that
includes the three Tailwind v4 at-rules: `@source`, `@theme`, and `@custom-variant`.
This allows stylelint to skip validation of these vendor-specific at-rules while
maintaining linting for other rules.
- Around line 2-3: Replace the hardcoded ./node_modules/ paths in the `@import`
and `@source` directives with bare package import paths to ensure compatibility
with Yarn workspaces (including PnP linkers) and standard Vite/Node module
resolution. Change the `@import` statement to use the bare path
"`@kleros/ui-components-library/dist/assets/theme.css`" and change the `@source`
directive to use the bare path "`@kleros/ui-components-library`", removing the
./node_modules/ prefix from both lines.

---

Duplicate comments:
In `@veashi-scanner/pages/TxPage.tsx`:
- Around line 13-15: The chainId parsing in TxPage.tsx has a validation issue
where Number(segments[0]) can return NaN, but hasChainId remains true based only
on the segments length check. This causes TxDetail to be called with an invalid
chainId (NaN), which makes useTransaction exit early without clearing the
loading state. Fix this by validating that the parsed chainId is actually a
valid number (not NaN) before setting hasChainId to true. The validation should
check both that segments.length >= 2 AND that Number(segments[0]) is not NaN.
Apply this same fix at the second occurrence around line 50.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f15a5a1e-bebf-4ca5-9987-803f1c082b9e

📥 Commits

Reviewing files that changed from the base of the PR and between d986dc7 and c33a859.

📒 Files selected for processing (22)
  • veashi-scanner/Layout.tsx
  • veashi-scanner/README.md
  • veashi-scanner/components/BridgeStatusCard.tsx
  • veashi-scanner/components/ChainFilterPanel.tsx
  • veashi-scanner/components/Header.tsx
  • veashi-scanner/components/MessagesTable.tsx
  • veashi-scanner/components/Pagination.tsx
  • veashi-scanner/components/SearchBar.tsx
  • veashi-scanner/components/StatusIndicator.tsx
  • veashi-scanner/eslint.config.mjs
  • veashi-scanner/globals.css
  • veashi-scanner/index.html
  • veashi-scanner/lib/envioClient.ts
  • veashi-scanner/main.tsx
  • veashi-scanner/package.json
  • veashi-scanner/pages/Home.tsx
  • veashi-scanner/pages/TxPage.tsx
  • veashi-scanner/tsconfig.app.json
  • veashi-scanner/tsconfig.json
  • veashi-scanner/tsconfig.node.json
  • veashi-scanner/vite-env.d.ts
  • veashi-scanner/vite.config.ts
💤 Files with no reviewable changes (5)
  • veashi-scanner/pages/Home.tsx
  • veashi-scanner/components/StatusIndicator.tsx
  • veashi-scanner/components/BridgeStatusCard.tsx
  • veashi-scanner/components/Pagination.tsx
  • veashi-scanner/components/ChainFilterPanel.tsx
✅ Files skipped from review due to trivial changes (5)
  • veashi-scanner/vite-env.d.ts
  • veashi-scanner/tsconfig.node.json
  • veashi-scanner/tsconfig.app.json
  • veashi-scanner/Layout.tsx
  • veashi-scanner/eslint.config.mjs
🚧 Files skipped from review as they are similar to previous changes (3)
  • veashi-scanner/components/MessagesTable.tsx
  • veashi-scanner/components/SearchBar.tsx
  • veashi-scanner/lib/envioClient.ts

Comment thread veashi-scanner/globals.css Outdated
Comment thread veashi-scanner/globals.css
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
veashi-scanner/lib/veashiHelpers.ts (1)

56-64: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Type assertion is functionally correct but could be more defensive.

The SonarCloud warning is a false positive in this context—the assertion is intentionally widening the type to access runtime properties that the SDK's TypeScript definition omits. However, using in operator checks would be more robust against SDK changes and eliminate the static analysis noise:

Optional improvement
-  // Check DeBridge. The SDK's route type omits these fields even though the
-  // route data includes them, so we access them through a narrow cast.
-  const deBridgeRoute = route as typeof route & { deBridgeAdapter?: string; deBridgeReporter?: string };
-  if (
-    isMatch(adapterAddress, deBridgeRoute.deBridgeAdapter) ||
-    isMatch(reporterAddress, deBridgeRoute.deBridgeReporter)
-  ) {
-    return Bridges.DEBRIDGE;
-  }
+  // Check DeBridge. The SDK's route type omits these fields even though the
+  // route data includes them, so we check for their presence at runtime.
+  const routeRecord = route as Record<string, unknown>;
+  const deBridgeAdapter = typeof routeRecord.deBridgeAdapter === "string" ? routeRecord.deBridgeAdapter : undefined;
+  const deBridgeReporter = typeof routeRecord.deBridgeReporter === "string" ? routeRecord.deBridgeReporter : undefined;
+  if (isMatch(adapterAddress, deBridgeAdapter) || isMatch(reporterAddress, deBridgeReporter)) {
+    return Bridges.DEBRIDGE;
+  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@veashi-scanner/lib/veashiHelpers.ts` around lines 56 - 64, The type assertion
for deBridgeRoute is functionally correct but can be made more defensive.
Instead of using a type assertion to access the deBridgeAdapter and
deBridgeReporter properties, use the `in` operator to check if these properties
actually exist on the route object before accessing them. This approach will be
more robust against SDK changes and will eliminate the static analysis warnings.
Replace the type assertion line and modify the conditional checks to use `in`
operator checks (e.g., 'deBridgeAdapter' in route and 'deBridgeReporter' in
route) before accessing these properties.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@veashi-scanner/lib/utils.ts`:
- Line 57: The hash comparison on line 57 normalizes the input hash but compares
it directly against the potentially unnormalized data.result.hash from the RPC
response. To ensure a proper case-insensitive comparison, normalize
data.result.hash to lowercase before comparing it with normalizedHash.
Additionally, replace the explicit null check with optional chaining syntax
(using the ?. operator) to address the SonarCloud hint and make the code more
concise while maintaining the same null-safety.

---

Nitpick comments:
In `@veashi-scanner/lib/veashiHelpers.ts`:
- Around line 56-64: The type assertion for deBridgeRoute is functionally
correct but can be made more defensive. Instead of using a type assertion to
access the deBridgeAdapter and deBridgeReporter properties, use the `in`
operator to check if these properties actually exist on the route object before
accessing them. This approach will be more robust against SDK changes and will
eliminate the static analysis warnings. Replace the type assertion line and
modify the conditional checks to use `in` operator checks (e.g.,
'deBridgeAdapter' in route and 'deBridgeReporter' in route) before accessing
these properties.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9f567259-0c79-4610-8111-1e0141fa8760

📥 Commits

Reviewing files that changed from the base of the PR and between c33a859 and fb50b65.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (11)
  • package.json
  • veashi-scanner/components/BridgeStatusCard.tsx
  • veashi-scanner/components/MessagesTable.tsx
  • veashi-scanner/components/tx/cards/AdaptersCard.tsx
  • veashi-scanner/components/tx/cards/BridgeSummaryCard.tsx
  • veashi-scanner/globals.css
  • veashi-scanner/hooks/useMessageScanner.ts
  • veashi-scanner/hooks/useTransaction.ts
  • veashi-scanner/lib/envioClient.ts
  • veashi-scanner/lib/utils.ts
  • veashi-scanner/lib/veashiHelpers.ts
✅ Files skipped from review due to trivial changes (1)
  • package.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • veashi-scanner/components/MessagesTable.tsx
  • veashi-scanner/components/tx/cards/AdaptersCard.tsx
  • veashi-scanner/components/BridgeStatusCard.tsx
  • veashi-scanner/hooks/useTransaction.ts
  • veashi-scanner/globals.css

Comment thread veashi-scanner/lib/utils.ts Outdated
@mani99brar mani99brar marked this pull request as ready for review June 29, 2026 07:11
@mani99brar mani99brar requested a review from jaybuidl as a code owner June 29, 2026 07:11
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@sonarqubecloud

sonarqubecloud Bot commented Jul 1, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant