"
-labels: ["bug", "triage"]
-assignees:
- - octocat
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for taking the time to fill out this bug report!
-
- - type: textarea
- id: what-happened
- attributes:
- label: What happened?
- description: Also tell us, what did you expect to happen?
- placeholder: |
- Steps to reproduce the behavior:
- 1.
- 2.
- 3.
-
- Expected behavior:
- ...
-
- Actual behavior:
- ...
- validations:
- required: true
-
- - type: textarea
- id: possible-fix
- attributes:
- label: Any suggestions for fixing this bug?
- description: If you have an idea to fix this bug, we'd love to hear it!
- validations:
- required: false
-
- - type: textarea
- id: logs
- attributes:
- label: Relevant log output
- description: Please copy and paste any relevant log output.
- render: shell
-
- - type: textarea
- id: environment
- attributes:
- label: Details about your environment
- description: Please provide the following information about your environment.
- placeholder: |
- ## Your Environment
- - Go Version:
- - Operating System:
- - Browser (if applicable):
- - Relevant env vars
-
- Tell us what you see!
- validations:
- required: false
diff --git a/.github/ISSUE_TEMPLATE/config.yaml b/.github/ISSUE_TEMPLATE/config.yaml
deleted file mode 100644
index bd9dfe4..0000000
--- a/.github/ISSUE_TEMPLATE/config.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
----
-blank_issues_enabled: false
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml
deleted file mode 100644
index d2222e5..0000000
--- a/.github/ISSUE_TEMPLATE/feature_request.yaml
+++ /dev/null
@@ -1,54 +0,0 @@
----
-name: "💡 Feature Request"
-description: Create a new ticket for a new feature request
-title: "💡 [REQUEST] - "
-labels: ["question"]
-body:
- - type: textarea
- id: implementation_pr
- attributes:
- label: "Implementation PR"
- description: Associated pull request
- placeholder: "# Pull Request ID"
- validations:
- required: false
- - type: textarea
- id: reference_issues
- attributes:
- label: "Reference Issues"
- description: Related issues
- placeholder: "# Issue ID(s)"
- validations:
- required: false
- - type: textarea
- id: summary
- attributes:
- label: "Summary"
- description: Provide a brief explanation of the feature
- placeholder: Describe your feature request
- validations:
- required: true
- - type: textarea
- id: basic_example
- attributes:
- label: "Basic Example"
- description: Provide some basic examples of your feature
- placeholder: A few specific details about your feature request
- validations:
- required: true
- - type: textarea
- id: drawbacks
- attributes:
- label: "Drawbacks"
- description: What are the drawbacks/impacts of your feature request?
- placeholder: Identify the drawbacks and impacts while remaining neutral on your feature request
- validations:
- required: true
- - type: textarea
- id: unresolved_question
- attributes:
- label: "Unresolved questions"
- description: What questions remain unresolved?
- placeholder: Identify any unresolved issues
- validations:
- required: false
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index 19e12b1..0000000
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# [Title of Your PR]
-
-**Key Changes:**
-
-- [ ] List major changes and core updates
-- [ ] Keep each line under 80 characters
-- [ ] Focus on the "what" and "why"
-
-**Added:**
-
-- [ ] New features/functionality
-- [ ] New files/configurations
-- [ ] New dependencies
-
-**Changed:**
-
-- [ ] Updates to existing code
-- [ ] Configuration changes
-- [ ] Dependency updates
-
-**Removed:**
-
-- [ ] Deleted files/code
-- [ ] Removed dependencies
-- [ ] Cleaned up configurations
-
----
-
-
-
diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml
deleted file mode 100644
index 440894d..0000000
--- a/.github/actionlint.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-self-hosted-runner:
- labels:
- - ubuntu24.04-amd64-8-core
diff --git a/.github/labeler.yaml b/.github/labeler.yaml
deleted file mode 100644
index a764319..0000000
--- a/.github/labeler.yaml
+++ /dev/null
@@ -1,76 +0,0 @@
----
-# Area Labels
-area/docs:
- - changed-files:
- - any-glob-to-any-file: "docs/**/*"
-
-area/examples:
- - changed-files:
- - any-glob-to-any-file: "examples/**/*"
-
-area/github:
- - changed-files:
- - any-glob-to-any-file: ".github/**/*"
-
-area/pre-commit:
- - changed-files:
- - any-glob-to-any-file: ".pre-commit-config.yaml"
- - any-glob-to-any-file: ".hooks/**/*"
-
-area/python:
- - changed-files:
- - any-glob-to-any-file: "pyproject.toml"
- - any-glob-to-any-file: "requirements.txt"
- - any-glob-to-any-file: "*.py"
-
-area/security:
- - changed-files:
- - any-glob-to-any-file: "SECURITY.md"
- - any-glob-to-any-file: "secrets.baseline"
-
-area/taskfiles:
- - changed-files:
- - any-glob-to-any-file: "Taskfile.yaml"
-
-area/tests:
- - changed-files:
- - any-glob-to-any-file: "tests/**/*"
-
-area/workspace:
- - changed-files:
- - any-glob-to-any-file: "python.code-workspace"
-
-# Development Labels
-area/dev:
- - changed-files:
- - any-glob-to-any-file: "dev/**/*"
-
-# Semantic Type Labels
-type/digest:
- - head-branch: ["^renovate/"]
- - head-branch: ["^deps/"]
-
-type/patch:
- - any: ["title:/^(?:Fix|Patch|Update)/"]
-
-type/minor:
- - any: ["title:/^(?:Add|Feature|Improve)/"]
-
-type/major:
- - any: ["title:/^(?:BREAKING)/"]
-
-type/break:
- - any: ["body:/BREAKING CHANGE:/"]
-
-# Documentation Labels
-type/docs:
- - changed-files:
- - any-glob-to-any-file: "docs/**/*"
- - any-glob-to-any-file: "*.md"
-
-# Core Files Labels
-type/core:
- - changed-files:
- - any-glob-to-any-file: "CODEOWNERS"
- - any-glob-to-any-file: "LICENSE"
- - any-glob-to-any-file: "README.md"
diff --git a/.github/labels.yaml b/.github/labels.yaml
deleted file mode 100644
index 7e6a6c6..0000000
--- a/.github/labels.yaml
+++ /dev/null
@@ -1,134 +0,0 @@
----
-# Area Labels
-- name: area/docs
- color: "72CCF3" # Light Blue
- description: >-
- Changes to documentation and guides
-
-- name: area/examples
- color: "BC9BE3" # Lavender
- description: >-
- Changes to example code and demonstrations
-
-- name: area/github
- color: "F4D1B7" # Peach
- description: >-
- Changes made to GitHub Actions
-
-- name: area/pre-commit
- color: "84B6EB" # Steel Blue
- description: >-
- Changes made to pre-commit hooks
-
-- name: area/python
- color: "7BD7E0" # Turquoise
- description: >-
- Changes to Python package configuration and dependencies
-
-- name: area/security
- color: "FF6600" # Orange
- description: >-
- Changes to security policies and configurations
-
-- name: area/taskfiles
- color: "66CCFF" # Sky Blue
- description: >-
- Changes made to Taskfiles
-
-- name: area/tests
- color: "99CC00" # Lime Green
- description: >-
- Changes to test files and testing infrastructure
-
-- name: area/workspace
- color: "FF99CC" # Pink
- description: >-
- Changes to VSCode workspace configuration
-
-- name: area/assets
- color: "FFA07A" # Light Salmon
- description: >-
- Changes to asset files
-
-- name: area/templates
- color: "DA70D6" # Orchid
- description: >-
- Changes to templates
-
-- name: area/scripts
- color: "40E0D0" # Turquoise
- description: >-
- Changes to script files
-
-- name: area/src
- color: "4682B4" # Steel Blue
- description: >-
- Changes to source code
-
-- name: area/ci
- color: "FF4500" # Orange Red
- description: >-
- Changes related to CI/CD configurations
-
-- name: area/shell
- color: "556B2F" # Dark Olive Green
- description: >-
- Changes to shell scripts
-
-- name: area/dev
- color: "CC6699" # Dusty Rose
- description: >-
- Changes to development tools and assets
-
-# Renovate Labels
-- name: renovate/container
- color: "9933CC" # Purple
- description: >-
- Docker container updates via Renovate
-
-- name: renovate/github-action
- color: "FF3366" # Hot Pink
- description: >-
- GitHub Action updates via Renovate
-
-- name: renovate/github-release
- color: "3399FF" # Bright Blue
- description: >-
- GitHub Release updates via Renovate
-
-# Semantic Type Labels
-- name: type/digest
- color: "FF66CC" # Bright Pink
- description: >-
- Dependency digest updates
-
-- name: type/patch
- color: "FFC300" # Golden Yellow
- description: >-
- Patch changes (fixes, updates)
-
-- name: type/minor
- color: "FFD700" # Gold
- description: >-
- Minor changes (features, improvements)
-
-- name: type/major
- color: "F6412D" # Red Orange
- description: >-
- Major changes
-
-- name: type/break
- color: "FF0000" # Bright Red
- description: >-
- Breaking changes
-
-# Documentation Labels
-- name: type/docs
- color: "0075CA" # Documentation Blue
- description: >-
- Documentation updates and improvements
-
-- name: type/core
- color: "A2EEEF" # Light Blue
- description: >-
- Changes to core repository files and configurations
diff --git a/.github/renovate.json b/.github/renovate.json
deleted file mode 100644
index c181218..0000000
--- a/.github/renovate.json
+++ /dev/null
@@ -1,134 +0,0 @@
-{
- "$schema": "https://docs.renovatebot.com/renovate-schema.json",
- "extends": [
- "config:recommended",
- ":disableRateLimiting",
- ":dependencyDashboard",
- ":semanticCommits",
- ":enablePreCommit",
- ":automergeDigest",
- ":automergeBranch"
- ],
- "dependencyDashboardTitle": "Renovate Dashboard 🤖",
- "minimumReleaseAge": "3 days",
- "suppressNotifications": [
- "prIgnoreNotification"
- ],
- "rebaseWhen": "conflicted",
- "commitBodyTable": true,
- "pre-commit": {
- "enabled": true
- },
- "enabledManagers": [
- "npm",
- "github-actions",
- "pip_requirements",
- "poetry",
- "pep621",
- "setup-cfg",
- "dockerfile"
- ],
- "timezone": "America/New_York",
- "schedule": [
- "before 4am"
- ],
- "labels": [
- "dependency"
- ],
- "packageRules": [
- {
- "matchUpdateTypes": [
- "patch"
- ],
- "matchCurrentVersion": "!/^0/",
- "automerge": true
- },
- {
- "matchDepTypes": [
- "devDependencies"
- ],
- "groupName": "dev dependencies"
- },
- {
- "groupName": "typescript-types",
- "matchPackagePatterns": [
- "^@types/"
- ]
- },
- {
- "groupName": "eslint packages",
- "matchPackagePatterns": [
- "eslint"
- ]
- },
- {
- "matchManagers": [
- "poetry",
- "pip_requirements"
- ],
- "groupName": "pytest packages",
- "groupSlug": "pytest",
- "separateMinorPatch": true,
- "matchPackagePatterns": [
- "^pytest"
- ]
- },
- {
- "matchManagers": [
- "poetry",
- "pip_requirements"
- ],
- "matchDepTypes": [
- "python"
- ],
- "allowedVersions": "^3.8",
- "enabled": true
- },
- {
- "description": "Auto merge lint and formatting tools",
- "matchManagers": ["npm"],
- "matchPackagePatterns": [
- "lint",
- "prettier",
- "eslint",
- "@typescript-eslint/",
- "stylelint",
- "jshint",
- "tslint"
- ],
- "automerge": true,
- "automergeType": "pr"
- },
- {
- "description": "Auto merge npm minor and patch updates",
- "matchManagers": ["npm"],
- "matchUpdateTypes": ["minor", "patch"],
- "matchCurrentVersion": "!/^0/",
- "automerge": true,
- "automergeType": "pr"
- },
- {
- "description": "Auto merge GitHub Actions minor updates",
- "matchManagers": ["github-actions"],
- "matchUpdateTypes": ["minor", "patch"],
- "automerge": true,
- "automergeType": "pr"
- },
- {
- "description": "Auto merge non-major updates",
- "matchUpdateTypes": [
- "minor",
- "patch"
- ],
- "automerge": true,
- "automergeType": "pr"
- }
- ],
- "vulnerabilityAlerts": {
- "enabled": true,
- "labels": [
- "security"
- ]
- },
- "lockFileMaintenance": { "enabled": true }
-}
diff --git a/.github/renovate.properties b/.github/renovate.properties
deleted file mode 100644
index a6b6168..0000000
--- a/.github/renovate.properties
+++ /dev/null
@@ -1,8 +0,0 @@
-RENOVATE_ASSIGNEES=["GangGreenTemperTatum"]
-RENOVATE_PLATFORM=github
-RENOVATE_AUTODISCOVER=true
-RENOVATE_AUTODISCOVER_FILTER="GangGreenTemperTatum/*"
-RENOVATE_PR_CONCURRENT_LIMIT=50
-RENOVATE_BRANCH_CONCURRENT_LIMIT=0
-RENOVATE_PR_HOURLY_LIMIT=0
-LOG_LEVEL=warn
\ No newline at end of file
diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml
deleted file mode 100644
index 145ec61..0000000
--- a/.github/workflows/pre-commit.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Pre-commit Checks
-
-on:
- pull_request:
- push:
- branches: [main]
-
-jobs:
- pre-commit:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
- with:
- python-version: '3.13'
- - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd #v3.0.1
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index bf37280..5187b51 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,30 +1,37 @@
-name: 🚀 Release
+name: Release
on:
workflow_dispatch:
env:
- NODE_VERSION: 20
+ NODE_VERSION: 22
PNPM_VERSION: 9
jobs:
release:
- name: Release
+ name: 🚀 Release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
+ - name: Verify main branch
+ run: |
+ if [[ "${{ github.ref_name }}" != "main" ]]; then
+ echo "Release can only be done on the main branch."
+ exit 1
+ fi
+
- name: Checkout project
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@v4
- name: Setup Node.js
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
+ uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup pnpm
- uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
+ uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: true
@@ -37,6 +44,7 @@ jobs:
run: |
if [[ -z "${{ secrets.PRIVATE_KEY }}" ]]; then
echo "Set an ed25519 key as PRIVATE_KEY in GitHub Action secret to sign."
+ exit 1
else
echo "${{ secrets.PRIVATE_KEY }}" > private_key.pem
openssl pkeyutl -sign -inkey private_key.pem -out plugin_package.zip.sig -rawin -in plugin_package.zip
@@ -48,13 +56,13 @@ jobs:
working-directory: dist
run: |
VERSION=$(unzip -p plugin_package.zip manifest.json | jq -r .version)
- echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
+ echo "version=${VERSION}" >> $GITHUB_OUTPUT
- name: Create release
- uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b #v1.20.0
+ uses: caido/action-release@v1
with:
tag: ${{ steps.meta.outputs.version }}
commit: ${{ github.sha }}
body: 'Release ${{ steps.meta.outputs.version }}'
artifacts: 'dist/plugin_package.zip,dist/plugin_package.zip.sig'
- immutableCreate: true
\ No newline at end of file
+ immutableCreate: true
diff --git a/.github/workflows/rigging_pr_description.yml b/.github/workflows/rigging_pr_description.yml
deleted file mode 100644
index f1f65b3..0000000
--- a/.github/workflows/rigging_pr_description.yml
+++ /dev/null
@@ -1,54 +0,0 @@
----
-name: Update PR Description with Rigging
-
-on:
- pull_request:
- types: [opened, synchronize]
-
-jobs:
- update-description:
- runs-on: ubuntu-latest
- permissions:
- pull-requests: write
- contents: read
-
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- with:
- fetch-depth: 0 # full history for proper diffing
-
- - name: Set up Python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
- with:
- python-version: "3.13"
-
- - name: Install uv
- run: |
- python -m pip install --upgrade pip
- pip install uv
-
- - name: Generate PR Description
- id: description
- env:
- OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- run: |
- DESCRIPTION="$(uv run --no-project .hooks/generate_pr_description.py --base-ref "origin/${{ github.base_ref }}" --exclude "./*.lock")"
- {
- echo "description<> "$GITHUB_OUTPUT"
-
- - name: Update PR Description
- uses: nefrob/pr-description@4dcc9f3ad5ec06b2a197c5f8f93db5e69d2fdca7 # v1.2.0
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- content: |
-
- ---
-
- ## Generated Summary
-
- ${{ steps.description.outputs.description }}
-
- This summary was generated with ❤️ by [rigging](https://docs.dreadnode.io/rigging/)
diff --git a/.github/workflows/semantic-prs.yaml b/.github/workflows/semantic-prs.yaml
deleted file mode 100644
index 26a1685..0000000
--- a/.github/workflows/semantic-prs.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
----
-name: "Semantic Lints PR"
-on:
- pull_request:
- branches:
- - main
- types:
- - opened
- - edited
- - synchronize
- - reopened
-
-permissions:
- pull-requests: read
-
-jobs:
- main:
- name: Validate PR title
- runs-on: ubuntu-latest
- steps:
- - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml
index d6d205b..82d83fa 100644
--- a/.github/workflows/validate.yml
+++ b/.github/workflows/validate.yml
@@ -4,41 +4,38 @@ on:
push:
branches:
- 'main'
- workflow_call:
pull_request:
- branches:
- - 'main'
+ workflow_call:
concurrency:
group: validate-${{ github.ref_name }}
cancel-in-progress: true
env:
- CAIDO_NODE_VERSION: 20
- CAIDO_PNPM_VERSION: 9
+ NODE_VERSION: 22
+ PNPM_VERSION: 9
jobs:
typecheck:
name: 'Typecheck'
runs-on: ubuntu-latest
timeout-minutes: 10
-
steps:
- name: Checkout repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@v4
- name: Setup Node.js
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
+ uses: actions/setup-node@v4
with:
- node-version: ${{ env.CAIDO_NODE_VERSION }}
+ node-version: ${{ env.NODE_VERSION }}
- name: Setup pnpm
- uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
+ uses: pnpm/action-setup@v4
with:
- version: ${{ env.CAIDO_PNPM_VERSION }}
+ version: ${{ env.PNPM_VERSION }}
- name: Install dependencies
- run: pnpm install
+ run: pnpm install --frozen-lockfile
- name: Run typechecker
run: pnpm typecheck
@@ -49,20 +46,92 @@ jobs:
timeout-minutes: 10
steps:
- name: Checkout repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@v4
- name: Setup Node.js
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
+ uses: actions/setup-node@v4
with:
- node-version: ${{ env.CAIDO_NODE_VERSION }}
+ node-version: ${{ env.NODE_VERSION }}
- name: Setup pnpm
- uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
+ uses: pnpm/action-setup@v4
with:
- version: ${{ env.CAIDO_PNPM_VERSION }}
+ version: ${{ env.PNPM_VERSION }}
- name: Install dependencies
- run: pnpm install
+ run: pnpm install --frozen-lockfile
- name: Run linter
- run: pnpm lint
\ No newline at end of file
+ run: pnpm lint
+
+ test:
+ name: 'Test'
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: ${{ env.PNPM_VERSION }}
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Run tests
+ run: pnpm test
+
+ knip:
+ name: 'Knip'
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: ${{ env.PNPM_VERSION }}
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Run knip
+ run: pnpm knip
+
+ build:
+ name: 'Build'
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: ${{ env.PNPM_VERSION }}
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Run build
+ run: pnpm build
diff --git a/.gitignore b/.gitignore
index f274dde..54e2773 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,156 +1,6 @@
-# Dependencies
-node_modules/
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-.pnpm-debug.log*
-
-# Documentation
-docs/
-documentation/
-
-# Build outputs
-dist/
-build/
-out/
-*.tsbuildinfo
-*.build.js
-*.build.js.map
-
-# Generated files
-packages/backend/src/bypass-data.generated.ts
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Coverage directory used by tools like istanbul
-coverage/
-*.lcov
-.nyc_output
-
-# ESLint cache
-.eslintcache
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variable files
-.env
-.env.development.local
-.env.test.local
-.env.production.local
-.env.local
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-out
-
-# Nuxt.js build / generate output
-.nuxt
+node_modules
dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# public
-
-# Vite build tool
-dist-ssr
-*.local
-
-# Rollup plugin TypeScript declarations cache
-.rpt2_cache/
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v2
-.yarn/cache
-.yarn/unplugged
-.yarn/build-state.yml
-.yarn/install-state.gz
-.pnp.*
-
-# Temporary folders
-tmp/
-temp/
-
-# Logs
-logs
-*.log
-
-# OS generated files
.DS_Store
-.DS_Store?
-._*
-.Spotlight-V100
-.Trashes
-ehthumbs.db
-Thumbs.db
-
-# IDE files
-.vscode/
-.idea/
-*.swp
-*.swo
-*~
-
-# Backup files
-*.bak
-*.tmp
-*.orig
-
-# TypeScript cache
+plugin_package.zip
+coverage
*.tsbuildinfo
-
-# Optional stylelint cache
-.stylelintcache
-
-# SvelteKit build / generate output
-.svelte-kit
-
-# Testing
-/coverage
-/.nyc_output
-
-# Playwright
-test-results/
-playwright-report/
-playwright/.cache/
-
-# Storybook build outputs
-.out
-.storybook-out
-storybook-static
-
-# Temporary files
-.tmp/
-.temp/
-.claude/
-private.pem
diff --git a/.hooks/.gitkeep b/.hooks/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/.hooks/check_pinned_hash_dependencies.py b/.hooks/check_pinned_hash_dependencies.py
deleted file mode 100755
index 728f82a..0000000
--- a/.hooks/check_pinned_hash_dependencies.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/env python
-import re
-import sys
-from pathlib import Path
-
-
-class GitHubActionChecker:
- def __init__(self) -> None:
- # Pattern for actions with SHA-1 hashes (pinned)
- self.pinned_pattern = re.compile(r"uses:\s+([^@\s]+)@([a-f0-9]{40})")
-
- # Pattern for actions with version tags (unpinned)
- self.unpinned_pattern = re.compile(
- r"uses:\s+([^@\s]+)@(v\d+(?:\.\d+)*(?:-[a-zA-Z0-9]+(?:\.\d+)*)?)",
- )
-
- # Pattern for all uses statements
- self.all_uses_pattern = re.compile(r"uses:\s+([^@\s]+)@([^\s\n]+)")
-
- def format_terminal_link(self, file_path: str, line_number: int) -> str:
- """Format a terminal link to a file and line number.
-
- Args:
- file_path: Path to the file
- line_number: Line number in the file
-
- Returns:
- str: Formatted string with file path and line number
- """
- return f"{file_path}:{line_number}"
-
- def get_line_numbers(self, content: str, pattern: re.Pattern[str]) -> list[tuple[str, int]]:
- """Find matches with their line numbers."""
- matches = []
- matches.extend(
- (match.group(0), i)
- for i, line in enumerate(content.splitlines(), 1)
- for match in pattern.finditer(line)
- )
- return matches
-
- def check_file(self, file_path: str) -> bool:
- """Check a single file for unpinned dependencies."""
- try:
- content = Path(file_path).read_text()
- except (FileNotFoundError, PermissionError, IsADirectoryError, OSError) as e:
- print(f"\033[91mError reading file {file_path}: {e}\033[0m")
- return False
-
- # Get matches with line numbers
- pinned_matches = self.get_line_numbers(content, self.pinned_pattern)
- unpinned_matches = self.get_line_numbers(content, self.unpinned_pattern)
- all_matches = self.get_line_numbers(content, self.all_uses_pattern)
-
- print(f"\n\033[1m[=] Checking file: {file_path}\033[0m")
-
- # Print pinned dependencies
- if pinned_matches:
- print("\033[92m[+] Pinned:\033[0m")
- for match, line_num in pinned_matches:
- print(f" |- {match} \033[90m({file_path}:{line_num})\033[0m")
-
- # Track all found actions for validation
- found_actions = set()
- for match, _ in pinned_matches + unpinned_matches:
- action_name = self.pinned_pattern.match(match) or self.unpinned_pattern.match(match)
- if action_name:
- found_actions.add(action_name.group(1))
-
- has_errors = False
-
- # Check for unpinned dependencies
- if unpinned_matches:
- has_errors = True
- print("\033[93m[!] Unpinned (using version tags):\033[0m")
- for match, line_num in unpinned_matches:
- print(f" |- {match} \033[90m({file_path}:{line_num})\033[0m")
-
- # Check for completely unpinned dependencies (no SHA or version)
- unpinned_without_hash = [
- (match, line_num)
- for match, line_num in all_matches
- if not any(match in pinned[0] for pinned in pinned_matches)
- and not any(match in unpinned[0] for unpinned in unpinned_matches)
- ]
-
- if unpinned_without_hash:
- has_errors = True
- print("\033[91m[!] Completely unpinned (no SHA or version):\033[0m")
- for match, line_num in unpinned_without_hash:
- print(
- f" |- {match} \033[90m({self.format_terminal_link(file_path, line_num)})\033[0m",
- )
-
- # Print summary
- total_actions = len(pinned_matches) + len(unpinned_matches) + len(unpinned_without_hash)
- if total_actions == 0:
- print("\033[93m[!] No GitHub Actions found in this file\033[0m")
- else:
- print("\n\033[1mSummary:\033[0m")
- print(f"Total actions: {total_actions}")
- print(f"Pinned: {len(pinned_matches)}")
- print(f"Unpinned with version: {len(unpinned_matches)}")
- print(f"Completely unpinned: {len(unpinned_without_hash)}")
-
- return not has_errors
-
-
-def main() -> None:
- checker = GitHubActionChecker()
- files_to_check = sys.argv[1:]
-
- if not files_to_check:
- print("\033[91mError: No files provided to check\033[0m")
- print("Usage: python script.py ...")
- sys.exit(1)
-
- results = {file: checker.check_file(file) for file in files_to_check}
-
- # Print final summary
- print("\n\033[1mFinal Results:\033[0m")
- for file, passed in results.items():
- status = "\033[92m✓ Passed\033[0m" if passed else "\033[91m✗ Failed\033[0m"
- print(f"{status} {file}")
-
- if not all(results.values()):
- sys.exit(1)
-
-
-if __name__ == "__main__":
- main()
diff --git a/.hooks/generate_docs.py b/.hooks/generate_docs.py
deleted file mode 100644
index f82044c..0000000
--- a/.hooks/generate_docs.py
+++ /dev/null
@@ -1,222 +0,0 @@
-import argparse # noqa: INP001
-import re
-import typing as t
-from pathlib import Path
-
-from markdown import Markdown # type: ignore [import-untyped]
-from markdownify import MarkdownConverter # type: ignore [import-untyped]
-from markupsafe import Markup
-from mkdocstrings_handlers.python._internal.config import PythonConfig
-from mkdocstrings_handlers.python._internal.handler import (
- PythonHandler,
-)
-
-# ruff: noqa: T201
-
-
-class CustomMarkdownConverter(MarkdownConverter): # type: ignore [misc]
- # Strip extra whitespace from code blocks
- def convert_pre(self, el: t.Any, text: str, parent_tags: t.Any) -> t.Any:
- return super().convert_pre(el, text.strip(), parent_tags)
-
- # bold items with doc-section-title in a span class
- def convert_span(self, el: t.Any, text: str, parent_tags: t.Any) -> t.Any: # noqa: ARG002
- if "doc-section-title" in el.get("class", []):
- return f"**{text.strip()}**"
- return text
-
- # Remove the div wrapper for inline descriptions
- def convert_div(self, el: t.Any, text: str, parent_tags: t.Any) -> t.Any:
- if "doc-md-description" in el.get("class", []):
- return text.strip()
- return super().convert_div(el, text, parent_tags)
-
- # Map mkdocstrings details classes to Mintlify callouts
- def convert_details(self, el: t.Any, text: str, parent_tags: t.Any) -> t.Any: # noqa: ARG002
- classes = el.get("class", [])
-
- # Handle source code details specially
- if "quote" in classes:
- summary = el.find("summary")
- if summary:
- file_path = summary.get_text().replace("Source code in ", "").strip()
- content = text[text.find("```") :]
- return f'\n\n{content}\n\n'
-
- callout_map = {
- "note": "Note",
- "warning": "Warning",
- "info": "Info",
- "tip": "Tip",
- }
-
- callout_type = None
- for cls in classes:
- if cls in callout_map:
- callout_type = callout_map[cls]
- break
-
- if not callout_type:
- return text
-
- content = text.strip()
- if content.startswith(callout_type):
- content = content[len(callout_type) :].strip()
-
- return f"\n<{callout_type}>\n{content}\n{callout_type}>\n"
-
- def convert_table(self, el: t.Any, text: str, parent_tags: t.Any) -> t.Any:
- # Check if this is a highlighttable (source code with line numbers)
- if "highlighttable" in el.get("class", []):
- code_cells = el.find_all("td", class_="code")
- if code_cells:
- code = code_cells[0].get_text()
- code = code.strip()
- code = code.replace("```", "~~~")
- return f"\n```python\n{code}\n```\n"
-
- return super().convert_table(el, text, parent_tags)
-
-
-class AutoDocGenerator:
- def __init__(self, source_paths: list[str], theme: str = "material", **options: t.Any) -> None:
- self.source_paths = source_paths
- self.theme = theme
- self.handler = PythonHandler(PythonConfig.from_data(), base_dir=Path.cwd())
- self.options = options
-
- self.handler._update_env( # noqa: SLF001
- Markdown(),
- config={"mdx": ["toc"]},
- )
-
- md = Markdown(extensions=["fenced_code"])
-
- def simple_convert_markdown(
- text: str,
- heading_level: int,
- html_id: str = "",
- **kwargs: t.Any,
- ) -> t.Any:
- return Markup(md.convert(text) if text else "") # noqa: S704 # nosec
-
- self.handler.env.filters["convert_markdown"] = simple_convert_markdown
-
- def generate_docs_for_module(
- self,
- module_path: str,
- ) -> str:
- options = self.handler.get_options(
- {
- "docstring_section_style": "list",
- "merge_init_into_class": True,
- "show_signature_annotations": True,
- "separate_signature": True,
- "show_source": True,
- "show_labels": False,
- "show_bases": False,
- **self.options,
- },
- )
-
- module_data = self.handler.collect(module_path, options)
- html = self.handler.render(module_data, options)
-
- return str(
- CustomMarkdownConverter(
- code_language="python",
- ).convert(html),
- )
-
- def process_mdx_file(self, file_path: Path) -> bool:
- content = file_path.read_text(encoding="utf-8")
- original_content = content
-
- # Find the header comment block
- header_match = re.search(
- r"\{\s*/\*\s*((?:::.*?\n?)*)\s*\*/\s*\}",
- content,
- re.MULTILINE | re.DOTALL,
- )
-
- if not header_match:
- return False
-
- header = header_match.group(0)
- module_lines = header_match.group(1).strip().split("\n")
-
- # Generate content for each module
- markdown_blocks = []
- for line in module_lines:
- if line.startswith(":::"):
- module_path = line.strip()[3:].strip()
- if module_path:
- markdown = self.generate_docs_for_module(module_path)
- markdown_blocks.append(markdown)
-
- keep_end = content.find(header) + len(header)
- new_content = content[:keep_end] + "\n\n" + "\n".join(markdown_blocks)
-
- # Write back if changed
- if new_content != original_content:
- file_path.write_text(new_content, encoding="utf-8")
- print(f"[+] Updated: {file_path}")
- return True
-
- return False
-
- def process_directory(self, directory: Path, pattern: str = "**/*.mdx") -> int:
- if not directory.exists():
- print(f"[!] Directory does not exist: {directory}")
- return 0
-
- files_processed = 0
- files_modified = 0
-
- for mdx_file in directory.glob(pattern):
- if mdx_file.is_file():
- files_processed += 1
- if self.process_mdx_file(mdx_file):
- files_modified += 1
-
- return files_modified
-
-
-def main() -> None:
- """Main entry point for the script."""
-
- parser = argparse.ArgumentParser(description="Generate auto-docs for MDX files")
- parser.add_argument("--directory", help="Directory containing MDX files", default="docs")
- parser.add_argument("--pattern", default="**/*.mdx", help="File pattern to match")
- parser.add_argument(
- "--source-paths",
- nargs="+",
- default=["dreadnode"],
- help="Python source paths for module discovery",
- )
- parser.add_argument(
- "--show-if-no-docstring",
- type=bool,
- default=False,
- help="Show module/class/function even if no docstring is present",
- )
- parser.add_argument("--theme", default="material", help="Theme to use for rendering")
-
- args = parser.parse_args()
-
- # Create generator
- generator = AutoDocGenerator(
- source_paths=args.source_paths,
- theme=args.theme,
- show_if_no_docstring=args.show_if_no_docstring,
- )
-
- # Process directory
- directory = Path(args.directory)
- modified_count = generator.process_directory(directory, args.pattern)
-
- print(f"\n[+] Auto-doc generation complete. {modified_count} files were updated.")
-
-
-if __name__ == "__main__":
- main()
diff --git a/.hooks/generate_pr_description.py b/.hooks/generate_pr_description.py
deleted file mode 100644
index 78729e8..0000000
--- a/.hooks/generate_pr_description.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# /// script
-# requires-python = ">=3.10"
-# dependencies = [
-# "rigging",
-# "typer",
-# ]
-# ///
-
-import asyncio
-import subprocess
-import typing as t
-
-import typer
-
-import rigging as rg
-
-TRUNCATION_WARNING = "\n---\n**Note**: Due to the large size of this diff, some content has been truncated."
-
-
-@rg.prompt
-def generate_pr_description(diff: str) -> t.Annotated[str, rg.Ctx("markdown")]: # type: ignore[empty-body]
- """
- Analyze the provided git diff and create a PR description in markdown format.
-
-
- - Keep the summary concise and informative.
- - Use bullet points to structure important statements.
- - Focus on key modifications and potential impact - if any.
- - Do not add in general advice or best-practice information.
- - Write like a developer who authored the changes.
- - Prefer flat bullet lists over nested.
- - Do not include any title structure.
- - If there are no changes, just provide "No relevant changes."
- - Order your bullet points by importance.
-
- """
-
-
-def get_diff(base_ref: str, source_ref: str, *, exclude: list[str] | None = None) -> str:
- """
- Get the git diff between two branches.
- """
-
- merge_base = subprocess.run(
- ["git", "merge-base", source_ref, base_ref],
- capture_output=True,
- text=True,
- check=True,
- ).stdout.strip()
-
- diff_command = ["git", "diff", "--no-color", merge_base, source_ref]
- if exclude:
- diff_command.extend(["--", ".", *[f":(exclude){path}" for path in exclude]])
-
- diff_text = subprocess.run(
- diff_command,
- capture_output=True,
- text=True,
- check=True,
- ).stdout
-
- return diff_text
-
-
-def main(
- base_ref: str = "origin/main",
- source_ref: str = "HEAD",
- generator_id: str = "openai/o3-mini",
- max_diff_lines: int = 10_000,
- exclude: list[str] | None = None,
-) -> None:
- """
- Use rigging to generate a PR description from a git diff.
- """
-
- diff = get_diff(base_ref, source_ref, exclude=exclude)
- diff_lines = diff.split("\n")
- if len(diff_lines) > max_diff_lines:
- diff = "\n".join(diff_lines[:max_diff_lines]) + TRUNCATION_WARNING
-
- description = asyncio.run(generate_pr_description.bind(generator_id)(diff))
-
- print(description)
-
-
-if __name__ == "__main__":
- typer.run(main)
diff --git a/.hooks/linters/yamllint.yaml b/.hooks/linters/yamllint.yaml
deleted file mode 100644
index 32312e4..0000000
--- a/.hooks/linters/yamllint.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
----
-extends: default
-
-rules:
- line-length:
- max: 400
- level: warning
- truthy: false
- comments:
- min-spaces-from-content: 1
- braces: disable
- indentation: disable
diff --git a/.hooks/post_merge.sh b/.hooks/post_merge.sh
deleted file mode 100755
index 2f8daf9..0000000
--- a/.hooks/post_merge.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-
-# Get pre-merge hash from the target branch
-old_hash=$(git show ORIG_HEAD:poetry.lock | md5sum 2> /dev/null || echo "")
-
-# Get current hash
-new_hash=$(md5sum poetry.lock 2> /dev/null || echo "")
-
-# Compare and run poetry install if changed
-if [ "$old_hash" != "$new_hash" ]; then
- echo "📦 Root dependencies changed. Running poetry install..."
- poetry install || {
- echo "❌ Failed to update dependencies"
- exit 1
- }
- echo "✅ Root dependencies updated!"
-else
- echo "📦 No root dependency changes"
-fi
-
-# Get pre-merge hash from the target branch
-old_hash=$(git show ORIG_HEAD:components/api/poetry.lock | md5sum 2> /dev/null || echo "")
-
-# Get current hash
-new_hash=$(md5sum components/api/poetry.lock 2> /dev/null || echo "")
-
-# Compare and run poetry install if changed
-if [ "$old_hash" != "$new_hash" ]; then
- echo "📦 API dependencies changed. Running poetry install..."
- cd components/api || exit
- if ! poetry install --with dev; then
- echo "❌ Failed to update dependencies"
- exit 1
- fi
- echo "✅ API dependencies updated!"
-else
- echo "📦 No API dependency changes"
-fi
diff --git a/.hooks/prettier.sh b/.hooks/prettier.sh
deleted file mode 100755
index c5e2ad3..0000000
--- a/.hooks/prettier.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-set -euo pipefail
-
-# Check if npm is installed
-if ! command -v npm &> /dev/null; then
- echo 'Error: npm is not installed.' >&2
- exit 1
-fi
-
-# Check if Prettier is installed, install it if missing
-if ! command -v prettier &> /dev/null; then
- echo 'Error: Prettier is not installed.' >&2
- echo 'Installing Prettier...'
- npm install -g prettier
-fi
-
-# Verify Prettier is installed
-if ! command -v prettier &> /dev/null; then
- echo 'Error: Prettier installation failed.' >&2
- exit 1
-fi
-
-# Run Prettier on staged .json, .yaml, and .yml files
-echo "Running Prettier on staged files..."
-
-# List all staged files, filter for the desired extensions, and run Prettier
-git diff --cached --name-only --diff-filter=d |
- grep -E '\.(json|ya?ml)$' |
- xargs -I {} prettier --write {}
-
-# Add the files back to staging area as Prettier may have modified them
-git diff --name-only --diff-filter=d |
- grep -E '\.(json|ya?ml)$' |
- xargs git add
-
-echo "Prettier formatting completed."
-exit 0
diff --git a/.mise/config.toml b/.mise/config.toml
new file mode 100644
index 0000000..95a863a
--- /dev/null
+++ b/.mise/config.toml
@@ -0,0 +1,13 @@
+[tools]
+node = "20"
+pnpm = "9"
+
+[tasks.validate]
+description = "Run all validation checks (install, typecheck, lint, test, knip)"
+run = """
+pnpm install --frozen-lockfile
+pnpm typecheck
+pnpm lint
+pnpm test
+pnpm knip
+"""
diff --git a/.npmrc b/.npmrc
deleted file mode 100644
index 61a4cd6..0000000
--- a/.npmrc
+++ /dev/null
@@ -1,2 +0,0 @@
-min-release-age=3
-ignore-scripts=true
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
deleted file mode 100644
index b318acd..0000000
--- a/.pre-commit-config.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-repos:
- # Standard pre-commit hooks
- - repo: https://github.com/pre-commit/pre-commit-hooks
- rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b #v5.0.0
- hooks:
- - id: check-added-large-files
- args: [--maxkb=36000]
- - id: check-executables-have-shebangs
- - id: check-shebang-scripts-are-executable
- - id: check-json
- - id: check-yaml
- - id: trailing-whitespace
- exclude: \.(ts|vue|css)$
-
- # Github actions
- - repo: https://github.com/rhysd/actionlint
- rev: 5db9d9cde2f3deb5035dea3e45f0a9fff2f29448 #v1.7.4
- hooks:
- - id: actionlint
- name: Check Github Actions
- args: ["--ignore", "SC2102"]
-
- - repo: local
- hooks:
- # Ensure our GH actions are pinned to a specific hash
- - id: check-github-actions
- name: Check GitHub Actions for Pinned Dependencies
- entry: python .hooks/check_pinned_hash_dependencies.py
- language: python
- files: \.github/.*\.yml$
diff --git a/.secrets.baseline b/.secrets.baseline
deleted file mode 100644
index e69de29..0000000
diff --git a/CODEOWNERS b/CODEOWNERS
deleted file mode 100644
index 033d561..0000000
--- a/CODEOWNERS
+++ /dev/null
@@ -1 +0,0 @@
-* @GangGreenTemperTatum
\ No newline at end of file
diff --git a/README.md b/README.md
index ae5d8da..68647eb 100644
--- a/README.md
+++ b/README.md
@@ -1,212 +1,70 @@
-# CSP Auditor
-
-
-_A comprehensive Content Security Policy (CSP) vulnerability scanner plugin for Caido, designed to automatically detect and analyze CSP headers for common security misconfigurations and vulnerabilities with easily available applicable gadgets._
-
-Brought to you by [@GangGreenTemperTatum](https://github.com/GangGreenTemperTatum), proud ambassador of the [Caido](https://caido.io/ambassadors) community!
-
-_Hack the planet 🤘_
-
-[](https://github.com/GangGreenTemperTatum/csp-auditor/network/members)
-[](https://github.com/GangGreenTemperTatum/csp-auditor/issues)
-[](https://github.com/GangGreenTemperTatum/csp-auditor/releases)
-[](https://github.com/GangGreenTemperTatum/csp-auditor/stargazers)
-[](https://github.com/GangGreenTemperTatum/csp-auditor/blob/main/LICENSE)
-
-[Report Bug](https://github.com/GangGreenTemperTatum/csp-auditor/issues) •
-[Request Feature](https://github.com/GangGreenTemperTatum/csp-auditor/issues)
-
-
-
-CSP Auditor is now available via the [Caido Plugin Library](https://caido.io/plugins)! 🥳 CSP Auditor was [submitted to the Caido Plugin Library](https://github.com/caido/store/pull/41) and is approved, it will be available for installation directly from the Caido plugin store page.
-
-[https://caido.io/plugins](./public/images/caido-plugin-store.png)
-
+
+
+
+
+ GitHub
+ •
+ Documentation
+ •
+ Discord
+
+
----
-
-- [CSP Auditor](#csp-auditor)
- - [Overview](#overview)
- - [Features](#features)
- - [Quick Start](#quick-start)
- - [Prerequisites](#prerequisites)
- - [Installation](#installation)
- - [Install from source (without auto-updates):](#install-from-source-without-auto-updates)
- - [Usage](#usage)
- - [Dashboard \& Analysis](#dashboard--analysis)
- - [Vulnerability Detection](#vulnerability-detection)
- - [Bypass Database](#bypass-database)
- - [Configuration](#configuration)
- - [Contributing](#contributing)
- - [Adding New Bypass Gadgets](#adding-new-bypass-gadgets)
- - [General Development](#general-development)
- - [License](#license)
- - [Star History](#star-history)
-
-## Overview
-
-CSP Auditor is a Caido plugin that helps you monitor and analyze Content Security Policies (CSP) in web applications, it is designed to mimic the [Burp Suite extension](https://github.com/portswigger/csp-auditor)'s functionality with additional improvements and integration with [`cspbypass.com`](https://cspbypass.com) for a built-in bypass database of real-world CSP bypass techniques, directly in Caido!
-
-## Features
-
-- **Real-time CSP Analysis**: Automatically analyzes CSP headers from intercepted HTTP responses
-- **34+ Vulnerability Checks**: Comprehensive detection of CSP misconfigurations including:
- - Script wildcard sources and unsafe directives
- - JSONP bypass risks and AngularJS template injection
- - AI/ML and Web3 service integration risks
- - Missing Trusted Types and essential directives
- - Deprecated headers and vulnerable library hosts
-- **209+ Bypass Payloads**: Integrated database of real-world CSP bypass techniques from [CSPBypass research](./data/csp-bypass-data.tsv)
- > A thank you to Rennie Pak and contributors of the project for the original [CSP gadgets](https://cspbypass.com/) 🙏
-- **Searchable Bypass Database**: Filter and copy bypass payloads directly from the plugin interface
-- **Vulnerability Modals**: Detailed vulnerability information with relevant bypass examples and payload copying
-- **Configurable Detection**: Enable/disable specific vulnerability checks via settings panel
-- **Caido Findings Integration**: Automatically create findings for detected vulnerabilities
-- **Scope Awareness**: Respect Caido's project scope settings for targeted analysis
-- **Export Functionality**: Export findings as JSON or CSV for reporting
-- **Dashboard Statistics**: Overview of analyzed policies, vulnerabilities by severity, and detection trends
-
-
-
----
-
-## Quick Start
+# CSP Auditor
-### Prerequisites
+Content Security Policy vulnerability scanner and analyzer for Caido. Automatically detects CSP headers in HTTP responses, analyzes them against 20+ security checks, and reports findings with remediation guidance.
-- [Caido](https://caido.io) (latest version)
-- Node.js and pnpm (for development)
+## Features
-### Installation
+- Real-time CSP header detection via response interception
+- 20+ vulnerability checks across 7 categories (Critical, Modern Threats, Missing Features, Policy Weaknesses, Style Issues, Legacy Issues, Advanced)
+- Built-in CSP bypass database with 205 payloads from security research
+- Configurable check presets (Aggressive, Recommended, Light)
+- Export findings as JSON or CSV
+- Scope-aware analysis (respects Caido project scope)
+- Auto-creation of Caido findings for detected vulnerabilities
-
+1. Open Caido
+2. Navigate to **Plugins**
+3. Search for "CSP Auditor"
+4. Click **Install**
-### Install from source (without auto-updates):
+### Manual Installation
-1. **Clone the repository:**
- ```bash
- git clone https://github.com/GangGreenTemperTatum/csp-auditor.git
- cd csp-auditor
- ```
+1. Install dependencies:
-2. **Install dependencies:**
```bash
pnpm install
```
-3. **Build the plugin:**
+2. Build the plugin:
+
```bash
pnpm build
```
-4. **Install in Caido:**
- - Open Caido
- - Go to Settings > Plugins
- - Click "Install from file"
- - Select the built plugin file from the `dist/` directory
-
----
-
-### Usage
+3. Install in Caido:
+ - Upload the `plugin_package.zip` file by clicking "Install Package" in Caido's plugins tab.
-CSP Auditor automatically monitors your HTTP traffic and analyzes CSP headers in real-time. Once installed, it works seamlessly in the background.
+## Usage
-#### Dashboard & Analysis
-- **View CSP Statistics**: Navigate to the CSP Auditor panel to see vulnerability counts by severity (high/medium/low/info)
-- **Analyze Individual Responses**: Click on any analyzed response to view detailed CSP policy breakdown and specific vulnerabilities
-- **Export Reports**: Export findings as JSON or CSV for documentation and reporting
-
-
-
-
-#### Vulnerability Detection
-- **Real-time Alerts**: Automatic detection of 34+ CSP misconfigurations as you browse
-- **Caido Findings**: Enable auto-creation of findings for detected vulnerabilities (toggle in settings)
-- **Severity Classification**: Vulnerabilities categorized by impact level with detailed descriptions
-
-
-
csp-auditor finding
-
-#### Bypass Database
-- **209+ Real-world Bypasses**: Searchable database of CSP bypass techniques from security research
-- **Copy Payloads**: One-click copying of bypass code for testing
-- **Contextual Examples**: Relevant bypasses shown in vulnerability modals for immediate testing
-
-
-
csp-auditor bypass gadget db
-
-#### Configuration
-- **Scope Awareness**: Respects Caido's project scope settings for targeted analysis
-- **Customizable Checks**: Enable/disable specific vulnerability types via settings panel
-- **Cache Management**: Clear analysis cache when needed
-
-
-
csp-audit settings
-
----
+1. Browse to web applications that serve CSP headers
+2. The plugin automatically intercepts responses and analyzes CSP policies
+3. View results in the **Dashboard** tab with sortable columns
+4. Expand rows to see individual findings with severity badges and remediation
+5. Use the **Database** tab to search 205 bypass payloads
+6. Configure which checks are active in the **Configuration** tab
## Contributing
-### Adding New Bypass Gadgets
-
-CSP Auditor uses a comprehensive database of bypass techniques sourced from security research. To add new bypass gadgets:
-
-1. **Edit the TSV file**: Add new entries to `data/csp-bypass-data.tsv` in the following format:
- ```
- domain.example.com
- ```
- - **Column 1**: Domain or service name
- - **Column 2**: The actual bypass payload/code
- - Use TAB character as separator (not spaces)
-
-2. **Technique Detection**: The plugin automatically categorizes bypasses by technique:
- - JSONP (contains `callback=` or `cb=`)
- - AngularJS (contains `ng-` or `angular`)
- - Alpine.js (contains `x-init` or `alpine`)
- - HTMX (contains `hx-`)
- - Hyperscript (contains `_="`)
- - Script Injection (contains `
-a.huodong.mi.com
-acs.aliexpress.com
-aax-eu.amazon.com
-accdn.lpsnmedia.net
-accounts.google.com
-acs.youku.com
-ajax.googleapis.com