{"id":45278124,"url":"https://github.com/ersinkoc/codeguardian","last_synced_at":"2026-02-21T02:03:50.728Z","repository":{"id":337096900,"uuid":"1152291079","full_name":"ersinkoc/CodeGuardian","owner":"ersinkoc","description":"Zero-dependency TypeScript codebase guardian that enforces architecture, security, performance, and quality rules as a pre-commit hook.","archived":false,"fork":false,"pushed_at":"2026-02-07T18:13:34.000Z","size":228,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-08T02:40:51.834Z","etag":null,"topics":["code","guardian","security"],"latest_commit_sha":null,"homepage":"http://codeguardian.oxog.dev/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ersinkoc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-07T16:56:03.000Z","updated_at":"2026-02-07T18:13:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ersinkoc/CodeGuardian","commit_stats":null,"previous_names":["ersinkoc/codeguardian"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ersinkoc/CodeGuardian","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ersinkoc%2FCodeGuardian","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ersinkoc%2FCodeGuardian/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ersinkoc%2FCodeGuardian/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ersinkoc%2FCodeGuardian/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ersinkoc","download_url":"https://codeload.github.com/ersinkoc/CodeGuardian/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ersinkoc%2FCodeGuardian/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29671513,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T00:11:43.526Z","status":"online","status_checked_at":"2026-02-21T02:00:07.432Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code","guardian","security"],"created_at":"2026-02-21T02:03:45.665Z","updated_at":"2026-02-21T02:03:50.722Z","avatar_url":"https://github.com/ersinkoc.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @oxog/codeguardian\n\n**Zero-dependency TypeScript codebase guardian** that enforces architecture, security, performance, and quality rules as a pre-commit hook.\n\nUnlike traditional linters that check syntax, codeguardian builds a **knowledge graph** of your codebase and evaluates every change against that graph. It understands your project's architectural patterns, detects security anti-patterns, catches performance pitfalls, and blocks or warns based on severity.\n\n## Features\n\n- **Codebase Knowledge Graph** — Maps all files, symbols, imports, and dependencies\n- **ESM \u0026 CommonJS Support** — Correctly resolves `.js`/`.ts` import extensions\n- **Incremental Analysis** — Only re-parses changed files (\u003c 2s pre-commit)\n- **29 Built-in Rules** — Architecture, security, performance, and quality checks\n- **Plugin System** — Extend with custom rules and plugins\n- **Zero Dependencies** — Only TypeScript as a peer dependency\n- **Pre-commit Hook** — Blocks commits with critical/error findings\n- **Multiple Output Formats** — Terminal, JSON, SARIF (GitHub Code Scanning)\n\n## Quick Start\n\n```bash\nnpm install @oxog/codeguardian --save-dev\nnpx codeguardian init\n```\n\nThat's it. codeguardian will now run on every commit.\n\n## Programmatic Usage\n\n```typescript\nimport { createGuardian } from '@oxog/codeguardian';\n\nconst guardian = createGuardian({\n  rootDir: process.cwd(),\n  tsconfig: './tsconfig.json',\n});\n\n// Full scan\nconst graph = await guardian.scan();\nconsole.log(`${graph.files.size} files, ${graph.symbols.size} symbols`);\n\n// Run analysis\nconst result = await guardian.run({ staged: true });\nif (result.blocked) {\n  console.error('Commit blocked!');\n  process.exit(1);\n}\n```\n\n## CLI\n\n```bash\ncodeguardian init                      # Setup project\ncodeguardian run                       # Analyze all files\ncodeguardian run --staged              # Analyze staged files (pre-commit)\ncodeguardian run --format json         # JSON output\ncodeguardian run --format sarif        # SARIF for GitHub\ncodeguardian run --plugin security     # Run specific plugin\ncodeguardian run --verbose             # Include info findings\ncodeguardian stats                     # Show graph statistics\ncodeguardian rules                     # List all rules\ncodeguardian conventions               # Show detected conventions\ncodeguardian scan --full               # Force full re-scan\ncodeguardian uninstall                 # Remove hook\n```\n\n## Configuration\n\nCreate `.codeguardian.json` in your project root:\n\n```json\n{\n  \"include\": [\"src/**/*.ts\"],\n  \"exclude\": [\"**/*.test.ts\"],\n  \"severity\": {\n    \"blockOn\": [\"critical\", \"error\"],\n    \"warnOn\": [\"warning\"]\n  },\n  \"plugins\": {\n    \"architecture\": {\n      \"enabled\": true,\n      \"layers\": [\"controller\", \"service\", \"repository\", \"util\"],\n      \"enforceDirection\": true,\n      \"maxFileLines\": 300,\n      \"maxFunctionLines\": 50\n    },\n    \"security\": {\n      \"enabled\": true,\n      \"checkInjection\": true,\n      \"checkSecrets\": true,\n      \"checkXSS\": true\n    },\n    \"performance\": {\n      \"enabled\": true,\n      \"checkN1Queries\": true,\n      \"checkMemoryLeaks\": true\n    },\n    \"quality\": {\n      \"enabled\": true,\n      \"maxCyclomaticComplexity\": 15\n    }\n  }\n}\n```\n\n## Core Plugins \u0026 Rules\n\n### Architecture (6 rules)\n| Rule | Severity | Description |\n|------|----------|-------------|\n| `architecture/layer-violation` | error | Lower layer importing from higher layer |\n| `architecture/circular-dependency` | error | Circular import chains (A -\u003e B -\u003e C -\u003e A) |\n| `architecture/file-role-mismatch` | warning | File content doesn't match directory role |\n| `architecture/god-file` | warning | File exceeds max line count |\n| `architecture/god-function` | warning | Function exceeds max line count |\n| `architecture/barrel-explosion` | info | Barrel files re-exporting too many symbols |\n\n### Security (8 rules)\n| Rule | Severity | Description |\n|------|----------|-------------|\n| `security/sql-injection` | critical | String concatenation in SQL queries |\n| `security/hardcoded-secret` | critical | API keys, tokens, passwords in code |\n| `security/eval-usage` | critical | eval(), Function(), setTimeout(string) |\n| `security/prototype-pollution` | error | Direct prototype assignment |\n| `security/xss-risk` | error | innerHTML, document.write |\n| `security/missing-auth-check` | warning | Controllers without auth references |\n| `security/insecure-random` | warning | Math.random() in security contexts |\n| `security/path-traversal` | error | Dynamic paths in file operations |\n\n### Performance (7 rules)\n| Rule | Severity | Description |\n|------|----------|-------------|\n| `performance/n1-query` | warning | Database calls (find, query, execute) inside loops |\n| `performance/sync-in-async` | warning | readFileSync in async functions |\n| `performance/memory-leak-risk` | warning | addEventListener without cleanup |\n| `performance/unbounded-query` | warning | Queries without LIMIT |\n| `performance/missing-index-hint` | info | Queries needing indexes |\n| `performance/heavy-import` | info | Full library imports |\n| `performance/blocking-operation` | warning | CPU-heavy ops in handlers |\n\n### Quality (8 rules)\n| Rule | Severity | Description |\n|------|----------|-------------|\n| `quality/cyclomatic-complexity` | warning | Functions exceeding complexity limit |\n| `quality/dead-code` | warning | Exported symbols never imported (supports ESM `.js` imports) |\n| `quality/any-type` | warning | Usage of `any` type |\n| `quality/no-error-handling` | warning | Async functions without try-catch |\n| `quality/inconsistent-naming` | info | Non-camelCase function names |\n| `quality/magic-number` | info | Numeric literals without constants |\n| `quality/empty-catch` | warning | Empty catch blocks |\n| `quality/nested-callbacks` | warning | Deeply nested callbacks (\u003e 3 levels) |\n\n## Custom Rules\n\n```typescript\nimport { defineRule, type Finding } from '@oxog/codeguardian';\n\nconst noConsole = defineRule({\n  name: 'custom/no-console',\n  severity: 'warning',\n  description: 'No console.log in production',\n  category: 'quality',\n  check: (context) =\u003e {\n    const findings: Finding[] = [];\n    context.walk(context.ast, {\n      CallExpression(node) {\n        if (context.isConsoleCall(node as any, 'log')) {\n          findings.push({\n            message: 'Remove console.log',\n            file: context.file.path,\n            line: 1,\n            column: 1,\n          });\n        }\n      },\n    });\n    return findings;\n  },\n});\n```\n\n## Custom Plugins\n\n```typescript\nimport { definePlugin, defineRule } from '@oxog/codeguardian';\n\nconst myPlugin = definePlugin({\n  name: 'my-team-rules',\n  version: '1.0.0',\n  install: (kernel) =\u003e {\n    kernel.registerRule(noConsole);\n    kernel.registerRule(anotherRule);\n  },\n});\n\nguardian.use(myPlugin);\n```\n\n## Inline Suppression\n\n```typescript\n// codeguardian-disable-next-line security/sql-injection\nconst query = `SELECT * FROM users WHERE id = ${id}`;\n\n// codeguardian-disable security/hardcoded-secret -- legacy code\nconst key = 'secret_live_abc123xyz';\n// codeguardian-enable security/hardcoded-secret\n```\n\n## Severity Levels\n\n| Level | Blocks Commit | When Shown |\n|-------|--------------|------------|\n| `critical` | Yes | Always |\n| `error` | Yes | Always |\n| `warning` | No | Always |\n| `info` | No | Only with `--verbose` |\n\n## Requirements\n\n- Node.js \u003e= 18\n- TypeScript \u003e= 5.0 (peer dependency)\n\n## Documentation\n\n| Document | Description |\n|----------|-------------|\n| [API Reference](docs/API_DOCS.md) | Complete API reference for all public functions, types, and plugins |\n| [Contributing](CONTRIBUTING.md) | Development setup, testing, writing rules/plugins, PR process |\n| [Troubleshooting](docs/TROUBLESHOOTING.md) | Common issues and solutions |\n| [Security Policy](SECURITY.md) | Vulnerability reporting and disclosure policy |\n| [Changelog](CHANGELOG.md) | Version history and release notes |\n| [Specification](docs/SPECIFICATION.md) | Package specification and design decisions |\n| [Implementation](docs/IMPLEMENTATION.md) | Architecture decisions and implementation guide |\n\n## Links\n\n- [Documentation](https://codeguardian.oxog.dev)\n- [GitHub](https://github.com/ersinkoc/codeguardian)\n- [npm](https://www.npmjs.com/package/@oxog/codeguardian)\n\n## License\n\nMIT - Ersin Koc\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fersinkoc%2Fcodeguardian","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fersinkoc%2Fcodeguardian","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fersinkoc%2Fcodeguardian/lists"}