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
9 changes: 9 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"Bash(pre-commit run:*)"
],
"deny": [],
"ask": []
}
}
24 changes: 24 additions & 0 deletions .commitlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"extends": ["@commitlint/config-conventional"],
"rules": {
"type-enum": [
2,
"always",
[
"feat",
"fix",
"docs",
"style",
"refactor",
"perf",
"test",
"build",
"ci",
"chore",
"revert"
]
],
"subject-case": [0],
"body-max-line-length": [0]
}
}
19 changes: 19 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# EditorConfig helps maintain consistent coding styles
# https://editorconfig.org

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
# Trailing whitespace in Markdown can be significant (line breaks)
trim_trailing_whitespace = false

[Makefile]
indent_style = tab
86 changes: 86 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
lint:
name: Lint & Validate
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Lint Markdown files
uses: DavidAnson/markdownlint-cli2-action@v14
with:
globs: "**/*.md"

- name: Check spelling
uses: streetsidesoftware/cspell-action@v5
with:
files: "**/*.md"
config: "./cspell.json"

- name: Check links
uses: lycheeverse/lychee-action@v1
with:
args: --verbose --no-progress --exclude-mail './**/*.md'
fail: true

- name: AISD forbidden words check
run: |
echo "Checking for forbidden words (should/might/could/typically/usually/often)..."
# Exclude README.md, CHANGELOG.md, and AGENTS.md from this check
if find . -name "*.md" ! -name "README.md" ! -name "CHANGELOG.md" ! -name "AGENTS.md" -exec grep -l -E "\b(should|might|could|typically|usually|often)\b" {} \; | grep -q .; then
echo "❌ Found forbidden words in the following files:"
find . -name "*.md" ! -name "README.md" ! -name "CHANGELOG.md" ! -name "AGENTS.md" -exec grep -Hn -E "\b(should|might|could|typically|usually|often)\b" {} \;
echo ""
echo "Use MUST/REQUIRED/FORBIDDEN instead per AISD style guide."
exit 1
fi
echo "✅ No forbidden words found"

- name: AISD line count check
run: |
echo "Checking docs/ files for line count (max 600)..."
failed=0
for file in docs/*.md docs/**/*.md; do
[ -f "$file" ] || continue
lines=$(wc -l < "$file")
if [ "$lines" -gt 600 ]; then
echo "❌ $file has $lines lines (max 600)"
failed=1
fi
done
if [ "$failed" -eq 1 ]; then
echo "Consider splitting large files."
exit 1
fi
echo "✅ All docs files within line limit"

commitlint:
name: Commit Messages
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Install commitlint
run: npm install -g @commitlint/cli @commitlint/config-conventional

- name: Validate PR commits
run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose
33 changes: 33 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Release

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: write

jobs:
release:
name: Semantic Release
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Install semantic-release
run: npm install -g semantic-release @semantic-release/changelog @semantic-release/git

- name: Run semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release
12 changes: 12 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"default": true,
"MD013": false,
"MD025": false,
"MD033": false,
"MD036": false,
"MD040": false,
"MD041": false,
"MD024": {
"siblings_only": true
}
}
48 changes: 48 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# See https://pre-commit.com for more information
# Install: pip install pre-commit && pre-commit install

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- id: end-of-file-fixer
- id: check-yaml
- id: check-merge-conflict
- id: check-added-large-files

- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.38.0
hooks:
- id: markdownlint
args: ["--fix"]

- repo: https://github.com/streetsidesoftware/cspell-cli
rev: v8.6.0
hooks:
- id: cspell
args: ["--no-progress", "--no-summary"]

# Conventional commits for semver
- repo: https://github.com/compilerla/conventional-pre-commit
rev: v3.4.0
hooks:
- id: conventional-pre-commit
stages: [commit-msg]

# Local AISD format validation
- repo: local
hooks:
- id: aisd-forbidden-words
name: AISD forbidden words check
entry: bash -c 'if grep -rn -E "\b(should|might|could|typically|usually|often)\b" "$@" 2>/dev/null; then echo "❌ Found forbidden words. Use MUST/REQUIRED/FORBIDDEN instead."; exit 1; fi' --
language: system
files: \.(md)$
exclude: ^(README\.md|CHANGELOG\.md|AGENTS\.md)$

- id: aisd-line-count
name: AISD line count check (max 600)
entry: bash -c 'for file in "$@"; do lines=$(wc -l < "$file"); if [ $lines -gt 600 ]; then echo "❌ $file has $lines lines (max 600). Consider splitting."; exit 1; fi; done' --
language: system
files: ^docs/.*\.md$
21 changes: 21 additions & 0 deletions .releaserc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md"
}
],
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
],
"@semantic-release/github"
]
}
Loading