Skip to content

feat(playground): VeKit Playground revamp · AI-first DX · CloudFront deploy#628

Merged
Agilulfo1820 merged 5 commits into
mainfrom
refactor/playground-revamp
May 21, 2026
Merged

feat(playground): VeKit Playground revamp · AI-first DX · CloudFront deploy#628
Agilulfo1820 merged 5 commits into
mainfrom
refactor/playground-revamp

Conversation

@Agilulfo1820

@Agilulfo1820 Agilulfo1820 commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Rebuild the playground (examples/playground/) as VeKit Playground: dashboard layout with a sidebar of 11 categorised routes (Getting Started, AI Skills, Connect & Auth, Identity, Smart Account, Transactions, Signing, Reading Data, Modals, Theming & i18n, Resources), a topbar with wallet + language + theme controls, and a redesigned hero on Getting Started.
  • AI-first DX: every demo section pairs a live preview with two copyable artifacts — the code snippet and a ready-made prompt for Claude Code / Cursor / any agent. The AIPromptBlock automatically prepends a "read these skills first" preamble with clickable links to the relevant skill on vechain/vechain-ai-skills.
  • New /ai-skills route ports the homepage AISkillsSection into the playground (11 VeChain AI skills, two install commands for CLI and Claude Code, prompt example).
  • /getting-started install section is now two AI prompts: "Start a new VeChain dApp" (primary, via create-vechain-dapp) and "Or: add VeChain Kit to an existing project" (secondary, with the install snippet preserved for manual setup). Both prompts recommend Chakra UI v3 + next-themes so devs target the modern stack.
  • Adds /ai-skills and a VeChain AI Skills resource card to /resources.
  • Rebrands to "VeKit Playground" in the sidebar, footer and metadata (title / description / OG / Twitter).
  • Deployment: two new GitHub Actions workflows:
    • deploy-playground-cloudfront.yaml — push to main whenever examples/playground/**, packages/vechain-kit/** or yarn.lock change. Deploys examples/playground/dist to the production CloudFront for playground.vechainkit.vechain.org.
    • deploy-playground-preview.yaml — per-PR previews under preview.vechainkit.vechain.org/<branch>/playground (reuses the existing preview bucket + CloudFront, no new infra). Mirrors the homepage preview gate (safe-to-deploy label for external PRs).
  • Documents the infra layout (vechain-kit-infra + vechain.org-domains) in the root README so the deploy chain is discoverable.

Infra pairing

Pairs with vechain/vechain-kit-infra#24, which provisions S3 + CloudFront + ACM + Route53 for playground.vechainkit.vechain.org.

Before the production workflow can run successfully:

  1. Merge vechain-kit-infra#24 and run terraform apply.
  2. Extend AWS_ACC_ROLE IAM policy to cover the new bucket (s3:PutObject, s3:DeleteObject, s3:ListBucket) and distribution (cloudfront:CreateInvalidation).
  3. Add two repo secrets:
    • AWS_PLAYGROUND_BUCKET_NAME = playground_bucket_name output
    • AWS_PLAYGROUND_CLOUDFRONT_DISTRIBUTION_ID = playground_cloudfront_distribution_id output

The preview workflow needs no new infra or secrets — it reuses AWS_PREVIEW_BUCKET_NAME + AWS_PREVIEW_CLOUDFRONT_DISTRIBUTION_ID already used by the homepage preview workflow.

Stack notes

  • Playground stays on Chakra UI v2 (the kit's component library is v2 too). AI prompts recommend Chakra UI v3 + next-themes for new dApps so consumers target the modern stack; the examples/next-chakra-v3 reference shows how to wire the kit's theme prop via useChakraContext().token.var(...) to keep tokens reactive.
  • New dependency: prism-react-renderer (~25 KB) for syntax-highlighted code blocks.
  • 250+ new i18n keys added across all 7 playground locales (en/de/es/fr/it/ja/zh) with English fallback for non-en; yarn translate at release time will fill the gaps.
  • Removed: 12-card FeaturesToTry, LoginUIControl, LanguageSelector, ThemeToggle, single-page Home.tsx, and the duplicate "Profile" card.

Test plan

  • yarn install:all && yarn build succeeds; examples/playground/dist/ contains an HTML file per route.
  • yarn dev (in examples/playground/) — open every sidebar route, confirm Live demo / View code / AI prompt tabs render, copy buttons toast.
  • Light/dark toggle + language switch — kit modals re-skin in sync.
  • Connect with VeWorld and with a Privy social login — Identity, Smart Account, Transactions and Signing pages all populate.
  • Send a B3TR test tx via Toast and Modal flows; sign a personal message and an EIP-712 typed payload.
  • Preview workflow on this PR posts a sticky comment with the preview URL; opening it shows the playground at the basePath.
  • After infra prerequisites land, push to main triggers Deploy Playground to Cloudfront; https://playground.vechainkit.vechain.org loads the playground.

🤖 Generated with Claude Code

Agilulfo1820 and others added 4 commits May 20, 2026 17:21
…ippets

Replace the single-page playground with a developer-first dashboard:
sidebar with 10 categorized routes, per-section live demos paired with
copy-able code snippets, hook badges that link to docs, and a status
badge system. Drops duplicate cards, deletes ~9 legacy components,
adds i18n coverage for 139 new strings across 7 languages, and fixes
the body centering / transparency issues exposed by the new layout.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Add a dedicated /ai-skills route (sourced from homepage) that lists
the 11 VeChain AI skills with copy-able install commands for the
Skills CLI and Claude Code plugin.

Extend DemoSection with an "AI prompt" tab. AIPromptBlock auto-
prepends a "read these skills first" preamble with clickable GitHub
URLs based on the section's required skills, so copy-paste into
Claude / Cursor / any agent gives them domain context up-front.

Restructure /getting-started install section into two AI prompts:
"Start a new VeChain dApp" (primary, via create-vechain-dapp) and
"Add to existing project" (secondary, with the install snippet
preserved for manual setup). Recommend Chakra UI v3 + next-themes
in scaffolding prompts to point devs at the modern stack.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Adopt the homepage logo treatment in the sidebar (native height={8},
no rounded box), rename the brand to "VeKit Playground" in the
sidebar heading and footer, and refresh title/description/OG/Twitter
metadata around the AI-first positioning.

Add VeChain AI Skills as the first card in the Resources page, with
a direct link to github.com/vechain/vechain-ai-skills.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Add deploy-playground-cloudfront.yaml: triggers on push to main when
examples/playground/** or packages/vechain-kit/** change, builds the
playground (yarn install:all && yarn build), syncs the static export to
the new S3 bucket and invalidates CloudFront. Mirrors the pattern of
deploy-cloudfront.yaml (homepage).

Document the infrastructure layout (vechain-kit-infra + vechain.org-domains)
in the root README so the deploy chain is discoverable.

Pairs with vechain/vechain-kit-infra#24, which provisions the bucket and
CloudFront distribution for playground.vechainkit.vechain.org.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR comprehensively redesigns the VeChain Kit playground from a simple home-page layout into a multi-page demo showcase with a reusable component library and improved navigation. It adds a CloudFront deployment workflow, introduces a demo component architecture (CodeBlock, DemoSection, AIPromptBlock), creates ten playground pages demonstrating kit features, refactors feature components, establishes a new layout system, and expands internationalization across six languages.

Changes

Deployment & Infrastructure

Layer / File(s) Summary
CloudFront deployment automation
.github/workflows/deploy-playground-cloudfront.yaml, README.md
New GitHub Actions workflow builds the playground, fixes dist permissions, configures AWS credentials, syncs to S3, and invalidates CloudFront; README documents the infrastructure setup (Terraform in separate repo, GitHub Actions triggers).

Demo Component Library & Dependencies

Layer / File(s) Summary
Code and prompt display components
examples/playground/package.json, examples/playground/src/app/components/demo/CodeBlock.tsx, examples/playground/src/app/components/demo/AIPromptBlock.tsx
Adds prism-react-renderer dependency; CodeBlock highlights code with line numbers and copy action; AIPromptBlock formats prompts with optional skill preamble, copy-to-clipboard, and tip footer.
Demo section and badge components
examples/playground/src/app/components/demo/DemoSection.tsx, examples/playground/src/app/components/demo/StatusBadge.tsx, examples/playground/src/app/components/demo/HookBadge.tsx, examples/playground/src/app/components/demo/ConnectGate.tsx, examples/playground/src/app/components/demo/CopyAddress.tsx
DemoSection wraps content in optional tabs (Live demo / View code / AI prompt); StatusBadge and HookBadge label features; ConnectGate gates content behind wallet connection; CopyAddress displays and copies addresses with i18n toasts.
Hero, install, and utility components
examples/playground/src/app/components/demo/Hero.tsx, examples/playground/src/app/components/demo/InstallSnippet.tsx, examples/playground/src/app/components/demo/index.ts
Hero renders gradient banner with wallet CTA and docs links; InstallSnippet tabs npm/yarn/pnpm install commands; demo/index barrel consolidates nine components and Status type.

Navigation & Layout System

Layer / File(s) Summary
Navigation configuration and routes
examples/playground/src/app/components/layout/navItems.ts
NavItems defines NAV_GROUPS with route metadata, icons from lucide, and optional status badges for grouping and rendering sidebar navigation.
Sidebar, TopBar, and responsive navigation
examples/playground/src/app/components/layout/Sidebar.tsx, examples/playground/src/app/components/layout/NavItem.tsx, examples/playground/src/app/components/layout/MobileNav.tsx, examples/playground/src/app/components/layout/TopBar.tsx
Sidebar iterates NAV_GROUPS and renders NavItems; NavItem shows active state and optional status badge; MobileNav wraps sidebar in responsive drawer; TopBar provides sticky header with wallet button, language dropdown, theme toggle, and mobile menu trigger.
Playground route layout wrapper
examples/playground/src/app/(playground)/layout.tsx
PlaygroundLayout renders responsive flex structure with Sidebar (medium+ screens), TopBar, and centered children container with color-mode background.

Playground Demo Pages

Layer / File(s) Summary
Getting started, resources, and AI skills
examples/playground/src/app/(playground)/getting-started/page.tsx, examples/playground/src/app/(playground)/resources/page.tsx, examples/playground/src/app/(playground)/ai-skills/page.tsx
GettingStartedPage introduces playground with feature tiles and VeChainKitProvider setup snippet; ResourcesPage lists external documentation links; AISkillsPage demonstrates AI skills with CLI commands, skill cards, and prompt example.
Connect and identity pages
examples/playground/src/app/(playground)/connect/page.tsx, examples/playground/src/app/(playground)/identity/page.tsx
ConnectPage showcases WalletButton variants and OAuth provider grids; IdentityPage displays account details (address, smart account, domain) and connection source within ConnectGate.
Data reading page
examples/playground/src/app/(playground)/data/page.tsx
DataPage reads and displays B3TR/VOT3 balances, token prices, and VeBetterDAO allocations/passport status via vechain-kit hooks with loading skeletons.
Signing, transactions, theming, smart account, and modals
examples/playground/src/app/(playground)/signing/page.tsx, examples/playground/src/app/(playground)/transactions/page.tsx, examples/playground/src/app/(playground)/theming/page.tsx, examples/playground/src/app/(playground)/smart-account/page.tsx, examples/playground/src/app/(playground)/modals/page.tsx
SigningPage demos useSignMessage and useSignTypedData with signature display; TransactionsPage builds and sends dummy transactions via toast/modal with status panel; ThemingPage toggles color mode and language; SmartAccountPage explains smart accounts and upgrade flow; ModalsPage catalogs available modals.
Root page and app layout metadata
examples/playground/src/app/page.tsx, examples/playground/src/app/layout.tsx
Index page redirects to /getting-started; root layout rebrands to "VeKit Playground · AI-first VeChain dApp toolkit" with updated Open Graph and Twitter metadata.

Feature Components & Modals

Layer / File(s) Summary
Identity and connection info display
examples/playground/src/app/components/features/Identity/IdentityPanel.tsx, examples/playground/src/app/components/features/ConnectionInfo/ConnectionInfo.tsx, examples/playground/src/app/components/features/AccountInfo/AccountInfo.tsx
IdentityPanel renders wallet address, smart account status, and domain via reusable InfoBlock helper with color-mode styling; ConnectionInfo displays source/network tags with i18n; AccountInfo refactored to show IdentityPanel and message.
Wallet and OAuth connection options
examples/playground/src/app/components/features/Connect/WalletButtonVariants.tsx, examples/playground/src/app/components/features/Connect/OAuthGrid.tsx, examples/playground/src/app/components/features/Connect/index.ts
WalletButtonVariants showcases modal/popover button variants and manual modal triggers; OAuthGrid renders provider buttons with icons; Connect index exports both components.
Modal launcher cards and catalog
examples/playground/src/app/components/features/ModalCatalog/ModalCard.tsx, examples/playground/src/app/components/features/ModalCatalog/ModalCatalog.tsx, examples/playground/src/app/components/features/ModalCatalog/index.ts
ModalCard renders clickable card with icon, title, hook badge, and keyboard support; ModalCatalog refactored to grid of modal-launch cards with consolidated hook wiring, replacing prior feature-card UI.
Signing and transaction result display
examples/playground/src/app/components/features/Signing/SignatureOutput.tsx, examples/playground/src/app/components/features/Transactions/TxResultPanel.tsx
SignatureOutput displays signature with copy button and toasts; TxResultPanel shows transaction status, ID with explorer link, gas, and error/retry handling.
Resource links and smart account info
examples/playground/src/app/components/features/Resources/ResourceList.tsx, examples/playground/src/app/components/features/SmartAccountInfo/SmartAccountInfo.tsx
ResourceList renders grid of external resource cards with icons and hover effects; SmartAccountInfo refactored to display three perks (explain, quick access, secure) with dynamic i18n and color-mode styling.
Login prompt and connection gating
examples/playground/src/app/components/features/LoginToContinueBox/LoginToContinueBox.tsx
LoginToContinueBox refactored to accept optional title/description/ctaLabel props with i18n fallbacks and responsive color-mode border/background styling.
VeBetterDAO info display
examples/playground/src/app/components/features/DaoInfo/DaoInfo.tsx
DaoInfo simplified to display current allocations round and passport validity via Tags with i18n and color-mode styling using DataRow helper.
Deprecated and removed feature components
Removed: DataReadingExample.tsx, LanguageSelector.tsx, LoginUIControl.tsx, FeatureCard.tsx, GithubCard.tsx, ThemeCard.tsx, LanguageCard.tsx, ThemeToggle.tsx, SigningExample.tsx, TransactionExamples.tsx; corresponding index barrel exports cleaned up
Old feature components removed; feature UI now integrated into demo pages using DemoSection and ConnectGate patterns.

Internationalization & Configuration

Layer / File(s) Summary
Multilingual playground catalog expansion
examples/playground/src/app/languages/de.json, examples/playground/src/app/languages/en.json, examples/playground/src/app/languages/es.json, examples/playground/src/app/languages/fr.json, examples/playground/src/app/languages/it.json, examples/playground/src/app/languages/ja.json, examples/playground/src/app/languages/zh.json
All locale files expanded from ~100 keys to ~400+ keys covering playground UI, onboarding prompts, feature descriptions, modal labels, AI prompts, and transaction examples; non-English locales use English values for new keys pending translation.
Global styling and build configuration
examples/playground/src/app/globals.css, examples/playground/tsconfig.json
globals.css updates background colors (#f7fafc light, #0c0c10 dark) and ensures full viewport height; tsconfig includes dist/dev and .next/dev type directories.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Suggested reviewers

  • victorkl400
  • mikeredmond

🐰 A playground transformed, so bright and new,
With pages for each skill and feature to brew,
Demo components stack like carrots in rows,
While modals and wallets and themes gently flow,
In languages many, from east unto west,
VeKit shines forth—a toolkit that's blessed! 🌟

✨ 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 refactor/playground-revamp

runs-on: ubuntu-latest
env:
NEXT_PUBLIC_BASE_PATH: ''
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment

env:
NEXT_PUBLIC_BASE_PATH: ''
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}
NEXT_PUBLIC_PRIVY_APP_ID: ${{ secrets.NEXT_PUBLIC_PRIVY_APP_ID }}

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment

NEXT_PUBLIC_BASE_PATH: ''
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}
NEXT_PUBLIC_PRIVY_APP_ID: ${{ secrets.NEXT_PUBLIC_PRIVY_APP_ID }}
NEXT_PUBLIC_PRIVY_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_PRIVY_CLIENT_ID }}

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment

NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}
NEXT_PUBLIC_PRIVY_APP_ID: ${{ secrets.NEXT_PUBLIC_PRIVY_APP_ID }}
NEXT_PUBLIC_PRIVY_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_PRIVY_CLIENT_ID }}
NEXT_PUBLIC_DELEGATOR_URL: ${{ secrets.NEXT_PUBLIC_DELEGATOR_URL }}

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4
with:
role-to-assume: ${{ secrets.AWS_ACC_ROLE }}

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment


- name: Deploy to S3
run: |
aws s3 sync ./examples/playground/dist s3://${{ secrets.AWS_PLAYGROUND_BUCKET_NAME }} --delete

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment


- name: Cloudfront Invalidation
run: |
AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_PLAYGROUND_CLOUDFRONT_DISTRIBUTION_ID }} --paths '/' '/*'

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment

@github-actions

github-actions Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 8.84 MB

ℹ️ View Unchanged
Filename Size
packages/vechain-kit/dist/assets 4.1 kB
packages/vechain-kit/dist/assets-C0RHiZ9a.mjs 51.4 kB
packages/vechain-kit/dist/assets-C0RHiZ9a.mjs.map 74.6 kB
packages/vechain-kit/dist/assets-CZs6EVH8.cjs 58.9 kB
packages/vechain-kit/dist/assets-CZs6EVH8.cjs.map 76.1 kB
packages/vechain-kit/dist/assets/index.cjs 716 B
packages/vechain-kit/dist/assets/index.d.cts 973 B
packages/vechain-kit/dist/assets/index.d.mts 973 B
packages/vechain-kit/dist/assets/index.mjs 718 B
packages/vechain-kit/dist/index-BJKHmsrV.d.mts 185 kB
packages/vechain-kit/dist/index-BJKHmsrV.d.mts.map 49.2 kB
packages/vechain-kit/dist/index-BvuXDx6d.d.mts 5.63 kB
packages/vechain-kit/dist/index-BvuXDx6d.d.mts.map 2.99 kB
packages/vechain-kit/dist/index-BwgdGqoi.d.cts 185 kB
packages/vechain-kit/dist/index-BwgdGqoi.d.cts.map 50.3 kB
packages/vechain-kit/dist/index-C8Uj8ple.d.cts 5.63 kB
packages/vechain-kit/dist/index-C8Uj8ple.d.cts.map 2.99 kB
packages/vechain-kit/dist/index.cjs 1.14 MB
packages/vechain-kit/dist/index.cjs.map 2.83 MB
packages/vechain-kit/dist/index.d.cts 24.5 kB
packages/vechain-kit/dist/index.d.mts 24.5 kB
packages/vechain-kit/dist/index.mjs 1.1 MB
packages/vechain-kit/dist/index.mjs.map 2.77 MB
packages/vechain-kit/dist/utils 4.1 kB
packages/vechain-kit/dist/utils-C4gc1L9t.cjs 27.4 kB
packages/vechain-kit/dist/utils-C4gc1L9t.cjs.map 68.2 kB
packages/vechain-kit/dist/utils-DPIscp9_.mjs 22.2 kB
packages/vechain-kit/dist/utils-DPIscp9_.mjs.map 67.5 kB
packages/vechain-kit/dist/utils/index.cjs 2.02 kB
packages/vechain-kit/dist/utils/index.d.cts 3.1 kB
packages/vechain-kit/dist/utils/index.d.mts 3.1 kB
packages/vechain-kit/dist/utils/index.mjs 2.04 kB

compressed-size-action

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 13

🧹 Nitpick comments (30)
.github/workflows/deploy-playground-cloudfront.yaml (1)

22-27: ⚡ Quick win

Add a job timeout to prevent stuck deploy runners.

Set an explicit timeout for build-and-deploy so hung installs/builds/invalidation don’t consume runners indefinitely.

⏱️ Proposed change
 jobs:
     build-and-deploy:
+        timeout-minutes: 30
         permissions:
             contents: read
             id-token: write
🤖 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 @.github/workflows/deploy-playground-cloudfront.yaml around lines 22 - 27,
The build-and-deploy job currently has no timeout and can hang indefinitely; add
a GitHub Actions job-level timeout by setting timeout-minutes under the
build-and-deploy job definition (e.g., add "timeout-minutes: 30" or an
appropriate value) so that the build-and-deploy job will be cancelled after the
specified minutes; update the job block containing build-and-deploy,
permissions, runs-on, and env to include the timeout-minutes key.
examples/playground/src/app/components/features/Signing/index.ts (1)

1-1: ⚡ Quick win

Use a path-alias re-export instead of a relative path.

Line 1 should follow the repo alias convention for src imports.

♻️ Suggested change
-export { SignatureOutput } from './SignatureOutput';
+export { SignatureOutput } from '`@/app/components/features/Signing/SignatureOutput`';

As per coding guidelines, "Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils".

🤖 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 `@examples/playground/src/app/components/features/Signing/index.ts` at line 1,
The export uses a relative path; replace it with the repo path-alias form.
Update the export in Signing/index.ts to re-export SignatureOutput via the
components alias (e.g., export { SignatureOutput } from
'`@components/features/Signing/SignatureOutput`') so it follows the '`@/`
/@components' import convention used across the repo and helps resolve imports
consistently.
examples/playground/src/app/components/features/Transactions/TxResultPanel.tsx (1)

15-15: ⚡ Quick win

Switch internal import to a src alias path.

Line 15 uses a relative import; align with the repo alias convention.

♻️ Suggested change
-import { CopyAddress } from '../../demo/CopyAddress';
+import { CopyAddress } from '`@/app/components/demo/CopyAddress`';

As per coding guidelines, "Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils".

🤖 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
`@examples/playground/src/app/components/features/Transactions/TxResultPanel.tsx`
at line 15, Replace the relative import for CopyAddress in TxResultPanel.tsx
with the repo path-alias version; change the import from
'../../demo/CopyAddress' to the `@components` alias (e.g.
'`@components/demo/CopyAddress`' or the appropriate '`@components/CopyAddress`'
location) so it follows the project convention and resolves via the src path
alias.
examples/playground/src/app/globals.css (1)

5-5: ⚡ Quick win

Use viewport-relative min-height for reliable full-screen layout.

min-height: 100% depends on ancestor sizing and can miss full viewport height in some rendering contexts. Prefer a viewport-based value here.

♻️ Proposed change
 html,
 body {
   margin: 0;
   width: 100%;
-  min-height: 100%;
+  min-height: 100vh;
+  min-height: 100dvh;
 }
🤖 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 `@examples/playground/src/app/globals.css` at line 5, The CSS rule currently
uses "min-height: 100%;" which relies on ancestor heights and can fail to fill
the viewport; update the rule that contains the min-height property in
globals.css to use a viewport-relative value (e.g., "min-height: 100vh" or the
newer "100dvh" for mobile viewport correctness) so the element reliably spans
full screen across rendering contexts.
examples/playground/src/app/components/layout/navItems.ts (1)

15-15: ⚡ Quick win

Use path alias imports in src files.

Replace the relative import with the configured alias form to keep import style consistent across the app.

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/components/layout/navItems.ts` at line 15,
Replace the relative import of the Status type in navItems.ts with the project
path-alias form; specifically update the import for Status (currently "import
type { Status } from '../demo/StatusBadge'") to use the configured components
alias (e.g., import from '`@components/demo/StatusBadge`') so imports in the src
tree follow the `@/`* and `@components` alias convention.
examples/playground/src/app/layout.tsx (1)

6-11: ⚡ Quick win

Migrate root layout imports to path aliases.

Use the configured aliases for these src imports (including the dynamic import path).

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/layout.tsx` around lines 6 - 11, The imports in
the root layout use relative src paths instead of the project's path aliases;
change the import of darkTheme and the dynamic import for
VechainKitProviderWrapper to use the configured aliases (e.g., import darkTheme
from '`@/theme`' and dynamic(() =>
import('`@/providers/VechainKitProviderWrapper`').then(m =>
m.VechainKitProviderWrapper))) so that darkTheme and VechainKitProviderWrapper
use the `@/` prefix consistent with the project's alias rules.
examples/playground/src/app/components/layout/NavItem.tsx (1)

8-8: ⚡ Quick win

Use path alias import for StatusBadge.

This import should follow the project alias convention.

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/components/layout/NavItem.tsx` at line 8, Replace
the relative import of StatusBadge in NavItem.tsx with the project path-alias
import; update the import statement that currently references
'../demo/StatusBadge' to use the `@components` alias (e.g. import { StatusBadge,
type Status } from '`@components/demo/StatusBadge`') so it follows the project's
alias convention for components.
examples/playground/src/app/page.tsx (1)

1-13: ⚡ Quick win

Prefer server redirect instead of client useEffect redirect.

This avoids a client-side blank frame and navigates immediately from the server in App Router.

Proposed fix
-'use client';
-
-import { useEffect } from 'react';
-import { useRouter } from 'next/navigation';
+import { redirect } from 'next/navigation';

 export default function Page() {
-    const router = useRouter();
-
-    useEffect(() => {
-        router.replace('/getting-started');
-    }, [router]);
-
-    return null;
+    redirect('/getting-started');
 }
🤖 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 `@examples/playground/src/app/page.tsx` around lines 1 - 13, Current
client-side redirect uses useEffect and useRouter in the Page component causing
a blank client frame; change to a server-side redirect by removing the 'use
client' directive and the useEffect/useRouter usage, import redirect from
'next/navigation', and call redirect('/getting-started') directly from the Page
server component (e.g., in the default exported Page function) so navigation
happens on the server without rendering a blank client page.
examples/playground/src/app/components/layout/TopBar.tsx (1)

14-15: ⚡ Quick win

Switch layout imports to alias paths.

Please replace these relative imports with the project alias convention.

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/components/layout/TopBar.tsx` around lines 14 -
15, Replace the relative imports in TopBar.tsx by using the project path
aliases: change the import of LanguageDropdown from './Header' to the components
alias (e.g., import { LanguageDropdown } from '`@components/Header`') and change
MobileNav from './MobileNav' to the components alias (e.g., import { MobileNav }
from '`@components/MobileNav`'); update any export names if needed to match those
symbols so LanguageDropdown and MobileNav resolve via the '`@components`' alias
per the project convention.
examples/playground/src/app/components/layout/Sidebar.tsx (1)

13-14: ⚡ Quick win

Convert local layout imports to aliases.

Use @/... aliases instead of relative imports here.

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/components/layout/Sidebar.tsx` around lines 13 -
14, Summary: Change relative imports in Sidebar.tsx to use project path aliases.
Update the two imports that currently use './NavItem' and './navItems' to their
aliased module paths (use `@components` for component files or `@/` for src-root if
preferred); e.g., import NavItem from '`@components/layout/NavItem`' and import {
NAV_GROUPS } from '`@components/layout/navItems`' (or use
'`@/components/layout/`...' if your alias is configured that way). Ensure the
import specifiers match the exported symbols NavItem and NAV_GROUPS and that
your tsconfig/webpack alias mapping supports the chosen aliases.
examples/playground/src/app/components/layout/MobileNav.tsx (1)

12-12: ⚡ Quick win

Use alias import for Sidebar.

Please switch this relative import to the configured alias style.

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/components/layout/MobileNav.tsx` at line 12, The
import of Sidebar in MobileNav.tsx uses a relative path; change it to use the
configured alias for components by replacing the relative import with the alias
import (e.g. import { Sidebar } from '`@components/layout/Sidebar`') so it follows
the project rule to use `@components` for component imports and matches the src
alias configuration.
examples/playground/src/app/(playground)/layout.tsx (1)

5-6: ⚡ Quick win

Use alias imports in playground layout.

These imports should use @/... aliases for consistency with repo standards.

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/`(playground)/layout.tsx around lines 5 - 6,
Replace the relative imports in layout.tsx with the project's path aliases so
they follow the coding guidelines: change the imports for the Sidebar and TopBar
components (symbols Sidebar and TopBar) from '../components/layout/Sidebar' and
'../components/layout/TopBar' to use the `@components` alias (e.g.
'`@components/layout/Sidebar`' and '`@components/layout/TopBar`'), ensuring other
imports in the file follow the same alias convention.
examples/playground/src/app/components/features/ModalCatalog/ModalCard.tsx (1)

13-13: ⚡ Quick win

Use path alias import instead of relative traversal.

Switch this import to @/* alias to match repository import conventions.

Proposed diff
-import { HookBadge } from '../../demo/HookBadge';
+import { HookBadge } from '`@/app/components/demo/HookBadge`';
As per coding guidelines, "`**/src/**/*.{ts,tsx}`: Use path aliases for imports: `@/*` for src root, `@hooks` for hooks, `@components` for components, `@utils` for utils".
🤖 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 `@examples/playground/src/app/components/features/ModalCatalog/ModalCard.tsx`
at line 13, Replace the relative import of HookBadge in ModalCard.tsx with the
repository path alias; locate the import statement that references HookBadge
(import { HookBadge } from '../../demo/HookBadge';) and change it to use the src
root alias (e.g., import { HookBadge } from '`@/components/demo/HookBadge`' or the
appropriate `@components/`@hooks alias per project conventions) so it follows the
project's "`@/src`" path-alias rules.
examples/playground/src/app/components/features/ModalCatalog/ModalCatalog.tsx (2)

31-31: ⚡ Quick win

Prefer path alias import here as well.

Use the @/* alias instead of a relative path.

Proposed diff
-import { ModalCard } from './ModalCard';
+import { ModalCard } from '`@/app/components/features/ModalCatalog/ModalCard`';
As per coding guidelines, "`**/src/**/*.{ts,tsx}`: Use path aliases for imports: `@/*` for src root, `@hooks` for hooks, `@components` for components, `@utils` for utils".
🤖 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
`@examples/playground/src/app/components/features/ModalCatalog/ModalCatalog.tsx`
at line 31, In ModalCatalog.tsx replace the relative import of ModalCard (import
{ ModalCard } from './ModalCard') with the project path-alias import (use the @
alias), e.g. import { ModalCard } from '`@components/`...ModalCard'; update the
import to match the repo's `@/`* alias convention and ensure any related imports
in ModalCatalog.tsx follow the same `@components/`@hooks/@utils aliasing style.

145-146: ⚡ Quick win

Use a stable non-localized key for card items.

key={c.title} can change with translations and risks collisions; use a stable identifier like hook.

Proposed diff
-            {cards.map((c) => (
-                <ModalCard key={c.title} {...c} />
+            {cards.map((c) => (
+                <ModalCard key={c.hook ?? c.title} {...c} />
             ))}
🤖 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
`@examples/playground/src/app/components/features/ModalCatalog/ModalCatalog.tsx`
around lines 145 - 146, The list rendering uses a localized and unstable key
(key={c.title}) which can change with translations and cause collisions; update
the cards.map usage to pass a stable, non-localized identifier such as c.hook as
the React key when rendering <ModalCard> (i.e., replace the key reference in the
ModalCard instantiation so it uses the unique hook property instead of title).
examples/playground/src/app/components/demo/DemoSection.tsx (1)

22-26: ⚡ Quick win

Use configured path aliases for internal imports.

Please replace relative imports in this file with the project aliases (@/*, @components, etc.) for consistency and maintainability.

As per coding guidelines, "**/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils".

🤖 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 `@examples/playground/src/app/components/demo/DemoSection.tsx` around lines 22
- 26, The imports in DemoSection.tsx use relative paths; update them to the
project's path aliases (e.g., `@components` or `@/`* as appropriate) so internal
imports follow the conventions. Replace the current imports for CodeBlock,
HookBadge, Status, StatusBadge and AIPromptBlock to their aliased module paths
(using `@components` or the src root alias) and ensure any tsconfig/webpack alias
mappings are respected so the named symbols (CodeBlock, HookBadge, Status,
StatusBadge, AIPromptBlock) resolve via the configured aliases.
examples/playground/src/app/components/demo/ConnectGate.tsx (1)

5-5: ⚡ Quick win

Switch internal import to project path alias.

Use the configured alias instead of a relative parent traversal import.

As per coding guidelines, "**/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils".

🤖 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 `@examples/playground/src/app/components/demo/ConnectGate.tsx` at line 5, The
import in ConnectGate.tsx uses a relative parent path; change it to the project
path alias per guidelines by replacing the import of LoginToContinueBox from
'../features/LoginToContinueBox' with the alias-based path (e.g., import {
LoginToContinueBox } from '`@components/features/LoginToContinueBox`' or the
appropriate '`@components/`...' location where LoginToContinueBox lives) so it
uses the configured '`@/src`' and '`@components`' aliases instead of a relative
traversal.
examples/playground/src/app/components/features/AccountInfo/AccountInfo.tsx (1)

4-4: ⚡ Quick win

Use path alias import for IdentityPanel.

Switch this relative import to the configured src alias.

Suggested change
-import { IdentityPanel } from '../Identity/IdentityPanel';
+import { IdentityPanel } from '`@/app/components/features/Identity/IdentityPanel`';

As per coding guidelines, **/src/**/*.{ts,tsx}: "Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils".

🤖 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 `@examples/playground/src/app/components/features/AccountInfo/AccountInfo.tsx`
at line 4, Replace the relative import of IdentityPanel with the project path
alias: change the import of IdentityPanel (currently "import { IdentityPanel }
from '../Identity/IdentityPanel'") to the alias-based import using the
configured components alias (e.g. "import { IdentityPanel } from
'`@components/Identity/IdentityPanel`'") so it follows the src alias rule and
coding guidelines.
examples/playground/src/app/components/features/Identity/IdentityPanel.tsx (1)

15-15: ⚡ Quick win

Use path alias import for CopyAddress.

Please replace the relative path with the configured src alias to keep imports stable during refactors.

Suggested change
-import { CopyAddress } from '../../demo/CopyAddress';
+import { CopyAddress } from '`@/app/components/demo/CopyAddress`';

As per coding guidelines, **/src/**/*.{ts,tsx}: "Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils".

🤖 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 `@examples/playground/src/app/components/features/Identity/IdentityPanel.tsx`
at line 15, Replace the relative import for the CopyAddress component with the
configured path alias; in IdentityPanel.tsx update the import of CopyAddress
(currently from '../../demo/CopyAddress') to use the project alias (e.g.
'`@components/demo/CopyAddress`' or '`@/app/components/demo/CopyAddress`' depending
on your alias mapping) so imports remain stable during refactors.
examples/playground/src/app/(playground)/identity/page.tsx (1)

5-8: ⚡ Quick win

Use path aliases for local module imports.

Line 5–8 should be converted from relative ../../... imports to @/....

As per coding guidelines, "/src//*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils**".

🤖 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 `@examples/playground/src/app/`(playground)/identity/page.tsx around lines 5 -
8, The four relative imports in page.tsx (DemoSection, ConnectGate,
IdentityPanel, ConnectionInfo) should use path aliases instead of ../../; update
the import statements to use the configured aliases (e.g., `@components/`...) so
they resolve from the src root per project convention, ensuring the symbols
DemoSection, ConnectGate, IdentityPanel and ConnectionInfo are imported via
their `@components` paths and not relative paths.
examples/playground/src/app/(playground)/connect/page.tsx (1)

5-9: ⚡ Quick win

Switch local imports to src aliases.

Line 5–9 should use @/... imports instead of ../../....

As per coding guidelines, "/src//*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils**".

🤖 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 `@examples/playground/src/app/`(playground)/connect/page.tsx around lines 5 -
9, Replace the relative imports in page.tsx with the project path aliases:
import DemoSection from '`@/components/demo/DemoSection`' (referencing
DemoSection) and import WalletButtonVariants and OAuthGrid from
'`@/components/features/Connect`' (referencing WalletButtonVariants and
OAuthGrid); update the import statements in
examples/playground/src/app/(playground)/connect/page.tsx to use these `@/`...
aliases so they follow the codebase guideline for src aliases.
examples/playground/src/app/(playground)/resources/page.tsx (1)

5-5: ⚡ Quick win

Prefer alias import for ResourceList.

Line 5 should use @/... instead of relative traversal to align with the src import convention.

As per coding guidelines, "/src//*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils**".

🤖 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 `@examples/playground/src/app/`(playground)/resources/page.tsx at line 5, The
import for ResourceList uses a relative path; change it to the project
path-alias form so it follows the src conventions—replace the existing relative
import with the alias-based import that references the ResourceList component
(e.g., import ResourceList from the `@components/`... location) ensuring the
symbol ResourceList and the module path match the project's alias configuration.
examples/playground/src/app/(playground)/getting-started/page.tsx (1)

25-29: ⚡ Quick win

Use path aliases for local imports in this page.

Line 25–29 currently traverse with ../../...; switch these to @/... aliases for consistency with the src import policy.

Proposed fix
-import { Hero } from '../../components/demo/Hero';
-import { InstallSnippet } from '../../components/demo/InstallSnippet';
-import { CodeBlock } from '../../components/demo/CodeBlock';
-import { DemoSection } from '../../components/demo/DemoSection';
+import { Hero } from '`@/app/components/demo/Hero`';
+import { InstallSnippet } from '`@/app/components/demo/InstallSnippet`';
+import { CodeBlock } from '`@/app/components/demo/CodeBlock`';
+import { DemoSection } from '`@/app/components/demo/DemoSection`';

As per coding guidelines, "/src//*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils**".

🤖 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 `@examples/playground/src/app/`(playground)/getting-started/page.tsx around
lines 25 - 29, Replace the relative local imports in page.tsx with the project
path aliases: change imports of Hero, InstallSnippet, CodeBlock, and DemoSection
from '../../components/demo/...' to use '`@components/demo/`...' so they follow
the src import policy (leave the external IconType import from 'react-icons'
unchanged); update the import statements for the symbols Hero, InstallSnippet,
CodeBlock, and DemoSection accordingly.
examples/playground/src/app/(playground)/data/page.tsx (1)

21-22: ⚡ Quick win

Replace relative imports with aliases.

Line 21–22 should use @/... imports per src import policy.

As per coding guidelines, "/src//*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils**".

🤖 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 `@examples/playground/src/app/`(playground)/data/page.tsx around lines 21 - 22,
Update the two relative imports in page.tsx to use path aliases per the project
policy: replace import of DemoSection and ConnectGate (symbols DemoSection and
ConnectGate) from '../../components/demo/DemoSection' and
'../../components/demo/ConnectGate' with the appropriate aliased imports (e.g.
'`@components/demo/DemoSection`' and '`@components/demo/ConnectGate`' or
'`@/components/demo/`...') so they follow the src import policy for components.
examples/playground/src/app/(playground)/ai-skills/page.tsx (1)

4-4: ⚡ Quick win

Use alias import for AISkillsSection.

Line 4 should use the @/... alias form instead of ../../....

As per coding guidelines, "/src//*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils**".

🤖 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 `@examples/playground/src/app/`(playground)/ai-skills/page.tsx at line 4,
Replace the relative import for AISkillsSection with the path-alias form; update
the import statement that references AISkillsSection so it uses the `@components`
alias (e.g. import { AISkillsSection } from
'`@components/features/AISkills/AISkillsSection`';) to comply with the project's
alias rules and avoid ../../ relative paths.
examples/playground/src/app/(playground)/smart-account/page.tsx (1)

7-9: ⚡ Quick win

Convert relative imports to aliases.

Please align these imports with the project’s alias convention.

Proposed refactor
-import { DemoSection } from '../../components/demo/DemoSection';
-import { ConnectGate } from '../../components/demo/ConnectGate';
-import { SmartAccountInfo } from '../../components/features/SmartAccountInfo';
+import { DemoSection } from '`@/app/components/demo/DemoSection`';
+import { ConnectGate } from '`@/app/components/demo/ConnectGate`';
+import { SmartAccountInfo } from '`@/app/components/features/SmartAccountInfo`';

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/`(playground)/smart-account/page.tsx around lines
7 - 9, Replace the three relative imports in page.tsx with project path aliases:
change imports of DemoSection, ConnectGate, and SmartAccountInfo to use the
`@components` alias (e.g., import { DemoSection } from
'`@components/demo/DemoSection`', import { ConnectGate } from
'`@components/demo/ConnectGate`', import { SmartAccountInfo } from
'`@components/features/SmartAccountInfo`') so they follow the `@/*`/`@components`
convention used across the repo.
examples/playground/src/app/(playground)/theming/page.tsx (1)

16-18: ⚡ Quick win

Use path aliases for local imports.

These imports should use the configured aliases rather than relative traversal.

Proposed refactor
-import { languageNames, supportedLanguages } from '../../../../i18n';
-import { DemoSection } from '../../components/demo/DemoSection';
+import { languageNames, supportedLanguages } from '`@/i18n`';
+import { DemoSection } from '`@/app/components/demo/DemoSection`';

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/`(playground)/theming/page.tsx around lines 16 -
18, Replace the relative imports with path aliases per the project guidelines:
change the import of languageNames and supportedLanguages from
'../../../../i18n' to use the src alias (e.g. '`@/i18n`') and change the
DemoSection import from '../../components/demo/DemoSection' to use the
components alias (e.g. '`@components/demo/DemoSection`'); update the two import
statements so they reference the aliased module paths instead of traversing
relative directories.
examples/playground/src/app/(playground)/modals/page.tsx (1)

5-7: ⚡ Quick win

Use aliases for component imports.

Please replace these relative imports with the configured project aliases.

Proposed refactor
-import { DemoSection } from '../../components/demo/DemoSection';
-import { ConnectGate } from '../../components/demo/ConnectGate';
-import { ModalCatalog } from '../../components/features/ModalCatalog';
+import { DemoSection } from '`@/app/components/demo/DemoSection`';
+import { ConnectGate } from '`@/app/components/demo/ConnectGate`';
+import { ModalCatalog } from '`@/app/components/features/ModalCatalog`';

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/`(playground)/modals/page.tsx around lines 5 - 7,
The imports DemoSection, ConnectGate and ModalCatalog use relative paths; update
them to use the project's path aliases (e.g. `@components`) per the guideline.
Replace '../../components/demo/DemoSection' with the alias-based import for
DemoSection, '../../components/demo/ConnectGate' with the alias-based import for
ConnectGate, and '../../components/features/ModalCatalog' with the alias-based
import for ModalCatalog so they import from `@components/`... (or the configured
`@components` path) instead of relative paths.
examples/playground/src/app/(playground)/signing/page.tsx (1)

11-13: ⚡ Quick win

Use project path aliases instead of relative imports.

Please switch these imports to the configured aliases to stay consistent with repo conventions.

Proposed refactor
-import { DemoSection } from '../../components/demo/DemoSection';
-import { ConnectGate } from '../../components/demo/ConnectGate';
-import { SignatureOutput } from '../../components/features/Signing/SignatureOutput';
+import { DemoSection } from '`@/app/components/demo/DemoSection`';
+import { ConnectGate } from '`@/app/components/demo/ConnectGate`';
+import { SignatureOutput } from '`@/app/components/features/Signing/SignatureOutput`';

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/`(playground)/signing/page.tsx around lines 11 -
13, Replace the three relative imports for DemoSection, ConnectGate, and
SignatureOutput with the project path aliases: import DemoSection and
ConnectGate from `@components/demo/`... and SignatureOutput from
`@components/features/Signing/`...; update the import specifiers so they use
"`@/`..." aliasing convention (e.g., `@components`) instead of
'../../components/...', ensuring the symbols DemoSection, ConnectGate, and
SignatureOutput are resolved via the configured path aliases.
examples/playground/src/app/(playground)/transactions/page.tsx (1)

22-25: ⚡ Quick win

Replace relative imports with configured aliases.

Please use repo aliases here for consistency and maintainability.

Proposed refactor
-import { b3trMainnetAddress } from '../../constants';
-import { DemoSection } from '../../components/demo/DemoSection';
-import { ConnectGate } from '../../components/demo/ConnectGate';
-import { TxResultPanel } from '../../components/features/Transactions/TxResultPanel';
+import { b3trMainnetAddress } from '`@/app/constants`';
+import { DemoSection } from '`@/app/components/demo/DemoSection`';
+import { ConnectGate } from '`@/app/components/demo/ConnectGate`';
+import { TxResultPanel } from '`@/app/components/features/Transactions/TxResultPanel`';

As per coding guidelines, **/src/**/*.{ts,tsx}: Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils.

🤖 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 `@examples/playground/src/app/`(playground)/transactions/page.tsx around lines
22 - 25, The import statements for b3trMainnetAddress, DemoSection, ConnectGate,
and TxResultPanel use relative paths; replace them with the project path aliases
(e.g. use `@/` for src root and `@components` for component imports) so the imports
become alias-based (e.g. import { b3trMainnetAddress } from '`@/constants`' and
import { DemoSection } from '`@components/demo/DemoSection`', etc.), ensuring
consistency with the configured tsconfig/webpack aliases.
🤖 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 `@examples/playground/package.json`:
- Around line 21-24: The package.json dependencies are incompatible with Next.js
16.2.3; update the dependency versions for react and react-dom from "^18" to
"^19", and align eslint packages by changing eslint-config-next and
`@next/eslint-plugin-next` to "16.2.3" (or the exact Next.js version); locate the
dependency entries "react", "react-dom", "eslint-config-next", and
"`@next/eslint-plugin-next`" in package.json and replace their version strings
accordingly so all Next.js-related packages are version-consistent.

In `@examples/playground/src/app/`(playground)/connect/page.tsx:
- Around line 11-43: The examples WALLET_BUTTON_SNIPPET and OAUTH_SNIPPET
reference a <Button> component but do not import it; update both snippets to
include the Button import (e.g., add an import for Button from the same package
used for WalletButton/useConnectModal and useLoginWithOAuth) so the examples are
copy-paste runnable; ensure the import appears alongside existing imports in
WALLET_BUTTON_SNIPPET (with WalletButton, useConnectModal) and in OAUTH_SNIPPET
(with useLoginWithOAuth).

In `@examples/playground/src/app/`(playground)/data/page.tsx:
- Around line 99-106: Change the address variable to be nullable instead of
defaulting to an empty string: replace the current const address =
account?.address ?? ''; with a nullable const address = account?.address; so the
hooks useGetB3trBalance, useGetVot3Balance and useIsPerson receive undefined
when no account exists and rely on their internal enabled checks (as done in
DaoInfo.tsx) to gate queries.
- Around line 87-94: VBD_SNIPPET currently calls hooks
(useCurrentAllocationsRoundId, useIsPerson) at module scope which violates React
rules of hooks; update VBD_SNIPPET to show a small React function component
(like BALANCE_SNIPPET and PRICE_SNIPPET) that receives props (e.g., address),
calls useCurrentAllocationsRoundId() and useIsPerson(address) inside the
component body, and then returns JSX illustrating how to read and render data
(roundId, isPerson); ensure the snippet demonstrates proper hook placement and
usage without calling hooks at top level.

In `@examples/playground/src/app/`(playground)/modals/page.tsx:
- Around line 9-15: The code sample string MODAL_SNIPPET is missing the Button
import so it won't run when copied; update the snippet to include Button in the
imports (e.g. import { useSendTokenModal, Button } from '`@vechain/vechain-kit`';)
so that the SendButton component can use <Button> without error—modify the
MODAL_SNIPPET constant to include that import line at the top.

In `@examples/playground/src/app/`(playground)/signing/page.tsx:
- Around line 34-73: The snippet constants SIGN_MESSAGE_SNIPPET and
SIGN_TYPED_DATA_SNIPPET are not self-contained because they reference <Button>
without importing or defining it; update both snippet strings to include a
minimal import/definition for Button (or import from the same UI library used
elsewhere in the project) at the top of each snippet so SignButton and
SignTypedButton can be copy/pasted and run immediately, ensuring the Button
symbol is present in each string.

In `@examples/playground/src/app/`(playground)/smart-account/page.tsx:
- Around line 11-17: The UPGRADE_SNIPPET references Button but doesn't import
it; update the snippet to import Button alongside useUpgradeSmartAccountModal
(e.g. add Button to the import statement) so the code example is copy-paste
runnable; locate the UPGRADE_SNIPPET constant and modify the import line to
include Button from the same source as useUpgradeSmartAccountModal.

In `@examples/playground/src/app/`(playground)/transactions/page.tsx:
- Around line 27-55: The TX_SNIPPET example is missing required symbols causing
it to break: add imports/definitions for useThor, Button, and B3TR_ADDRESS so
the snippet is copy-paste runnable; specifically, update the TX_SNIPPET string
to import useThor from the kit (or reference the existing hook), import or
define a simple Button component (or use the project's Button) and define
B3TR_ADDRESS (e.g., a placeholder constant) and ensure IB3TR__factory remains
imported — update the snippet around the top imports and any top-level constants
so useThor, Button, and B3TR_ADDRESS are present and referenced correctly.

In `@examples/playground/src/app/components/demo/CodeBlock.tsx`:
- Around line 16-19: The CodeBlockProps interface uses a plain string for the
language prop which conflicts with prism-react-renderer's typed API; import and
use prism-react-renderer's exported Language type and change the type of
language to Language (e.g., language?: Language) wherever CodeBlockProps or the
CodeBlock component signature is declared/used (including the other occurrence
referenced around line 93) and update any related default/prop forwarding to
satisfy the Highlight component's typed contract.

In `@examples/playground/src/app/components/demo/index.ts`:
- Around line 1-10: The barrel file is using relative re-exports; update each
export to use path aliases per guidelines so they are consistent with the rest
of the src tree. Replace the module specifiers for the exported symbols
(CodeBlock, HookBadge, StatusBadge, Status type, CopyAddress, DemoSection, Hero,
InstallSnippet, ConnectGate, AIPromptBlock) to the appropriate aliases (e.g.
`@components/demo/`... or `@components/`... as applicable) instead of './...'; keep
the export names unchanged and preserve the type export for Status as well.

In `@examples/playground/src/app/components/demo/InstallSnippet.tsx`:
- Line 4: Replace the relative import of the CodeBlock component with the
project path alias; change the import that references './CodeBlock' so it uses
the '`@/`*' alias convention (e.g., import from '`@components/`...' or
'`@/components/`...' depending on the repo alias mapping) to match other imports
and coding guidelines; update any sibling imports in InstallSnippet.tsx that
follow the same pattern to use the alias as well.

In `@examples/playground/src/app/components/features/Identity/IdentityPanel.tsx`:
- Around line 88-99: The InfoBlock for the wallet may render empty when
connectedWallet?.address is missing; update the rendering logic in IdentityPanel
so InfoBlock displays a sensible fallback (e.g., use account.address when
available) or is omitted entirely when no address exists. Locate the InfoBlock
usage and change the conditional around its children (and/or the whole
InfoBlock) to prefer connectedWallet.address || account.address for CopyAddress,
and only render the InfoBlock when that resolvedAddress is truthy.

In `@examples/playground/src/app/components/layout/NavItem.tsx`:
- Around line 24-25: The active calculation in NavItem.tsx incorrectly uses
normalized.endsWith(href) and can match unrelated routes; update the logic for
the active variable to use an exact match or a section-prefix match instead—for
example, keep normalized === href, and replace normalized.endsWith(href) with
normalized.startsWith(href === '/' ? '/' : href.endsWith('/') ? href : href +
'/'), and ensure both normalized and href are normalized (trailing slash
handling) so only the intended route or its subpaths mark the item active.

---

Nitpick comments:
In @.github/workflows/deploy-playground-cloudfront.yaml:
- Around line 22-27: The build-and-deploy job currently has no timeout and can
hang indefinitely; add a GitHub Actions job-level timeout by setting
timeout-minutes under the build-and-deploy job definition (e.g., add
"timeout-minutes: 30" or an appropriate value) so that the build-and-deploy job
will be cancelled after the specified minutes; update the job block containing
build-and-deploy, permissions, runs-on, and env to include the timeout-minutes
key.

In `@examples/playground/src/app/`(playground)/ai-skills/page.tsx:
- Line 4: Replace the relative import for AISkillsSection with the path-alias
form; update the import statement that references AISkillsSection so it uses the
`@components` alias (e.g. import { AISkillsSection } from
'`@components/features/AISkills/AISkillsSection`';) to comply with the project's
alias rules and avoid ../../ relative paths.

In `@examples/playground/src/app/`(playground)/connect/page.tsx:
- Around line 5-9: Replace the relative imports in page.tsx with the project
path aliases: import DemoSection from '`@/components/demo/DemoSection`'
(referencing DemoSection) and import WalletButtonVariants and OAuthGrid from
'`@/components/features/Connect`' (referencing WalletButtonVariants and
OAuthGrid); update the import statements in
examples/playground/src/app/(playground)/connect/page.tsx to use these `@/`...
aliases so they follow the codebase guideline for src aliases.

In `@examples/playground/src/app/`(playground)/data/page.tsx:
- Around line 21-22: Update the two relative imports in page.tsx to use path
aliases per the project policy: replace import of DemoSection and ConnectGate
(symbols DemoSection and ConnectGate) from '../../components/demo/DemoSection'
and '../../components/demo/ConnectGate' with the appropriate aliased imports
(e.g. '`@components/demo/DemoSection`' and '`@components/demo/ConnectGate`' or
'`@/components/demo/`...') so they follow the src import policy for components.

In `@examples/playground/src/app/`(playground)/getting-started/page.tsx:
- Around line 25-29: Replace the relative local imports in page.tsx with the
project path aliases: change imports of Hero, InstallSnippet, CodeBlock, and
DemoSection from '../../components/demo/...' to use '`@components/demo/`...' so
they follow the src import policy (leave the external IconType import from
'react-icons' unchanged); update the import statements for the symbols Hero,
InstallSnippet, CodeBlock, and DemoSection accordingly.

In `@examples/playground/src/app/`(playground)/identity/page.tsx:
- Around line 5-8: The four relative imports in page.tsx (DemoSection,
ConnectGate, IdentityPanel, ConnectionInfo) should use path aliases instead of
../../; update the import statements to use the configured aliases (e.g.,
`@components/`...) so they resolve from the src root per project convention,
ensuring the symbols DemoSection, ConnectGate, IdentityPanel and ConnectionInfo
are imported via their `@components` paths and not relative paths.

In `@examples/playground/src/app/`(playground)/layout.tsx:
- Around line 5-6: Replace the relative imports in layout.tsx with the project's
path aliases so they follow the coding guidelines: change the imports for the
Sidebar and TopBar components (symbols Sidebar and TopBar) from
'../components/layout/Sidebar' and '../components/layout/TopBar' to use the
`@components` alias (e.g. '`@components/layout/Sidebar`' and
'`@components/layout/TopBar`'), ensuring other imports in the file follow the same
alias convention.

In `@examples/playground/src/app/`(playground)/modals/page.tsx:
- Around line 5-7: The imports DemoSection, ConnectGate and ModalCatalog use
relative paths; update them to use the project's path aliases (e.g. `@components`)
per the guideline. Replace '../../components/demo/DemoSection' with the
alias-based import for DemoSection, '../../components/demo/ConnectGate' with the
alias-based import for ConnectGate, and '../../components/features/ModalCatalog'
with the alias-based import for ModalCatalog so they import from `@components/`...
(or the configured `@components` path) instead of relative paths.

In `@examples/playground/src/app/`(playground)/resources/page.tsx:
- Line 5: The import for ResourceList uses a relative path; change it to the
project path-alias form so it follows the src conventions—replace the existing
relative import with the alias-based import that references the ResourceList
component (e.g., import ResourceList from the `@components/`... location) ensuring
the symbol ResourceList and the module path match the project's alias
configuration.

In `@examples/playground/src/app/`(playground)/signing/page.tsx:
- Around line 11-13: Replace the three relative imports for DemoSection,
ConnectGate, and SignatureOutput with the project path aliases: import
DemoSection and ConnectGate from `@components/demo/`... and SignatureOutput from
`@components/features/Signing/`...; update the import specifiers so they use
"`@/`..." aliasing convention (e.g., `@components`) instead of
'../../components/...', ensuring the symbols DemoSection, ConnectGate, and
SignatureOutput are resolved via the configured path aliases.

In `@examples/playground/src/app/`(playground)/smart-account/page.tsx:
- Around line 7-9: Replace the three relative imports in page.tsx with project
path aliases: change imports of DemoSection, ConnectGate, and SmartAccountInfo
to use the `@components` alias (e.g., import { DemoSection } from
'`@components/demo/DemoSection`', import { ConnectGate } from
'`@components/demo/ConnectGate`', import { SmartAccountInfo } from
'`@components/features/SmartAccountInfo`') so they follow the `@/*`/`@components`
convention used across the repo.

In `@examples/playground/src/app/`(playground)/theming/page.tsx:
- Around line 16-18: Replace the relative imports with path aliases per the
project guidelines: change the import of languageNames and supportedLanguages
from '../../../../i18n' to use the src alias (e.g. '`@/i18n`') and change the
DemoSection import from '../../components/demo/DemoSection' to use the
components alias (e.g. '`@components/demo/DemoSection`'); update the two import
statements so they reference the aliased module paths instead of traversing
relative directories.

In `@examples/playground/src/app/`(playground)/transactions/page.tsx:
- Around line 22-25: The import statements for b3trMainnetAddress, DemoSection,
ConnectGate, and TxResultPanel use relative paths; replace them with the project
path aliases (e.g. use `@/` for src root and `@components` for component imports) so
the imports become alias-based (e.g. import { b3trMainnetAddress } from
'`@/constants`' and import { DemoSection } from '`@components/demo/DemoSection`',
etc.), ensuring consistency with the configured tsconfig/webpack aliases.

In `@examples/playground/src/app/components/demo/ConnectGate.tsx`:
- Line 5: The import in ConnectGate.tsx uses a relative parent path; change it
to the project path alias per guidelines by replacing the import of
LoginToContinueBox from '../features/LoginToContinueBox' with the alias-based
path (e.g., import { LoginToContinueBox } from
'`@components/features/LoginToContinueBox`' or the appropriate '`@components/`...'
location where LoginToContinueBox lives) so it uses the configured '`@/src`' and
'`@components`' aliases instead of a relative traversal.

In `@examples/playground/src/app/components/demo/DemoSection.tsx`:
- Around line 22-26: The imports in DemoSection.tsx use relative paths; update
them to the project's path aliases (e.g., `@components` or `@/`* as appropriate) so
internal imports follow the conventions. Replace the current imports for
CodeBlock, HookBadge, Status, StatusBadge and AIPromptBlock to their aliased
module paths (using `@components` or the src root alias) and ensure any
tsconfig/webpack alias mappings are respected so the named symbols (CodeBlock,
HookBadge, Status, StatusBadge, AIPromptBlock) resolve via the configured
aliases.

In `@examples/playground/src/app/components/features/AccountInfo/AccountInfo.tsx`:
- Line 4: Replace the relative import of IdentityPanel with the project path
alias: change the import of IdentityPanel (currently "import { IdentityPanel }
from '../Identity/IdentityPanel'") to the alias-based import using the
configured components alias (e.g. "import { IdentityPanel } from
'`@components/Identity/IdentityPanel`'") so it follows the src alias rule and
coding guidelines.

In `@examples/playground/src/app/components/features/Identity/IdentityPanel.tsx`:
- Line 15: Replace the relative import for the CopyAddress component with the
configured path alias; in IdentityPanel.tsx update the import of CopyAddress
(currently from '../../demo/CopyAddress') to use the project alias (e.g.
'`@components/demo/CopyAddress`' or '`@/app/components/demo/CopyAddress`' depending
on your alias mapping) so imports remain stable during refactors.

In `@examples/playground/src/app/components/features/ModalCatalog/ModalCard.tsx`:
- Line 13: Replace the relative import of HookBadge in ModalCard.tsx with the
repository path alias; locate the import statement that references HookBadge
(import { HookBadge } from '../../demo/HookBadge';) and change it to use the src
root alias (e.g., import { HookBadge } from '`@/components/demo/HookBadge`' or the
appropriate `@components/`@hooks alias per project conventions) so it follows the
project's "`@/src`" path-alias rules.

In
`@examples/playground/src/app/components/features/ModalCatalog/ModalCatalog.tsx`:
- Line 31: In ModalCatalog.tsx replace the relative import of ModalCard (import
{ ModalCard } from './ModalCard') with the project path-alias import (use the @
alias), e.g. import { ModalCard } from '`@components/`...ModalCard'; update the
import to match the repo's `@/`* alias convention and ensure any related imports
in ModalCatalog.tsx follow the same `@components/`@hooks/@utils aliasing style.
- Around line 145-146: The list rendering uses a localized and unstable key
(key={c.title}) which can change with translations and cause collisions; update
the cards.map usage to pass a stable, non-localized identifier such as c.hook as
the React key when rendering <ModalCard> (i.e., replace the key reference in the
ModalCard instantiation so it uses the unique hook property instead of title).

In `@examples/playground/src/app/components/features/Signing/index.ts`:
- Line 1: The export uses a relative path; replace it with the repo path-alias
form. Update the export in Signing/index.ts to re-export SignatureOutput via the
components alias (e.g., export { SignatureOutput } from
'`@components/features/Signing/SignatureOutput`') so it follows the '`@/`
/@components' import convention used across the repo and helps resolve imports
consistently.

In
`@examples/playground/src/app/components/features/Transactions/TxResultPanel.tsx`:
- Line 15: Replace the relative import for CopyAddress in TxResultPanel.tsx with
the repo path-alias version; change the import from '../../demo/CopyAddress' to
the `@components` alias (e.g. '`@components/demo/CopyAddress`' or the appropriate
'`@components/CopyAddress`' location) so it follows the project convention and
resolves via the src path alias.

In `@examples/playground/src/app/components/layout/MobileNav.tsx`:
- Line 12: The import of Sidebar in MobileNav.tsx uses a relative path; change
it to use the configured alias for components by replacing the relative import
with the alias import (e.g. import { Sidebar } from
'`@components/layout/Sidebar`') so it follows the project rule to use `@components`
for component imports and matches the src alias configuration.

In `@examples/playground/src/app/components/layout/NavItem.tsx`:
- Line 8: Replace the relative import of StatusBadge in NavItem.tsx with the
project path-alias import; update the import statement that currently references
'../demo/StatusBadge' to use the `@components` alias (e.g. import { StatusBadge,
type Status } from '`@components/demo/StatusBadge`') so it follows the project's
alias convention for components.

In `@examples/playground/src/app/components/layout/navItems.ts`:
- Line 15: Replace the relative import of the Status type in navItems.ts with
the project path-alias form; specifically update the import for Status
(currently "import type { Status } from '../demo/StatusBadge'") to use the
configured components alias (e.g., import from '`@components/demo/StatusBadge`')
so imports in the src tree follow the `@/`* and `@components` alias convention.

In `@examples/playground/src/app/components/layout/Sidebar.tsx`:
- Around line 13-14: Summary: Change relative imports in Sidebar.tsx to use
project path aliases. Update the two imports that currently use './NavItem' and
'./navItems' to their aliased module paths (use `@components` for component files
or `@/` for src-root if preferred); e.g., import NavItem from
'`@components/layout/NavItem`' and import { NAV_GROUPS } from
'`@components/layout/navItems`' (or use '`@/components/layout/`...' if your alias is
configured that way). Ensure the import specifiers match the exported symbols
NavItem and NAV_GROUPS and that your tsconfig/webpack alias mapping supports the
chosen aliases.

In `@examples/playground/src/app/components/layout/TopBar.tsx`:
- Around line 14-15: Replace the relative imports in TopBar.tsx by using the
project path aliases: change the import of LanguageDropdown from './Header' to
the components alias (e.g., import { LanguageDropdown } from
'`@components/Header`') and change MobileNav from './MobileNav' to the components
alias (e.g., import { MobileNav } from '`@components/MobileNav`'); update any
export names if needed to match those symbols so LanguageDropdown and MobileNav
resolve via the '`@components`' alias per the project convention.

In `@examples/playground/src/app/globals.css`:
- Line 5: The CSS rule currently uses "min-height: 100%;" which relies on
ancestor heights and can fail to fill the viewport; update the rule that
contains the min-height property in globals.css to use a viewport-relative value
(e.g., "min-height: 100vh" or the newer "100dvh" for mobile viewport
correctness) so the element reliably spans full screen across rendering
contexts.

In `@examples/playground/src/app/layout.tsx`:
- Around line 6-11: The imports in the root layout use relative src paths
instead of the project's path aliases; change the import of darkTheme and the
dynamic import for VechainKitProviderWrapper to use the configured aliases
(e.g., import darkTheme from '`@/theme`' and dynamic(() =>
import('`@/providers/VechainKitProviderWrapper`').then(m =>
m.VechainKitProviderWrapper))) so that darkTheme and VechainKitProviderWrapper
use the `@/` prefix consistent with the project's alias rules.

In `@examples/playground/src/app/page.tsx`:
- Around line 1-13: Current client-side redirect uses useEffect and useRouter in
the Page component causing a blank client frame; change to a server-side
redirect by removing the 'use client' directive and the useEffect/useRouter
usage, import redirect from 'next/navigation', and call
redirect('/getting-started') directly from the Page server component (e.g., in
the default exported Page function) so navigation happens on the server without
rendering a blank client page.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

Comment on lines 21 to 24
"next": "~16.2.3",
"prism-react-renderer": "^2.4.1",
"react": "^18",
"react-dom": "^18",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

For Next.js 16.2.3, what are the required peer versions for react, react-dom, eslint-config-next, and @next/eslint-plugin-next?

💡 Result:

For Next.js 16.2.3, the required peer versions and compatibility guidelines are as follows: React and React DOM: Next.js 16 (including 16.2.3) requires React 19 [1][2]. Specifically, it is designed to leverage features from the React 19.x release cycle (such as React 19.2+) [3][4][1]. Projects should maintain parity between react and react-dom versions [1]. eslint-config-next and @next/eslint-plugin-next: These packages are versioned in lockstep with the main Next.js framework [5]. For Next.js 16.2.3, you should use the corresponding version 16.2.3 of eslint-config-next and @next/eslint-plugin-next to ensure compatibility [6][7][5]. General Guidance: The official recommendation for Next.js 16 is to install the latest available versions of the framework and its primary dependencies using the following command [1]: npm install next@latest react@latest react-dom@latest If you are managing peer dependency conflicts in a monorepo or specific environment, it is common practice to pin these versions in your root package.json or via package manager overrides (such as pnpm overrides) to ensure the entire dependency tree uses the exact same version of React [8]. Note that as of May 2026, security advisories recommend ensuring you are on patched versions of both React (19.2.1+) and Next.js (16.0.10+) to mitigate known vulnerabilities [4].

Citations:


Critical dependency version incompatibilities with Next.js 16.2.3.

This configuration has incompatible versions:

  • react and react-dom are set to ^18, but Next.js 16.2.3 requires React 19 (specifically 19.2+)
  • eslint-config-next and @next/eslint-plugin-next are pinned to 14.x, but must match Next.js version (16.2.3)

Update to: react@^19, react-dom@^19, [email protected], @next/[email protected].

🤖 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 `@examples/playground/package.json` around lines 21 - 24, The package.json
dependencies are incompatible with Next.js 16.2.3; update the dependency
versions for react and react-dom from "^18" to "^19", and align eslint packages
by changing eslint-config-next and `@next/eslint-plugin-next` to "16.2.3" (or the
exact Next.js version); locate the dependency entries "react", "react-dom",
"eslint-config-next", and "`@next/eslint-plugin-next`" in package.json and replace
their version strings accordingly so all Next.js-related packages are
version-consistent.

Comment on lines +11 to +43
const WALLET_BUTTON_SNIPPET = `import { WalletButton, useConnectModal } from '@vechain/vechain-kit';

// 1. Default modal variant
<WalletButton />

// 2. Popover (desktop only)
<WalletButton connectionVariant="popover" />

// 3. Custom button style
<WalletButton
buttonStyle={{
background: '#f08098',
color: 'white',
border: '2px solid #000',
}}
/>

// 4. Fully custom button
const { open } = useConnectModal();
<Button onClick={() => open()}>Sign in</Button>
`;

const OAUTH_SNIPPET = `import { useLoginWithOAuth } from '@vechain/vechain-kit';

function GoogleLogin() {
const { initOAuth } = useLoginWithOAuth();
return (
<Button onClick={() => initOAuth({ provider: 'google' })}>
Continue with Google
</Button>
);
}
`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -A25 -B2 "WALLET_BUTTON_SNIPPET|OAUTH_SNIPPET|<Button|import \\{ Button \\}" "examples/playground/src/app/(playground)/connect/page.tsx"

Repository: vechain/vechain-kit

Length of output: 3221


🏁 Script executed:

#!/bin/bash
# Check the imports at the top of the file to understand the context and confirm Button source
head -20 "examples/playground/src/app/(playground)/connect/page.tsx"

Repository: vechain/vechain-kit

Length of output: 607


Add missing Button imports to example code snippets.

Both WALLET_BUTTON_SNIPPET (line 30) and OAUTH_SNIPPET (line 38) render <Button> but don't import it, making the copyable examples non-functional out of the box.

Proposed fix
 const WALLET_BUTTON_SNIPPET = `import { WalletButton, useConnectModal } from '`@vechain/vechain-kit`';
+import { Button } from '`@chakra-ui/react`';
 
 // 1. Default modal variant
 <WalletButton />
 const OAUTH_SNIPPET = `import { useLoginWithOAuth } from '`@vechain/vechain-kit`';
+import { Button } from '`@chakra-ui/react`';
 
 function GoogleLogin() {
📝 Committable suggestion

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

Suggested change
const WALLET_BUTTON_SNIPPET = `import { WalletButton, useConnectModal } from '@vechain/vechain-kit';
// 1. Default modal variant
<WalletButton />
// 2. Popover (desktop only)
<WalletButton connectionVariant="popover" />
// 3. Custom button style
<WalletButton
buttonStyle={{
background: '#f08098',
color: 'white',
border: '2px solid #000',
}}
/>
// 4. Fully custom button
const { open } = useConnectModal();
<Button onClick={() => open()}>Sign in</Button>
`;
const OAUTH_SNIPPET = `import { useLoginWithOAuth } from '@vechain/vechain-kit';
function GoogleLogin() {
const { initOAuth } = useLoginWithOAuth();
return (
<Button onClick={() => initOAuth({ provider: 'google' })}>
Continue with Google
</Button>
);
}
`;
const WALLET_BUTTON_SNIPPET = `import { WalletButton, useConnectModal } from '`@vechain/vechain-kit`';
import { Button } from '`@chakra-ui/react`';
// 1. Default modal variant
<WalletButton />
// 2. Popover (desktop only)
<WalletButton connectionVariant="popover" />
// 3. Custom button style
<WalletButton
buttonStyle={{
background: '`#f08098`',
color: 'white',
border: '2px solid `#000`',
}}
/>
// 4. Fully custom button
const { open } = useConnectModal();
<Button onClick={() => open()}>Sign in</Button>
`;
const OAUTH_SNIPPET = `import { useLoginWithOAuth } from '`@vechain/vechain-kit`';
import { Button } from '`@chakra-ui/react`';
function GoogleLogin() {
const { initOAuth } = useLoginWithOAuth();
return (
<Button onClick={() => initOAuth({ provider: 'google' })}>
Continue with Google
</Button>
);
}
`;
🤖 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 `@examples/playground/src/app/`(playground)/connect/page.tsx around lines 11 -
43, The examples WALLET_BUTTON_SNIPPET and OAUTH_SNIPPET reference a <Button>
component but do not import it; update both snippets to include the Button
import (e.g., add an import for Button from the same package used for
WalletButton/useConnectModal and useLoginWithOAuth) so the examples are
copy-paste runnable; ensure the import appears alongside existing imports in
WALLET_BUTTON_SNIPPET (with WalletButton, useConnectModal) and in OAUTH_SNIPPET
(with useLoginWithOAuth).

Comment on lines +87 to +94
const VBD_SNIPPET = `import {
useCurrentAllocationsRoundId,
useIsPerson,
} from '@vechain/vechain-kit';

const { data: roundId } = useCurrentAllocationsRoundId();
const { data: isPerson } = useIsPerson(address);
`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -A12 -B4 "const VBD_SNIPPET|useCurrentAllocationsRoundId\\(|useIsPerson\\(" "examples/playground/src/app/(playground)/data/page.tsx"

Repository: vechain/vechain-kit

Length of output: 1380


🏁 Script executed:

rg -n "VBD_SNIPPET" "examples/playground/src/app/(playground)/data/page.tsx" -A 5 -B 2

Repository: vechain/vechain-kit

Length of output: 839


🏁 Script executed:

rg -n "const [A-Z_]+_SNIPPET = \`" "examples/playground/src/app/(playground)/data/page.tsx"

Repository: vechain/vechain-kit

Length of output: 219


🏁 Script executed:

rg -n -A 10 "const BALANCE_SNIPPET|const PRICE_SNIPPET" "examples/playground/src/app/(playground)/data/page.tsx"

Repository: vechain/vechain-kit

Length of output: 800


VBD_SNIPPET shows invalid React hook usage.

The snippet calls hooks at module level (useCurrentAllocationsRoundId, useIsPerson) outside a component body, which violates React's rules of hooks. Other code examples in the same file (BALANCE_SNIPPET and PRICE_SNIPPET) correctly wrap hooks within function components. This example should follow the same pattern to avoid misleading developers.

Proposed fix
 const VBD_SNIPPET = `import {
     useCurrentAllocationsRoundId,
     useIsPerson,
 } from '`@vechain/vechain-kit`';
 
-const { data: roundId } = useCurrentAllocationsRoundId();
-const { data: isPerson } = useIsPerson(address);
+function PassportStatus({ address }) {
+    const { data: roundId } = useCurrentAllocationsRoundId();
+    const { data: isPerson } = useIsPerson(address);
+    return (
+        <>
+            <p>Round: {roundId ?? '—'}</p>
+            <p>Valid passport: {isPerson ? 'Yes' : 'No'}</p>
+        </>
+    );
+}
 `;
📝 Committable suggestion

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

Suggested change
const VBD_SNIPPET = `import {
useCurrentAllocationsRoundId,
useIsPerson,
} from '@vechain/vechain-kit';
const { data: roundId } = useCurrentAllocationsRoundId();
const { data: isPerson } = useIsPerson(address);
`;
const VBD_SNIPPET = `import {
useCurrentAllocationsRoundId,
useIsPerson,
} from '`@vechain/vechain-kit`';
function PassportStatus({ address }) {
const { data: roundId } = useCurrentAllocationsRoundId();
const { data: isPerson } = useIsPerson(address);
return (
<>
<p>Round: {roundId ?? '—'}</p>
<p>Valid passport: {isPerson ? 'Yes' : 'No'}</p>
</>
);
}
`;
🤖 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 `@examples/playground/src/app/`(playground)/data/page.tsx around lines 87 - 94,
VBD_SNIPPET currently calls hooks (useCurrentAllocationsRoundId, useIsPerson) at
module scope which violates React rules of hooks; update VBD_SNIPPET to show a
small React function component (like BALANCE_SNIPPET and PRICE_SNIPPET) that
receives props (e.g., address), calls useCurrentAllocationsRoundId() and
useIsPerson(address) inside the component body, and then returns JSX
illustrating how to read and render data (roundId, isPerson); ensure the snippet
demonstrates proper hook placement and usage without calling hooks at top level.

Comment on lines +99 to +106
const address = account?.address ?? '';

const { data: b3tr, isLoading: l1 } = useGetB3trBalance(address);
const { data: vot3, isLoading: l2 } = useGetVot3Balance(address);
const { data: vetPrice, isLoading: l3 } = useGetTokenUsdPrice('VET');
const { data: roundId } = useCurrentAllocationsRoundId();
const { data: isPerson } = useIsPerson(address);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -A24 -B6 "const address|useGetB3trBalance\\(|useGetVot3Balance\\(|useIsPerson\\(" "examples/playground/src/app/(playground)/data/page.tsx"
rg -n -A30 -B2 "useGetB3trBalance|useGetVot3Balance|useIsPerson" --type ts --type tsx

Repository: vechain/vechain-kit

Length of output: 2954


🏁 Script executed:

fd -t f "\.ts$|\.tsx$" --path "*src*" | xargs rg "useGetB3trBalance|useGetVot3Balance|useIsPerson" -A 8 -B 1 | head -100

Repository: vechain/vechain-kit

Length of output: 17506


🏁 Script executed:

fd -t f "\.ts$|\.tsx$" -p "*hooks*" | xargs rg "export.*useGetB3trBalance|export.*useGetVot3Balance|export.*useIsPerson|function useGetB3trBalance|function useGetVot3Balance|function useIsPerson" -A 15 | head -150

Repository: vechain/vechain-kit

Length of output: 6889


🏁 Script executed:

rg "enabled:" "examples/playground/src/app/(playground)/data/page.tsx" -B 5 -A 5

Repository: vechain/vechain-kit

Length of output: 45


🏁 Script executed:

cat packages/vechain-kit/src/hooks/api/wallet/useGetB3trBalance.ts

Repository: vechain/vechain-kit

Length of output: 1186


🏁 Script executed:

cat packages/vechain-kit/src/hooks/api/wallet/useGetVot3Balance.ts

Repository: vechain/vechain-kit

Length of output: 1186


Remove empty string default and keep address nullable; the hooks' internal enabled checks will prevent queries with missing address.

The hooks (useGetB3trBalance, useGetVot3Balance, useIsPerson) already have enabled: !!address && !!network.type internally, so they're protected. However, defaulting address to '' is semantically incorrect. Change const address = account?.address ?? ''; to const address = account?.address; to pass the address as nullable (matching the pattern in DaoInfo.tsx), letting the hooks' built-in enabled checks handle the query gating.

🤖 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 `@examples/playground/src/app/`(playground)/data/page.tsx around lines 99 -
106, Change the address variable to be nullable instead of defaulting to an
empty string: replace the current const address = account?.address ?? ''; with a
nullable const address = account?.address; so the hooks useGetB3trBalance,
useGetVot3Balance and useIsPerson receive undefined when no account exists and
rely on their internal enabled checks (as done in DaoInfo.tsx) to gate queries.

Comment on lines +9 to +15
const MODAL_SNIPPET = `import { useSendTokenModal } from '@vechain/vechain-kit';

function SendButton() {
const { open } = useSendTokenModal();
return <Button onClick={() => open()}>Send tokens</Button>;
}
`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

MODAL_SNIPPET needs the Button import to be copy-ready.

Without it, the sample fails when pasted as-is.

Proposed fix
-const MODAL_SNIPPET = `import { useSendTokenModal } from '`@vechain/vechain-kit`';
+const MODAL_SNIPPET = `import { Button } from '`@chakra-ui/react`';
+import { useSendTokenModal } from '`@vechain/vechain-kit`';
🤖 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 `@examples/playground/src/app/`(playground)/modals/page.tsx around lines 9 -
15, The code sample string MODAL_SNIPPET is missing the Button import so it
won't run when copied; update the snippet to include Button in the imports (e.g.
import { useSendTokenModal, Button } from '`@vechain/vechain-kit`';) so that the
SendButton component can use <Button> without error—modify the MODAL_SNIPPET
constant to include that import line at the top.

Comment on lines +16 to +19
interface CodeBlockProps {
code: string;
language?: string;
label?: string;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In prism-react-renderer v2.x, what is the TypeScript type of the Highlight languageprop, and isstring accepted?

💡 Result:

In prism-react-renderer v2.x, the Highlight language prop is typed as Language (a union of supported Prism language keys) rather than plain string. The docs describe language as Language and the tokenization options type uses language: Language [1]. Is string accepted? No: the intended TypeScript type for language is Language, not string. Passing a general string value would not type-check unless you narrow/cast it to Language (or use the escape hatch via a custom Prism setup) [1][2].

Citations:


🏁 Script executed:

# Check if CodeBlock.tsx file exists and read it
find . -name "CodeBlock.tsx" -type f 2>/dev/null | head -5

Repository: vechain/vechain-kit

Length of output: 123


🏁 Script executed:

# Check package.json for prism-react-renderer version
cat package.json | grep -A 2 -B 2 "prism-react-renderer"

Repository: vechain/vechain-kit

Length of output: 45


🏁 Script executed:

# Search for Language type imports or usage in the project
rg "Language.*from.*prism-react-renderer" --type ts --type tsx

Repository: vechain/vechain-kit

Length of output: 91


🏁 Script executed:

# Read the CodeBlock.tsx file
cat -n ./examples/playground/src/app/components/demo/CodeBlock.tsx

Repository: vechain/vechain-kit

Length of output: 6202


🏁 Script executed:

# Check for package.json in examples/playground
find ./examples/playground -name "package.json" -type f

Repository: vechain/vechain-kit

Length of output: 98


🏁 Script executed:

# Search for Language type imports more broadly
rg "Language.*prism-react-renderer" -A 2 -B 2

Repository: vechain/vechain-kit

Length of output: 45


🏁 Script executed:

# Read examples/playground/package.json
cat ./examples/playground/package.json

Repository: vechain/vechain-kit

Length of output: 1269


🏁 Script executed:

# Also check root package.json for prism-react-renderer
cat ./package.json | grep -i "prism"

Repository: vechain/vechain-kit

Length of output: 45


🏁 Script executed:

# Check if Language type is used elsewhere in the codebase
rg "type.*Language" --type ts --type tsx | head -20

Repository: vechain/vechain-kit

Length of output: 91


🏁 Script executed:

# Search in node_modules to verify Language type export (if available)
find ./examples/playground/node_modules/prism-react-renderer -name "*.d.ts" 2>/dev/null | head -5

Repository: vechain/vechain-kit

Length of output: 45


🏁 Script executed:

# Search for Language type usage without file type flag
rg "Language" --glob "*.ts" --glob "*.tsx" | grep -i "prism\|language" | head -10

Repository: vechain/vechain-kit

Length of output: 903


🏁 Script executed:

# Check prism-react-renderer npm documentation through web to confirm Language export
curl -s https://registry.npmjs.org/prism-react-renderer/2.4.1 | jq '.readme' 2>/dev/null | head -50

Repository: vechain/vechain-kit

Length of output: 68


🏁 Script executed:

# Try to find type definitions or exports from prism-react-renderer in the installed package
find . -path "*/node_modules/prism-react-renderer/*" -name "index.d.ts" -o -name "*.d.ts" 2>/dev/null | head -10

Repository: vechain/vechain-kit

Length of output: 202


🏁 Script executed:

# Check the prism-react-renderer GitHub repository for Language type
web_search "prism-react-renderer Language type export TypeScript"

Repository: vechain/vechain-kit

Length of output: 114


🌐 Web query:

prism-react-renderer v2.4.1 Language type TypeScript export

💡 Result:

In prism-react-renderer v2.4.1, the language type used for the language prop in the Highlight component is exported as the named TypeScript type Language [1][2]. You can import this type directly from the package to ensure type safety when defining which languages your code blocks support: import { Highlight, Language } from "prism-react-renderer"; const language: Language = "tsx"; The library includes this type to strictly define the set of supported languages that Prism is configured to handle within the bundled, vendored version of Prism it provides [1][2][3]. If you need to support languages not included in the default bundle, you may need to extend your Prism configuration or provide a custom Prism instance via the prism prop on the Highlight component [2][3].

Citations:


Narrow language to Prism's supported language type.

Using string for language violates Highlight's typed API contract. prism-react-renderer v2.4.1 exports a Language type for strict language validation.

Suggested fix
-import { Highlight, themes } from 'prism-react-renderer';
+import { Highlight, themes } from 'prism-react-renderer';
+import type { Language } from 'prism-react-renderer';

 interface CodeBlockProps {
     code: string;
-    language?: string;
+    language?: Language;
     label?: string;
 }

Also applies to: 93-93

🤖 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 `@examples/playground/src/app/components/demo/CodeBlock.tsx` around lines 16 -
19, The CodeBlockProps interface uses a plain string for the language prop which
conflicts with prism-react-renderer's typed API; import and use
prism-react-renderer's exported Language type and change the type of language to
Language (e.g., language?: Language) wherever CodeBlockProps or the CodeBlock
component signature is declared/used (including the other occurrence referenced
around line 93) and update any related default/prop forwarding to satisfy the
Highlight component's typed contract.

Comment on lines +1 to +10
export { CodeBlock } from './CodeBlock';
export { HookBadge } from './HookBadge';
export { StatusBadge } from './StatusBadge';
export type { Status } from './StatusBadge';
export { CopyAddress } from './CopyAddress';
export { DemoSection } from './DemoSection';
export { Hero } from './Hero';
export { InstallSnippet } from './InstallSnippet';
export { ConnectGate } from './ConnectGate';
export { AIPromptBlock } from './AIPromptBlock';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Convert barrel re-exports to @/* aliases for consistency.

Use path aliases here as well to keep module specifiers consistent across the src tree.

Proposed change
-export { CodeBlock } from './CodeBlock';
-export { HookBadge } from './HookBadge';
-export { StatusBadge } from './StatusBadge';
-export type { Status } from './StatusBadge';
-export { CopyAddress } from './CopyAddress';
-export { DemoSection } from './DemoSection';
-export { Hero } from './Hero';
-export { InstallSnippet } from './InstallSnippet';
-export { ConnectGate } from './ConnectGate';
-export { AIPromptBlock } from './AIPromptBlock';
+export { CodeBlock } from '`@/app/components/demo/CodeBlock`';
+export { HookBadge } from '`@/app/components/demo/HookBadge`';
+export { StatusBadge } from '`@/app/components/demo/StatusBadge`';
+export type { Status } from '`@/app/components/demo/StatusBadge`';
+export { CopyAddress } from '`@/app/components/demo/CopyAddress`';
+export { DemoSection } from '`@/app/components/demo/DemoSection`';
+export { Hero } from '`@/app/components/demo/Hero`';
+export { InstallSnippet } from '`@/app/components/demo/InstallSnippet`';
+export { ConnectGate } from '`@/app/components/demo/ConnectGate`';
+export { AIPromptBlock } from '`@/app/components/demo/AIPromptBlock`';

As per coding guidelines, "Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils".

📝 Committable suggestion

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

Suggested change
export { CodeBlock } from './CodeBlock';
export { HookBadge } from './HookBadge';
export { StatusBadge } from './StatusBadge';
export type { Status } from './StatusBadge';
export { CopyAddress } from './CopyAddress';
export { DemoSection } from './DemoSection';
export { Hero } from './Hero';
export { InstallSnippet } from './InstallSnippet';
export { ConnectGate } from './ConnectGate';
export { AIPromptBlock } from './AIPromptBlock';
export { CodeBlock } from '`@/app/components/demo/CodeBlock`';
export { HookBadge } from '`@/app/components/demo/HookBadge`';
export { StatusBadge } from '`@/app/components/demo/StatusBadge`';
export type { Status } from '`@/app/components/demo/StatusBadge`';
export { CopyAddress } from '`@/app/components/demo/CopyAddress`';
export { DemoSection } from '`@/app/components/demo/DemoSection`';
export { Hero } from '`@/app/components/demo/Hero`';
export { InstallSnippet } from '`@/app/components/demo/InstallSnippet`';
export { ConnectGate } from '`@/app/components/demo/ConnectGate`';
export { AIPromptBlock } from '`@/app/components/demo/AIPromptBlock`';
🤖 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 `@examples/playground/src/app/components/demo/index.ts` around lines 1 - 10,
The barrel file is using relative re-exports; update each export to use path
aliases per guidelines so they are consistent with the rest of the src tree.
Replace the module specifiers for the exported symbols (CodeBlock, HookBadge,
StatusBadge, Status type, CopyAddress, DemoSection, Hero, InstallSnippet,
ConnectGate, AIPromptBlock) to the appropriate aliases (e.g.
`@components/demo/`... or `@components/`... as applicable) instead of './...'; keep
the export names unchanged and preserve the type export for Status as well.

'use client';

import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/react';
import { CodeBlock } from './CodeBlock';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Use the project path alias instead of a relative import.

Switch this import to @/* alias to match the repository import convention.

Proposed change
-import { CodeBlock } from './CodeBlock';
+import { CodeBlock } from '`@/app/components/demo/CodeBlock`';

As per coding guidelines, "Use path aliases for imports: @/* for src root, @hooks for hooks, @components for components, @utils for utils".

📝 Committable suggestion

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

Suggested change
import { CodeBlock } from './CodeBlock';
import { CodeBlock } from '`@/app/components/demo/CodeBlock`';
🤖 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 `@examples/playground/src/app/components/demo/InstallSnippet.tsx` at line 4,
Replace the relative import of the CodeBlock component with the project path
alias; change the import that references './CodeBlock' so it uses the '`@/`*'
alias convention (e.g., import from '`@components/`...' or '`@/components/`...'
depending on the repo alias mapping) to match other imports and coding
guidelines; update any sibling imports in InstallSnippet.tsx that follow the
same pattern to use the alias as well.

Comment on lines +88 to +99
<InfoBlock
title={
connection.isConnectedWithPrivy
? t('Embedded Wallet')
: t('Wallet')
}
icon={LuWallet}
>
{connectedWallet?.address && (
<CopyAddress address={connectedWallet.address} />
)}
</InfoBlock>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid rendering an empty wallet info card.

When connectedWallet?.address is missing, the card renders with no content. Consider falling back to account.address or conditionally hiding the card.

Suggested change
-                <InfoBlock
-                    title={
-                        connection.isConnectedWithPrivy
-                            ? t('Embedded Wallet')
-                            : t('Wallet')
-                    }
-                    icon={LuWallet}
-                >
-                    {connectedWallet?.address && (
-                        <CopyAddress address={connectedWallet.address} />
-                    )}
-                </InfoBlock>
+                {(connectedWallet?.address || account.address) && (
+                    <InfoBlock
+                        title={
+                            connection.isConnectedWithPrivy
+                                ? t('Embedded Wallet')
+                                : t('Wallet')
+                        }
+                        icon={LuWallet}
+                    >
+                        <CopyAddress
+                            address={connectedWallet?.address ?? account.address}
+                        />
+                    </InfoBlock>
+                )}
🤖 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 `@examples/playground/src/app/components/features/Identity/IdentityPanel.tsx`
around lines 88 - 99, The InfoBlock for the wallet may render empty when
connectedWallet?.address is missing; update the rendering logic in IdentityPanel
so InfoBlock displays a sensible fallback (e.g., use account.address when
available) or is omitted entirely when no address exists. Locate the InfoBlock
usage and change the conditional around its children (and/or the whole
InfoBlock) to prefer connectedWallet.address || account.address for CopyAddress,
and only render the InfoBlock when that resolvedAddress is truthy.

Comment on lines +24 to +25
const active =
normalized === href || normalized.endsWith(href);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Active nav matching can mis-highlight unrelated routes.

normalized.endsWith(href) can mark wrong items active when path suffixes overlap. Prefer exact match or section-prefix match.

Proposed fix
-    const active =
-        normalized === href || normalized.endsWith(href);
+    const active =
+        normalized === href || normalized.startsWith(`${href}/`);
📝 Committable suggestion

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

Suggested change
const active =
normalized === href || normalized.endsWith(href);
const active =
normalized === href || normalized.startsWith(`${href}/`);
🤖 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 `@examples/playground/src/app/components/layout/NavItem.tsx` around lines 24 -
25, The active calculation in NavItem.tsx incorrectly uses
normalized.endsWith(href) and can match unrelated routes; update the logic for
the active variable to use an exact match or a section-prefix match instead—for
example, keep normalized === href, and replace normalized.endsWith(href) with
normalized.startsWith(href === '/' ? '/' : href.endsWith('/') ? href : href +
'/'), and ensure both normalized and href are normalized (trailing slash
handling) so only the intended route or its subpaths mark the item active.

Mirrors deploy-preview.yaml (homepage) but for the playground. Triggers
on pull_request_target when examples/playground/**, packages/vechain-kit/**
or yarn.lock change, gates external PRs behind the safe-to-deploy label,
builds the playground with NEXT_PUBLIC_BASE_PATH=/<branch>/playground,
syncs to the existing preview bucket under <branch>/playground/, invalidates
the preview CloudFront, and posts the URL as a sticky comment on the PR.

Reuses AWS_PREVIEW_BUCKET_NAME and AWS_PREVIEW_CLOUDFRONT_DISTRIBUTION_ID
— no new infra needed.

URL pattern: https://preview.vechainkit.vechain.org/<branch>/playground

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
(github.event.label.name == 'safe-to-deploy') ||
(github.event.pull_request.head.repo.full_name == github.repository) && github.event.pull_request.head.ref != 'main'
env:
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment

(github.event.pull_request.head.repo.full_name == github.repository) && github.event.pull_request.head.ref != 'main'
env:
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}
NEXT_PUBLIC_PRIVY_APP_ID: ${{ secrets.NEXT_PUBLIC_PRIVY_APP_ID }}

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment

env:
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}
NEXT_PUBLIC_PRIVY_APP_ID: ${{ secrets.NEXT_PUBLIC_PRIVY_APP_ID }}
NEXT_PUBLIC_PRIVY_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_PRIVY_CLIENT_ID }}

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment

NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}
NEXT_PUBLIC_PRIVY_APP_ID: ${{ secrets.NEXT_PUBLIC_PRIVY_APP_ID }}
NEXT_PUBLIC_PRIVY_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_PRIVY_CLIENT_ID }}
NEXT_PUBLIC_DELEGATOR_URL: ${{ secrets.NEXT_PUBLIC_DELEGATOR_URL }}

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4
with:
role-to-assume: ${{ secrets.AWS_ACC_ROLE }}

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment


- name: Deploy to S3
run: |
aws s3 sync ./examples/playground/dist s3://${{ secrets.AWS_PREVIEW_BUCKET_NAME }}/${{ steps.process-branch-name.outputs.processedBranchName }}/playground --delete

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment


- name: Cloudfront Invalidation
run: |
AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_PREVIEW_CLOUDFRONT_DISTRIBUTION_ID }} --paths '/' '/*'

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.

⚠️ [zizmor] <zizmor/secrets-outside-env> reported by reviewdog 🐶
secrets referenced without a dedicated environment: secret is accessed outside of a dedicated environment

@Agilulfo1820 Agilulfo1820 merged commit e89373d into main May 21, 2026
10 checks passed
@Agilulfo1820 Agilulfo1820 deleted the refactor/playground-revamp branch May 21, 2026 12:48
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