feat: add Vue ecosystem review support#2241
Conversation
Add vue-reviewer agent specializing in: - Composition API correctness and reactivity pitfalls (ref/reactive/computed/watch) - Vue 3.5+ reactive props destructure (stabilized, with watch limitation notes) - Composable patterns, template security, accessibility - Pinia state management, Vue Router navigation, Nuxt SSR safety - Vue-specific performance (shallowRef, v-memo, KeepAlive) Scope clearly delineated from typescript-reviewer for cross-invocation on .vue PRs.
Add rules/vue/coding-style.md: - <script setup> Composition API enforcement - Naming conventions (PascalCase components, useCamelCase composables) - SFC structure order, props/emits/slots patterns - Vue 3.5+ reactive props destructure with native default values - Template conventions, import ordering Add rules/vue/hooks.md: - ref() vs reactive() guidance and replacement pitfalls - Vue 3.5+ reactive props destructure (version-specific: Vue<3.5 loses reactivity, 3.5+ reactive by default with watch limitation) - computed() purity rules, watch vs watchEffect comparison - Watcher cleanup with onWatcherCleanup() (Vue 3.5+) and onCleanup callback - useTemplateRef() (Vue 3.5+) replacing name-matched plain refs - Composable conventions (use prefix, reactive returns, MaybeRef inputs) - shallowRef/shallowReactive for large data structures
Add rules/vue/patterns.md: - Presentational vs Container component design - Provide/Inject, Scoped Slots, Teleport (with 3.5+ defer prop) - State management decision tree and Pinia Setup Store patterns - Vue Router navigation guards, lazy loading, reactive route params - v-for/v-if patterns, v-model (Vue 3.4+ defineModel) - Scoped CSS (:deep, :slotted), KeepAlive with max, Dynamic Components - Vue 3.5+ new APIs: useId(), data-allow-mismatch, Suspense - Nuxt-specific patterns and Vue 2 migration notes Add rules/vue/security.md: - v-html XSS audit (DOMPurify sanitization checklist) - Unsafe URL binding validation (javascript:/data: scheme prevention) - Custom directive innerHTML injection - Secret exposure via VITE_ prefix and Nuxt runtimeConfig - Nuxt Nitro server API input validation with zod - localStorage/sessionStorage token risks, SSR browser API guards - target=_blank rel=noopener, CSP minimum policy - Prototype pollution, source maps in production - Vue 3.5+ SSR hydration mismatch security notes
Add rules/vue/testing.md: - Vitest + Vue Test Utils + @pinia/testing stack - Component mounting (mount vs shallowMount), stubs and mocks - Composable testing with effectScope and mountComposable helper - Pinia store testing pattern (setActivePinia + ) - Vue Router testing with createMemoryHistory - Async assertion pitfalls (flushPromises/nextTick) - Testing implementation details vs rendered output - Coverage thresholds: 80%+ for composables/stores, smoke tests for components - Vitest configuration with jsdom environment and v8 coverage
Add skills/vue-patterns/SKILL.md covering: - Project structure (feature-first layout, file naming) - Component architecture (SFC order, presentational vs container, props/emits) - Composables (use prefix, MaybeRef/toValue, cleanup, vs mixins) - State management decision tree (local → props → provide/inject → Pinia → server state) - Vue Router patterns (lazy loading, navigation guards, reactive params) - Template patterns (v-if/v-else, v-show, v-for, v-model with defineModel) - Performance techniques (shallowRef, v-memo, v-once, KeepAlive, Suspense) - Testing stack and patterns (Vitest, Vue Test Utils, Pinia testing) - Nuxt-specific patterns (auto-imports, useAsyncData, server routes, runtime config) - Vue 3.5+ new APIs section: reactive props destructure, useTemplateRef, onWatcherCleanup, useId, defer Teleport, lazy hydration - Anti-patterns table with Vue 3.5+ version-specific notes
Add commands/vue-review.md providing: - /vue-review command entry point for Vue.js code review - Automated checks: eslint with eslint-plugin-vue, vue-tsc, npm audit - Review categories with severity (CRITICAL/HIGH/MEDIUM) - Vue 3.5+ specific items: reactive props destructure, useTemplateRef, onWatcherCleanup - Scope vs /code-review and typescript-reviewer (non-overlapping lanes) - Example review report output format - Integration guidance with build/test commands
|
ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR. |
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR adds comprehensive Vue.js code review support to ECC, including a new ChangesVue.js Code Review Support
Sequence DiagramsequenceDiagram
participant User
participant CLI as /vue-review
participant VueAgent as vue-reviewer
participant TSAgent as typescript-reviewer
participant Registry as COMMAND-REGISTRY
participant Rules as rules/vue/*
User->>CLI: invoke `/vue-review` or command call
CLI->>VueAgent: analyze Vue files (security, reactivity, patterns)
CLI->>TSAgent: run TypeScript checks (types, imports)
VueAgent->>Rules: consult style/hooks/patterns/security/testing docs
CLI->>Registry: record/lookup `vue-review` command metadata
VueAgent-->>User: formatted Vue review report
TSAgent-->>User: TypeScript findings
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. 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 |
|
| Filename | Overview |
|---|---|
| agents/vue-reviewer.md | New Vue.js reviewer agent with comprehensive scope table, versioned Vue 3.5+ guidance, prompt-injection defense baseline, and well-defined approval criteria. Correctly delineates vue-reviewer vs typescript-reviewer lanes. |
| commands/vue-review.md | New /vue-review command matching agent scope; CRITICAL section correctly qualifies prop destructuring with Vue < 3.5 version caveat. |
| rules/vue/testing.md | Solid Vue testing guidance (Vitest, Vue Test Utils, Pinia, Router), but the header extension reference to react/testing.md is an incorrect cross-framework dependency. |
| rules/vue/coding-style.md | Comprehensive Vue coding-style rules covering API style, SFC ordering, props/emits, slots, template conventions, and version-split guidance for Vue 3.5+ props destructuring. |
| rules/vue/hooks.md | Detailed composable and reactivity rules — ref vs reactive, watcher pitfalls, version-aware props destructuring, onWatcherCleanup (Vue 3.5+), and module-scope side-effect prohibition. |
| rules/vue/security.md | Vue security rules covering v-html XSS, unsafe URL bindings, env variable exposure, Nuxt runtime config, localStorage token storage, target=_blank, prototype pollution, and CSP guidance. |
| rules/vue/patterns.md | Vue architecture patterns for container/presentational split, provide/inject, Pinia setup stores, Vue Router guards, list rendering, forms, Teleport, KeepAlive, and Vue 3.5+ APIs. |
| skills/vue-patterns/SKILL.md | 471-line skill covering project structure, component architecture, composables, Pinia, Vue Router, templates, performance, testing, Nuxt SSR, Vue 3.5+ APIs, and anti-patterns table. |
| scripts/ci/catalog.js | Removes the rc.1 release-note regex check from both parseReadmeExpectations and syncEnglishReadme, decoupling the historical changelog entry from live catalog counts. |
| docs/COMMAND-REGISTRY.json | Adds vue-review command entry, bumps totalCommands and testing count. typescript-reviewer added to topAgents with count:2. |
| manifests/install-components.json | Adds framework:vue and skill:vue-patterns install components, both resolved through the shared framework-language module — consistent with other framework skills. |
| tests/ci/validators.test.js | Fixture README updated to use 9/9/9 for the historical release-note line; test now asserts that value is PRESERVED after sync, correctly matching the catalog.js behavior change. |
| tests/ci/catalog.test.js | rc.1 release-note assertion removed, replaced with a check that fixture value 7/7/7 is preserved post-sync. Consistent and correct. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["/vue-review command"] --> B["vue-reviewer agent"]
A --> C["typescript-reviewer agent"]
B --> D["rules/vue/coding-style.md"]
B --> E["rules/vue/hooks.md"]
B --> F["rules/vue/patterns.md"]
B --> G["rules/vue/security.md"]
B --> H["rules/vue/testing.md"]
B --> I["skills/vue-patterns/SKILL.md"]
C --> J["(existing typescript rules)"]
B --> K{Scope split}
K -->|"Vue-specific"| L["Reactivity · Composables · v-html · Pinia · Router · SSR · a11y"]
K -->|"Deferred to TS reviewer"| M["any abuse · async · Node.js security · generic XSS"]
Reviews (2): Last reviewed commit: "fix: address Vue review PR feedback" | Re-trigger Greptile
| { | ||
| "agent": "planner", | ||
| "count": 1 | ||
| }, | ||
| { | ||
| "agent": "python-reviewer", | ||
| "count": 1 | ||
| } |
There was a problem hiding this comment.
python-reviewer silently dropped from topAgents statistics
python-reviewer is still referenced by commands/python-review.md (count: 1), so it should remain in the topAgents block. Removing it while adding typescript-reviewer with count: 2 suggests the list may have been updated by hand to keep a fixed length rather than being regenerated from the full command set. If the catalog-check script validates this block, the test may be passing a truncated list rather than an exhaustive one.
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/COMMAND-REGISTRY.json`:
- Around line 923-938: The vue-review registry entry currently lists only the
"vue-patterns" skill; update the "vue-review" command's skills array (the JSON
object where "command": "vue-review") to include the shared "accessibility"
skill alongside "vue-patterns" so the review flow pulls in the common a11y
guidance.
In `@rules/vue/hooks.md`:
- Around line 220-243: The dynamic example in rules/vue/hooks.md uses the
reactive refId incorrectly and the template ref is static; update the example so
the template uses a dynamic ref attribute (e.g., :ref="refId") and call
useTemplateRef with the string key (unwrapped refId.value) so the call and
template match (refer to useTemplateRef, refId, dynamicEl in the snippet). Also
update skills/vue-patterns/SKILL.md to reword the “Supports dynamic ref IDs”
line to explicitly state the function expects the string template-ref key (not a
Ref object) so readers aren’t misled.
In `@rules/vue/patterns.md`:
- Around line 63-68: The v-for example declares only item but the slot uses
index; update the loop declaration to include the index (i.e. use the (item,
index) form in the v-for on the <li>) and ensure the :key remains valid (use
item.id or index consistently) so the snippet compiles and the slot prop :index
is defined for the <slot name="item" :item="item" :index="index" /> usage.
In `@rules/vue/security.md`:
- Around line 139-147: Update the example to match Nuxt’s Zod pattern: call
readValidatedBody(event, bodySchema.parse) instead of passing .safeParse
(replace the current readValidatedBody call that uses z.object(...).safeParse
with z.object(...).parse), then treat the returned value as the validated body
(e.g., const body = await readValidatedBody(...)) and remove the subsequent if
(!body.success) { throw ... } branch so no manual success/error checking is
performed.
In `@rules/vue/testing.md`:
- Around line 211-229: The router test snippet incorrectly uses
createWebHistory(); change it to createMemoryHistory() when creating the router
(the createRouter call) so tests use an in-memory history; update the import to
reference createMemoryHistory instead of createWebHistory and keep the rest
(router.push, router.isReady, mount(UserPage) with global.plugins) unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: c5a3d8d1-7bb0-47a7-8318-c270e6e30384
📒 Files selected for processing (19)
.claude-plugin/marketplace.json.claude-plugin/plugin.jsonAGENTS.mdREADME.mdREADME.zh-CN.mdagents/vue-reviewer.mdcommands/vue-review.mddocs/COMMAND-REGISTRY.jsondocs/zh-CN/AGENTS.mddocs/zh-CN/README.mdmanifests/install-components.jsonmanifests/install-modules.jsonpackage.jsonrules/vue/coding-style.mdrules/vue/hooks.mdrules/vue/patterns.mdrules/vue/security.mdrules/vue/testing.mdskills/vue-patterns/SKILL.md
📜 Review details
⏰ 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: Greptile Review
🧰 Additional context used
📓 Path-based instructions (10)
commands/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Commands should be formatted as Markdown with description frontmatter.
Files:
commands/vue-review.md
{agents,skills,commands}/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Use lowercase filenames with hyphens (e.g.,
python-reviewer.md,tdd-workflow.md) for agents, skills, and commands.
Files:
commands/vue-review.mdagents/vue-reviewer.mdskills/vue-patterns/SKILL.md
{skills,commands,agents,rules}/**
⚙️ CodeRabbit configuration file
{skills,commands,agents,rules}/**: Focus on prompt-injection resilience, tool-permission scope, destructive action guards, and secret exfiltration risks.
Files:
commands/vue-review.mdagents/vue-reviewer.mdrules/vue/coding-style.mdrules/vue/hooks.mdrules/vue/testing.mdrules/vue/security.mdskills/vue-patterns/SKILL.mdrules/vue/patterns.md
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,swift,kt,rs,c,cpp,h,hpp,properties,yml,yaml,json,env,config}
📄 CodeRabbit inference engine (.cursor/rules/common-security.md)
NEVER hardcode secrets in source code - ALWAYS use environment variables or a secret manager
Files:
manifests/install-components.jsonmanifests/install-modules.jsonpackage.jsondocs/COMMAND-REGISTRY.json
**/*.{js,ts,jsx,tsx,json,env*}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Do not hardcode secrets, API keys, passwords, or tokens
Files:
manifests/install-components.jsonmanifests/install-modules.jsonpackage.jsondocs/COMMAND-REGISTRY.json
**/*.{js,ts,jsx,tsx,py,java,go,rs,kt,cpp,cc,h,hpp,fs,fsx,json,yaml,yml,env,conf,config,properties,xml}
📄 CodeRabbit inference engine (AGENTS.md)
No hardcoded secrets (API keys, passwords, tokens); use environment variables or a secret manager
Files:
manifests/install-components.jsonmanifests/install-modules.jsonpackage.jsondocs/COMMAND-REGISTRY.json
agents/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Agents should be formatted as Markdown with YAML frontmatter containing name, description, tools, and model fields.
Files:
agents/vue-reviewer.md
{package.json,*.config.js,scripts/**/*.js}
📄 CodeRabbit inference engine (CLAUDE.md)
Package manager detection should support npm, pnpm, yarn, and bun, with configuration via CLAUDE_PACKAGE_MANAGER environment variable or project config.
Files:
package.json
skills/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Skills should be formatted as Markdown with clear sections for When to Use, How It Works, and Examples.
Files:
skills/vue-patterns/SKILL.md
README.md
📄 CodeRabbit inference engine (CLAUDE.md)
When working on README.md files, use the
/readmeskill.
Files:
README.md
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Organize code by feature/domain, not by type, with high cohesion and low coupling
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Validate all user inputs at system boundaries using schema-based validation
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Handle errors at every level; provide user-friendly messages in UI code and detailed context logging server-side
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Enable CSRF protection on all endpoints
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Verify authentication and authorization on all sensitive operations
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Implement rate limiting on all endpoints
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Error messages should not leak sensitive data
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Write tests before implementation using TDD workflow: write test first (RED), write minimal implementation (GREEN), refactor (IMPROVE)
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Maintain minimum 80% test coverage across unit tests, integration tests, and E2E tests
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Use conventional commits format: <type>: <description> with types (feat, fix, refactor, docs, test, chore, perf, ci)
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: New workflow contributions should land in `skills/` first as the canonical workflow surface
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Delegate to specialized agents: planner for complex features, tdd-guide for new features/bugs, code-reviewer after writing code, security-reviewer for sensitive code
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Use Repository pattern to encapsulate data access: implement standard interface (findAll, findById, create, update, delete) with business logic depending on abstract interface
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:22.952Z
Learning: Use consistent API response envelope format with success indicator, data payload, error message, and pagination metadata
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:42.677Z
Learning: Use the Agent-First approach: delegate domain-specific tasks to specialized agents (planner, architect, code-reviewer, security-reviewer, tdd-guide, etc.) rather than handling all tasks directly
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:42.677Z
Learning: Plan complex features before implementation using the planner agent; identify dependencies, risks, and break work into phases
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:42.677Z
Learning: Use the security-reviewer agent for code containing sensitive operations or before committing security-critical code
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:42.677Z
Learning: Follow conventional commit format: `<type>: <description>` where type is feat, fix, refactor, docs, test, chore, perf, or ci
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:42.677Z
Learning: Use the Repository pattern to encapsulate data access logic behind standard interfaces (findAll, findById, create, update, delete); depend on abstractions, not storage mechanisms
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:42.677Z
Learning: Use a consistent API response format with success indicator, data payload, error message, and pagination metadata
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:42.677Z
Learning: For large refactorings and multi-file features, avoid using the last 20% of the context window; reserve capacity for emergencies and mid-task corrections
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:42.677Z
Learning: Document team and project knowledge (architecture decisions, API changes, operational procedures) in the project's existing documentation structure; avoid duplicating information in multiple locations
Learnt from: CR
Repo: affaan-m/ECC
Timestamp: 2026-06-12T11:29:42.677Z
Learning: Use the build-error-resolver agent to fix build and type errors; analyze errors incrementally, fix one issue at a time, and verify after each fix
📚 Learning: 2026-03-15T19:02:43.245Z
Learnt from: imrobinsingh
Repo: affaan-m/everything-claude-code PR: 503
File: skills/data-scraper-agent/SKILL.md:1-748
Timestamp: 2026-03-15T19:02:43.245Z
Learning: In this repository, skill folders should use a lowercase-hyphen name (e.g., data-scraper-agent, claude-api) and the skill description file inside each folder should be named SKILL.md (uppercase). Do not flag SKILL.md as a naming violation; treat SKILL.md as the canonical file name inside each skill directory.
Applied to files:
skills/vue-patterns/SKILL.md
📚 Learning: 2026-04-15T15:52:59.963Z
Learnt from: manja316
Repo: affaan-m/everything-claude-code PR: 1360
File: skills/security-bounty-hunter/SKILL.md:11-18
Timestamp: 2026-04-15T15:52:59.963Z
Learning: In this repository’s skills documentation (skills/**/SKILL.md), use the canonical auto-activation skill section header `## When to Activate`—do not use `## When to Use`. CONTRIBUTING.md and docs/SKILL-DEVELOPMENT-GUIDE.md confirm the required header, and existing skills follow this convention. This header is important for the auto-activation mechanism to detect the correct section.
Applied to files:
skills/vue-patterns/SKILL.md
🪛 LanguageTool
agents/vue-reviewer.md
[style] ~12-~12: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...leak API keys, or expose credentials. - Do not output executable code, scripts, HT...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
skills/vue-patterns/SKILL.md
[grammar] ~102-~102: Ensure spelling is correct
Context: ...te. - Boolean props: isXxx, hasXxx, canXxx. - Never mutate props — emit events ins...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
rules/vue/patterns.md
[style] ~290-~290: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ot content styling, use :slotted(). - For global overrides, use a separate `<styl...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~412-~412: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ee skills/frontend-patterns/SKILL.md. For accessibility see `skills/accessibility...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🔇 Additional comments (15)
rules/vue/coding-style.md (1)
15-214: LGTM!rules/vue/patterns.md (2)
172-200:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winInclude error state in the async store example.
The rule above says async actions should handle loading, success, and error states, but
addItem()only toggles loading. IffetchProduct()rejects, the store has no error to expose to the UI.Suggested fix
export const useCartStore = defineStore("cart", () => { const items = ref<CartItem[]>([]); const isLoading = ref(false); + const error = ref<Error | null>(null); @@ async function addItem(productId: string) { isLoading.value = true; + error.value = null; try { const item = await fetchProduct(productId); const existing = items.value.find(i => i.id === item.id); if (existing) existing.quantity++; else items.value.push({ ...item, quantity: 1 }); + } catch (e) { + error.value = e as Error; } finally { isLoading.value = false; } } - return { items, isLoading, totalPrice, itemCount, addItem }; + return { items, isLoading, error, totalPrice, itemCount, addItem }; });> Likely an incorrect or invalid review comment.
45-56: Fix Vue examples to match the documented provide/inject and async-action rules
Provide/inject example uses a string key even though the rule says to use a shared
Symbolkey; update it accordingly.Suggested fix
+const themeKey = Symbol("theme"); const theme = ref<Theme>("light"); -provide("theme", readonly(theme)); +provide(themeKey, readonly(theme)); // Consumer — in any descendant -const theme = inject<Ref<Theme>>("theme"); +const theme = inject<Ref<Theme>>(themeKey);Scoped-slots example passes
:index="index"to the slot, but thev-forshown isv-for="item in items"(noindexis declared), so the example is broken as written.Pinia async example: confirm the async action body actually sets/clears
loading/successand assignserrorper the surrounding rule (even iferroris declared).agents/vue-reviewer.md (1)
1-206: LGTM!commands/vue-review.md (1)
1-175: LGTM!manifests/install-components.json (1)
1-634: LGTM!manifests/install-modules.json (1)
1-935: LGTM!package.json (1)
1-375: LGTM!.claude-plugin/marketplace.json (1)
1-48: LGTM!.claude-plugin/plugin.json (1)
1-32: LGTM!AGENTS.md (1)
3-3: LGTM!Also applies to: 152-154
README.md (1)
157-157: LGTM!Also applies to: 428-428, 558-558, 1510-1512, 1671-1673
README.zh-CN.md (1)
167-167: LGTM!Also applies to: 231-231, 1143-1145, 1251-1253
docs/zh-CN/AGENTS.md (1)
3-3: LGTM!Also applies to: 149-151
docs/zh-CN/README.md (1)
231-231: LGTM!Also applies to: 1143-1145, 1251-1253
| { | ||
| "command": "vue-review", | ||
| "description": "Comprehensive Vue.js code review for Composition API correctness, reactivity, composable patterns, template security, accessibility, and Vue-specific performance. Invokes the vue-reviewer agent (and typescript-reviewer alongside on .vue/.ts changes).", | ||
| "type": "testing", | ||
| "primaryAgents": [ | ||
| "typescript-reviewer", | ||
| "vue-reviewer" | ||
| ], | ||
| "allAgents": [ | ||
| "typescript-reviewer", | ||
| "vue-reviewer" | ||
| ], | ||
| "skills": [ | ||
| "vue-patterns" | ||
| ], | ||
| "path": "commands/vue-review.md" |
There was a problem hiding this comment.
Add the shared accessibility skill to vue-review.
The command and agent both advertise a11y checks, but the registry entry only wires vue-patterns. That leaves the Vue review flow without the shared accessibility guidance that other review commands pull in.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/COMMAND-REGISTRY.json` around lines 923 - 938, The vue-review registry
entry currently lists only the "vue-patterns" skill; update the "vue-review"
command's skills array (the JSON object where "command": "vue-review") to
include the shared "accessibility" skill alongside "vue-patterns" so the review
flow pulls in the common a11y guidance.
| ## `useTemplateRef()` (Vue 3.5+) | ||
|
|
||
| Use `useTemplateRef()` instead of matching a plain `ref` variable name to the template `ref` attribute. It supports dynamic ref IDs and provides better type safety. | ||
|
|
||
| ```vue | ||
| <script setup lang="ts"> | ||
| import { useTemplateRef } from "vue"; | ||
|
|
||
| // Static ref | ||
| const inputEl = useTemplateRef<HTMLInputElement>("input"); | ||
|
|
||
| // Dynamic ref | ||
| const refId = ref("input"); | ||
| const dynamicEl = useTemplateRef<HTMLInputElement>(refId); | ||
| </script> | ||
|
|
||
| <template> | ||
| <input ref="input" type="text" /> | ||
| </template> | ||
| ``` | ||
|
|
||
| - The string passed to `useTemplateRef()` must match the `ref` attribute value in the template, **not** the variable name. | ||
| - `@vue/language-tools` 2.1+ provides auto-completion and warnings for `useTemplateRef`. | ||
|
|
There was a problem hiding this comment.
Fix useTemplateRef() docs: dynamic ref example uses wrong argument type and doesn’t match the template.
- In
rules/vue/hooks.md, the “Dynamic ref” example passesrefId(Ref<string>) touseTemplateRef(...), butuseTemplateReftakes the string template-ref key; also the template usesref="input"(static), so it doesn’t demonstrate a dynamic ref—either use:ref="refId"and pass the unwrapped string (e.g.,refId.value), or remove the reactive-ID example. - In
skills/vue-patterns/SKILL.md, the “Supports dynamic ref IDs” line should clarify that the argument is the string key (not the reactive ref object).
https://vuejs.org/guide/essentials/template-refs
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@rules/vue/hooks.md` around lines 220 - 243, The dynamic example in
rules/vue/hooks.md uses the reactive refId incorrectly and the template ref is
static; update the example so the template uses a dynamic ref attribute (e.g.,
:ref="refId") and call useTemplateRef with the string key (unwrapped
refId.value) so the call and template match (refer to useTemplateRef, refId,
dynamicEl in the snippet). Also update skills/vue-patterns/SKILL.md to reword
the “Supports dynamic ref IDs” line to explicitly state the function expects the
string template-ref key (not a Ref object) so readers aren’t misled.
| <!-- Child --> | ||
| <template> | ||
| <ul> | ||
| <li v-for="item in items" :key="item.id"> | ||
| <slot name="item" :item="item" :index="index" /> | ||
| </li> |
There was a problem hiding this comment.
Declare index in the v-for example.
The slot props reference index, but the loop only declares item, so the snippet doesn’t compile as written.
Suggested fix
- <li v-for="item in items" :key="item.id">
+ <li v-for="(item, index) in items" :key="item.id">
<slot name="item" :item="item" :index="index" />📝 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.
| <!-- Child --> | |
| <template> | |
| <ul> | |
| <li v-for="item in items" :key="item.id"> | |
| <slot name="item" :item="item" :index="index" /> | |
| </li> | |
| <!-- Child --> | |
| <template> | |
| <ul> | |
| <li v-for="(item, index) in items" :key="item.id"> | |
| <slot name="item" :item="item" :index="index" /> | |
| </li> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@rules/vue/patterns.md` around lines 63 - 68, The v-for example declares only
item but the slot uses index; update the loop declaration to include the index
(i.e. use the (item, index) form in the v-for on the <li>) and ensure the :key
remains valid (use item.id or index consistently) so the snippet compiles and
the slot prop :index is defined for the <slot name="item" :item="item"
:index="index" /> usage.
| // Validate body (for POST/PUT) | ||
| const body = await readValidatedBody(event, z.object({ | ||
| name: z.string().min(1).max(100), | ||
| email: z.string().email(), | ||
| }).safeParse); | ||
|
|
||
| if (!body.success) { | ||
| throw createError({ statusCode: 400, message: body.error.message }); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the exact example around the referenced lines
sed -n '120,170p' rules/vue/security.md | cat -n
# Find all usages of readValidatedBody in the repo (to confirm expected calling convention)
rg -n "readValidatedBody\(" -S . || trueRepository: affaan-m/ECC
Length of output: 1920
🌐 Web query:
Nuxt 3 readValidatedBody(event schema.parse) safeParse return shape success error
💡 Result:
When you use readValidatedBody in Nuxt 3 (powered by the H3 server framework) with a Zod schema's safeParse method, the returned object follows the standard Zod safeParse result shape [1][2]. The result object will have one of the two following structures [3]: 1. Success case: { success: true, data: T } - success: A boolean value of true. - data: The validated and parsed data (of type T). 2. Error case: { success: false, error: ZodError } - success: A boolean value of false. - error: A ZodError object containing detailed information about the validation failure, accessible via the.errors array or the.issues array [1][3][2]. Unlike passing.parse (which automatically throws an error on validation failure), passing.safeParse to readValidatedBody allows you to handle validation results manually in your event handler, typically by checking the success property to return a custom error response (e.g., HTTP 400) or continue processing [1][2]. Example usage: export default defineEventHandler(async (event) => { const result = await readValidatedBody(event, myZodSchema.safeParse); if (!result.success) { throw createError({ status: 400, message: 'Invalid data', data: result.error.issues, // Or result.error.errors }); } const data = result.data; // Proceed with valid data });
Citations:
- 1: https://humanonlyweb.com/blog/validating-api-routes-in-nuxt-with-zod
- 2: https://soubiran.dev/posts/nuxt-going-full-stack-how-to-streamline-form-validation
- 3: https://github.com/colinhacks/zod/blob/main/packages/zod/src/v4/classic/parse.ts
🌐 Web query:
site:nuxt.com readValidatedBody readValidatedBody(event safeParse parse zod
💡 Result:
In Nuxt 4 (Nitro), the typical pattern is: 1) Build a Zod schema for the expected request body. 2) Call readValidatedBody(event, schema.parse) inside your defineEventHandler. 3) Destructure the validated fields from the returned object. Example (from Nuxt docs): ts import { z } from 'zod' const bodySchema = z.object({ email: z.email(), password: z.string().min(8), }) export default defineEventHandler(async (event) => { const { email, password } = await readValidatedBody(event, bodySchema.parse) // ...use validated values }) Nuxt’s server-side API also documents body reading with readBody(event), and notes a common caveat for webhook validation: validators may rely on the raw body being available (often cached/cloned), so you generally read/validate in the right order. For Zod validation specifically, Nuxt shows readValidatedBody with bodySchema.parse as the validator callback. [1][2][3]
Citations:
- 1: https://nuxt.com/docs/4.x/directory-structure/server
- 2: https://nuxt.com/docs/guide/recipes/sessions-and-authentication
- 3: https://nuxt.com/modules/webhook-validators
Align readValidatedBody example with Nuxt’s Zod pattern
Nuxt’s own examples use readValidatedBody(event, bodySchema.parse) and treat the return value as the validated body data (no body.success / body.error branch). If updating this example to match Nuxt, switch from .safeParse to .parse and remove the if (!body.success) { ... } block. (nuxt.com)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@rules/vue/security.md` around lines 139 - 147, Update the example to match
Nuxt’s Zod pattern: call readValidatedBody(event, bodySchema.parse) instead of
passing .safeParse (replace the current readValidatedBody call that uses
z.object(...).safeParse with z.object(...).parse), then treat the returned value
as the validated body (e.g., const body = await readValidatedBody(...)) and
remove the subsequent if (!body.success) { throw ... } branch so no manual
success/error checking is performed.
| import { createRouter, createWebHistory } from "vue-router"; | ||
| import { mount } from "@vue/test-utils"; | ||
| import UserPage from "./UserPage.vue"; | ||
|
|
||
| const router = createRouter({ | ||
| history: createWebHistory(), | ||
| routes: [ | ||
| { path: "/users/:id", component: UserPage, props: true }, | ||
| ], | ||
| }); | ||
|
|
||
| // Navigate before mounting | ||
| await router.push("/users/42"); | ||
| await router.isReady(); | ||
|
|
||
| const wrapper = mount(UserPage, { | ||
| global: { plugins: [router] }, | ||
| }); | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the referenced section in the repo
ls -la
sed -n '180,260p' rules/vue/testing.mdRepository: affaan-m/ECC
Length of output: 7545
🌐 Web query:
Vue Router createMemoryHistory test SSR recommended vs createWebHistory guidance
💡 Result:
For Server-Side Rendering (SSR) in Vue, createMemoryHistory is the required and recommended choice, whereas createWebHistory is recommended for client-side browser applications [1][2][3]. The essential guidance for these modes is as follows: createMemoryHistory: This mode is designed specifically for non-browser environments like Node.js [1][2]. Because it does not rely on the browser's window or location objects, it prevents ReferenceErrors (e.g., window is not defined) that occur if you attempt to use createWebHistory on the server [3]. Key characteristics include: - It does not interact with the browser URL nor automatically trigger initial navigation [1][2]. - It requires you to manually perform the initial navigation (e.g., calling router.push) to match the incoming server request URL [1][2][4]. - It is the standard for SSR setups [5][6]. createWebHistory: This is the recommended mode for standard Single Page Applications (SPAs) running in the browser [1][2]. - It utilizes the browser's History API to manage navigation [1]. - It is unsuitable for direct use in SSR environments because it expects a DOM environment and will fail when attempting to access browser-only globals [3]. Testing Guidance: When writing tests, the choice depends on your environment: - SSR/Node-based tests: Use createMemoryHistory to simulate routing without requiring a browser environment [1][2]. - Browser-based component tests: You can use createWebHistory or even createMemoryHistory if you wish to avoid browser URL changes during tests [1][2][7]. Regardless of the mode, ensure that each test creates its own isolated router instance to avoid cross-test state pollution [7]. In summary, for any SSR-related logic, use createMemoryHistory. For client-side rendering, use createWebHistory [1][2]. Most developers implement a factory function or a conditional check to switch between these modes based on the environment (server vs. client) [8][9].
Citations:
- 1: https://router.vuejs.org/guide/essentials/history-mode.html
- 2: https://github.com/vuejs/router/blob/245082aa/packages/docs/guide/essentials/history-mode.md
- 3: https://stackoverflow.com/questions/73925944/quasar-ssr-app-window-is-not-defined-from-vue-router
- 4: https://github.com/vuejs/router/blob/ea8e3e21/packages/router/src/history/memory.ts
- 5: https://nitro.build/examples/vite-ssr-vue-router
- 6: https://www.typeerror.org/docs/vue_router~4/guide/migration/index
- 7: https://test-utils.vuejs.org/guide/advanced/vue-router
- 8: https://php.fyi/articles/vue-3-ssr
- 9: How to do manual SSR vuejs/router#2065
Use createMemoryHistory() in the router test snippet
The “Vue Router Testing” example uses createWebHistory(), contradicting the section guidance to use createMemoryHistory() for tests (to avoid URL/history state leaks and browser coupling).
Suggested fix
-import { createRouter, createWebHistory } from "vue-router";
+import { createRouter, createMemoryHistory } from "vue-router";
@@
- history: createWebHistory(),
+ history: createMemoryHistory(),📝 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.
| import { createRouter, createWebHistory } from "vue-router"; | |
| import { mount } from "@vue/test-utils"; | |
| import UserPage from "./UserPage.vue"; | |
| const router = createRouter({ | |
| history: createWebHistory(), | |
| routes: [ | |
| { path: "/users/:id", component: UserPage, props: true }, | |
| ], | |
| }); | |
| // Navigate before mounting | |
| await router.push("/users/42"); | |
| await router.isReady(); | |
| const wrapper = mount(UserPage, { | |
| global: { plugins: [router] }, | |
| }); | |
| ``` | |
| import { createRouter, createMemoryHistory } from "vue-router"; | |
| import { mount } from "`@vue/test-utils`"; | |
| import UserPage from "./UserPage.vue"; | |
| const router = createRouter({ | |
| history: createMemoryHistory(), | |
| routes: [ | |
| { path: "/users/:id", component: UserPage, props: true }, | |
| ], | |
| }); | |
| // Navigate before mounting | |
| await router.push("/users/42"); | |
| await router.isReady(); | |
| const wrapper = mount(UserPage, { | |
| global: { plugins: [router] }, | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@rules/vue/testing.md` around lines 211 - 229, The router test snippet
incorrectly uses createWebHistory(); change it to createMemoryHistory() when
creating the router (the createRouter call) so tests use an in-memory history;
update the import to reference createMemoryHistory instead of createWebHistory
and keep the rest (router.push, router.isReady, mount(UserPage) with
global.plugins) unchanged.
|
ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
commands/vue-review.md (1)
13-13:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAlign typecheck command with agent spec — respect project's canonical command, not just
vue-tsc.Line 13 and lines 86-87 prescribe
vue-tsc --noEmitexclusively, but the upstream agent spec (agents/vue-reviewer.md:138-139) states "Run the project's typecheck command if present (vue-tsc --noEmit). Skip cleanly for JS-only projects." and listsnpm run typecheck --if-presentas the recommended fallback. The command doc should honor this contract: attempt the project's own typecheck command first, fall back tovue-tsc, and report clearly if neither exists.Without this flexibility, the command may fail on projects that use custom typecheck scripts (e.g.,
npm run check:typesortsc --noEmit) or lackvue-tscentirely.🔧 Suggested clarification
Line 13 (current):
3. **Typecheck**: Run `vue-tsc --noEmit` or the project's canonical typecheck commandLines 86-87 (current):
# Vue-specific typecheck vue-tsc --noEmitRevised to align with agent spec:
# Vue-specific typecheck (use project's canonical command if present) npm run typecheck --if-present 2>/dev/null || vue-tsc --noEmitAnd clarify in text:
## Automated Checks Run ```bash # Lint (required) npx eslint . --ext .vue,.ts,.js # Vue-specific typecheck (try project's command first, then vue-tsc) npm run typecheck --if-present 2>/dev/null || vue-tsc --noEmitIf both
npm run typecheckandvue-tscare unavailable, report as HIGH config issue.</details> Also applies to: 86-87 <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@commands/vue-review.mdat line 13, Update the typecheck step to honor the
agent spec by trying the project's canonical typecheck command first and falling
back to vue-tsc; replace the hardcoded "vue-tsc --noEmit" references with logic
that runs "npm run typecheck --if-present" (or the project's typecheck script)
and then "vue-tsc --noEmit" as a fallback, and ensure the docs/instructions
clearly state to report a HIGH config issue if neither command is available—look
for the occurrences of "vue-tsc --noEmit" in the file (the typecheck step and
the bash snippet around lines with the Vue-specific typecheck) and update the
text and example command accordingly.</details> <!-- cr-comment:v1:4ffe2aeae8ae5c971e8e541c --> </blockquote></details> </blockquote></details>🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. Inline comments: In `@commands/vue-review.md`: - Line 51: The doc currently claims "Destructuring reactive props in Vue < 3.5 (breaks reactivity)" but doesn't state the command's Vue version scope; either declare the version at the top of commands/vue-review.md (e.g., "This command targets Vue 3.5+ projects") if the tool only supports Vue 3.5+, or make the rule version-agnostic by rewording the category string "Destructuring reactive props..." to note it affects pre-3.5 projects (for example "Destructuring reactive props (may break reactivity in Vue < 3.5)") so readers know the compatibility; update the top-level intro or the category line accordingly to match the chosen scope. --- Outside diff comments: In `@commands/vue-review.md`: - Line 13: Update the typecheck step to honor the agent spec by trying the project's canonical typecheck command first and falling back to vue-tsc; replace the hardcoded "vue-tsc --noEmit" references with logic that runs "npm run typecheck --if-present" (or the project's typecheck script) and then "vue-tsc --noEmit" as a fallback, and ensure the docs/instructions clearly state to report a HIGH config issue if neither command is available—look for the occurrences of "vue-tsc --noEmit" in the file (the typecheck step and the bash snippet around lines with the Vue-specific typecheck) and update the text and example command accordingly.🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID:
bcdaa82b-2e13-4057-a010-a2d0413f63d0📒 Files selected for processing (5)
README.mdcommands/vue-review.mdscripts/ci/catalog.jstests/ci/catalog.test.jstests/ci/validators.test.js💤 Files with no reviewable changes (1)
- scripts/ci/catalog.js
📜 Review details
⏰ 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: Greptile Review
🧰 Additional context used
📓 Path-based instructions (17)
**/*.{js,ts,jsx,tsx,py,java,cs,go,rb,php,scala,kt}
📄 CodeRabbit inference engine (.cursor/rules/common-coding-style.md)
**/*.{js,ts,jsx,tsx,py,java,cs,go,rb,php,scala,kt}: Always create new objects, never mutate existing ones. Use immutable patterns to prevent hidden side effects and enable safe concurrency
Organize code into many small files (200-400 lines typical, 800 lines max) organized by feature/domain rather than by type
Always handle errors explicitly at every level and never silently swallow errors
Always validate all user input before processing at system boundaries
Use schema-based validation where available
Fail fast with clear error messages when validation fails
Never trust external data (API responses, user input, file content)
Ensure code is readable and well-named
Keep functions small (less than 50 lines)
Keep files focused (less than 800 lines)
Avoid deep nesting (more than 4 levels)
Do not use hardcoded values; use constants or configuration insteadFiles:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,swift,kt,rs,c,cpp,h,hpp}
📄 CodeRabbit inference engine (.cursor/rules/common-security.md)
No hardcoded secrets (API keys, passwords, tokens) - validate before any commit
Files:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php}
📄 CodeRabbit inference engine (.cursor/rules/common-security.md)
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php}: All user inputs must be validated
Enable CSRF protection on all state-changing endpoints
Verify authentication and authorization for all protected endpoints
Implement rate limiting on all endpoints to prevent abuse
Ensure error messages do not leak sensitive data in responsesFiles:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,sql}
📄 CodeRabbit inference engine (.cursor/rules/common-security.md)
Use parameterized queries to prevent SQL injection
Files:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{js,ts,jsx,tsx,html,php,java,cs,rb,go}
📄 CodeRabbit inference engine (.cursor/rules/common-security.md)
Implement XSS prevention by sanitizing HTML output
Files:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,swift,kt,rs,c,cpp,h,hpp,properties,yml,yaml,json,env,config}
📄 CodeRabbit inference engine (.cursor/rules/common-security.md)
NEVER hardcode secrets in source code - ALWAYS use environment variables or a secret manager
Files:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/typescript-coding-style.md)
**/*.{ts,tsx,js,jsx}: Use spread operator for immutable updates in TypeScript/JavaScript instead of direct mutation
Use async/await with try-catch for error handling in TypeScript/JavaScript
Use Zod for schema-based input validation in TypeScript/JavaScript
No console.log statements in production code; use proper logging libraries instead
**/*.{ts,tsx,js,jsx}: Auto-format JavaScript/TypeScript files using Prettier after edit
Warn aboutconsole.logstatements in edited files
Check all modified files forconsole.logstatements before session ends
**/*.{ts,tsx,js,jsx}: Use the ApiResponse interface pattern with generic type parameter:interface ApiResponse<T> { success: boolean; data?: T; error?: string; meta?: { total: number; page: number; limit: number; } }
Implement custom React hooks following the pattern: export a named function with use prefix, generic type parameters, and proper useEffect cleanup for side effects
**/*.{ts,tsx,js,jsx}: Never hardcode secrets; always use environment variables for sensitive credentials like API keys
Throw an error when required environment variables are not configured to fail fast and ensure security prerequisites are metUse Playwright as the E2E testing framework for critical user flows in TypeScript/JavaScript
Files:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{test,spec}.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{test,spec}.{js,ts,jsx,tsx}: Write tests before implementation (test-driven development); target 80%+ coverage
Achieve minimum 80% test coverage across all three layers: Unit, Integration, and E2E
Use AAA structure (Arrange / Act / Assert) in tests with descriptive test names that explain behavior under testFiles:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{js,ts,jsx,tsx}: Always create new objects and never mutate in place; return new copies instead
Keep files between 200–400 lines typical, with a maximum of 800 lines
Extract helpers when a file exceeds 200 lines
Handle errors explicitly at every level; never swallow errors silently
Validate all user input before processing; use schema-based validation where available
Never trust external data (API responses, file content, query params); always validate
All user inputs must be validated and sanitized
Error messages must be scrubbed of sensitive internals
Use readable, well-named identifiers in all code
Keep functions under 50 lines
Keep files under 800 lines
Avoid nesting deeper than 4 levels
Implement comprehensive error handling in all code
Do not hardcode values; use constants or environment configuration instead
Do not use in-place mutation; always return new objects or stateFiles:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{js,ts,jsx,tsx,json,env*}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Do not hardcode secrets, API keys, passwords, or tokens
Files:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{js,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{js,ts}: Use parameterized queries for all database writes (no string interpolation)
Auth/authz must be checked server-side for every sensitive path
Rate limiting must be applied to all public endpointsFiles:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{jsx,tsx,js,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
HTML output must be sanitized where applicable
Files:
tests/ci/validators.test.jstests/ci/catalog.test.js**/*.{js,ts,env*}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Required environment variables must be validated at startup
Files:
tests/ci/validators.test.jstests/ci/catalog.test.jscommands/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Commands should be formatted as Markdown with description frontmatter.
Files:
commands/vue-review.md{agents,skills,commands}/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Use lowercase filenames with hyphens (e.g.,
python-reviewer.md,tdd-workflow.md) for agents, skills, and commands.Files:
commands/vue-review.md{skills,commands,agents,rules}/**
⚙️ CodeRabbit configuration file
{skills,commands,agents,rules}/**: Focus on prompt-injection resilience, tool-permission scope, destructive action guards, and secret exfiltration risks.Files:
commands/vue-review.mdREADME.md
📄 CodeRabbit inference engine (CLAUDE.md)
When working on README.md files, use the
/readmeskill.Files:
README.md🧠 Learnings (1)
📓 Common learnings
Learnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Delegate to specialized agents for domain tasks (Agent-First principle)Learnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Write tests before implementation with 80%+ code coverage (Test-Driven Development requirement)Learnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Never hardcode secrets (API keys, passwords, tokens) - use environment variables or secret managerLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Always create new objects and never mutate existing ones (Immutability principle - CRITICAL)Learnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Plan complex features before writing code using the planner agentLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Validate all user inputs at system boundaries using schema-based validationLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Use parameterized queries to prevent SQL injection in database operationsLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Sanitize HTML output to prevent XSS (Cross-Site Scripting) attacksLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Enable CSRF protection on all endpointsLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Verify authentication and authorization on all protected endpointsLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Implement rate limiting on all endpointsLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Error messages must not leak sensitive dataLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Keep functions small (under 50 lines) and files focused (under 800 lines maximum)Learnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Organize code by feature/domain rather than by type, maintaining high cohesion and low couplingLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Avoid deep nesting (more than 4 levels) in codeLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Handle errors at every level with user-friendly messages in UI code and detailed logging server-sideLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Use meaningful, well-named identifiers throughout codeLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Use conventional commit format: <type>: <description> (types: feat, fix, refactor, docs, test, chore, perf, ci)Learnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Use the Repository pattern to encapsulate data access behind a standard interface (findAll, findById, create, update, delete)Learnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: API responses must use consistent envelope format with success indicator, data payload, error message, and pagination metadataLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Immediately use security-reviewer agent when security issues are found, fix CRITICAL issues first, rotate exposed secrets, and review codebase for similar issuesLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Use planner agent for complex feature implementation, tdd-guide agent for new features and bug fixes, and code-reviewer agent immediately after writing/modifying codeLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Use build-error-resolver agent to analyze, fix incrementally, and verify build errors after each fixLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Capture personal debugging notes and preferences in auto memory, team/project knowledge in project docs, and avoid duplicating information already in code commentsLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:23.982Z Learning: Avoid using the last 20% of context window for large refactoring and multi-file features; lower-sensitivity tasks tolerate higher context utilizationLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:42.029Z Learning: Write tests before implementation using Test-Driven Development workflow: write test (RED) → implement (GREEN) → refactor (IMPROVE)Learnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:42.029Z Learning: Organize code by functional/domain areas rather than by type; aim for high cohesion and low couplingLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:42.029Z Learning: Use conventional commit format: `<type>: <description>` with types: feat, fix, refactor, docs, test, chore, perf, ciLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:42.029Z Learning: Delegate complex features to appropriate specialist agents: planner for implementation planning, architect for system design, tdd-guide for test-driven development, code-reviewer for quality, security-reviewer for security issuesLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:42.029Z Learning: Never compromise on security; validate all inputs, use security-reviewer agent for security-sensitive code before committingLearnt from: CR Repo: affaan-m/ECC Timestamp: 2026-06-12T11:45:42.029Z Learning: Plan complex features before implementation; identify dependencies and risks, break work into phases🔇 Additional comments (3)
README.md (1)
157-157: LGTM!tests/ci/catalog.test.js (1)
259-259: LGTM!tests/ci/validators.test.js (1)
598-598: LGTM!
| - Secret in client bundle (`VITE_*`, Nuxt `public` runtimeConfig) | ||
| - Server endpoint without input validation (Nuxt Nitro) | ||
| - `localStorage`/`sessionStorage` for session tokens | ||
| - Destructuring reactive props in Vue < 3.5 (breaks reactivity) |
There was a problem hiding this comment.
Clarify Vue version scope for the "destructuring reactive props" rule.
Line 51 states "Destructuring reactive props in Vue < 3.5 (breaks reactivity)" as a CRITICAL issue. This implies Vue 3.5+ does not have this issue (or it is not a concern for this project). However, the command documentation does not declare a Vue version constraint at the top level. If this command targets Vue 3.5+ exclusively, that should be stated upfront (e.g., "This command targets Vue 3.5+ projects"). If it supports earlier versions, the category should be reworded to be version-agnostic or clarify the scope.
📝 Suggested fix
Option A: Add a version constraint to the intro (if this command is Vue 3.5+ only):
# Vue Code Review
+**Target**: Vue 3.5+ projects (Composition API, `<script setup>`).
+
This command invokes the **vue-reviewer** agent for Vue-specific code review.Option B: Reword the category to be version-inclusive:
- - Destructuring reactive props in Vue < 3.5 (breaks reactivity)
+ - Destructuring reactive props without `.value` (breaks reactivity in Composition API)📝 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.
| - Destructuring reactive props in Vue < 3.5 (breaks reactivity) | |
| - Destructuring reactive props without `.value` (breaks reactivity in Composition API) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@commands/vue-review.md` at line 51, The doc currently claims "Destructuring
reactive props in Vue < 3.5 (breaks reactivity)" but doesn't state the command's
Vue version scope; either declare the version at the top of
commands/vue-review.md (e.g., "This command targets Vue 3.5+ projects") if the
tool only supports Vue 3.5+, or make the rule version-agnostic by rewording the
category string "Destructuring reactive props..." to note it affects pre-3.5
projects (for example "Destructuring reactive props (may break reactivity in Vue
< 3.5)") so readers know the compatibility; update the top-level intro or the
category line accordingly to match the chosen scope.
- agent.yaml: register epic-* commands (#2236) and vue-review (#2241) - package.json files: drop stray skills/ml-adoption-playbook entry (follows orphan-skill publish pattern; not in install-modules.json) - unicode-safety: strip decorative emoji from dashboard-web.js (#2100) and brand-discovery refs (#2221) to pass the CI gate - agent-compress: raise catalog token canary 5000 -> 6000 for the 67-agent catalog Full suite green (2836/2836).
What Changed
vue-patternsin npm publish files and selective install manifests.Why This Change
Adds first-class Vue/Nuxt/Pinia/Vue Router guidance to ECC, matching the existing framework review surfaces.
Testing Done
node scripts/ci/check-unicode-safety.js; node scripts/ci/validate-agents.js; node scripts/ci/validate-commands.js; node scripts/ci/validate-rules.js; node scripts/ci/validate-skills.js; node scripts/ci/validate-hooks.js; node scripts/ci/validate-install-manifests.js; node scripts/ci/validate-no-personal-paths.js; npm run catalog:check; npm run command-registry:checknode tests/ci/validators.test.jsnode tests/ci/catalog.test.jsnode tests/ci/command-registry.test.jsnode tests/lib/install-manifests.test.jsnode tests/scripts/npm-publish-surface.test.jsnpm run lintexited 0 locallynpm testfull suite: local run exceeded 5 minutes in existingtests/scripts/control-pane.test.js; targeted PR-relevant checks passedType of Change
feat:New featurefix:Bug fixrefactor:Code refactoring