-
Notifications
You must be signed in to change notification settings - Fork 7
sync(release/v0.3.x): sync develop features #279
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sync(release/v0.3.x): sync develop features #279
Conversation
WalkthroughAdds a VitePress badge system (sidebar + markdown) with utilities, styles, and docs; updates docs build tooling and scripts; introduces Sender newline handling and a new MCP Server Picker slot; adds TypeScript config for docs; restructures CI workflows (new PR CI, e2e removal) and supporting scripts for building and copying docs/playground. Changes
Sequence Diagram(s)sequenceDiagram
participant VitePress
participant SidebarPlugin
participant FS as FileSystem
participant GrayMatter as FrontMatter
VitePress->>SidebarPlugin: configResolved(vpConfig)
activate SidebarPlugin
SidebarPlugin->>SidebarPlugin: locate sidebar entries (array/object)
loop each sidebar item with `link`
SidebarPlugin->>FS: resolve file path (root + srcDir + link)
FS-->>SidebarPlugin: markdown content
SidebarPlugin->>GrayMatter: parse(markdown)
GrayMatter-->>SidebarPlugin: data.badge
SidebarPlugin->>SidebarPlugin: withBadge(item.text, badge)
SidebarPlugin->>SidebarPlugin: update item.text
end
SidebarPlugin-->>VitePress: modified config
deactivate SidebarPlugin
sequenceDiagram
participant MarkdownRenderer
participant MarkdownPlugin
participant BadgeUtils
MarkdownRenderer->>MarkdownPlugin: register plugin (md.use)
activate MarkdownPlugin
MarkdownPlugin->>MarkdownPlugin: override text renderer rule
deactivate MarkdownPlugin
MarkdownRenderer->>MarkdownPlugin: render text node
activate MarkdownPlugin
MarkdownPlugin->>MarkdownPlugin: test MARKDOWN_BADGE_REGEX
alt match
MarkdownPlugin->>BadgeUtils: createBadgeHTML(token)
BadgeUtils-->>MarkdownPlugin: badge HTML
MarkdownPlugin-->>MarkdownRenderer: return transformed HTML
else no match
MarkdownPlugin-->>MarkdownRenderer: delegate to default renderer
end
deactivate MarkdownPlugin
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
📦 Package Previewpnpm add https://pkg.pr.new/opentiny/tiny-robot/@opentiny/tiny-robot@5a5c797 pnpm add https://pkg.pr.new/opentiny/tiny-robot/@opentiny/tiny-robot-kit@5a5c797 pnpm add https://pkg.pr.new/opentiny/tiny-robot/@opentiny/tiny-robot-svgs@5a5c797 commit: 5a5c797 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
scripts/copy-playground.js (1)
32-35: Use dynamic paths in log messages.The log messages reference hardcoded paths (
docs/dist/playground) but the script now copies from user-provided source/dest arguments, which could be different.🔎 Suggested fix
- console.log('Copying playground dist to docs/dist/playground...') + console.log(`Copying from ${source} to ${dest}...`) cpSync(source, dest, { recursive: true, force: true }) - console.log('✓ Successfully copied playground to docs/dist/playground') + console.log(`✓ Successfully copied from ${source} to ${dest}`)
🧹 Nitpick comments (4)
packages/components/src/sender/composables/useKeyboardHandler.ts (1)
87-102: Consider improving scroll behavior to keep cursor visible.The function correctly inserts the newline and updates the cursor position. However, setting
scrollTop = scrollHeightalways scrolls to the bottom, which may scroll past the cursor if the newline was inserted in the middle of a long text.🔎 Suggested improvement
Consider letting the browser handle cursor visibility or using a more targeted scroll approach:
// 设置光标位置到换行符之后,并滚动到光标位置 setTimeout(() => { const newCursorPos = start + 1 target.selectionStart = target.selectionEnd = newCursorPos - // 滚动到光标所在位置,确保光标可见 - target.scrollTop = target.scrollHeight }, 0)Alternatively, calculate the cursor's actual position and scroll to that specific location, or rely on the browser's default behavior which typically keeps the cursor visible after programmatic selection changes.
scripts/build-docs.js (1)
22-24: Consider logging the full error for debugging.The error handler only logs
error.message, which may lose valuable debugging information like stack traces.🔎 Suggested improvement
} catch (error) { - console.error('Error building docs:', error.message) + console.error('Error building docs:', error) process.exit(1) }.github/workflows/pr-deploy-preview.yml (1)
66-79: Consider case-insensitive SHA regex.The regex
/@[a-f0-9]{40}/on line 73 only matches lowercase hex digits, but Git SHAs could theoretically contain uppercase letters. While GitHub typically uses lowercase, using a case-insensitive pattern would be more robust.🔎 Suggested improvement
const packages = output.packages.map((p) => { - const shortUrl = p.url.replace(/@[a-f0-9]{40}/, '@' + sha); + const shortUrl = p.url.replace(/@[a-fA-F0-9]{40}/, '@' + sha); return 'pnpm add ' + shortUrl; }).join('\n\n');docs/.vitepress/plugins/badge/SidebarPlugin.ts (1)
137-162: Consider handling links that already include .md extension.The file path construction on line 146 appends
.mdto the link, which could result in.md.mdif the link already includes the extension. While VitePress links typically omit the extension, defensive handling would be more robust.🔎 Suggested improvement
function readBadgeFromFrontmatter( link: string, rootDir: string, srcDir: string, baseDir: string, matter: any, debug: boolean, ): string | undefined { try { + const linkPath = link.endsWith('.md') ? link : `${link}.md` - const filePath = path.join(rootDir, srcDir, baseDir, `${link}.md`) + const filePath = path.join(rootDir, srcDir, baseDir, linkPath) if (!fs.existsSync(filePath)) { return undefined }
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
.github/workflows/auto-publish.yml.github/workflows/dispatch-publish.yml.github/workflows/e2e-tests.yml.github/workflows/pr-ci-build.yml.github/workflows/pr-ci-e2e-test.yml.github/workflows/pr-ci-publish-packages.yml.github/workflows/pr-ci.yml.github/workflows/pr-cleanup.yml.github/workflows/pr-deploy-preview.ymldocs/.vitepress/config.mtsdocs/.vitepress/plugins/badge/MarkdownPlugin.tsdocs/.vitepress/plugins/badge/SidebarPlugin.tsdocs/.vitepress/plugins/badge/constants.tsdocs/.vitepress/plugins/badge/index.tsdocs/.vitepress/plugins/badge/utils.tsdocs/.vitepress/theme/style.cssdocs/.vitepress/themeConfig.tsdocs/package.jsondocs/src/components/mcp-server-picker.mddocs/src/components/sender.mddocs/src/guide/plugin-badge.mddocs/tsconfig.jsonpackage.jsonpackages/components/src/mcp-server-picker/index.vuepackages/components/src/sender/composables/useKeyboardHandler.tsscripts/build-docs.jsscripts/copy-playground.js
💤 Files with no reviewable changes (1)
- .github/workflows/e2e-tests.yml
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-18T09:29:47.974Z
Learnt from: SonyLeo
Repo: opentiny/tiny-robot PR: 119
File: packages/components/src/attachments/index.less:213-213
Timestamp: 2025-06-18T09:29:47.974Z
Learning: 在 packages/components/src/attachments/index.less 中,.tr-file-card__close 的背景色使用了硬编码的 rgb(194, 194, 194),但这个UI元素(关闭按钮)将会被直接替换为图标,所以不需要抽取为CSS变量。
Applied to files:
docs/.vitepress/theme/style.css
🧬 Code graph analysis (7)
docs/.vitepress/plugins/badge/MarkdownPlugin.ts (3)
docs/.vitepress/plugins/badge/index.ts (1)
MarkdownBadgePlugin(6-6)docs/.vitepress/plugins/badge/constants.ts (1)
MARKDOWN_BADGE_REGEX(48-48)docs/.vitepress/plugins/badge/utils.ts (1)
createBadgeHTML(57-61)
docs/.vitepress/plugins/badge/SidebarPlugin.ts (2)
docs/.vitepress/plugins/badge/index.ts (2)
SidebarBadgeOptions(10-10)SidebarBadgePlugin(5-5)docs/.vitepress/plugins/badge/utils.ts (1)
withBadge(66-69)
docs/.vitepress/config.mts (3)
docs/.vitepress/plugins/badge/SidebarPlugin.ts (1)
SidebarBadgePlugin(35-73)docs/.vitepress/plugins/badge/MarkdownPlugin.ts (1)
MarkdownBadgePlugin(34-53)docs/.vitepress/themeConfig.ts (1)
themeConfig(61-61)
docs/.vitepress/plugins/badge/utils.ts (1)
docs/.vitepress/plugins/badge/constants.ts (5)
VERSION_NUMBER_REGEX(43-43)BadgeValue(13-13)BadgeType(8-8)BADGE_TEXT_MAP(18-23)BADGE_CLASS_MAP(28-33)
scripts/build-docs.js (1)
scripts/copy-playground.js (1)
args(5-5)
packages/components/src/sender/composables/useKeyboardHandler.ts (1)
packages/components/src/sender/index.type.ts (1)
SubmitTrigger(15-15)
scripts/copy-playground.js (1)
scripts/build-docs.js (1)
args(4-4)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build / build
🔇 Additional comments (42)
packages/components/src/mcp-server-picker/index.vue (1)
306-306: LGTM! Clean extensibility enhancement.The new
header-actionsslot provides a well-positioned extensibility point in the header area, allowing consumers to inject custom actions without modifying the component's core behavior.docs/src/components/mcp-server-picker.md (1)
83-89: LGTM! Documentation accurately reflects the new slot.The Slots section correctly documents the new
header-actionsslot with an accurate description and proper formatting consistent with the rest of the documentation.docs/src/components/sender.md (3)
20-24: Documentation accurately describes the new auto-switch behavior.The updated tip correctly explains both width-based and keyboard-triggered mode switching. This aligns with the implementation in
useKeyboardHandler.ts.
149-175: Comprehensive documentation of keyboard behavior.The information block and tip sections clearly explain the interaction between submission types and newline shortcuts. The behavior descriptions accurately match the implementation in
useKeyboardHandler.ts.
162-163: Keyboard reference table correctly updated.The updated entries for Ctrl+Enter and Shift+Enter accurately reflect their dual functionality based on
submitTypeconfiguration.packages/components/src/sender/composables/useKeyboardHandler.ts (2)
109-129: Well-structured newline handling logic.The function correctly implements the documented behavior for Ctrl+Enter and Shift+Enter when
submitType="enter". The early return pattern, mutually exclusive modifier checks, and optional mode switching are all properly implemented.
134-187: Improved control flow with clearer prioritization.The updated
handleKeyPressfunction now prioritizes newline handling before other operations, which correctly prevents conflicts with submission logic. The simplified submission check usingcheckSubmitShortcutimproves readability and maintainability.docs/tsconfig.json (1)
1-15: LGTM! TypeScript configuration is well-structured.The tsconfig.json is properly configured for a VitePress documentation site with appropriate compiler options, including strict mode and bundler module resolution.
.github/workflows/dispatch-publish.yml (1)
85-91: LGTM! Docs build consolidation is correctly implemented.The workflow now uses the new
build:docs --nocomponentscommand, which aligns with the components already being built in step 7. ThePLAYGROUND_BASEenvironment variable is properly scoped to the Build VitePress step.docs/.vitepress/theme/style.css (1)
227-288: LGTM! Comprehensive badge styling with dark mode support.The version badge styles are well-structured with clear variants (new, deprecated, beta, alpha) and proper dark mode adaptations. The styling integrates cleanly with the badge plugin system.
.github/workflows/auto-publish.yml (1)
106-112: LGTM! Consistent docs build refactoring.The auto-publish workflow correctly uses the new
build:docs --nocomponentscommand, maintaining consistency with the dispatch-publish workflow and the new build orchestration approach.docs/src/guide/plugin-badge.md (1)
1-285: LGTM! Comprehensive and well-structured documentation.The badge plugin guide provides clear explanations, practical examples, and complete configuration instructions. The documentation covers both Markdown content badges and sidebar badges thoroughly, with helpful usage scenarios and notes.
.github/workflows/pr-cleanup.yml (1)
1-34: LGTM! Well-designed cleanup workflow.The PR cleanup workflow properly handles preview deployment teardown using
pull_request_targetfor write permissions, includes appropriate error tolerance withcontinue-on-error: true, and provides user feedback via comments. The workflow is secure as it doesn't checkout potentially untrusted code.docs/package.json (1)
10-10: Both package versions are valid and secure.Verified:
@types/[email protected]and[email protected]exist on npm and have no known security advisories. No CVEs are reported for either version.docs/.vitepress/themeConfig.ts (1)
1-61: LGTM! Clean VitePress theme configuration.The centralized theme configuration structure is well-organized and properly separates navigation, sidebar, and shared items. The export pattern aligns with how it's consumed in
config.mts.docs/.vitepress/config.mts (4)
6-7: LGTM! Proper plugin and config imports.The badge plugin imports and themeConfig import are correctly structured and align with the new modular configuration approach.
40-40: LGTM! Badge plugin correctly registered.The
SidebarBadgePlugin()is properly added to the Vite plugins array and will process sidebar items to add version badges.
62-63: LGTM! Markdown badge plugin correctly configured.The
MarkdownBadgePluginis properly registered to process version badge markers in Markdown content.
70-70: LGTM! ThemeConfig properly spread.The spread of
themeConfigcorrectly merges the centralized navigation and sidebar configuration fromthemeConfig.ts.package.json (2)
2-2: LGTM! Package rename for clarity.The rename from "root" to "robot-root" provides better clarity for the monorepo root package.
10-11: LGTM! Consolidated build scripts.The transition to dedicated Node scripts (
build-docs.jsand explicit arguments tocopy-playground.js) improves maintainability and aligns with the refactored script implementations.scripts/copy-playground.js (2)
4-16: LGTM! Good refactor to CLI-driven paths.The transition from hardcoded paths to command-line arguments makes the script more flexible and reusable. The path resolution logic correctly handles both absolute and relative paths.
18-30: LGTM! Comprehensive validation.The validation checks for source existence and destination parent directory are thorough and provide clear error messages.
.github/workflows/pr-ci-build.yml (1)
15-62: LGTM! Well-structured build workflow.The build job properly sets up the environment, caches dependencies, builds components and docs, and uploads artifacts with appropriate retention. The artifact naming using the PR head SHA ensures uniqueness.
.github/workflows/pr-ci.yml (1)
1-43: LGTM! Well-orchestrated CI pipeline.The workflow properly coordinates build, publish, and e2e-test jobs with appropriate conditions and dependencies. The concurrency control prevents redundant runs, and the PR title-based skip logic is sensible for documentation-only changes.
Note: The
skip-playground: trueparameter passed to the build workflow is currently unused (flagged separately in pr-ci-build.yml)..github/workflows/pr-ci-e2e-test.yml (1)
1-58: LGTM! Well-structured E2E test workflow.The workflow properly sets up the test environment, downloads build artifacts, installs Playwright with Chromium dependencies, and uploads test reports. The 60-minute timeout is reasonable for E2E tests, and the artifact retention (13 days) provides a good balance for debugging.
docs/.vitepress/plugins/badge/index.ts (1)
1-10: LGTM! Clean barrel export.The barrel export properly consolidates the badge plugin ecosystem exports, providing a single entry point for consumers. The separation of named exports, wildcard exports, and type-only exports follows best practices.
.github/workflows/pr-deploy-preview.yml (3)
108-116: LGTM!The Surge deployment configuration is correct. The domain naming pattern ensures unique preview URLs per PR, and the artifact path aligns with the expected build output structure.
118-145: Well-designed preview feedback flow.The three-stage comment system (deploying → success/failed) provides excellent user feedback. The use of
maintain-one-commentwith markers ensures a clean PR conversation without comment spam.
9-47: Excellent error handling and security posture.The workflow demonstrates good practices:
- Minimal required permissions
- Clear conditional execution logic
- Proper error handling for required artifacts
- Graceful degradation for optional artifacts
docs/.vitepress/plugins/badge/SidebarPlugin.ts (4)
100-132: LGTM!The sidebar processing logic correctly handles nested structures, uses Set-based deduplication to prevent duplicate badge application, and gracefully skips items without links.
52-71: Good error handling with informative logging.The plugin includes comprehensive error handling that prevents crashes while providing useful feedback through console warnings and the optional debug mode.
24-37: Clear interface with sensible defaults.The plugin options interface is well-documented. The
srcDirdefault of'src'appears project-specific; ensure it aligns with your VitePress configuration.
52-53: gray-matter is properly declared in dependencies.The plugin dynamically imports
gray-matterat lines 52-53, and this dependency is correctly listed indocs/package.jsonas version^4.0.3. No action needed.docs/.vitepress/plugins/badge/MarkdownPlugin.ts (2)
37-52: Correct stateful regex handling.The implementation properly resets
lastIndexon line 43 before using the global regex inreplace(). This prevents bugs that could arise from the regex's stateful behavior.
34-52: Well-structured markdown-it plugin.The plugin follows markdown-it conventions correctly by preserving the original renderer and providing appropriate fallbacks. The early return pattern on line 48 is efficient.
docs/.vitepress/plugins/badge/constants.ts (2)
35-43: Well-documented version regex.The regex correctly validates version numbers and includes helpful comments explaining the pattern and examples of valid/invalid inputs.
45-48: LGTM!The markdown badge regex correctly captures all badge types and uses a global flag for multiple matches. The pattern aligns well with
VERSION_NUMBER_REGEX.docs/.vitepress/plugins/badge/utils.ts (4)
8-20: Solid XSS prevention.The
escapeHtmlfunction correctly escapes all critical HTML special characters. Keeping it private and simple is appropriate for this use case.
29-44: Clean badge resolution logic.The functions correctly handle both predefined badge types and version numbers. The fallback to the badge value itself (line 43) provides flexibility for custom badges.
54-61: Secure HTML generation.The function correctly escapes user-controlled text while using predefined CSS classes from the constants map. The order of operations ensures XSS protection.
63-69: LGTM!The
withBadgefunction provides a clean API for appending badges to text, with appropriate spacing.
bbb912c to
1feaea6
Compare
🧹 Preview Cleaned UpThe preview deployment has been removed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
docs/.vitepress/plugins/badge/SidebarPlugin.ts (3)
1-1: Consider specifying which ESLint rules to disable.A blanket
eslint-disablesuppresses all linting for the file. It's better practice to disable only the specific rules that conflict with this code.🔎 Suggested improvement
-/* eslint-disable */ +/* eslint-disable @typescript-eslint/no-explicit-any */
35-38: Consider stronger typing for the plugin return type.The return type
anyloses type safety. While VitePress/Vite plugin types can be complex, usingPluginfrom Vite would improve IDE support and catch issues earlier.🔎 Suggested improvement
+import type { Plugin } from 'vite' + -export function SidebarBadgePlugin(options?: SidebarBadgeOptions): any { +export function SidebarBadgePlugin(options?: SidebarBadgeOptions): Plugin {
145-161: Validate that badge value is a string before returning.The frontmatter
data.badgecould be any type (number, object, array). The current type assertion could propagate unexpected values.🔎 Suggested fix
const content = fs.readFileSync(filePath, 'utf-8') const { data } = matter(content) - return data.badge as string | undefined + return typeof data.badge === 'string' ? data.badge : undefined } catch (error) {
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
docs/.vitepress/config.mtsdocs/.vitepress/plugins/badge/MarkdownPlugin.tsdocs/.vitepress/plugins/badge/SidebarPlugin.tsdocs/.vitepress/plugins/badge/constants.tsdocs/.vitepress/plugins/badge/index.tsdocs/.vitepress/plugins/badge/utils.tsdocs/.vitepress/theme/style.cssdocs/package.jsondocs/src/guide/plugin-badge.mddocs/tsconfig.json
✅ Files skipped from review due to trivial changes (1)
- docs/src/guide/plugin-badge.md
🚧 Files skipped from review as they are similar to previous changes (4)
- docs/.vitepress/plugins/badge/MarkdownPlugin.ts
- docs/.vitepress/theme/style.css
- docs/.vitepress/plugins/badge/constants.ts
- docs/tsconfig.json
🧰 Additional context used
🧬 Code graph analysis (1)
docs/.vitepress/plugins/badge/SidebarPlugin.ts (1)
docs/.vitepress/plugins/badge/utils.ts (1)
withBadge(66-69)
🔇 Additional comments (10)
docs/package.json (1)
10-14: LGTM!The new devDependencies are appropriate for the badge plugin system:
@types/nodefor Node.js type definitions andgray-matterfor frontmatter parsing in the SidebarBadgePlugin.docs/.vitepress/config.mts (3)
6-6: LGTM!Clean import of the badge plugins from the new plugin barrel file.
81-81: LGTM!The SidebarBadgePlugin is correctly integrated into the Vite plugins array. Using default options is appropriate for the standard documentation setup.
103-104: LGTM!The MarkdownBadgePlugin is correctly integrated using the markdown-it plugin pattern via
md.use().docs/.vitepress/plugins/badge/index.ts (1)
1-10: LGTM!Clean barrel file that properly centralizes exports for the badge plugin ecosystem. The separation of type exports is a good practice.
docs/.vitepress/plugins/badge/SidebarPlugin.ts (1)
40-72: LGTM on the plugin lifecycle and error handling.The implementation correctly:
- Guards against re-processing with the
vpConfigcheck- Uses dynamic import for gray-matter (lazy loading)
- Handles missing config gracefully with warnings
- Provides debug logging option
docs/.vitepress/plugins/badge/utils.ts (4)
11-20: Good XSS prevention implementation.The
escapeHtmlfunction properly escapes all critical HTML special characters. Using a lookup map with a single regex replacement is efficient.
57-61: LGTM with security consideration noted.The badge text is properly escaped via
escapeHtml. The class name comes from the hardcodedBADGE_CLASS_MAPconstants, so it's safe from injection. Good security practice.
32-34: Type assertion relies on external validation.The cast
badge as BadgeTypeassumes the caller has validated that non-version badges are validBadgeTypevalues. This works given the current usage pattern, but consider adding validation if the public API surface expands.
66-69: LGTM!Clean utility function that combines text with the generated badge HTML.
c0bfdc5 to
1feaea6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (5)
.github/workflows/pr-ci-publish-packages.yml (4)
40-41: Consider using frozen lockfile for build reproducibility.Using
--no-frozen-lockfilein CI can lead to non-reproducible builds and unexpected dependency updates. Consider switching to the default frozen lockfile mode (plainpnpm i) to ensure consistency between CI runs.
6-9: Remove unused input or utilize it.The
pr-numberinput is declared as required but is never referenced in the workflow. Either remove this input if it's not needed, or use it if there's a missing implementation.
43-47: Fix artifact SHA reference for workflow_call context.This workflow is triggered via
workflow_call, not apull_requestevent. The expressiongithub.event.pull_request.head.shawill be unavailable, causing the artifact download to fail or use an incorrect SHA.🔎 Proposed fix
Add a SHA input to the workflow:
on: workflow_call: inputs: pr-number: description: 'Pull Request number' type: number required: true + sha: + description: 'Commit SHA to use for artifacts' + type: string + required: trueThen update the artifact name:
- name: Download build artifacts uses: actions/download-artifact@v4 with: - name: build-${{ github.event.pull_request.head.sha || github.sha }} + name: build-${{ inputs.sha }} path: .And update line 69 similarly:
- name: pkg-pr-new-output-${{ github.event.pull_request.head.sha || github.sha }} + name: pkg-pr-new-output-${{ inputs.sha }}
66-71: Fix artifact SHA reference for workflow_call context.Same issue as the download step:
github.event.pull_request.head.shais unavailable inworkflow_callcontext. Use theinputs.shaapproach suggested in the previous comment..github/workflows/pr-ci-build.yml (1)
6-9: Unused workflow input.The
skip-playgroundinput is defined but never used in the workflow. Either remove the unused input or implement conditional logic to skip relevant steps when this flag is true.
🧹 Nitpick comments (8)
docs/src/components/sender.md (1)
168-174: Detailed newline shortcut explanation enhances user guidance.This new tip section provides helpful clarification on exactly which keys insert newlines under different submitType configurations. The breakdown by submitType makes it easy for users to find the behavior they need.
Optional suggestion: Consider adding a simple visual (e.g., a side-by-side comparison showing "Press X to submit, Press Y to newline" for each submitType) in a future iteration if users report confusion, but the current text explanation is clear and complete.
packages/components/src/sender/composables/useKeyboardHandler.ts (1)
87-102: Consider refining scroll behavior after newline insertion.The
insertNewLinefunction always scrolls toscrollHeight(bottom), which might be disruptive if the user is viewing earlier content in a large textarea. Consider scrolling just enough to make the cursor visible instead:target.scrollTop = Math.max(0, target.scrollTop + target.offsetHeight)or use
scrollIntoViewon the cursor position..github/workflows/pr-deploy-preview.yml (1)
108-116: Consider pinning the Surge CLI version.Using
npx surgerelies on npm's default resolution, which might fetch different versions over time. For reproducible deployments, consider pinning to a specific version:- npx surge --project ./artifacts/docs/dist --domain $DEPLOY_DOMAIN --token $SURGE_TOKEN + npx [email protected] --project ./artifacts/docs/dist --domain $DEPLOY_DOMAIN --token $SURGE_TOKEN.github/workflows/pr-cleanup.yml (1)
18-18: Consider consistent Surge CLI version with deploy workflow.For consistency with the deploy workflow, consider using the same Surge version approach. If the deploy workflow pins a version (as suggested in my earlier comment), this cleanup workflow should use the same version.
.github/workflows/pr-ci-build.yml (2)
39-40: Consider using frozen lockfile for build reproducibility.Using
--no-frozen-lockfilein CI can lead to non-reproducible builds and unexpected dependency updates. Consider switching to the default frozen lockfile mode (plainpnpm i) to ensure consistency between CI runs.
52-62: Consider exposing SHA as an output or accepting it as input.For better integration with downstream workflows (like
pr-ci-publish-packages.yml), consider either:
- Adding a workflow output that exposes the SHA used for artifact naming, or
- Accepting SHA as an input to ensure consistency across workflow calls.
This would make artifact references more explicit and reliable across the CI pipeline.
docs/.vitepress/plugins/badge/SidebarPlugin.ts (2)
111-129: Consider handling nested sidebar items.The current implementation only processes top-level
group.itemsbut does not recursively handle nested item structures. If sidebar items can contain nesteditemsarrays, those badges won't be applied.Verify whether the sidebar structure supports nesting:
#!/bin/bash # Check if sidebar items can be nested rg -n "items.*items" docs/.vitepress/config.mts ast-grep --pattern $'sidebar: { $$$ items: [ $$$ items: $_ $$$ ] $$$ }'
115-126: Consider validating badge values before applying.The plugin applies any badge value from frontmatter without validation. If an invalid or unexpected badge value is encountered, it might render incorrectly or cause issues in the UI.
Consider adding validation to ensure the badge value matches expected types (e.g., checking against BADGE_TEXT_MAP keys if available) before calling
withBadge.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
.github/workflows/auto-publish.yml.github/workflows/dispatch-publish.yml.github/workflows/e2e-tests.yml.github/workflows/pr-ci-build.yml.github/workflows/pr-ci-e2e-test.yml.github/workflows/pr-ci-publish-packages.yml.github/workflows/pr-ci.yml.github/workflows/pr-cleanup.yml.github/workflows/pr-deploy-preview.ymldocs/.vitepress/config.mtsdocs/.vitepress/plugins/badge/MarkdownPlugin.tsdocs/.vitepress/plugins/badge/SidebarPlugin.tsdocs/.vitepress/plugins/badge/constants.tsdocs/.vitepress/plugins/badge/index.tsdocs/.vitepress/plugins/badge/utils.tsdocs/.vitepress/theme/style.cssdocs/.vitepress/themeConfig.tsdocs/package.jsondocs/src/components/mcp-server-picker.mddocs/src/components/sender.mddocs/src/guide/plugin-badge.mddocs/tsconfig.jsonpackage.jsonpackages/components/src/mcp-server-picker/index.vuepackages/components/src/sender/composables/useKeyboardHandler.tsscripts/build-docs.jsscripts/copy-playground.js
💤 Files with no reviewable changes (1)
- .github/workflows/e2e-tests.yml
🚧 Files skipped from review as they are similar to previous changes (6)
- docs/tsconfig.json
- docs/.vitepress/theme/style.css
- docs/.vitepress/plugins/badge/index.ts
- docs/.vitepress/plugins/badge/utils.ts
- docs/.vitepress/plugins/badge/MarkdownPlugin.ts
- docs/src/guide/plugin-badge.md
🧰 Additional context used
🧬 Code graph analysis (3)
scripts/copy-playground.js (1)
scripts/build-docs.js (1)
args(4-4)
docs/.vitepress/plugins/badge/SidebarPlugin.ts (2)
docs/.vitepress/plugins/badge/index.ts (2)
SidebarBadgeOptions(10-10)SidebarBadgePlugin(5-5)docs/.vitepress/plugins/badge/utils.ts (1)
withBadge(66-69)
packages/components/src/sender/composables/useKeyboardHandler.ts (1)
packages/components/src/sender/index.type.ts (1)
SubmitTrigger(15-15)
🔇 Additional comments (21)
docs/src/components/sender.md (3)
20-24: Clear and helpful update to auto-switch behavior documentation.The revised tip accurately explains the two conditions for single-line mode auto-switching: width overflow and Ctrl+Enter/Shift+Enter (when
submitType="enter"). This provides users with upfront clarity on the interaction between input modes and keyboard shortcuts.
149-155: Excellent addition of submitType and newline behavior reference.The new info block clearly documents the three submitType modes and their corresponding newline behavior, along with the important note about auto-switching to multi-line when using newline shortcuts in single-line mode. This serves as a solid reference point for users.
162-163: Keyboard shortcut table correctly reflects updated behavior.The table now accurately shows that Ctrl+Enter and Shift+Enter apply to both
submitType="ctrlEnter"(andsubmitType="shiftEnter"respectively) andsubmitType="enter"(for newline). The conditions are correctly combined.docs/src/components/mcp-server-picker.md (1)
83-89: LGTM! Clear documentation for the new slot.The Slots section is well-structured and properly documents the new
header-actionsslot, following the same format as the Props and Events sections.packages/components/src/mcp-server-picker/index.vue (1)
306-306: LGTM! Proper slot implementation.The
header-actionsslot is correctly placed in the header's right section, providing a clean extension point for consumers to add custom header actions.docs/.vitepress/plugins/badge/constants.ts (1)
1-48: LGTM! Well-structured badge constants.The type definitions, mappings, and regex patterns are clearly documented and correctly implemented. The VERSION_NUMBER_REGEX properly supports semantic versioning with optional prefixes and metadata, and the MARKDOWN_BADGE_REGEX correctly matches badge markers in documentation.
packages/components/src/sender/composables/useKeyboardHandler.ts (2)
109-129: LGTM! Clean newline handling logic.The
handleNewLinefunction correctly manages Ctrl+Enter and Shift+Enter behavior, properly switching modes when needed and inserting newlines appropriately.
134-187: LGTM! Well-structured keyboard event handling.The refactored
handleKeyPressfunction has a clear flow with proper priority ordering: composing check → newline handling → suggestion navigation → escape handling → submit check. The simplified submit logic is cleaner and easier to maintain..github/workflows/pr-deploy-preview.yml (2)
61-106: LGTM! Robust package preview comment handling.The script properly handles both creating and updating package preview comments using an identifier marker, ensuring idempotent updates and preventing comment spam.
22-28: The artifact naming is correct and will match in all valid execution scenarios. Thepr-ci-build.ymlworkflow uploads artifacts asbuild-${{ github.event.pull_request.head.sha || github.sha }}when called frompr-ci.yml(triggered by PR events), andpr-deploy-preview.ymldownloads the same artifact usingbuild-${{ github.event.workflow_run.head_sha }}. The conditiongithub.event.workflow_run.event == 'pull_request'ensures the deploy workflow only runs for PR-triggered CI runs, guaranteeing the SHA variables match.docs/package.json (1)
10-10: LGTM! Appropriate devDependencies for badge plugin support.The additions of
@types/nodefor TypeScript type definitions andgray-matterfor frontmatter parsing align well with the new badge plugin functionality introduced in this PR.Also applies to: 14-14
docs/.vitepress/config.mts (1)
6-7: LGTM! Clean integration of badge plugins and centralized theme config.The badge plugins are properly registered in both the Vite plugin chain (SidebarBadgePlugin) and the markdown-it processor (MarkdownBadgePlugin). Extracting the theme configuration to a separate module improves maintainability.
Also applies to: 40-40, 62-63, 70-70
.github/workflows/pr-cleanup.yml (1)
23-34: LGTM! Proper cleanup status communication.The cleanup comment uses
maintain-one-commentwith a body identifier, ensuring idempotent updates and clear communication of the cleanup status to PR participants.scripts/build-docs.js (1)
1-25: LGTM!The build orchestration logic is clear and correct. The conditional component build based on the
--nocomponentsflag, sequential execution of builds, and error handling are well implemented..github/workflows/auto-publish.yml (1)
106-111: LGTM!The consolidated docs build approach with the
--nocomponentsflag is efficient since components are already built in step 7. The addition ofPLAYGROUND_BASEenvironment variable aligns with the unified docs build strategy.docs/.vitepress/themeConfig.ts (1)
1-61: LGTM!The theme configuration is well-structured with proper reuse of
sharedSidebarItemsacross multiple routes, and clear separation of navigation and sidebar concerns..github/workflows/dispatch-publish.yml (1)
85-90: LGTM!The consolidated docs build approach mirrors the changes in
auto-publish.ymland correctly skips component rebuilding since they're already built in step 7.scripts/copy-playground.js (1)
1-39: LGTM!The refactoring to use CLI arguments makes the script more flexible and reusable. The validation logic for arguments, source existence, and destination parent directory is thorough, and error handling is appropriate.
docs/.vitepress/plugins/badge/SidebarPlugin.ts (2)
35-73: LGTM with minor observations.The plugin initialization and config resolution logic is well-structured with proper error handling and debug logging. The early return pattern (line 44) prevents re-processing, and the dynamic import of gray-matter is a good practice for optional dependencies.
145-150: Path construction works correctly for the current sidebar configuration, which uses only simple relative paths.The code at line 146 constructs paths assuming link values are simple relative paths (e.g.,
'quick-start','container') without leading slashes. This assumption is valid because the sidebar configuration inthemeConfig.tsconsistently uses this format. The function includes defensive error handling—it checks file existence before reading and returnsundefinedgracefully on errors, protecting against malformed links.package.json (1)
10-11: LGTM! Script refactoring improves maintainability.The refactored build scripts are cleaner and more maintainable. Moving the build orchestration to
scripts/build-docs.jsand making the playground copy arguments explicit improves clarity and reduces command-line complexity.
| - name: Install dependencies | ||
| run: pnpm i --no-frozen-lockfile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use --frozen-lockfile in CI for reproducibility.
Installing dependencies without --frozen-lockfile in CI environments can lead to non-deterministic builds if the lockfile is out of sync with package.json. This can cause tests to pass locally but fail in CI, or vice versa.
🔎 Proposed fix
- name: Install dependencies
- run: pnpm i --no-frozen-lockfile
+ run: pnpm i --frozen-lockfile📝 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.
| - name: Install dependencies | |
| run: pnpm i --no-frozen-lockfile | |
| - name: Install dependencies | |
| run: pnpm i --frozen-lockfile |
🤖 Prompt for AI Agents
In .github/workflows/pr-ci-e2e-test.yml around lines 35 to 36, the CI step runs
"pnpm i --no-frozen-lockfile" which allows installs to modify or ignore the
lockfile and causes non-deterministic builds; change the command to use "pnpm i
--frozen-lockfile" so the job fails if the lockfile is out of sync and ensures
reproducible installs in CI.
| - name: Upload Playwright Test Report | ||
| uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| with: | ||
| name: playwright-report-${{ github.sha }} | ||
| path: packages/test/playwright-report/ | ||
| retention-days: 13 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent artifact naming with download step.
Line 56 uses github.sha for the artifact name, but line 41 uses github.event.pull_request.head.sha || github.sha. This inconsistency could lead to mismatched artifact names when the workflow runs in different contexts.
🔎 Proposed fix
- name: Upload Playwright Test Report
uses: actions/upload-artifact@v4
if: always()
with:
- name: playwright-report-${{ github.sha }}
+ name: playwright-report-${{ github.event.pull_request.head.sha || github.sha }}
path: packages/test/playwright-report/
retention-days: 13🤖 Prompt for AI Agents
.github/workflows/pr-ci-e2e-test.yml around lines 52 to 58: the uploaded
Playwright artifact name uses github.sha which is inconsistent with the download
step that expects github.event.pull_request.head.sha || github.sha; update the
artifact name expression to use the same conditional
(github.event.pull_request.head.sha || github.sha) so the upload and download
steps reference an identical artifact name.
| publish-packages: | ||
| needs: [build] | ||
| if: github.event_name == 'pull_request' | ||
| uses: ./.github/workflows/pr-ci-publish-packages.yml | ||
| with: | ||
| pr-number: ${{ github.event.pull_request.number }} | ||
| secrets: inherit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass SHA to publish-packages workflow.
The pr-ci-publish-packages.yml workflow needs a sha input to correctly reference build artifacts (see comments on that file). Add the SHA input here:
🔎 Proposed fix
publish-packages:
needs: [build]
if: github.event_name == 'pull_request'
uses: ./.github/workflows/pr-ci-publish-packages.yml
with:
pr-number: ${{ github.event.pull_request.number }}
+ sha: ${{ github.event.pull_request.head.sha || github.sha }}
secrets: inherit🤖 Prompt for AI Agents
In .github/workflows/pr-ci.yml around lines 32 to 38, the publish-packages job
isn't passing the commit SHA to the called workflow; add a sha input to the with
block (matching the pr-ci-publish-packages.yml expected input) and set it to the
PR head SHA (use ${{ github.event.pull_request.head.sha }}), ensuring the child
workflow can correctly reference the build artifacts.
| - name: Remove Surge deployment | ||
| run: | | ||
| DEPLOY_DOMAIN=preview-${{ github.event.pull_request.number }}-tiny-robot.surge.sh | ||
| echo "Removing deployment: $DEPLOY_DOMAIN" | ||
| npx surge teardown $DEPLOY_DOMAIN --token $SURGE_TOKEN | ||
| env: | ||
| SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} | ||
| continue-on-error: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Compare domain patterns in both workflows
echo "=== Deploy workflow domain pattern ==="
rg "DEPLOY_DOMAIN=" .github/workflows/pr-deploy-preview.yml -A 1
echo ""
echo "=== Cleanup workflow domain pattern ==="
rg "DEPLOY_DOMAIN=" .github/workflows/pr-cleanup.yml -A 1Repository: opentiny/tiny-robot
Length of output: 424
🏁 Script executed:
#!/bin/bash
# Find the step that outputs pr.number in the deploy workflow
rg -B 5 "steps.pr.outputs.number" .github/workflows/pr-deploy-preview.yml | head -20Repository: opentiny/tiny-robot
Length of output: 903
🏁 Script executed:
#!/bin/bash
# Find the step that has id: pr and outputs the number
rg -B 2 -A 5 "id: pr" .github/workflows/pr-deploy-preview.ymlRepository: opentiny/tiny-robot
Length of output: 306
Fix domain pattern mismatch between deploy and cleanup workflows.
The cleanup workflow uses github.event.pull_request.number to construct the domain, while the deploy workflow reads the PR number from artifacts/pr_number.txt via steps.pr.outputs.number. This mismatch means cleanup may attempt to remove a different deployment URL than what was deployed.
Update the cleanup workflow to use the same PR number source as deploy:
DEPLOY_DOMAIN=preview-${{ steps.pr.outputs.number }}-tiny-robot.surge.sh
Alternatively, update the deploy workflow to use github.event.pull_request.number directly so both workflows reference the same context variable.
🤖 Prompt for AI Agents
.github/workflows/pr-cleanup.yml lines 14-21: The cleanup job builds the
DEPLOY_DOMAIN using github.event.pull_request.number which differs from the
deploy workflow that uses steps.pr.outputs.number, causing cleanup to target the
wrong URL; update the cleanup workflow to read the PR number from the same
source as deploy by replacing github.event.pull_request.number with
steps.pr.outputs.number (DEPLOY_DOMAIN=preview-${{ steps.pr.outputs.number
}}-tiny-robot.surge.sh), or instead change the deploy workflow to emit/derive
the PR number from github.event.pull_request.number so both workflows use the
same variable.

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