Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
language: en-US
tone_instructions: Be concise and technical. Focus on critical issues first (bugs, security, accessibility), then suggestions. Prioritize actionable feedback over observations.
early_access: false
enable_free_tier: true
reviews:
profile: assertive
request_changes_workflow: false
# Disable GitHub PR comments - we use Claude Code locally for reviews
high_level_summary: false
high_level_summary_placeholder: '@coderabbitai summary'
high_level_summary_in_walkthrough: false
# Disable auto-title - we craft conventional commits manually
auto_title_placeholder: '@coderabbitai'
auto_title_instructions: ''
# Disable status checks - we use trunk locally
review_status: false
commit_status: false
fail_commit_status: false
collapse_walkthrough: true
changed_files_summary: false
sequence_diagrams: false
assess_linked_issues: false
related_issues: false
related_prs: false
suggested_labels: false
auto_apply_labels: false
suggested_reviewers: false
auto_assign_reviewers: false
poem: false
labeling_instructions:
- label: bug
instructions: Apply to any code that fixes incorrect behavior or errors
- label: enhancement
instructions: Apply to new features or improvements to existing features
- label: docs
instructions: Apply to documentation updates or improvements
- label: test
instructions: Apply to test additions or improvements
- label: refactor
instructions: Apply to code restructuring without behavior changes
- label: performance
instructions: Apply to performance improvements or optimizations
- label: security
instructions: Apply to security fixes or improvements
- label: animation
instructions: Apply to changes to animation logic or Motion integration
- label: accessibility
instructions: Apply to accessibility improvements (a11y, keyboard, screen readers)
- label: breaking-change
instructions: Apply to changes that break backward compatibility
path_filters: []
path_instructions:
- path: src/lib/utils/**/*.ts
instructions: Ensure all exported functions use arrow function syntax (const fn = () => {}). All functions must have comprehensive JSDoc comments with @param, @returns, and @example tags. Verify type safety and check for potential ReDoS vulnerabilities in regex patterns.
- path: src/lib/**/*.svelte
instructions: Review Svelte 5 runes usage ($state, $derived, $effect). Ensure proper cleanup in $effect blocks. Check for memory leaks and performance issues. Verify SSR compatibility.
- path: '**/*.spec.ts'
instructions: Ensure tests are comprehensive with good coverage of edge cases, error paths, and accessibility. Tests should be well-named and describe the expected behavior clearly.
- path: docs/**/*
instructions: Verify examples are correct, runnable, and match current API. Check for broken links and ensure code examples follow project conventions.
- path: tests/**/*.ts
instructions: Ensure e2e tests are reliable, avoid flakiness, and test real user scenarios. Verify proper waits and assertions.
- path: docs/e2e/**/*.ts
instructions: Ensure e2e tests are reliable, avoid flakiness, and test real user scenarios. Verify proper waits and assertions.
abort_on_close: true
disable_cache: false
auto_review:
enabled: true
auto_incremental_review: true
ignore_title_keywords: []
labels: []
drafts: false
base_branches: []
finishing_touches:
docstrings:
enabled: false
unit_tests:
enabled: false
tools:
ast-grep:
rule_dirs: []
util_dirs: []
essential_rules: true
packages: []
shellcheck:
enabled: false # Not needed for TS/Svelte project
ruff:
enabled: false # Python linter - not needed
markdownlint:
enabled: true
github-checks:
enabled: true
timeout_ms: 90000
languagetool:
enabled: false
biome:
enabled: true # Good for TypeScript/JavaScript
hadolint:
enabled: false # Docker linter - not needed
swiftlint:
enabled: false # Swift linter - not needed
phpstan:
enabled: false # PHP linter - not needed
level: default
golangci-lint:
enabled: false # Go linter - not needed
yamllint:
enabled: true
gitleaks:
enabled: true # Security - keep enabled
checkov:
enabled: false # Infrastructure security - not needed
detekt:
enabled: false # Kotlin linter - not needed
eslint:
enabled: true # Essential for TypeScript/JavaScript
rubocop:
enabled: false # Ruby linter - not needed
buf:
enabled: false # Protobuf linter - not needed
regal:
enabled: false # Rego linter - not needed
actionlint:
enabled: true # Useful for GitHub Actions
pmd:
enabled: false # Java linter - not needed
cppcheck:
enabled: false # C/C++ linter - not needed
semgrep:
enabled: true # Security patterns - useful
circleci:
enabled: false # Not using CircleCI
sqlfluff:
enabled: false # SQL linter - not needed
prismaLint:
enabled: false # Prisma ORM - not needed
oxc:
enabled: true # Fast JavaScript/TypeScript linter
shopifyThemeCheck:
enabled: false # Shopify themes - not needed
chat:
# Disable auto-reply - we interact via Claude Code, not GitHub comments
auto_reply: false
integrations:
jira:
usage: disabled
linear:
usage: disabled
knowledge_base:
opt_out: false
web_search:
enabled: false
learnings:
scope: local
issues:
scope: local
jira:
usage: disabled
project_keys: []
linear:
usage: disabled
team_keys: []
pull_requests:
scope: local
# Code generation disabled - we write docs and tests via Claude Code
code_generation:
docstrings:
enabled: false
unit_tests:
enabled: false
Comment on lines +166 to +170

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
python - <<'PY'
import sys, subprocess

try:
    import yaml
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", "pyyaml", "-q"])
    import yaml

with open(".coderabbit.yaml", "r", encoding="utf-8") as f:
    cfg = yaml.safe_load(f) or {}

errors = []

doc = ((cfg.get("code_generation") or {}).get("docstrings") or {})
doc_allowed = {"language", "path_instructions"}
doc_bad = sorted(set(doc.keys()) - doc_allowed)
if doc_bad:
    errors.append(f"code_generation.docstrings unsupported keys: {doc_bad}")

ut = ((cfg.get("code_generation") or {}).get("unit_tests") or {})
ut_allowed = {"path_instructions"}
ut_bad = sorted(set(ut.keys()) - ut_allowed)
if ut_bad:
    errors.append(f"code_generation.unit_tests unsupported keys: {ut_bad}")

print("\n".join(errors) if errors else "No unsupported code_generation keys found.")
PY

Repository: humanspeak/svelte-virtual-chat

Length of output: 187


Remove unsupported enabled keys from code_generation config at Lines 168 and 170

code_generation.docstrings.enabled and code_generation.unit_tests.enabled are not valid schema keys. CodeRabbit will ignore these settings. Use path_instructions instead to configure these sections.

Suggested fix
 code_generation:
     docstrings:
-        enabled: false
+        path_instructions: []
     unit_tests:
-        enabled: false
+        path_instructions: []
📝 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.

Suggested change
code_generation:
docstrings:
enabled: false
unit_tests:
enabled: false
code_generation:
docstrings:
path_instructions: []
unit_tests:
path_instructions: []
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.coderabbit.yaml around lines 166 - 170, Remove the unsupported keys
code_generation.docstrings.enabled and code_generation.unit_tests.enabled from
the code_generation block and instead configure those sections using the
supported path_instructions option; locate the code_generation.docstrings and
code_generation.unit_tests entries in the file, delete the enabled lines, and
add or update path_instructions for each respective section to control behavior
per the CodeRabbit schema.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copied from svelte-markdown where it works. If CodeRabbit ignores these keys, no harm done.

9 changes: 9 additions & 0 deletions docs/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

# Generated outputs
node_modules/
.svelte-kit/
build/
17 changes: 17 additions & 0 deletions docs/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte"
}
}
],
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
"printWidth": 100,
"semi": false,
"singleQuote": true,
"tabWidth": 4,
"trailingComma": "none",
"useTabs": false
}
16 changes: 14 additions & 2 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,44 @@
"private": true,
"type": "module",
"scripts": {
"build": "vite build",
"build": "tsx ./scripts/fetch-github-stats.ts && node ./scripts/generate-sitemap-manifest.mjs && tsx ./scripts/generate-social-cards.ts && vite build",
"cf-typegen": "wrangler types && mv worker-configuration.d.ts src/",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"deploy": "npm run build && wrangler deploy",
"dev": "vite dev",
"format": "prettier --write .",
"generate-social": "tsx ./scripts/generate-social-cards.ts",
"lint": "prettier --check . && eslint .",
"preview": "vite preview",
"sitemap:manifest": "node ./scripts/generate-sitemap-manifest.mjs"
"sitemap:manifest": "node ./scripts/generate-sitemap-manifest.mjs",
"sitemap:watch": "chokidar 'src/routes/**/*.svelte' 'src/routes/**/*.svx' 'src/routes/**/*.md' -c 'node ./scripts/generate-sitemap-manifest.mjs' --initial --silent",
"social:watch": "chokidar 'src/lib/components/shared-link/OG.svelte' 'scripts/generate-social-cards.ts' -c 'tsx ./scripts/generate-social-cards.ts' --initial --silent"
},
"dependencies": {
"@humanspeak/docs-kit": "github:humanspeak/docs-kit#2026.3.31",
"@humanspeak/svelte-markdown": "^1.4.1",
"@humanspeak/svelte-virtual-chat": "workspace:*"
},
"devDependencies": {
"@icons-pack/svelte-simple-icons": "^7.2.0",
"@lucide/svelte": "^1.8.0",
"@sveltejs/adapter-cloudflare": "^7.2.8",
"@sveltejs/kit": "^2.57.1",
"@sveltejs/vite-plugin-svelte": "^7.0.0",
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.2.2",
"chokidar-cli": "^3.0.0",
"eslint": "^10.2.0",
"mdsvex": "^0.12.7",
"mode-watcher": "^1.1.0",
"prettier": "^3.8.2",
"prettier-plugin-svelte": "^3.5.1",
"prettier-plugin-tailwindcss": "^0.7.2",
"shiki": "^4.0.2",
"svelte": "^5.55.4",
"svelte-check": "^4.4.6",
"tailwindcss": "^4.2.2",
"tsx": "^4.21.0",
"typescript": "^6.0.2",
"vite": "^8.0.8",
"wrangler": "^4.82.2"
Expand Down
12 changes: 12 additions & 0 deletions docs/scripts/fetch-github-stats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { fetchGitHubStats } from '@humanspeak/docs-kit/scripts/fetch-github-stats'
import path from 'path'
import { fileURLToPath } from 'url'
import { docsConfig } from '../src/lib/docs-config'

const __dirname = path.dirname(fileURLToPath(import.meta.url))

await fetchGitHubStats({
repo: docsConfig.repo,
fallbackStars: docsConfig.fallbackStars,
outputPath: path.resolve(__dirname, '..', 'src', 'lib', 'github-stats.json')
})
17 changes: 17 additions & 0 deletions docs/scripts/generate-social-cards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { generateSocialCards } from '@humanspeak/docs-kit/scripts/generate-social-cards'
import path from 'path'
import { fileURLToPath } from 'url'
import { docsConfig } from '../src/lib/docs-config'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const ROOT = path.resolve(__dirname, '..')

await generateSocialCards({
npmPackage: docsConfig.npmPackage,
defaultTitle: docsConfig.name,
defaultDescription:
'A high-performance virtual chat viewport for Svelte 5. Follow-bottom, streaming-stable, history-aware.',
defaultFeatures: docsConfig.defaultFeatures,
rootDir: ROOT,
fontsDir: path.join(ROOT, 'node_modules/@humanspeak/docs-kit/dist/fonts')
})
43 changes: 31 additions & 12 deletions docs/src/app.css
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
@import 'tailwindcss';
@source '../node_modules/@humanspeak/docs-kit/dist';
@import '@humanspeak/docs-kit/styles/base.css';
@plugin '@tailwindcss/typography';
Comment on lines +2 to +4

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== app.css header =="
nl -ba docs/src/app.css | sed -n '1,20p'

echo
echo "== stylelint config candidates =="
fd -HI 'stylelint|\.stylelintrc'

echo
echo "== stylelint rule snippets (if present) =="
rg -n --iglob '*stylelint*' 'ignoreAtRules|at-rule-no-unknown|no-invalid-position-at-import-rule|scss/at-rule-no-unknown' || true

Repository: humanspeak/svelte-virtual-chat

Length of output: 154


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== app.css content (first 30 lines) =="
head -30 docs/src/app.css || echo "File not found or error reading"

echo
echo "== stylelint config files =="
fd -HI 'stylelint' --type f

echo
echo "== .stylelintrc* files =="
fd -HI '\.stylelintrc' --type f

echo
echo "== stylelint.config files =="
fd -HI 'stylelint\.config' --type f

Repository: humanspeak/svelte-virtual-chat

Length of output: 1027


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== .stylelintrc.json content =="
cat .stylelintrc.json

echo
echo "== Check for at-rule rules in config =="
rg -A5 -B5 'at-rule|ignoreAtRules' .stylelintrc.json || true

Repository: humanspeak/svelte-virtual-chat

Length of output: 1923


🌐 Web query:

stylelint-config-standard-scss default rules at-rule-no-unknown

💡 Result:

In stylelint-config-standard-scss (latest v17.0.0 as of 2026-01-15), the "at-rule-no-unknown" rule is disabled (set to null) and replaced by the SCSS-specific "scss/at-rule-no-unknown" rule, which is enabled (true). This configuration extends stylelint-config-standard (which enables "at-rule-no-unknown": true) and stylelint-config-recommended-scss. The recommended-scss config bundles stylelint-scss plugin and turns on error-checking rules including scss/at-rule-no-unknown, while overriding the standard at-rule-no-unknown to support SCSS at-rules like @use, @extend, @mixin, etc.

Citations:


🌐 Web query:

Tailwind v4 @source @plugin at-rule ordering requirements

💡 Result:

Tailwind CSS v4 does not enforce a strict ordering requirement for @source and @plugin at-rules beyond standard CSS rules for @import statements. All Tailwind-specific at-rules like @source, @plugin, @config, @theme, @utility, and @variant are processed during the Tailwind compilation phase regardless of their position in the CSS file, as long as they appear in the input CSS processed by Tailwind's engine (CLI, Vite plugin, or PostCSS plugin). Standard CSS requires @import rules to precede all other rules, but Tailwind's directives (@source, @plugin, etc.) have no such restriction among themselves. Example valid CSS structure from official docs and examples: @import "tailwindcss"; @theme { --color-brand-500: oklch(62.45% 0.179 264.23); } @source "../node_modules/@my-company/ui-lib"; @plugin "@tailwindcss/typography"; @utility my-utility { margin: 1rem; } @source can appear after @import "tailwindcss" (result 5,3), and @plugin is shown similarly (result 3,7). No sources indicate errors or requirements for specific order between @source and @plugin. Tailwind processes the entire CSS file's directives collectively. Layer ordering (@layer theme, base, components, utilities) is handled automatically by Tailwind's output using native CSS cascade layers, independent of input order (result 5,10,21).

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for scss/at-rule-no-unknown references =="
rg 'scss/at-rule-no-unknown|ignoreAtRules.*source|ignoreAtRules.*plugin' . --type json || echo "Not found - means not configured"

echo
echo "== Check if `@source` and `@plugin` would be flagged =="
echo "Current stylelint config extends stylelint-config-standard-scss"
echo "Which has scss/at-rule-no-unknown ENABLED by default"
echo "Without ignoreAtRules configuration, `@source` and `@plugin` WILL be flagged as unknown"

Repository: humanspeak/svelte-virtual-chat

Length of output: 412


Configure stylelint to recognize Tailwind v4 at-rules before merge.

The stylelint config extends stylelint-config-standard-scss, which has scss/at-rule-no-unknown enabled. This rule will flag @source and @plugin as unknown at-rules, blocking CI/deploys. Add to .stylelintrc.json:

{
  "rules": {
    "scss/at-rule-no-unknown": {
      "ignoreAtRules": ["source", "plugin", "config", "theme", "utility", "variant"]
    }
  }
}

Note: The at-rule ordering in docs/src/app.css is already correct per CSS standards (@import directives first). Tailwind v4 does not enforce ordering constraints between its custom at-rules.

🧰 Tools
🪛 Stylelint (17.7.0)

[error] 3-3: Invalid position for @import rule (no-invalid-position-at-import-rule)

(no-invalid-position-at-import-rule)


[error] 2-2: Unexpected unknown at-rule "@source" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)


[error] 4-4: Unexpected unknown at-rule "@plugin" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/src/app.css` around lines 2 - 4, Update the Stylelint config to
whitelist Tailwind v4 custom at-rules so stylelint won't flag `@source` and
`@plugin` in docs/src/app.css: in .stylelintrc.json add/modify the
"scss/at-rule-no-unknown" rule to include an "ignoreAtRules" array containing
"source", "plugin", "config", "theme", "utility", and "variant", ensuring the
existing config still extends "stylelint-config-standard-scss".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These are Tailwind CSS 4 directives — not standard CSS at-rules. They're processed by the Tailwind Vite plugin. Same pattern as svelte-markdown's docs.


:root {
--brand-500: #6366f1;
--brand-600: #4f46e5;
--brand-700: #4338ca;
/* Project-specific: landing page decorative styles */
.orb-a-bg {
background: radial-gradient(
circle at 30% 30%,
color-mix(in oklab, var(--color-brand-100) 40%, transparent),
color-mix(in oklab, var(--color-brand-100) 10%, transparent)
);
}

body {
font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
sans-serif;
.orb-b-bg {
background: radial-gradient(
circle at 70% 50%,
color-mix(in oklab, var(--color-brand-500) 30%, transparent),
color-mix(in oklab, var(--color-brand-500) 8%, transparent)
);
}

@keyframes sheen {
0%,
100% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
}

.sheen-gradient {
background-size: 200% 100%;
animation: sheen 6s ease-in-out infinite;
}
4 changes: 2 additions & 2 deletions docs/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#3dbba0" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
<div style="display: contents" class="w-full">%sveltekit.body%</div>
</body>
</html>
3 changes: 3 additions & 0 deletions docs/src/hooks.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createDocsKitHandle } from '@humanspeak/docs-kit/hooks'

export const handle = createDocsKitHandle()
1 change: 1 addition & 0 deletions docs/src/lib/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading