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
1 change: 1 addition & 0 deletions .humancov
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ test/badge.test.js ai false false claude-code -
test/cli.test.js ai false false claude-code -
test/comments.test.js ai false false claude-code -
test/ignore.test.js ai false false claude-code -
test/init.test.js ai false false claude-code -
test/manifest.test.js ai false false claude-code -
test/parser.test.js ai false false claude-code -
test/report.test.js ai false false claude-code -
Expand Down
77 changes: 76 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,76 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Build and Run

```bash
npm install # install deps (single dep: `ignore`)
npm test # run all tests (node:test, no framework)
node --test test/parser.test.js # run a single test file
node bench/perf.js # run benchmarks
npx humancov scan # run the CLI locally
npm run ci # run CI locally via `act` (requires act installed)
```

No build step - pure ESM (`"type": "module"` in package.json), runs directly with Node >= 18.

## Architecture

The CLI entry point is `bin/humancov.js` - a thin dispatcher that parses args and delegates to modules in `src/`:

- `scanner.js` - core scan logic. Lists files via `git ls-files` (falls back to recursive walk), filters through ignore patterns, calls parser on each file, aggregates summary stats.
- `parser.js` - reads first 20 lines of a file, extracts `AI-Provenance-*` headers using comment-syntax-aware parsing.
- `comments.js` - maps file extensions to comment prefixes (`//`, `#`, `<!--`, `/*`, `--`). Also defines binary extension set (returns `null` for binaries).
- `ignore.js` - loads `.humancov-ignore` plus built-in default patterns, returns an `ignore` instance for filtering.
- `report.js` - formats scan results as human-readable text or JSON.
- `badge.js` - generates shields.io badge URL from scan summary with color thresholds.
- `manifest.js` - writes `.humancov` TSV manifest file from scan results.
- `init.js` - appends AI-Provenance instructions to AI tool config files (CLAUDE.md, AGENTS.md, .cursorrules, .github/copilot-instructions.md). For modern rule directories (`.cursor/rules/`, `.windsurf/rules/`), it creates a dedicated `humancov.mdc` / `humancov.md` rule file.

Tests in `test/` mirror `src/` 1:1 (e.g., `test/parser.test.js` tests `src/parser.js`). All tests use Node's built-in `node:test` and `node:assert`.

## Key Design Decisions

- Zero build, zero transpilation - ship raw ESM JS files.
- Single runtime dependency (`ignore` for gitignore-pattern matching).
- File headers are the source of truth - the `.humancov` manifest is derived from them.
- Headers must appear in the first 20 lines, using the file's native comment syntax.
- When both manifest and headers exist and conflict, headers win.
- Version is read from `package.json` at runtime (no hardcoded version).

## Pre-commit Hook

The repo uses a local pre-commit hook that auto-updates the `.humancov` manifest and README badge. See README.md "Pre-commit Hook" section for setup.

## Branching and workflow

GitHub Flow - everything happens on `main`.

| Branch/Ref | Purpose |
|---|---|
| `main` | Single source of truth. All PRs merge here. |
| `feature/*`, `fix/*`, `docs/*`, `refactor/*`, `test/*` | Short-lived branches. Deleted after merge. |
| tag `v*` | Release trigger (npm publish). |

No long-lived `dev` branch. Work happens in short feature branches merged to `main` via PR (squash merge).

```bash
git checkout main
git pull origin main
git checkout -b feature/xxx
# work, commit freely (WIP commits are fine, they get squashed)
git push origin feature/xxx
gh pr create --base main --fill
gh pr merge --squash --delete-branch
git checkout main
git pull origin main
```

Questions / proposals / bug reports go to GitHub Issues.

---

# AI-Provenance Spec v0.1

A lightweight, machine-readable convention for tracking the origin, review status, and test status of files in repositories where AI-generated and human-written code coexist.
Expand Down Expand Up @@ -193,7 +266,9 @@ A pre-commit hook CAN warn if a new file with `Origin: ai` is added without the

## 7. Ignored Files

Files matching patterns in `.humancov-ignore` (same syntax as `.gitignore`) are excluded from scanning and badge calculation. Typical ignores:
humancov automatically respects the project's `.gitignore` (if present). For extra humancov-specific exclusions, add patterns to `.humancov-ignore` at the repo root (same syntax as `.gitignore`).

Resolution order: built-in defaults → `.gitignore` → `.humancov-ignore`.

```
# .humancov-ignore
Expand Down
144 changes: 66 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![license](https://img.shields.io/badge/license-CC0--1.0-brightgreen)](https://creativecommons.org/publicdomain/zero/1.0/)
[![node](https://img.shields.io/node/v/humancov)](https://nodejs.org/)
[![GitHub](https://img.shields.io/github/stars/enixCode/humancov?style=social)](https://github.com/enixCode/humancov)
![Human Reviewed](https://img.shields.io/badge/human--reviewed-17%25%20of%20AI%20files-red)
![Human Reviewed](https://img.shields.io/badge/human--reviewed-16%25%20of%20AI%20files-red)

A lightweight CLI that tracks AI-generated vs human-written code in your repo.

Expand All @@ -15,18 +15,38 @@ Add provenance headers to your files, scan, and know exactly what's been human-r

## Install

Install as a dev dependency in your project:

```bash
npm install -g humancov
npm install --save-dev humancov
npx humancov scan
```

Or locally:
Requires **Node >= 18**.

---

## AI Tool Setup

Run `humancov init` **first** - it teaches your AI coding tool to tag every file it generates with provenance headers automatically.

```bash
npm install humancov
npx humancov scan
humancov init
```

Requires **Node >= 18**.
It detects existing config files (or rule directories) and appends the instructions block. If a modern rules directory exists, a dedicated rule file is created instead.

| Tool | Config file |
|---|---|
| Claude Code | `CLAUDE.md` |
| AGENTS.md (cross-tool) | `AGENTS.md` |
| Cursor (legacy) | `.cursorrules` |
| Cursor (rules dir) | `.cursor/rules/humancov.mdc` |
| Windsurf (legacy) | `.windsurfrules` |
| Windsurf (rules dir) | `.windsurf/rules/humancov.md` |
| GitHub Copilot | `.github/copilot-instructions.md` |

If the file already contains AI-Provenance instructions, it skips it. If no config files are found, it lists the supported files.

---

Expand Down Expand Up @@ -83,67 +103,56 @@ Of AI files:
| `humancov init` | Add AI-Provenance instructions to AI tool configs |
| `humancov --version` | Print version |

---

## AI Tool Setup
### Examples

Use `humancov init` to automatically add provenance instructions to your AI coding tool configs.
**`--json`** - per-file provenance data:

It detects existing config files and appends the instructions block:
```json
{
"files": [
{ "file": "src/scanner.js", "origin": "ai", "generator": "claude-code", "reviewed": "false", ... },
{ "file": "lib/utils.py", "origin": "human", "reviewed": "true", ... }
],
"summary": { "total": 22, "ai": 18, "human": 0, "mixed": 0, "unknown": 4, "reviewed": 3, "tested": 5 }
}
```

| Tool | Config file |
|---|---|
| Claude Code | `CLAUDE.md` |
| Cursor | `.cursorrules` |
| Windsurf | `.windsurfrules` |
| GitHub Copilot | `.github/copilot-instructions.md` |
**`--badge`** - shields.io URL + markdown snippet:

```bash
humancov init
```
https://img.shields.io/badge/human--reviewed-17%25%20of%20AI%20files-red
![Human Reviewed](https://img.shields.io/badge/human--reviewed-17%25%20of%20AI%20files-red)
```

If the file already contains AI-Provenance instructions, it skips it. If no config files are found, it lists the supported files.
**`--check 80`** - CI gate (exits 1 on failure):

```
Reviewed: 17% (threshold: 80%)
FAIL: 17% < 80%
```

---

## Header Keys

Headers use the prefix `AI-Provenance-` in a comment at the top of the file.

| Key | Required | Values | Description |
|---|---|---|---|
| `Origin` | yes | `ai`, `human`, `mixed` | Who wrote the file |
| `Generator` | no | free-text | Tool used (`claude-code`, `copilot`, `codex`...) |
| `Reviewed` | yes | `true`, `false`, `partial` | Human review status |
| `Tested` | no | `true`, `false`, `partial` | Human test status |
| `Confidence` | no | `high`, `medium`, `low` | Reviewer confidence |
| `Notes` | no | free-text | Any context |

### Comment styles
Add `AI-Provenance-` headers in a comment block at the top of any file (first 20 lines). Use your language's comment syntax (`//`, `#`, `<!--`, `/*`, `--`).

Headers adapt to the file's language:

```javascript
// AI-Provenance-Origin: ai // JS, TS, Java, Go, Rust, C...
```
```python
# AI-Provenance-Origin: ai # Python, Ruby, Shell, YAML...
```
```html
<!-- AI-Provenance-Origin: ai --> <!-- HTML, XML, SVG, Vue, Markdown -->
```
```css
/* AI-Provenance-Origin: ai */ /* CSS, SCSS, Less */
```
```sql
-- AI-Provenance-Origin: ai -- SQL, Lua
```
| Key | Required | Values |
|---|---|---|
| `Origin` | yes | `ai`, `human`, `mixed` |
| `Generator` | no | tool name (`claude-code`, `copilot`, `codex`...) |
| `Reviewed` | yes | `true`, `false`, `partial` |
| `Tested` | no | `true`, `false`, `partial` |
| `Confidence` | no | `high`, `medium`, `low` |
| `Notes` | no | free-text |

---

## Ignore Files

Create `.humancov-ignore` at repo root (gitignore syntax) to exclude files from scanning:
humancov automatically respects your **`.gitignore`** - no extra setup needed. Anything ignored by git is ignored by humancov.

For humancov-specific ignores on top of `.gitignore`, create `.humancov-ignore` at repo root (same gitignore syntax):

```gitignore
*.md
Expand All @@ -153,7 +162,9 @@ dist/
coverage/
```

Default ignores: `node_modules/`, `.git/`, `.humancov`, `.humancov-ignore`, `*.md`, `*.lock`, `LICENSE`, `.gitignore`, `.github/`.
**Resolution order:** built-in defaults → `.gitignore` → `.humancov-ignore`.

Built-in defaults: `node_modules/`, `.git/`, `.humancov`, `.humancov-ignore`, `*.md`, `*.lock`, `LICENSE`, `.gitignore`, `.github/`.

---

Expand Down Expand Up @@ -192,11 +203,10 @@ Exits with code 1 if the reviewed percentage is below the threshold.

A pre-commit hook keeps the badge and `.humancov` manifest up to date automatically on every commit.

**Option A - via `humancov init`:**

Run `humancov init` and your AI tool will propose installing the hook for you.

**Option B - manual setup:**
<details>
<summary>Manual setup</summary>

Create `.git/hooks/pre-commit` with this content:

Expand Down Expand Up @@ -233,6 +243,8 @@ chmod +x .git/hooks/pre-commit

> **Note:** `.git/hooks/` is local and not shared via git. Each contributor needs to set up the hook on their machine. If your team uses [husky](https://typicode.github.io/husky/) or a similar tool, add the hook content to your shared hooks directory instead.

</details>

---

## Manifest
Expand Down Expand Up @@ -275,30 +287,6 @@ Aggregate stats and output report

---

## Performance

Benchmarked on a standard machine with Node >= 18. Run `node bench/perf.js` to reproduce.

| Operation | Scope | Avg |
|---|---|---|
| Comment prefix lookup | 10,000 lookups | ~12ms |
| Ignore pattern loading | single load | ~0.1ms |
| Badge URL generation | 1,000 generations | ~0.1ms |
| Header parsing | 7 files | ~3ms |
| Full repo scan | 8 tracked files | ~90ms |

**Scaling (scanFiles):**

| Files | Avg | Min | Max |
|---|---|---|---|
| 100 | ~120ms | ~80ms | ~220ms |
| 500 | ~175ms | ~145ms | ~295ms |
| 1,000 | ~265ms | ~220ms | ~340ms |

Scales near-linearly. The main cost is `git ls-files` + file I/O in the scanner - utility modules add negligible overhead.

---

## Spec

See the [AI-Provenance Spec v0.1](https://github.com/enixCode/humancov/blob/main/CLAUDE.md) for the full specification.
Expand Down
Loading
Loading