scaffolding-vue-components — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited scaffolding-vue-components (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Gather from user:
src/components/, components/, or feature folderDerive file paths:
src/components/Button/
├── Button.vue
├── Button.test.ts
├── Button.stories.ts
└── index.tsVue vs Nuxt:
ls nuxt.config.* 2>/dev/null && echo "Nuxt project"
ls vite.config.* vue.config.* 2>/dev/null && echo "Vue project"Styling approach:
grep -l "module.css\|module.scss" src/**/*.vue 2>/dev/null | head -1 && echo "CSS Modules"
grep -l "<style scoped" src/**/*.vue 2>/dev/null | head -1 && echo "Scoped styles"
npm ls tailwindcss 2>/dev/null && echo "Tailwind CSS"State management:
npm ls pinia vuex 2>/dev/nullTest framework:
npm ls vitest @vue/test-utils 2>/dev/nullUse the standard Composition API structure:
<script setup lang="ts"> with typed props and emitswithDefaults(defineProps<Props>(), { ... }) for defaultsdefineEmits<{ event: [payload] }>() for typed events<style module> with design tokensSee component-templates.md for full templates including:
Use Vitest with Vue Test Utils:
import { describe, it, expect } from "vitest";
import { mount } from "@vue/test-utils";
import ComponentName from "./ComponentName.vue";
describe("ComponentName", () => {
it("renders slot content", () => {
const wrapper = mount(ComponentName, {
slots: { default: "Hello" },
});
expect(wrapper.text()).toContain("Hello");
});
it("emits click when not disabled", async () => {
const wrapper = mount(ComponentName);
await wrapper.trigger("click");
expect(wrapper.emitted("click")).toHaveLength(1);
});
});See testing.md for more patterns including Pinia testing and async components.
Use CSF3 format for Storybook 7+:
import type { Meta, StoryObj } from "@storybook/vue3";
import ComponentName from "./ComponentName.vue";
const meta: Meta<typeof ComponentName> = {
title: "Components/ComponentName",
component: ComponentName,
tags: ["autodocs"],
argTypes: {
variant: { control: "select", options: ["primary", "secondary"] },
},
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
args: { label: "Primary Button", variant: "primary" },
};See storybook.md for slot stories, decorators, and interactions.
index.ts:
export { default as ComponentName } from "./ComponentName.vue";v-model support (Vue 3.4+):
<script setup lang="ts">
const modelValue = defineModel<string>({ default: "" });
</script>Expose methods:
<script setup lang="ts">
const focus = () => inputRef.value?.focus();
defineExpose({ focus });
</script>Provide/Inject:
// Parent
provide("state", reactive({ active: 0 }));
// Child
const state = inject<{ active: number }>("state");See advanced-patterns.md for compound components, generics, and Nuxt patterns.
Before completing:
.vue).$style in template and <style module>.@vue/test-utils and configure Vitest for Vue..storybook/main.js uses @storybook/vue3.setActivePinia(createPinia()) in beforeEach.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.