Skip to content

Conversation

@zerob13
Copy link
Collaborator

@zerob13 zerob13 commented Oct 14, 2025

Summary

  • default the streaming artifact dialog to the code view unless preview-only types have finished loading, so partial content keeps updating correctly
  • track manually dismissed artifact contexts so the dialog stays closed until the next generation
  • allow user-triggered artifact previews to bypass the dismissal guard

Testing

  • pnpm run lint

https://chatgpt.com/codex/tasks/task_e_68ee2f1a78bc832c8749adf13f9428de

Summary by CodeRabbit

  • New Features

    • Per-context dismissal so closed previews don’t auto-reopen.
    • Option to force-open an artifact preview from actions.
    • Smarter auto-preview defaults for images, mermaid, and react artifacts plus a user-set preview flag.
    • Improved language normalization/detection so the editor language better matches artifact content.
    • Editor cleanup on component unmount to avoid leftover resources.
  • Bug Fixes

    • Back/close now consistently dismisses previews.
    • More reliable behavior when switching artifacts and when artifact status changes.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 14, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds per-context artifact dismissal to the artifact store (dismissedContexts + makeContextKey), exposes dismissArtifact(), extends showArtifact(...) with optional { force } behavior and updates call sites to pass { force: true }; refactors ArtifactDialog and CodeArtifact for language normalization, preview-state tracking, and Monaco teardown.

Changes

Cohort / File(s) Summary
Artifact store: dismissal & options
src/renderer/src/stores/artifact.ts
Adds dismissedContexts and makeContextKey; showArtifact(..., options?: { force?: boolean }) respects dismissed contexts unless force is true; adds and exposes dismissArtifact().
Dialog: preview lifecycle & language handling
src/renderer/src/components/artifacts/ArtifactDialog.vue
Replaces hideArtifact with dismissArtifact; adds userHasSetPreview, activeArtifactContext, getArtifactContextKey, AUTO_PREVIEW_TYPES, getDefaultPreviewState; introduces language normalization, improved watchers for artifact/status/language, initializes editor on mount, and onBeforeUnmount Monaco cleanup.
Code artifact: language normalization & preview
src/renderer/src/components/artifacts/CodeArtifact.vue
Adds sanitizeLanguage for initial codeLanguage and detection results; updates preview to call showArtifact(..., { force: true }).
Preview entrypoints: forced show option
src/renderer/src/components/artifacts/ArtifactPreview.vue, src/renderer/src/components/markdown/MarkdownRenderer.vue
Updated artifactStore.showArtifact(...) calls to include { force: true } as fourth argument.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant UI as Component (Dialog/Preview/Code/Markdown)
  participant Store as ArtifactStore
  participant D as DismissedContexts

  User->>UI: request show/preview artifact
  UI->>Store: showArtifact(artifact, messageId, threadId, { force? })
  alt options.force == true
    Store->>D: remove(contextKey)
    Store-->>UI: show artifact
  else
    Store->>D: has(contextKey)?
    alt dismissed
      Store-->>UI: skip show
    else
      Store-->>UI: show artifact
    end
  end

  User->>UI: close/back
  UI->>Store: dismissArtifact()
  Store->>D: add(contextKey)
  Store-->>UI: hide artifact
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I’m a rabbit tapping keys beneath moonlight,
Contexts kept tidy, previews set just right.
Force the show or gently dismiss,
I hop through states with a tiny twist,
Code and canvas gleam in midnight light. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly summarizes the primary change by indicating a fix to “stabilize streaming artifact dialog behavior,” which aligns with the PR objectives of improving the artifact dialog’s loading, dismissal, and preview logic. It is concise, specific, and focused on the main feature affected without unnecessary details or generic phrasing. This makes it easy for reviewers to understand the intent at a glance.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/fix-artifactdialog-loading-issues

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

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting

Copy link
Contributor

@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: 0

🧹 Nitpick comments (3)
src/renderer/src/stores/artifact.ts (2)

16-18: Prefer type alias over interface for small option bags

Use a type alias to follow the repo guideline (prefer types over interfaces).

As per coding guidelines

-interface ShowArtifactOptions {
-  force?: boolean
-}
+type ShowArtifactOptions = { force?: boolean }

56-67: Consider a small API to clear old dismissed contexts

The Set can grow over long sessions. Expose a reset helper (global or per-thread) and add it to the store return.

 const dismissArtifact = () => {
   if (currentArtifact.value && currentMessageId.value && currentThreadId.value) {
     const contextKey = makeContextKey(
       currentArtifact.value.id,
       currentMessageId.value,
       currentThreadId.value
     )
     dismissedContexts.value.add(contextKey)
   }
   hideArtifact()
 }
+
+const resetDismissedContexts = (scope?: { threadId?: string }) => {
+  // Clear all by default
+  if (!scope?.threadId) {
+    dismissedContexts.value.clear()
+    return
+  }
+  // Or clear only entries for a specific thread
+  dismissedContexts.value = new Set(
+    [...dismissedContexts.value].filter((k) => !k.startsWith(`${scope.threadId}:`))
+  )
+}

Add to return:

   hideArtifact,
   dismissArtifact,
+  resetDismissedContexts,
   validateContext,

Also applies to: 82-92

src/renderer/src/components/artifacts/ArtifactDialog.vue (1)

255-255: Preview-state logic matches spec; consider simplifying watchers

  • Defaults to code view until preview-only types are loaded; preserves user toggle via userHasSetPreview. Looks right.
  • Small simplification opportunity: compute isPreview from (artifact, status, userHasSetPreview, userSelection) to reduce two watchers and duplication.

Example direction:

  • Track userSelection: 'preview' | 'code' | null
  • isPreview = computed(() => userSelection != null ? userSelection === 'preview' : getDefaultPreviewState(artifact))

Optional, defer if out of scope.

Also applies to: 349-359, 362-362, 372-384, 391-403

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8f271c and 0dd1ed0.

📒 Files selected for processing (5)
  • src/renderer/src/components/artifacts/ArtifactDialog.vue (6 hunks)
  • src/renderer/src/components/artifacts/ArtifactPreview.vue (1 hunks)
  • src/renderer/src/components/artifacts/CodeArtifact.vue (1 hunks)
  • src/renderer/src/components/markdown/MarkdownRenderer.vue (1 hunks)
  • src/renderer/src/stores/artifact.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (20)
src/renderer/src/**/*

📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)

src/renderer/src/**/*: All user-facing strings must use i18n keys (avoid hardcoded user-visible text in code)
Use the 'vue-i18n' framework for all internationalization in the renderer
Ensure all user-visible text in the renderer uses the translation system

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/**/*.{vue,ts,js,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

渲染进程代码放在 src/renderer

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability
Implement proper state management with Pinia
Utilize Vue Router for navigation and route management
Leverage Vue's built-in reactivity system for efficient data handling

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/src/**/*.vue

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

Use scoped styles to prevent CSS conflicts between components

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/*.{ts,tsx,vue}: Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
Use TypeScript for all code; prefer types over interfaces.
Avoid enums; use const objects instead.
Use arrow functions for methods and computed properties.
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/**/*.{vue,ts}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

Implement lazy loading for routes and components.

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/**/*.{ts,vue}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching.
Implement SEO best practices using Nuxt's useHead and useSeoMeta.

Use Pinia for frontend state management (do not introduce alternative state libraries)

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use English for all logs and comments

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Enable and adhere to strict TypeScript typing (avoid implicit any, prefer precise types)

Use PascalCase for TypeScript types and classes

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/{src,shell,floating}/**/*.vue

📄 CodeRabbit inference engine (CLAUDE.md)

src/renderer/{src,shell,floating}/**/*.vue: Use Vue 3 Composition API for all components
All user-facing strings must use i18n keys via vue-i18n (no hard-coded UI strings)
Use Tailwind CSS utilities and ensure styles are scoped in Vue components

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/src/components/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Organize UI components by feature within src/renderer/src/

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/src/**

📄 CodeRabbit inference engine (AGENTS.md)

Place Vue 3 app source under src/renderer/src (components, stores, views, i18n, lib)

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/src/**/*.{vue,ts}

📄 CodeRabbit inference engine (AGENTS.md)

All user-facing strings must use vue-i18n ($t/keys) rather than hardcoded literals

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
**/*.{ts,tsx,js,jsx,vue,css,scss,md,json,yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

Prettier style: single quotes, no semicolons, print width 100; run pnpm run format

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx,vue}: Use OxLint for JS/TS code; keep lint clean
Use camelCase for variables and functions
Use SCREAMING_SNAKE_CASE for constants

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/stores/artifact.ts
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
src/renderer/**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

Name Vue component files in PascalCase (e.g., ChatInput.vue)

Files:

  • src/renderer/src/components/markdown/MarkdownRenderer.vue
  • src/renderer/src/components/artifacts/CodeArtifact.vue
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
  • src/renderer/src/components/artifacts/ArtifactPreview.vue
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)

**/*.{js,jsx,ts,tsx}: 使用 OxLint 进行代码检查
Log和注释使用英文书写

Files:

  • src/renderer/src/stores/artifact.ts
src/{main,renderer}/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)

src/{main,renderer}/**/*.ts: Use context isolation for improved security
Implement proper inter-process communication (IPC) patterns
Optimize application startup time with lazy loading
Implement proper error handling and logging for debugging

Files:

  • src/renderer/src/stores/artifact.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-logging.mdc)

**/*.{ts,tsx}: 始终使用 try-catch 处理可能的错误
提供有意义的错误信息
记录详细的错误日志
优雅降级处理
日志应包含时间戳、日志级别、错误代码、错误描述、堆栈跟踪(如适用)、相关上下文信息
日志级别应包括 ERROR、WARN、INFO、DEBUG
不要吞掉错误
提供用户友好的错误信息
实现错误重试机制
避免记录敏感信息
使用结构化日志
设置适当的日志级别

Files:

  • src/renderer/src/stores/artifact.ts
src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/pinia-best-practices.mdc)

src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx}: Use modules to organize related state and actions
Implement proper state persistence for maintaining data across sessions
Use getters for computed state properties
Utilize actions for side effects and asynchronous operations
Keep the store focused on global state, not component-specific data

Files:

  • src/renderer/src/stores/artifact.ts
⏰ 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-check (x64)
🔇 Additional comments (6)
src/renderer/src/stores/artifact.ts (1)

27-42: Per-context dismissal guard + force override look correct

Respects previously dismissed contexts and allows user-triggered force to show. Matches the PR intent.

src/renderer/src/components/markdown/MarkdownRenderer.vue (1)

80-82: LGTM: user-triggered preview bypasses dismissal

Passing { force: true } aligns with the new store API and UX.

src/renderer/src/components/artifacts/ArtifactPreview.vue (1)

316-318: LGTM: explicit force when opening from preview card

Ensures previews open even if the context was previously dismissed via the dialog.

Confirm that using hideArtifact (Line 304) on second click (toggle-close) is intentional vs dismissArtifact. If toggling should suppress auto-reopen during streaming, switch to dismissArtifact.

src/renderer/src/components/artifacts/CodeArtifact.vue (1)

190-192: LGTM: forced display for HTML/SVG preview

Matches the store’s new options and intended behavior.

src/renderer/src/components/artifacts/ArtifactDialog.vue (2)

19-21: Use dismissArtifact on back/close

Correctly records a manual dismissal and hides the dialog, matching the per-context guard.


233-234: Typed import for ArtifactState

Good addition; keeps helpers strongly typed.

Copy link
Contributor

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/renderer/src/components/artifacts/CodeArtifact.vue (2)

130-168: Replace hardcoded language display names with i18n keys.

All language display names are hardcoded strings, which violates the coding guidelines requiring all user-facing text to use i18n translation keys via vue-i18n. As per coding guidelines.

Refactor to use i18n keys. For example:

 const displayLanguage = computed(() => {
   const lang = codeLanguage.value
-  const displayNames: Record<string, string> = {
-    javascript: 'JavaScript',
-    typescript: 'TypeScript',
-    python: 'Python',
+  const displayNames: Record<string, string> = {
+    javascript: t('languages.javascript'),
+    typescript: t('languages.typescript'),
+    python: t('languages.python'),
     // ... rest of mappings
   }

Then add corresponding keys to your i18n locale files:

{
  "languages": {
    "javascript": "JavaScript",
    "typescript": "TypeScript",
    "python": "Python",
    // ... etc
  }
}

202-202: Remove or sanitize the language fallback.

The fallback lowerLang || props.block.artifact?.language introduces inconsistency. Since lowerLang comes from the already-sanitized codeLanguage.value, falling back to the unsanitized props.block.artifact?.language defeats the purpose of sanitization. If lowerLang is empty, the fallback should also be sanitized or simply removed (empty string is valid).

Apply this diff to sanitize the fallback:

-      language: lowerLang || props.block.artifact?.language,
+      language: lowerLang || sanitizeLanguage(props.block.artifact?.language),

Or remove the fallback entirely if empty language is acceptable:

-      language: lowerLang || props.block.artifact?.language,
+      language: lowerLang,
🧹 Nitpick comments (3)
src/renderer/src/components/artifacts/CodeArtifact.vue (3)

74-89: Add explicit return type annotation.

For better type safety and clarity, explicitly annotate the return type as string.

Apply this diff:

-const sanitizeLanguage = (language?: string | null) => {
+const sanitizeLanguage = (language?: string | null): string => {
   if (!language) return ''
   const normalized = language.trim().toLowerCase()

78-88: Expand language alias mappings for better coverage.

The current alias list is limited. Consider adding common aliases like jsjavascript, tstypescript, pypython, shshell, ymlyaml, etc., to improve normalization consistency across different language identifiers.

Apply this diff to add common aliases:

   switch (normalized) {
+    case 'js':
+      return 'javascript'
+    case 'ts':
+      return 'typescript'
+    case 'py':
+      return 'python'
     case 'md':
       return 'markdown'
     case 'plain':
     case 'text':
       return 'plaintext'
     case 'htm':
       return 'html'
+    case 'sh':
+      return 'shell'
+    case 'yml':
+      return 'yaml'
     default:
       return normalized
   }

74-89: Consider extracting sanitizeLanguage to a shared utility module.

Since multiple artifact-related components might need language normalization (ArtifactDialog, ArtifactPreview, etc.), consider extracting this helper to a shared utility file like src/renderer/src/lib/language-utils.ts for better reusability and maintainability.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0dd1ed0 and b30f1bf.

📒 Files selected for processing (2)
  • src/renderer/src/components/artifacts/ArtifactDialog.vue (6 hunks)
  • src/renderer/src/components/artifacts/CodeArtifact.vue (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/renderer/src/components/artifacts/ArtifactDialog.vue
🧰 Additional context used
📓 Path-based instructions (16)
src/renderer/src/**/*

📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)

src/renderer/src/**/*: All user-facing strings must use i18n keys (avoid hardcoded user-visible text in code)
Use the 'vue-i18n' framework for all internationalization in the renderer
Ensure all user-visible text in the renderer uses the translation system

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/**/*.{vue,ts,js,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

渲染进程代码放在 src/renderer

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability
Implement proper state management with Pinia
Utilize Vue Router for navigation and route management
Leverage Vue's built-in reactivity system for efficient data handling

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/src/**/*.vue

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

Use scoped styles to prevent CSS conflicts between components

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/*.{ts,tsx,vue}: Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
Use TypeScript for all code; prefer types over interfaces.
Avoid enums; use const objects instead.
Use arrow functions for methods and computed properties.
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/**/*.{vue,ts}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

Implement lazy loading for routes and components.

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/**/*.{ts,vue}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching.
Implement SEO best practices using Nuxt's useHead and useSeoMeta.

Use Pinia for frontend state management (do not introduce alternative state libraries)

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use English for all logs and comments

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Enable and adhere to strict TypeScript typing (avoid implicit any, prefer precise types)

Use PascalCase for TypeScript types and classes

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/{src,shell,floating}/**/*.vue

📄 CodeRabbit inference engine (CLAUDE.md)

src/renderer/{src,shell,floating}/**/*.vue: Use Vue 3 Composition API for all components
All user-facing strings must use i18n keys via vue-i18n (no hard-coded UI strings)
Use Tailwind CSS utilities and ensure styles are scoped in Vue components

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/src/components/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Organize UI components by feature within src/renderer/src/

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/src/**

📄 CodeRabbit inference engine (AGENTS.md)

Place Vue 3 app source under src/renderer/src (components, stores, views, i18n, lib)

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/src/**/*.{vue,ts}

📄 CodeRabbit inference engine (AGENTS.md)

All user-facing strings must use vue-i18n ($t/keys) rather than hardcoded literals

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
**/*.{ts,tsx,js,jsx,vue,css,scss,md,json,yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

Prettier style: single quotes, no semicolons, print width 100; run pnpm run format

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx,vue}: Use OxLint for JS/TS code; keep lint clean
Use camelCase for variables and functions
Use SCREAMING_SNAKE_CASE for constants

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
src/renderer/**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

Name Vue component files in PascalCase (e.g., ChatInput.vue)

Files:

  • src/renderer/src/components/artifacts/CodeArtifact.vue
🔇 Additional comments (2)
src/renderer/src/components/artifacts/CodeArtifact.vue (2)

207-209: LGTM! User-triggered preview bypasses dismissal guard.

The { force: true } option correctly implements the PR objective of allowing user-triggered artifact previews to bypass the dismissal guard.


91-91: LGTM! Consistent sanitization across language handling.

The sanitizeLanguage helper is correctly applied in initialization (line 91), detection (line 96), and watch logic (line 237), ensuring consistent language normalization throughout the component lifecycle.

Also applies to: 96-96, 237-237

Copy link
Contributor

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (14)
src/renderer/src/components/artifacts/ArtifactDialog.vue (14)

1-1: Fix Prettier formatting to pass CI checks.

The pipeline reports a Prettier formatting failure. Run the following command to fix:

pnpm run format

14-14: Replace Chinese comment with English.

The coding guidelines require all comments to be in English.

Apply this diff:

-      <!-- 顶部导航栏 -->
+      <!-- Top navigation bar -->

As per coding guidelines.


314-314: Replace any type with proper HTMLElement type.

Using any violates the strict TypeScript guidelines.

Apply this diff:

-const codeEditor = ref<any>(null)
+const codeEditor = ref<HTMLDivElement | null>(null)

As per coding guidelines.


26-27: Replace Chinese comment with English.

Apply this diff:

-          <!-- 预览/代码切换按钮组 -->
+          <!-- Preview/Code toggle button group -->

As per coding guidelines.


52-53: Replace Chinese comment with English.

Apply this diff:

-          <!-- 设备尺寸切换按钮组 (仅在HTML预览时显示) -->
+          <!-- Device size toggle buttons (shown only in HTML preview) -->

As per coding guidelines.


95-96: Replace Chinese comment with English.

Apply this diff:

-          <!-- 尺寸微调输入框 (仅在平板和手机模式下显示) -->
+          <!-- Size adjustment inputs (shown only in tablet and mobile modes) -->

As per coding guidelines.


143-144: Replace Chinese comment with English.

Apply this diff:

-          <!-- 导出按钮 -->
+          <!-- Export buttons -->

As per coding guidelines.


195-196: Replace Chinese comment with English.

Apply this diff:

-      <!-- 内容区域 -->
+      <!-- Content area -->

As per coding guidelines.


258-259: Replace Chinese comment with English.

Apply this diff:

-const tabletHeight = ref(1024) // 4:3 比例
-const mobileHeight = ref(667) // 16:9 比例
+const tabletHeight = ref(1024) // 4:3 aspect ratio
+const mobileHeight = ref(667) // 16:9 aspect ratio

As per coding guidelines.


529-530: Replace Chinese comment with English.

Apply this diff:

-    // 如果是 Mermaid 图表,需要先渲染成 SVG
+    // If it's a Mermaid diagram, render it to SVG first

As per coding guidelines.


537-538: Replace Chinese comment with English.

Apply this diff:

-    // 确保 SVG 内容是有效的
+    // Ensure SVG content is valid

As per coding guidelines.


579-579: Replace Chinese string with i18n key.

The error log contains a hardcoded Chinese string. According to coding guidelines, all user-facing strings must use i18n keys, and logs should be in English.

Apply this diff:

-      console.error('复制失败', e)
+      console.error('Copy failed', e)

As per coding guidelines.


592-596: Replace Chinese comment with English.

Apply this diff:

-  // 检查是否是 iframe 类型的 artifact (HTML 或 React)
+  // Check if this is an iframe-type artifact (HTML or React)

As per coding guidelines.


600-608: Replace Chinese comments with English.

Apply this diff:

   if (isIframeArtifact) {
-    // 对于 iframe 类型,我们使用 iframe 元素作为滚动容器
+    // For iframe types, use the iframe element as the scroll container
     containerSelector = '.html-iframe-wrapper'
     targetSelector = '.html-iframe-wrapper'
   } else {
-    // 非 iframe 类型使用默认配置
+    // Non-iframe types use default configuration
     containerSelector = '.artifact-scroll-container'
     targetSelector = '.artifact-dialog-content'
   }

As per coding guidelines.

🧹 Nitpick comments (2)
src/renderer/src/components/artifacts/ArtifactDialog.vue (2)

282-306: LGTM! Consider extracting type mapping.

The normalizeLanguage function correctly derives language from artifact properties with appropriate fallbacks.

For maintainability, consider extracting the type-to-language mapping:

const ARTIFACT_TYPE_TO_LANGUAGE = {
  'application/vnd.ant.code': 'plaintext',
  'text/markdown': 'markdown',
  'text/html': 'html',
  'image/svg+xml': 'svg',
  'application/vnd.ant.mermaid': 'mermaid',
  'application/vnd.ant.react': 'jsx'
} as const

const normalizeLanguage = (artifact: ArtifactState | null) => {
  if (!artifact) return ''
  
  const explicit = sanitizeLanguage(artifact.language)
  if (explicit) return explicit
  
  return ARTIFACT_TYPE_TO_LANGUAGE[artifact.type] || sanitizeLanguage(artifact.type)
}

425-484: Consider consolidating editor cleanup.

Both the isOpen watcher (lines 425-432) and onBeforeUnmount (lines 482-484) call cleanupEditor(). While defensive, this may be redundant. Consider whether cleanup on dialog close is needed if onBeforeUnmount always runs before component destruction.

If the dialog can be closed without unmounting the component, the current dual-cleanup approach is correct. Otherwise, onBeforeUnmount alone would suffice.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b30f1bf and 0a1dbee.

📒 Files selected for processing (1)
  • src/renderer/src/components/artifacts/ArtifactDialog.vue (6 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
src/renderer/src/**/*

📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)

src/renderer/src/**/*: All user-facing strings must use i18n keys (avoid hardcoded user-visible text in code)
Use the 'vue-i18n' framework for all internationalization in the renderer
Ensure all user-visible text in the renderer uses the translation system

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/**/*.{vue,ts,js,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

渲染进程代码放在 src/renderer

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability
Implement proper state management with Pinia
Utilize Vue Router for navigation and route management
Leverage Vue's built-in reactivity system for efficient data handling

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/src/**/*.vue

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

Use scoped styles to prevent CSS conflicts between components

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/*.{ts,tsx,vue}: Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
Use TypeScript for all code; prefer types over interfaces.
Avoid enums; use const objects instead.
Use arrow functions for methods and computed properties.
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/**/*.{vue,ts}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

Implement lazy loading for routes and components.

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/**/*.{ts,vue}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching.
Implement SEO best practices using Nuxt's useHead and useSeoMeta.

Use Pinia for frontend state management (do not introduce alternative state libraries)

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use English for all logs and comments

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Enable and adhere to strict TypeScript typing (avoid implicit any, prefer precise types)

Use PascalCase for TypeScript types and classes

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/{src,shell,floating}/**/*.vue

📄 CodeRabbit inference engine (CLAUDE.md)

src/renderer/{src,shell,floating}/**/*.vue: Use Vue 3 Composition API for all components
All user-facing strings must use i18n keys via vue-i18n (no hard-coded UI strings)
Use Tailwind CSS utilities and ensure styles are scoped in Vue components

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/src/components/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Organize UI components by feature within src/renderer/src/

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/src/**

📄 CodeRabbit inference engine (AGENTS.md)

Place Vue 3 app source under src/renderer/src (components, stores, views, i18n, lib)

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/src/**/*.{vue,ts}

📄 CodeRabbit inference engine (AGENTS.md)

All user-facing strings must use vue-i18n ($t/keys) rather than hardcoded literals

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
**/*.{ts,tsx,js,jsx,vue,css,scss,md,json,yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

Prettier style: single quotes, no semicolons, print width 100; run pnpm run format

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx,vue}: Use OxLint for JS/TS code; keep lint clean
Use camelCase for variables and functions
Use SCREAMING_SNAKE_CASE for constants

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

Name Vue component files in PascalCase (e.g., ChatInput.vue)

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
🪛 GitHub Actions: PR Check
src/renderer/src/components/artifacts/ArtifactDialog.vue

[error] 1-1: Prettier formatting check failed (exit code 1) for ArtifactDialog.vue. Run 'prettier --write' to fix formatting.

🔇 Additional comments (9)
src/renderer/src/components/artifacts/ArtifactDialog.vue (9)

265-280: LGTM! Clean language normalization.

The sanitizeLanguage function properly handles common language aliases with good defensive null/undefined checks.


325-331: LGTM! Stable context key generation.

The getArtifactContextKey function properly creates stable context identifiers for dismissal tracking, aligning with the PR objectives.


368-370: Verify language detection is still needed.

Since codeLanguage is now initialized with normalizeLanguage(artifactStore.currentArtifact) at line 308, the condition !codeLanguage.value at line 368 may rarely (or never) be true, preventing auto-detection from running. If auto-detection is still needed as a fallback for unrecognized types, consider checking for 'plaintext' or empty string instead:

-    if (!codeLanguage.value) {
+    if (!codeLanguage.value || codeLanguage.value === 'plaintext') {
       throttledDetectLanguage(newCode)
     }

Alternatively, if explicit language from normalizeLanguage should always take precedence, the current logic is correct and this check serves as a safety net.


405-423: LGTM! Proper editor lifecycle management.

The watcher correctly initializes the Monaco editor only when all conditions are met (dialog open, code view active, element available). The flush: 'post' option ensures the DOM is ready.


437-447: Excellent! Aligns perfectly with PR objectives.

The AUTO_PREVIEW_TYPES set combined with the status !== 'loaded' check (line 445) ensures the dialog defaults to code view during streaming and only switches to preview for specific types after content has fully loaded. This directly implements the PR objective: "Default the streaming artifact dialog to the code view unless preview-only types have finished loading."


449-452: LGTM! Tracks explicit user preview toggles.

Setting userHasSetPreview when the user explicitly changes the preview mode is essential for preserving their choice during streaming updates.


458-475: LGTM! Respects user choice and loading state.

The status watcher properly respects userHasSetPreview (line 466) and defers to getDefaultPreviewState only when the user hasn't explicitly set a preference. This ensures user actions persist while still providing sensible defaults for loaded artifacts.


337-378: Consider removing deep: true to avoid performance issues
The deep watcher may fire on every property change during streaming. No existing performance-streaming tests were found—manually validate streaming performance or remove deep: true and rely on the separate content watcher for granular updates.


19-19: artifactStore.dismissArtifact is defined in the artifact store
The dismissArtifact method is declared (lines 56–63) and exported (line 89) in src/renderer/src/stores/artifact.ts, so this call is valid.

@zerob13 zerob13 merged commit a83d76a into dev Oct 14, 2025
1 of 2 checks passed
Copy link
Contributor

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/renderer/src/components/artifacts/ArtifactDialog.vue (1)

571-575: Use English in logs

-      console.error('复制失败', e)
+      console.error('Copy failed', e)

As per coding guidelines.

♻️ Duplicate comments (2)
src/renderer/src/components/artifacts/ArtifactDialog.vue (2)

427-427: Replace Chinese comment with English

-// 截图相关功能
+// Screenshot functionality

As per coding guidelines.


471-473: Replace Chinese comment with English

-  // 获取应用版本
+  // Get application version

As per coding guidelines.

🧹 Nitpick comments (5)
src/renderer/src/components/artifacts/ArtifactDialog.vue (5)

265-281: Normalize languages for Monaco; drop mermaid early-return so code view updates

  • Monaco doesn’t register mermaid or svg; map to markdown/xml for highlighting.
  • Remove the mermaid early return to keep code view in sync.

Apply:

@@
-    case 'image/svg+xml':
-      return 'svg'
+    case 'image/svg+xml':
+      return 'xml'
@@
-    case 'application/vnd.ant.mermaid':
-      return 'mermaid'
+    case 'application/vnd.ant.mermaid':
+      return 'markdown'

And:

-    if (codeLanguage.value === 'mermaid') {
-      return
-    }

Also applies to: 282-306, 363-365


337-362: Don’t remount preview on every streaming update

componentKey.value++ runs on each currentArtifact change; this remounts preview components repeatedly. Only bump when the artifact context actually changes.

-    componentKey.value++
@@
-    if (isNewArtifact) {
+    if (isNewArtifact) {
+      componentKey.value++
       activeArtifactContext.value = newContextKey
       userHasSetPreview.value = false
       isPreview.value = getDefaultPreviewState(newArtifact)
     }

367-375: Reduce duplicate code updates; rely on dedicated watchers

updateCode is executed in this deep watcher and also in the content and language watchers, causing redundant updates. Make this watcher shallow and drop the inline update.

@@
-    const newCode = newArtifact.content || ''
-
-    if (!codeLanguage.value) {
-      throttledDetectLanguage(newCode)
-    }
-
-    updateCode(newCode, codeLanguage.value)
+    const newCode = newArtifact.content || ''
+    if (!codeLanguage.value) throttledDetectLanguage(newCode)
@@
-    deep: true // Add deep watching to catch property changes
+    // Shallow watch; content and language updates handled by dedicated watchers

Also applies to: 376-379, 393-404


406-417: Guard Monaco initialization to avoid duplicate editors; type the ref

Add a readiness flag to prevent re-creating the editor on every toggle/open.

@@
-const codeEditor = ref<any>(null)
+const codeEditor = ref<HTMLDivElement | null>(null)
+const editorReady = ref(false)
@@
-  ([editorEl, previewActive, open]) => {
+  ([editorEl, previewActive, open]) => {
     if (!open || previewActive || !editorEl) return
-    void createEditor(editorEl, artifactStore.currentArtifact?.content || '', codeLanguage.value)
+    if (editorReady.value) {
+      updateCode(artifactStore.currentArtifact?.content || '', codeLanguage.value)
+      return
+    }
+    void createEditor(editorEl, artifactStore.currentArtifact?.content || '', codeLanguage.value)
+    editorReady.value = true
   },
@@
   (open) => {
     if (!open) {
       cleanupEditor()
+      editorReady.value = false
     }
   }
 )
@@
 onBeforeUnmount(() => {
   cleanupEditor()
+  editorReady.value = false
 })

Also applies to: 418-425, 475-477, 314-315


325-334: Reuse artifact store’s makeContextKey

Export makeContextKey from src/renderer/src/stores/artifact.ts, import it in ArtifactDialog.vue, and replace the manual ${threadId}:${messageId}:${artifact.id} logic with makeContextKey(artifact.id, messageId, threadId) to ensure consistency.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a1dbee and 2aa1295.

📒 Files selected for processing (1)
  • src/renderer/src/components/artifacts/ArtifactDialog.vue (6 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
src/renderer/src/**/*

📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)

src/renderer/src/**/*: All user-facing strings must use i18n keys (avoid hardcoded user-visible text in code)
Use the 'vue-i18n' framework for all internationalization in the renderer
Ensure all user-visible text in the renderer uses the translation system

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/**/*.{vue,ts,js,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

渲染进程代码放在 src/renderer

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability
Implement proper state management with Pinia
Utilize Vue Router for navigation and route management
Leverage Vue's built-in reactivity system for efficient data handling

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/src/**/*.vue

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

Use scoped styles to prevent CSS conflicts between components

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/*.{ts,tsx,vue}: Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
Use TypeScript for all code; prefer types over interfaces.
Avoid enums; use const objects instead.
Use arrow functions for methods and computed properties.
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/**/*.{vue,ts}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

Implement lazy loading for routes and components.

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/**/*.{ts,vue}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching.
Implement SEO best practices using Nuxt's useHead and useSeoMeta.

Use Pinia for frontend state management (do not introduce alternative state libraries)

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use English for all logs and comments

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Enable and adhere to strict TypeScript typing (avoid implicit any, prefer precise types)

Use PascalCase for TypeScript types and classes

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/{src,shell,floating}/**/*.vue

📄 CodeRabbit inference engine (CLAUDE.md)

src/renderer/{src,shell,floating}/**/*.vue: Use Vue 3 Composition API for all components
All user-facing strings must use i18n keys via vue-i18n (no hard-coded UI strings)
Use Tailwind CSS utilities and ensure styles are scoped in Vue components

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/src/components/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Organize UI components by feature within src/renderer/src/

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/src/**

📄 CodeRabbit inference engine (AGENTS.md)

Place Vue 3 app source under src/renderer/src (components, stores, views, i18n, lib)

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/src/**/*.{vue,ts}

📄 CodeRabbit inference engine (AGENTS.md)

All user-facing strings must use vue-i18n ($t/keys) rather than hardcoded literals

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
**/*.{ts,tsx,js,jsx,vue,css,scss,md,json,yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

Prettier style: single quotes, no semicolons, print width 100; run pnpm run format

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx,vue}: Use OxLint for JS/TS code; keep lint clean
Use camelCase for variables and functions
Use SCREAMING_SNAKE_CASE for constants

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
src/renderer/**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

Name Vue component files in PascalCase (e.g., ChatInput.vue)

Files:

  • src/renderer/src/components/artifacts/ArtifactDialog.vue
⏰ 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-check (x64)
🔇 Additional comments (3)
src/renderer/src/components/artifacts/ArtifactDialog.vue (3)

19-21: Back button: switch to dismissArtifact looks correct

Updated to artifactStore.dismissArtifact aligns with store API changes.


430-441: Auto-preview defaults match PR intent

AUTO_PREVIEW_TYPES and getDefaultPreviewState implement “preview when loaded for preview-only types.” Looks good.


443-446: User choice persists across streaming updates

setPreview marks userHasSetPreview; the status watcher respects it. This fixes the prior reset issue during partial updates.

Please confirm artifact.id remains stable during streaming; otherwise userHasSetPreview could reset unexpectedly on identity changes.

Also applies to: 454-465

@zerob13 zerob13 deleted the codex/fix-artifactdialog-loading-issues branch January 6, 2026 12:18
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.

2 participants