diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 0000000..02aa60f --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,118 @@ +# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json + +language: en-US +tone_instructions: >- + Be direct and concise. Use imperative mood. Skip filler + and marketing language. Assume the reader is a competent + developer. State facts, not opinions. + +reviews: + profile: chill + instructions: >- + Do not report minor severity issues or formatting nits (markdown structure, + heading levels, trailing punctuation, blank lines in blockquotes). Focus on + critical and major issues that affect correctness, security, or public API + behavior. + sequence_diagrams: true + poem: false + auto_review: + enabled: true + drafts: false + auto_incremental_review: true + auto_pause_after_reviewed_commits: 0 + ignore_title_keywords: + - 'WIP' + - 'DO NOT MERGE' + base_branches: + - main + - dev + + # Never edit PR title or description. Reviews go in comments only. + high_level_summary: false + high_level_summary_placeholder: '' + auto_title_placeholder: '' + collapse_walkthrough: true + + path_filters: + - '!pnpm-lock.yaml' + - '!**/*.snap' + - '!docs/public/**' + - '!playground/**' + - '!playground-astro/**' + + path_instructions: + - path: 'packages/notivue/core/**' + instructions: | + This is the core notification engine. Pay close attention to: + - Reactivity correctness (Vue 3 reactive/ref usage) + - Type safety (strict TypeScript) + - Public API surface: any change here affects all consumers + - Backwards compatibility of exported types and functions + - path: 'packages/notivue/Notivue/**' + instructions: | + Main wrapper component with aria-live region for accessibility. + Ensure ARIA attributes and live region behavior are correct. + - path: 'packages/notivue/Notifications/**' + instructions: | + Pre-built notification components and themes. + Check CSS variable usage, theme consistency, and icon accessibility. + - path: 'packages/notivue/nuxt/**' + instructions: | + Nuxt module integration. Verify module hooks, auto-imports, + and compatibility with Nuxt 4 conventions. + - path: 'packages/notivue/astro/**' + instructions: | + Astro integration. Ensure SSR/island compatibility + and correct lifecycle handling. + - path: 'tests/**' + instructions: | + Test suite using Vitest (unit) and Cypress (component). + Includes accessibility testing via cypress-axe. + Ensure tests are deterministic and cover edge cases. + - path: 'docs/**' + instructions: | + VitePress documentation. Check code examples for accuracy, + correct imports, and consistency with the actual API. + + tools: + eslint: + enabled: false + biome: + enabled: false + markdownlint: + enabled: false + actionlint: + enabled: true + gitleaks: + enabled: true + + finishing_touches: + docstrings: + enabled: false + unit_tests: + enabled: false + simplify: + enabled: false + +chat: + auto_reply: true + allow_non_org_members: false + +code_generation: + unit_tests: + path_instructions: + - path: 'tests/**' + instructions: | + This project uses Cypress component tests as the primary + test suite, not unit tests. Include cypress-axe accessibility + checks where relevant. Use cypress-real-events for user + interaction testing. A small Vitest suite exists in + tests/config/ for configuration logic only. + +knowledge_base: + learnings: + scope: local + web_search: + enabled: true + code_guidelines: + enabled: true diff --git a/.cursorignore b/.cursorignore new file mode 100644 index 0000000..4401f7f --- /dev/null +++ b/.cursorignore @@ -0,0 +1,2 @@ +!docs/ +!.claude/ \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index f31a6f5..8a6a5cb 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1 @@ -polar: smastrom buy_me_a_coffee: smastrom diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a5c0953..b1c5c4e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,9 +5,13 @@ on: tags: ['v*'] workflow_dispatch: +permissions: {} + jobs: tests-workflow: uses: ./.github/workflows/tests.yml + permissions: + contents: read publish: needs: tests-workflow runs-on: ubuntu-latest diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a4f2876..2737e2f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,13 +4,18 @@ on: pull_request: branches: - main + - dev push: branches: - main + - dev tags-ignore: - '*' workflow_call: +permissions: + contents: read + jobs: cypress-run: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 00e1d7a..810a051 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ pnpm-debug.log* .vscode .idea +.cursor .DS_Store node_modules @@ -13,3 +14,5 @@ notivue-*.tgz .nuxt pnpm-lock.yaml +docs/ +.claude/ diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 0000000..c5d3d6e --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,21 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "printWidth": 100, + "semi": false, + "singleQuote": true, + "tabWidth": 3, + "trailingComma": "es5", + "useTabs": false, + "ignorePatterns": [".vscode/**", "node_modules/**", "dist/**", "target/**"], + "sortPackageJson": { + "sortScripts": true + }, + "overrides": [ + { + "files": ["*.md"], + "options": { + "tabWidth": 2 + } + } + ] +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 0000000..0737ecb --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,93 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript", "unicorn", "oxc"], + "jsPlugins": ["./oxlint-plugins.mjs"], + "categories": { + "correctness": "off", + "perf": "off", + "restriction": "off", + "suspicious": "off", + "pedantic": "off", + "style": "off", + "nursery": "off" + }, + "rules": { + "stylistic/sort-imports": [ + "error", + { + "internalPattern": ["^@/.+"], + "newlinesBetween": 1, + "customGroups": [ + { "groupName": "vue-files", "elementNamePattern": "\\.vue$" }, + { "groupName": "constants", "elementNamePattern": "/constants(/|$)" } + ], + "groups": [ + "vue-files", + "type", + "builtin", + "external", + "internal", + "constants", + ["parent", "sibling", "index"], + "side-effect", + "style", + "unknown" + ] + } + ], + "stylistic/padding-line-between-statements": [ + "error", + { "blankLine": "always", "prev": "import", "next": "*" }, + { "blankLine": "any", "prev": "import", "next": "import" }, + { + "blankLine": "always", + "prev": ["block-like", "if", "for", "while", "do", "switch", "try"], + "next": "*" + }, + { + "blankLine": "always", + "prev": "*", + "next": ["block-like", "if", "for", "while", "do", "switch", "try"] + }, + { + "blankLine": "any", + "prev": ["block-like", "if", "for", "while", "do", "switch", "try"], + "next": ["block-like", "if", "for", "while", "do", "switch", "try"] + }, + { "blankLine": "always", "prev": "expression", "next": ["const", "let"] }, + { "blankLine": "always", "prev": ["const", "let"], "next": "expression" }, + { "blankLine": "always", "prev": "const", "next": "let" }, + { "blankLine": "always", "prev": "let", "next": "const" }, + { + "blankLine": "always", + "prev": [ + { "selector": "ExpressionStatement[expression.type='AssignmentExpression']" }, + { "selector": "ExpressionStatement[expression.type='UpdateExpression']" } + ], + "next": [ + { "selector": "ExpressionStatement[expression.type='CallExpression']" }, + { "selector": "ExpressionStatement[expression.type='AwaitExpression']" } + ] + }, + { + "blankLine": "always", + "prev": [ + { "selector": "ExpressionStatement[expression.type='CallExpression']" }, + { "selector": "ExpressionStatement[expression.type='AwaitExpression']" } + ], + "next": [ + { "selector": "ExpressionStatement[expression.type='AssignmentExpression']" }, + { "selector": "ExpressionStatement[expression.type='UpdateExpression']" } + ] + }, + { + "blankLine": "always", + "prev": "*", + "next": ["return", "throw", "break", "continue"] + } + ] + }, + "env": { + "builtin": true + } +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..ecec947 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,63 @@ +# Agents + +## Project + +Notivue is a public OSS Vue 3 toast notification library. Treat `packages/notivue` as the product, with Nuxt and Astro integrations, playgrounds for manual checks, docs for the public contract, and `tests` as the regression suite. + +- Keep changes small and library-grade. Prefer existing APIs, file layout, and naming over new patterns. +- Protect public exports, types, CSS entrypoints, accessibility behavior, SSR compatibility, and backwards compatibility unless the user explicitly asks for a breaking change. +- For behavior changes, update or add focused tests near the affected area. Cypress component tests are the main suite; Vitest is used for config logic. +- Never run development servers unless the user explicitly requests them. +- Use `pnpm` and the repo scripts: `pnpm build`, `pnpm test`, `pnpm test:unit`, `pnpm format:check`, `pnpm dev`, `pnpm dev:astro`. + +## Notivue stream layout + +- Notification rows use `width: max-content` on `
{{ item.message }}
- - +