Skip to content

Conversation

@gene9831
Copy link
Collaborator

@gene9831 gene9831 commented Feb 6, 2026

  • Added support for playground configuration in the vitepress-demo-plugin.
  • Updated the plugin version to 1.5.0 and included a patch for it.
  • Implemented a new event listener for code playground interactions in the theme.
  • Adjusted the markdown configuration to enable playground features.

Summary by CodeRabbit

Release Notes

  • New Features

    • Enabled interactive playground UI for code examples across documentation
    • Added ability to open code examples in a dedicated playground environment
  • Dependencies

    • Updated vitepress-demo-plugin to version 1.5.0
    • Added playground framework and Vue dependencies

- Added support for playground configuration in the vitepress-demo-plugin.
- Updated the plugin version to 1.5.0 and included a patch for it.
- Implemented a new event listener for code playground interactions in the theme.
- Adjusted the markdown configuration to enable playground features.
@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

Walkthrough

The changes integrate a code playground feature into the VitePress documentation site. Updates include enabling the playground plugin with code transformation in the config, adding an event-driven code-playground listener in the theme setup, updating dependencies to include the tiny-robot-playground package, and patching the vitepress-demo-plugin to expose new playground configuration APIs.

Changes

Cohort / File(s) Summary
VitePress Configuration
.vitepress/config.mts
Supplies plugin options to vitepressDemoPlugin: enables playground UI with playground: { show: true } and adds a codeTransformer function to rewrite import.meta.env.BASE_URL with VITEPRESS_BASE.
Theme Event Integration
.vitepress/theme/index.ts
Imports playground utilities, augments Window interface with __CODE_PLAYGROUND_LISTENED__ flag, and introduces listenCodePlaygroundEvent() function to subscribe to code-playground custom events, generate a store, and open the playground in a new tab.
Dependencies
package.json
Adds @opentiny/tiny-robot-playground as devDependency, updates vitepress-demo-plugin to 1.5.0, adds vue ^3.5.13 as direct dependency, and configures pnpm patched dependencies for the vitepress-demo-plugin patch.
Plugin Enhancement
patches/vitepress-demo-plugin@1.5.0.patch
Extends VitepressDemoBoxConfig public API with codeplayer, playground, and codeTransformer fields; integrates playground UI and event dispatching into plugin runtime; applies code transformation during code loading; updates package.json exports to expose the module entry point.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hops with glee through playgrounds new,
Code transforms in VitePress too!
Events whisper, stores align,
Tiny robots dance divine! ✨🎪

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main changes: enhancing playground functionality (new event listeners, playground integration) and updating dependencies (vitepress-demo-plugin, @opentiny/tiny-robot-playground, vue).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.vitepress/theme/index.ts:
- Around line 115-125: Guard against missing/malformed props.playground and
invalid package strings: wrap the decodeURIComponent/JSON.parse into a try/catch
and default extraPackages to [] if parsing fails or props.playground is falsy;
in the mapping for extraPackages (the map that uses lastIndexOf('@') and
produces { [pkg]: version }), validate each pkgAndVersion string, handle cases
where lastIndexOf('@') <= 0 (treat the entire string as the package name and set
version to '' or undefined) and skip empty names; finally reduce into
extraImports as before. Update the code around props.playground, extraPackages,
extraImports and the map/reduce logic to include these guards and fallbacks.
🧹 Nitpick comments (3)
.vitepress/theme/index.ts (2)

108-108: Hardcoded 'latest' version tag is non-deterministic.

Using 'latest' for tinyRobotVersion means the playground will resolve to whatever version is current at runtime, which may not match the docs site's own dependency version. Consider reading the version from the installed package or a build-time constant for reproducibility.


29-33: Mixin mounted hook runs for every component instance.

listenCodePlaygroundEvent() is called on every component mount site-wide. The guard flag (__CODE_PLAYGROUND_LISTENED__) makes it safe, but a one-time call during enhanceApp (outside the mixin) would be cleaner and avoid the repeated no-op invocations.

Suggested approach
   enhanceApp({ app }) {
     setupDarkModeListener()
+    listenCodePlaygroundEvent()

     app.mixin({
       mounted() {
         registerServiceWorker()
-        listenCodePlaygroundEvent()
       },
     })

This also applies to registerServiceWorker() if it doesn't truly need the component lifecycle.

patches/vitepress-demo-plugin@1.5.0.patch (1)

32-201: Patching compiled dist files is fragile — consider upstreaming.

This patch modifies minified JS directly, which will break on any upstream release that changes the dist output (even a patch release, though pinning to 1.5.0 mitigates this). If the playground feature is broadly useful, consider contributing it upstream to vitepress-demo-plugin to reduce the long-term maintenance burden of this patch.

Comment on lines +115 to +125
const extraPackages: string[] = JSON.parse(decodeURIComponent(props.playground))?.packages || []
const extraImports = extraPackages
.map((pkgAndVersion) => {
const index = pkgAndVersion.lastIndexOf('@')
const pkg = pkgAndVersion.slice(0, index)
const version = pkgAndVersion.slice(index + 1)
return { [pkg]: version }
})
.reduce((acc, curr) => {
return { ...acc, ...curr }
}, {})
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Unguarded JSON.parse will crash the event handler if props.playground is missing or malformed.

If props.playground is undefined, empty, or not valid URI-encoded JSON, JSON.parse(decodeURIComponent(...)) throws and silently kills the handler — no playground opens, no error feedback to the user.

Additionally, the lastIndexOf('@') splitting strategy silently corrupts entries that lack a version suffix (e.g. "@scope/pkg" → pkg = "", version = "scope/pkg"; "pkg" → pkg = "pk", version = "pkg").

Proposed fix
-    const extraPackages: string[] = JSON.parse(decodeURIComponent(props.playground))?.packages || []
-    const extraImports = extraPackages
-      .map((pkgAndVersion) => {
-        const index = pkgAndVersion.lastIndexOf('@')
-        const pkg = pkgAndVersion.slice(0, index)
-        const version = pkgAndVersion.slice(index + 1)
-        return { [pkg]: version }
-      })
-      .reduce((acc, curr) => {
-        return { ...acc, ...curr }
-      }, {})
+    let extraImports: Record<string, string> = {}
+    try {
+      const extraPackages: string[] = JSON.parse(decodeURIComponent(props.playground))?.packages || []
+      extraImports = Object.fromEntries(
+        extraPackages
+          .map((pkgAndVersion) => {
+            const index = pkgAndVersion.lastIndexOf('@')
+            // Ensure '@' is found and is not the first char of a scoped package with no version
+            if (index > 0) {
+              return [pkgAndVersion.slice(0, index), pkgAndVersion.slice(index + 1)]
+            }
+            return [pkgAndVersion, 'latest']
+          })
+      )
+    } catch {
+      console.warn('Failed to parse playground packages', props.playground)
+    }
📝 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 extraPackages: string[] = JSON.parse(decodeURIComponent(props.playground))?.packages || []
const extraImports = extraPackages
.map((pkgAndVersion) => {
const index = pkgAndVersion.lastIndexOf('@')
const pkg = pkgAndVersion.slice(0, index)
const version = pkgAndVersion.slice(index + 1)
return { [pkg]: version }
})
.reduce((acc, curr) => {
return { ...acc, ...curr }
}, {})
let extraImports: Record<string, string> = {}
try {
const extraPackages: string[] = JSON.parse(decodeURIComponent(props.playground))?.packages || []
extraImports = Object.fromEntries(
extraPackages
.map((pkgAndVersion) => {
const index = pkgAndVersion.lastIndexOf('@')
// Ensure '@' is found and is not the first char of a scoped package with no version
if (index > 0) {
return [pkgAndVersion.slice(0, index), pkgAndVersion.slice(index + 1)]
}
return [pkgAndVersion, 'latest']
})
)
} catch {
console.warn('Failed to parse playground packages', props.playground)
}
🤖 Prompt for AI Agents
In @.vitepress/theme/index.ts around lines 115 - 125, Guard against
missing/malformed props.playground and invalid package strings: wrap the
decodeURIComponent/JSON.parse into a try/catch and default extraPackages to []
if parsing fails or props.playground is falsy; in the mapping for extraPackages
(the map that uses lastIndexOf('@') and produces { [pkg]: version }), validate
each pkgAndVersion string, handle cases where lastIndexOf('@') <= 0 (treat the
entire string as the package name and set version to '' or undefined) and skip
empty names; finally reduce into extraImports as before. Update the code around
props.playground, extraPackages, extraImports and the map/reduce logic to
include these guards and fallbacks.

@gene9831 gene9831 closed this Feb 6, 2026
@gene9831 gene9831 deleted the gene9831/tiny-robot-playground branch February 6, 2026 03:17
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