diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml
index eacdbaa..a1b6c2e 100644
--- a/.github/workflows/validate-pr.yml
+++ b/.github/workflows/validate-pr.yml
@@ -33,23 +33,31 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile
- - name: Biome check (format + lint)
- run: bunx nx affected --target=check --base=origin/${{ github.base_ref }}
+ - name: Run Biome CI
+ env:
+ BIOME_CONFIG_PATH: ./biome.json
+ run: bunx biome ci --reporter=github --diagnostic-level=error . --verbose
- - name: JSDoc validation
- run: bunx nx affected --target=validate:jsdoc --base=origin/${{ github.base_ref }}
+ - name: Run markdown linter
+ run: bunx markdownlint-cli2 "**/*.md" "#node_modules" "#**/node_modules"
- - name: Markdown validation
- run: bunx nx affected --target=validate:markdown --base=origin/${{ github.base_ref }}
+ - name: Validate TSDoc on affected projects
+ run: bunx nx affected --target=validate:tsdoc --base=origin/${{ github.base_ref }} --output-style=stream
- name: Type check affected projects
- run: bunx nx affected --target=type-check --base=origin/${{ github.base_ref }}
+ run: bunx nx affected --target=type-check --base=origin/${{ github.base_ref }} --output-style=stream
- name: Run tests on affected projects
- run: bunx nx affected --target=test --base=origin/${{ github.base_ref }}
+ run: bunx nx affected --target=test --base=origin/${{ github.base_ref }} --output-style=stream
- name: Build affected projects
- run: bunx nx affected --target=build --base=origin/${{ github.base_ref }} --exclude='tag:skip-ci'
+ run: bunx nx affected --target=build --base=origin/${{ github.base_ref }} --exclude='tag:skip-ci' --output-style=stream
+
+ - name: Validate TypeScript skills
+ run: bunx nx affected --target=validate:skills --base=origin/${{ github.base_ref }} --output-style=stream
+
+ - name: Validate SKILL.md files
+ run: bunx nx affected --target=validate:skill-md --base=origin/${{ github.base_ref }} --configuration=strict --output-style=stream
- name: Summary
if: always()
@@ -57,12 +65,13 @@ jobs:
echo "## ✅ Validation Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "All validation checks passed:" >> $GITHUB_STEP_SUMMARY
- echo "- ✅ Biome check (format + lint)" >> $GITHUB_STEP_SUMMARY
- echo "- ✅ JSDoc validation" >> $GITHUB_STEP_SUMMARY
- echo "- ✅ Markdown validation" >> $GITHUB_STEP_SUMMARY
+ echo "- ✅ Code formatting" >> $GITHUB_STEP_SUMMARY
+ echo "- ✅ Markdown linting" >> $GITHUB_STEP_SUMMARY
+ echo "- ✅ Code linting (affected)" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Type checking (affected)" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Tests (affected)" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Build (affected)" >> $GITHUB_STEP_SUMMARY
+ echo "- ✅ Skill validation (affected)" >> $GITHUB_STEP_SUMMARY
security:
name: Security Analysis
@@ -76,17 +85,17 @@ jobs:
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.28.0
with:
- scan-type: "fs"
- scan-ref: "."
- format: "sarif"
- output: "trivy-results.sarif"
+ scan-type: 'fs'
+ scan-ref: '.'
+ format: 'sarif'
+ output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v3
if: always()
continue-on-error: true
with:
- sarif_file: "trivy-results.sarif"
+ sarif_file: 'trivy-results.sarif'
pr-analysis:
name: PR Analysis
diff --git a/.gitignore b/.gitignore
index efa7888..fb4964c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,5 +58,6 @@ tmp/
# OpenCode
.opencode/
+!.opencode/skills/
.context/
.nx/
\ No newline at end of file
diff --git a/.opencode/skills/biomejs/SKILL.md b/.opencode/skills/biomejs/SKILL.md
new file mode 100644
index 0000000..9ed8f9a
--- /dev/null
+++ b/.opencode/skills/biomejs/SKILL.md
@@ -0,0 +1,492 @@
+---
+name: biomejs
+description:
+ Resolve BiomeJS linting errors and warnings with fix-forward approach (never ignore/suppress). Covers formatting,
+ correctness, suspicious patterns, style, complexity, and performance rules.
+license: MIT
+compatibility: opencode
+metadata:
+ category: linting
+ tool: biome
+---
+
+## What I do
+
+I help resolve all BiomeJS errors and warnings by **fixing the root cause**, never by adding ignore comments or
+suppressions.
+
+## Core Principles
+
+1. **NEVER use suppression comments** - Do not use `// biome-ignore`, `// biome-ignore lint`, or any suppression
+ directives
+2. **Fix forward, not backward** - Address the underlying issue rather than disabling the rule
+3. **Prefer automated fixes** - Use `biome check --write` or `biome lint --write` when safe
+4. **Manual fixes for unsafe changes** - When Biome flags a change as unsafe, carefully implement the fix manually
+5. **Understand the intent** - Each rule exists to catch real issues; fix them properly
+
+## When to use me
+
+- After running `biome check`, `biome lint`, or `biome format` and seeing errors
+- When CI fails due to Biome linting violations
+- When refactoring code and needing to address Biome warnings
+- When reviewing Biome output and unsure how to fix specific rules
+
+## How to resolve errors
+
+### Step 1: Run Biome to see all issues
+
+```bash
+# Check all files (dry run - shows issues without fixing)
+biome check .
+
+# Check specific file or directory
+biome check src/components/
+
+# Show detailed diagnostics with code frames
+biome check --verbose .
+```
+
+### Step 2: Apply safe fixes automatically
+
+```bash
+# Apply all safe fixes (formatting + safe lint fixes)
+biome check --write .
+
+# Apply only safe lint fixes
+biome lint --write .
+
+# Apply only formatting fixes
+biome format --write .
+```
+
+### Step 3: Address remaining unsafe issues manually
+
+For each remaining error, understand the rule and fix properly:
+
+## Rule Categories and Fix Strategies
+
+### Formatting Rules
+
+**Issues**: Incorrect indentation, spacing, line breaks, quote style
+
+**Fix**: Use `biome format --write` or adjust manually:
+
+- Follow project's `biome.json` formatter settings
+- Use spaces/tabs consistently per config
+- Maintain consistent line ending style
+
+### Correctness Rules (High Priority)
+
+These catch actual bugs - **always fix immediately**:
+
+**noUnusedVariables** - Remove unused variables/imports or use them
+
+```typescript
+// BAD
+const unused = 5; // Never used
+
+// GOOD
+const used = 5;
+console.log(used);
+```
+
+**noUnreachable** - Remove unreachable code after return/throw
+
+```typescript
+// BAD
+function foo() {
+ return 1;
+ console.log("never reached"); // Remove this
+}
+
+// GOOD
+function foo() {
+ return 1;
+}
+```
+
+**noUndeclaredVariables** - Declare variables or import them
+
+```typescript
+// BAD
+console.log(undeclaredVar); // Not defined
+
+// GOOD
+const declaredVar = "value";
+console.log(declaredVar);
+```
+
+**noDebugger** - Remove `debugger` statements before committing
+
+```typescript
+// BAD
+function process() {
+ debugger; // Remove
+ return data;
+}
+
+// GOOD
+function process() {
+ return data;
+}
+```
+
+### Suspicious Rules
+
+These indicate likely bugs or problematic patterns:
+
+**noExplicitAny** - Use specific types instead of `any`
+
+```typescript
+// BAD
+function process(data: any) { ... }
+
+// GOOD
+interface Data { id: string; value: number }
+function process(data: Data) { ... }
+// Or use unknown with type guards
+function process(data: unknown) {
+ if (typeof data === 'string') { ... }
+}
+```
+
+**noArrayIndexKey** - Use stable unique IDs for React keys
+
+```typescript
+// BAD
+items.map((item, index) =>
)
+
+// GOOD
+items.map((item) => )
+```
+
+**noDoubleEquals** - Use strict equality (=== !==)
+
+```typescript
+// BAD
+if (value == null) // type coercion
+
+// GOOD
+if (value === null || value === undefined)
+// Or if intentional:
+if (value == null) // Refactor to be explicit
+```
+
+**noConsoleLog** - Remove or replace console.log statements
+
+```typescript
+// BAD
+console.log("debug"); // In production code
+
+// GOOD
+// Use proper logging library
+// Or remove if temporary debugging
+```
+
+### Style Rules
+
+**useTemplate** - Use template literals instead of string concatenation
+
+```typescript
+// BAD
+const message = "Hello, " + name + "!";
+
+// GOOD
+const message = `Hello, ${name}!`;
+```
+
+**useConst** - Use const for variables that don't change
+
+```typescript
+// BAD
+let x = 5; // Never reassigned
+
+// GOOD
+const x = 5;
+```
+
+**useSingleVarDeclarator** - Declare one variable per statement
+
+```typescript
+// BAD
+const a = 1,
+ b = 2,
+ c = 3;
+
+// GOOD
+const a = 1;
+const b = 2;
+const c = 3;
+```
+
+**useNamingConvention** - Follow naming conventions
+
+```typescript
+// BAD (depending on config)
+const my_variable = 1;
+const MyVariable = 1;
+
+// GOOD
+const myVariable = 1; // camelCase
+const MY_CONSTANT = 1; // CONST_CASE for constants
+```
+
+### Complexity Rules
+
+**noForEach** - Use for-of loops for better performance and control
+
+```typescript
+// BAD
+array.forEach((item) => { ... });
+
+// GOOD
+for (const item of array) { ... }
+```
+
+**noBannedTypes** - Avoid problematic types (String, Number, Boolean, Object, {})
+
+```typescript
+// BAD
+function process(obj: Object) { ... }
+function process(obj: {}) { ... }
+
+// GOOD
+function process(obj: Record) { ... }
+// Or use specific interfaces
+interface Config { ... }
+function process(obj: Config) { ... }
+```
+
+**useSimplifiedLogicExpression** - Simplify complex boolean logic
+
+```typescript
+// BAD
+if (a === true) { ... }
+if (b === false) { ... }
+
+// GOOD
+if (a) { ... }
+if (!b) { ... }
+```
+
+### Performance Rules
+
+**noAccumulatingSpread** - Avoid spread in reduce (creates new objects each iteration)
+
+```typescript
+// BAD (O(n²) complexity)
+array.reduce((acc, item) => ({ ...acc, [item.key]: item }), {});
+
+// GOOD (O(n) complexity)
+const result = {};
+for (const item of array) {
+ result[item.key] = item;
+}
+```
+
+**noDelete** - Use undefined assignment or Map/Set instead of delete
+
+```typescript
+// BAD
+delete obj.property;
+
+// GOOD
+obj.property = undefined;
+// Or use Map for dynamic keys
+const map = new Map();
+map.set("key", value);
+map.delete("key"); // OK for Map
+```
+
+## Configuration-Specific Issues
+
+### biome.json Not Found
+
+Ensure `biome.json` or `biome.jsonc` exists in project root:
+
+```json
+{
+ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
+ "organizeImports": {
+ "enabled": true
+ },
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": true
+ }
+ },
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "space",
+ "indentWidth": 2
+ }
+}
+```
+
+### Import Organization
+
+Run `biome check --write` to automatically organize imports. Manual organization:
+
+- Group imports: external libs → internal absolute → relative
+- Sort alphabetically within groups
+- Remove unused imports
+
+### File-Specific Issues
+
+Some issues require project-level thinking:
+
+**noGlobalAssign** - Don't modify global objects
+
+```typescript
+// BAD
+Array.prototype.custom = () => {};
+window.globalVar = 1;
+
+// GOOD
+// Extend via proper subclassing or utility functions
+function customArrayMethod(array) { ... }
+```
+
+**noRestrictedGlobals** - Use allowed globals only
+
+```typescript
+// BAD
+const name = "value"; // Uses global window.name
+const status = 200; // Uses global window.status
+
+// GOOD
+const userName = "value";
+const httpStatus = 200;
+```
+
+## Common Workflows
+
+### Before Committing Code
+
+```bash
+# 1. Check everything
+biome check .
+
+# 2. Apply safe fixes
+biome check --write .
+
+# 3. Review remaining issues manually
+biome check --verbose .
+
+# 4. Fix each remaining issue (NO suppression comments!)
+```
+
+### CI/CD Integration
+
+```bash
+# In CI, fail on any issues (don't use --write)
+biome check .
+
+# Or with specific error formatting
+biome check --error-on-warnings --reporter=github .
+```
+
+#### Debugging CI Failures Locally
+
+When CI pipelines fail due to Biome errors, always replicate the issue locally first:
+
+```bash
+# Run the exact same command CI runs (check your .github/workflows/validate-pr.yml)
+biome ci --reporter=github --diagnostic-level=error . --verbose
+
+# Or if using biome check in CI:
+biome check --error-on-warnings --reporter=github .
+
+# Compare local results with CI output to identify environment differences
+```
+
+**Why run locally first?**
+
+- Faster iteration than waiting for CI
+- Can use `--write` flag to auto-fix issues locally
+- Identifies environment-specific issues (e.g., Biome version mismatches, config resolution)
+- Allows using `--verbose` for detailed diagnostics
+- Prevents commit noise from trial-and-error fixes
+
+**Common CI/Local discrepancies:**
+
+1. **Different Biome versions** - Ensure local version matches CI: `bunx biome --version`
+2. **Config not found** - CI might run from different working directory; use explicit `--config-path`
+3. **Line ending differences** - Windows (CRLF) vs Linux (LF); configure `formatter.lineEnding` in biome.json
+4. **File paths** - CI may check files you haven't modified; run on entire codebase locally: `biome check .`
+
+**Steps to resolve CI failures:**
+
+1. Run the same Biome command locally that failed in CI
+2. Apply fixes with `biome check --write .` (or manual fixes for unsafe changes)
+3. Verify all issues resolved: `biome check .`
+4. Commit and push changes
+
+### Large Refactors
+
+```bash
+# Format everything first
+biome format --write .
+
+# Fix safe linting issues
+biome lint --write .
+
+# Tackle remaining issues file by file
+biome check --verbose src/specific-file.ts
+```
+
+## Emergency Recovery
+
+If you encounter Biome errors that block work:
+
+1. **Check if it's a configuration error**
+
+ ```bash
+ biome check --config-path=./biome.json --verbose
+ ```
+
+2. **Ensure Biome is up to date**
+
+ ```bash
+ npm update @biomejs/biome
+ # or
+ yarn upgrade @biomejs/biome
+ ```
+
+3. **Validate biome.json syntax**
+
+ ```bash
+ npx @biomejs/biome migrate --write
+ ```
+
+4. **Check for file encoding issues**
+ - Ensure files are UTF-8 encoded
+ - Check for BOM markers that might confuse parser
+
+## Remember
+
+✅ **DO**:
+
+- Fix the underlying issue
+- Use `biome check --write` for safe fixes
+- Remove unused code
+- Add proper types
+- Simplify complex expressions
+- Follow project conventions
+
+❌ **NEVER**:
+
+- Add `// biome-ignore` comments
+- Use `// biome-ignore lint` suppressions
+- Disable rules globally to avoid fixing issues
+- Commit code with intentional Biome violations
+
+## Getting More Help
+
+For specific rule documentation:
+
+- Run `biome explain ` (e.g., `biome explain noDebugger`)
+- Visit https://biomejs.dev/linter/rules/
+- Check error messages for specific guidance
+- Reference: https://biomejs.dev/reference/diagnostics/
diff --git a/biome.json b/biome.json
index a0a6bef..69c0cb9 100644
--- a/biome.json
+++ b/biome.json
@@ -1,29 +1,46 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.13/schema.json",
+ "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
"files": {
- "experimentalScannerIgnores": ["**/*.html", "**/fonts/**"]
- },
- "vcs": {
- "enabled": true,
- "clientKind": "git",
- "useIgnoreFile": true,
- "defaultBranch": "main"
+ "ignoreUnknown": false,
+ "includes": [
+ "**",
+ "!**/dist",
+ "!**/node_modules",
+ "!libs/docs-builder/src/components/Header.astro",
+ "!libs/docs-builder/src/components/ASCIISiteTitle.astro"
+ ]
},
"formatter": {
"enabled": true,
+ "formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
+ "lineEnding": "lf",
"lineWidth": 120,
- "lineEnding": "lf"
- },
- "javascript": {
- "formatter": {
- "quoteStyle": "single",
- "semicolons": "always",
- "trailingCommas": "all",
- "bracketSpacing": true,
- "arrowParentheses": "always"
- }
+ "attributePosition": "auto",
+ "bracketSameLine": false,
+ "bracketSpacing": true,
+ "expand": "auto",
+ "useEditorconfig": true,
+ "includes": [
+ "**",
+ "!**/node_modules",
+ "!**/dist",
+ "!**/build",
+ "!**/coverage",
+ "!**/*.lock",
+ "!**/bun.lock",
+ "!**/pnpm-lock.yaml",
+ "!**/package-lock.json",
+ "!**/yarn.lock",
+ "!**/.nx",
+ "!**/.cache",
+ "!**/*.log",
+ "!**/.DS_Store",
+ "!./.nx/cache",
+ "!./.nx/workspace-data"
+ ]
},
"linter": {
"enabled": true,
@@ -34,111 +51,171 @@
"level": "warn",
"options": { "maxAllowedComplexity": 15 }
},
- "noForEach": "warn",
"useArrowFunction": "error"
},
+ "correctness": {
+ "noUnusedVariables": "error"
+ },
"style": {
"useImportType": "error",
- "useExportType": "error",
"useNodejsImportProtocol": "error",
- "noNonNullAssertion": "warn",
- "useConst": "error"
+ "useNumberNamespace": "error",
+ "useForOf": "error",
+ "noNegationElse": "off"
},
"suspicious": {
- "noExplicitAny": "warn",
- "noConsole": {
- "level": "error",
- "options": { "allow": ["warn", "error", "info", "debug"] }
- }
- },
- "correctness": {
- "noUnusedVariables": "error",
- "noUnusedImports": "error"
- },
- "performance": {
- "noDelete": "warn"
+ "noDoubleEquals": "error"
}
+ },
+ "includes": [
+ "**",
+ "!node_modules/",
+ "!dist/",
+ "!build/",
+ "!.nx/",
+ "!coverage/",
+ "!bun.lock"
+ ]
+ },
+ "javascript": {
+ "formatter": {
+ "jsxQuoteStyle": "double",
+ "quoteProperties": "asNeeded",
+ "trailingCommas": "all",
+ "semicolons": "always",
+ "arrowParentheses": "always",
+ "bracketSameLine": false,
+ "quoteStyle": "single",
+ "attributePosition": "auto",
+ "bracketSpacing": true
+ }
+ },
+ "html": {
+ "formatter": {
+ "indentScriptAndStyle": false,
+ "selfCloseVoidElements": "always"
}
},
"overrides": [
{
- "includes": ["**/*.json"],
- "formatter": {
- "lineWidth": 80
- }
+ "includes": ["*.json", "*.json5", "*.jsonc"],
+ "javascript": { "formatter": { "quoteStyle": "double" } },
+ "formatter": { "indentWidth": 2, "lineWidth": 80 }
},
+ { "includes": ["*.md"], "formatter": { "lineWidth": 120 } },
+ { "includes": ["**/*.json"], "javascript": { "globals": [] } },
{
- "includes": ["**/scripts/**/*.{ts,js}", "**/tools/**/*.{ts,js}"],
+ "includes": ["**/*.ts", "**/*.tsx"],
+ "javascript": {
+ "globals": [
+ "require",
+ "console",
+ "__filename",
+ "module",
+ "process",
+ "Buffer",
+ "__dirname",
+ "exports"
+ ]
+ },
"linter": {
"rules": {
- "suspicious": {
- "noAssignInExpressions": "off",
- "noExplicitAny": "off",
- "noImplicitAnyLet": "off",
- "useIterableCallbackReturn": "off"
- },
"complexity": {
- "noExcessiveCognitiveComplexity": "off",
- "noForEach": "off"
- }
- }
- }
- },
- {
- "includes": ["**/*.test.ts", "**/*.spec.ts", "**/*test-utils*.ts"],
- "linter": {
- "rules": {
- "suspicious": {
- "noExplicitAny": "off",
- "noConsole": "off"
+ "noBannedTypes": "error",
+ "noUselessThisAlias": "error",
+ "noUselessTypeConstraint": "error"
+ },
+ "correctness": {
+ "noUndeclaredVariables": "off",
+ "noUnusedVariables": "error"
+ },
+ "style": {
+ "noCommonJs": "error",
+ "noNamespace": "error",
+ "useArrayLiterals": "error",
+ "useAsConstAssertion": "error",
+ "useConst": "error"
},
- "complexity": {
- "noExcessiveCognitiveComplexity": "off",
- "noForEach": "off"
- }
- }
- }
- },
- {
- "includes": ["**/*.d.ts"],
- "linter": {
- "rules": {
"suspicious": {
- "noExplicitAny": "off"
+ "noExplicitAny": "warn",
+ "noExtraNonNullAssertion": "error",
+ "noMisleadingInstantiator": "error",
+ "noNonNullAssertedOptionalChain": "error",
+ "noTsIgnore": "error",
+ "noUnsafeDeclarationMerging": "error",
+ "noVar": "error",
+ "useNamespaceKeyword": "error"
}
}
}
},
{
- "includes": ["libs/docs-builder/**/*.js", "**/pages/**/*.js"],
+ "includes": ["**/*.test.ts", "**/*.spec.ts", "**/types/bun-test.d.ts"],
"linter": {
"rules": {
+ "complexity": {
+ "noExcessiveCognitiveComplexity": "off"
+ },
"suspicious": {
- "noAssignInExpressions": "off",
"noExplicitAny": "off"
},
- "complexity": {
- "noExcessiveCognitiveComplexity": "off"
+ "style": {
+ "noNonNullAssertion": "off"
}
}
}
},
{
- "includes": ["**/scripts/**/*.{ts,js}", "**/tools/**/*.{ts,js}"],
+ "includes": [
+ "packages/opencode-notification/src/notifier.ts",
+ "packages/opencode-config/src/loader.ts",
+ "libs/docs-builder/test-links.js",
+ "packages/opencode-warcraft-notifications-plugin/pages/test-links.js",
+ "packages/opencode-warcraft-notifications-plugin/src/notification.ts",
+ "packages/opencode-warcraft-notifications-plugin/src/schema-validator.ts",
+ "packages/opencode-font/scripts/**/*.ts",
+ "tools/executors/**/*.ts",
+ "tools/executors/**/*.test.ts"
+ ],
"linter": {
"rules": {
+ "complexity": {
+ "noExcessiveCognitiveComplexity": "off"
+ },
"suspicious": {
- "noAssignInExpressions": "off",
"noExplicitAny": "off",
- "noImplicitAnyLet": "off",
- "useIterableCallbackReturn": "off"
+ "noAssignInExpressions": "off"
},
- "complexity": {
- "noExcessiveCognitiveComplexity": "off",
- "noForEach": "off"
+ "style": {
+ "noNonNullAssertion": "off",
+ "noCommonJs": "off"
}
}
}
+ },
+ {
+ "includes": ["packages/opencode-font/**/*"],
+ "linter": { "enabled": false },
+ "formatter": { "enabled": false }
+ },
+ {
+ "includes": ["**/*.js", "**/*.jsx"],
+ "javascript": {
+ "globals": [
+ "require",
+ "console",
+ "__filename",
+ "module",
+ "process",
+ "Buffer",
+ "__dirname",
+ "exports"
+ ]
+ }
}
- ]
+ ],
+ "assist": {
+ "enabled": true,
+ "actions": { "source": { "organizeImports": "on" } }
+ }
}
diff --git a/lefthook.yml b/lefthook.yml
index 54c9446..c05084e 100644
--- a/lefthook.yml
+++ b/lefthook.yml
@@ -1,45 +1,39 @@
# Lefthook configuration for opencode-plugins
-# Leverages Nx to run tasks on affected packages with Biome
+# Leverages Nx to run tasks on affected packages
# For more information: https://lefthook.dev/configuration/
pre-commit:
parallel: true
commands:
- # Biome check (lint + format) on affected packages
+ # Lint and format affected packages with Biome (combines format + lint)
biome:
- run: bunx nx affected --target=check --base=HEAD~1 --head=HEAD --parallel=3
+ run: bunx nx affected --target=lint --base=HEAD~1 --head=HEAD --parallel=3 --batch
- # Validate JSDoc on affected packages
- jsdoc:
- run: bunx nx affected --target=validate:jsdoc --base=HEAD~1 --head=HEAD --parallel=3
+ # Validate TSDoc on affected packages
+ validate-tsdoc:
+ run: bunx nx affected --target=validate:tsdoc --base=HEAD~1 --head=HEAD
# Type-check affected packages using Nx
type-check:
run: bunx nx affected --target=type-check --base=HEAD~1 --head=HEAD --parallel=3
- # Lint markdown files
+ # Lint markdown files in root
markdown-lint:
- glob: "*.md"
+ glob: '*.md'
run: bunx markdownlint-cli2 {staged_files}
-pre-push:
- commands:
- # Biome check on all affected packages
- check:
- run: bunx nx affected --target=check --base=origin/main --head=HEAD --parallel=3
-
- # Validate JSDoc on all affected packages
- jsdoc:
- run: bunx nx affected --target=validate:jsdoc --base=origin/main --head=HEAD --parallel=3
-
- # Validate markdown on all affected packages
- markdown:
- run: bunx nx affected --target=validate:markdown --base=origin/main --head=HEAD --parallel=3
+ # Validate skills when skill files change
+ validate-skills:
+ glob: '**/skills/**/*.ts'
+ run: bunx nx affected --target=validate:skills --base=HEAD~1 --head=HEAD
- # Type-check all affected packages
- type-check:
- run: bunx affected --target=type-check --base=origin/main --head=HEAD --parallel=3
+ # Validate SKILL.md files when they change
+ validate-skill-md:
+ glob: '**/SKILL.md'
+ run: bunx nx affected --target=validate:skill-md --base=HEAD~1 --head=HEAD
+pre-push:
+ commands:
# Run tests on affected packages
test:
run: bunx nx affected --target=test --base=origin/main --head=HEAD --parallel=3
@@ -48,9 +42,13 @@ pre-push:
build:
run: bunx nx affected --target=build --base=origin/main --head=HEAD --parallel=3
+ # Lint all affected packages (final check)
+ lint-all:
+ run: bunx nx affected --target=lint --base=origin/main --head=HEAD --parallel=3
+
# Skip hooks configuration
# To skip a hook, run: LEFTHOOK=0 git commit
-# To skip specific commands: LEFTHOOK_EXCLUDE=biome git commit
+# To skip specific commands: LEFTHOOK_EXCLUDE=lint git commit
output:
- execution
diff --git a/libs/docs-builder/src/components/ASCIISiteTitle.astro b/libs/docs-builder/src/components/ASCIISiteTitle.astro
index 8b65f2b..82d36a7 100644
--- a/libs/docs-builder/src/components/ASCIISiteTitle.astro
+++ b/libs/docs-builder/src/components/ASCIISiteTitle.astro
@@ -1,7 +1,7 @@
---
// Simple text-based site title
// For custom ASCII art, you can use a library like figlet or create your own
-const _siteTitle = 'WarcraftNotifications';
+const siteTitle = 'WarcraftNotifications';
---
diff --git a/libs/docs-builder/src/components/Header.astro b/libs/docs-builder/src/components/Header.astro
index 16f45df..d5dd6c7 100644
--- a/libs/docs-builder/src/components/Header.astro
+++ b/libs/docs-builder/src/components/Header.astro
@@ -1,4 +1,8 @@
---
+import ASCIISiteTitle from './ASCIISiteTitle.astro';
+import SocialIcons from 'virtual:starlight/components/SocialIcons';
+import Search from 'virtual:starlight/components/Search';
+import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
---