cai-miner 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,32 @@
1
+ # Changelog
2
+
3
+ All notable changes to cai-miner are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2026-11-10
10
+
11
+ First public release. This is the version GHAgentCI was mined with; until then
12
+ the tool was developed under the working name `awe`.
13
+
14
+ ### Added
15
+
16
+ - `cai-miner` command (also `python -m cai_miner`) that walks the first-parent
17
+ history of each workflow file in local git clones and detects coding-agent
18
+ invocations in every revision.
19
+ - Tiered evidence: `uses`, `run`, `path` and `ghaw` are strong; `job`, `url`
20
+ and `env` are weak and only count with `--include-weak`.
21
+ - Exact detection of GitHub Agentic Workflows from the compiler header, and
22
+ full parsing of their manifests into `ghaw_manifests.csv`.
23
+ - Outputs `repositories.csv`, `revisions.csv`, `steps.csv` and
24
+ `ghaw_manifests.csv`, plus an optional content-addressed store of every
25
+ distinct workflow revision.
26
+ - Bundled, frozen detector catalogues (`catalogue.toml`, `default.toml`,
27
+ `marketplace.toml`); `catalogue.toml` is the default.
28
+ - Blob accounting and bulk backfill for partial clones, so incomplete
29
+ repositories are reported rather than silently under-counted.
30
+
31
+ [Unreleased]: https://github.com/unlv-evol/cai-miner/compare/v0.1.0...HEAD
32
+ [0.1.0]: https://github.com/unlv-evol/cai-miner/releases/tag/v0.1.0
@@ -0,0 +1,40 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use this tool, please cite it as below."
3
+ title: "cai-miner: Coding-Agent Invocations Miner"
4
+ abstract: >-
5
+ A command line tool that mines the git history of CI workflow files and
6
+ detects coding-agent invocations inside them, including GitHub Agentic
7
+ Workflows, for large-scale studies of agentic continuous integration on
8
+ GitHub.
9
+ version: 0.1.0
10
+ license: MIT
11
+ repository-code: "https://github.com/unlv-evol/cai-miner"
12
+ url: "https://pypi.org/project/cai-miner/"
13
+ type: software
14
+ keywords:
15
+ - mining software repositories
16
+ - continuous integration
17
+ - GitHub Actions
18
+ - coding agents
19
+ - dataset
20
+ authors:
21
+ - family-names: "Ogenrwot"
22
+ given-names: "Daniel"
23
+ email: "ogenrwot@unlv.nevada.edu"
24
+ affiliation: "University of Nevada, Las Vegas"
25
+ orcid: "https://orcid.org/0000-0002-0133-8164"
26
+ - family-names: "Delgado Cervantes"
27
+ given-names: "Jorge Gonzalo"
28
+ email: "delgaj10@unlv.nevada.edu"
29
+ affiliation: "University of Nevada, Las Vegas"
30
+ orcid: "https://orcid.org/0009-0005-5155-8914"
31
+ - family-names: "Kim"
32
+ given-names: "Woojoong"
33
+ email: "kimw19@unlv.nevada.edu"
34
+ affiliation: "University of Nevada, Las Vegas"
35
+ orcid: "https://orcid.org/0009-0007-8068-1035"
36
+ - family-names: "Businge"
37
+ given-names: "John"
38
+ email: "john.businge@unlv.edu"
39
+ affiliation: "University of Nevada, Las Vegas"
40
+ orcid: "https://orcid.org/0000-0003-3206-7085"
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 The cai-miner authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,210 @@
1
+ Metadata-Version: 2.4
2
+ Name: cai-miner
3
+ Version: 0.1.0
4
+ Summary: Mine coding-agent invocations from the git history of GitHub Actions workflows
5
+ Keywords: mining software repositories,github actions,continuous integration,coding agents,llm,dataset
6
+ Author: Daniel Ogenrwot, Jorge Gonzalo Delgado Cervantes, Woojoong Kim, John Businge
7
+ Author-email: Daniel Ogenrwot <ogenrwot@unlv.nevada.edu>, Jorge Gonzalo Delgado Cervantes <delgaj10@unlv.nevada.edu>, Woojoong Kim <kimw19@unlv.nevada.edu>, John Businge <john.businge@unlv.edu>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: POSIX
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Classifier: Topic :: Software Development :: Version Control :: Git
23
+ Classifier: Typing :: Typed
24
+ Requires-Dist: pyyaml>=6.0
25
+ Requires-Python: >=3.11
26
+ Project-URL: Homepage, https://github.com/unlv-evol/cai-miner
27
+ Project-URL: Repository, https://github.com/unlv-evol/cai-miner
28
+ Project-URL: Issues, https://github.com/unlv-evol/cai-miner/issues
29
+ Project-URL: Changelog, https://github.com/unlv-evol/cai-miner/blob/main/CHANGELOG.md
30
+ Description-Content-Type: text/markdown
31
+
32
+ # cai-miner
33
+
34
+ [![CI](https://github.com/unlv-evol/cai-miner/actions/workflows/ci.yml/badge.svg)](https://github.com/unlv-evol/cai-miner/actions/workflows/ci.yml)
35
+ [![PyPI](https://img.shields.io/pypi/v/cai-miner.svg)](https://pypi.org/project/cai-miner/)
36
+ [![Python](https://img.shields.io/pypi/pyversions/cai-miner.svg)](https://pypi.org/project/cai-miner/)
37
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/unlv-evol/cai-miner/blob/main/LICENSE)
38
+
39
+ **cai-miner** (Coding-Agent Invocations miner) mines the git history of GitHub
40
+ Actions workflow files and finds the **coding-agent invocations** inside them:
41
+ the steps that run Claude Code, Codex, Copilot, Gemini, Cursor, Aider and
42
+ similar agents as part of a repository's continuous integration.
43
+
44
+ For every workflow file that invokes an agent at some point, it emits the
45
+ file's whole history (before the agent arrived, while it was there, and after
46
+ it was removed), one row per agent invocation, and repository-level
47
+ denominators. It is the tool behind the **GHAgentCI** dataset.
48
+
49
+ ## Why content-based detection
50
+
51
+ Agent context files such as `CLAUDE.md` or `AGENTS.md` can be classified by
52
+ path, since the filename names the agent. An agentic CI workflow cannot: it is
53
+ an ordinary `.github/workflows/whatever.yml`, indistinguishable by name from a
54
+ build or lint workflow. cai-miner therefore parses every revision of every
55
+ workflow file, walks its jobs and steps, and matches each step against a
56
+ catalogue of agents.
57
+
58
+ Not every mention of an agent is an invocation; a workflow that sets
59
+ `ANTHROPIC_API_KEY` may just be feeding a test suite. Evidence is therefore
60
+ tiered:
61
+
62
+ | evidence | meaning | strength |
63
+ | -------- | ------- | -------- |
64
+ | `uses` | a step invokes a dedicated agent GitHub Action | strong |
65
+ | `run` | a step shell-invokes an agent CLI | strong |
66
+ | `path` | the workflow file has a reserved, agent-specific name | strong |
67
+ | `ghaw` | the file was compiled by GitHub Agentic Workflows | strong |
68
+ | `job` | a job carries a reserved, agent-specific id | weak |
69
+ | `url` | a step talks to an LLM inference endpoint | weak |
70
+ | `env` | an agent or LLM credential is bound at that scope | weak |
71
+
72
+ A revision counts as agentic only with strong evidence, unless you pass
73
+ `--include-weak`.
74
+
75
+ ## Installation
76
+
77
+ cai-miner needs Python 3.11 or newer and `git` 2.30 or newer on the `PATH`. Its
78
+ only Python dependency is PyYAML.
79
+
80
+ ```bash
81
+ uv tool install cai-miner # recommended: an isolated, global command
82
+ pipx install cai-miner # equivalent with pipx
83
+ pip install cai-miner # into the current environment
84
+ ```
85
+
86
+ Or run it once without installing: `uvx cai-miner --help`.
87
+
88
+ ## Quickstart
89
+
90
+ cai-miner works on local clones. A size-capped partial clone without a working
91
+ tree is the fastest way to get one (see [cloning](https://github.com/unlv-evol/cai-miner/blob/main/docs/cloning.md)):
92
+
93
+ ```bash
94
+ git clone --filter=blob:limit=64k --no-checkout --single-branch \
95
+ https://github.com/vitejs/vite.git clones/vite
96
+
97
+ # Agent invocations across the whole history, as CSV on stdout
98
+ cai-miner clones/vite
99
+
100
+ # Full outputs for many clones, plus every distinct workflow revision
101
+ cai-miner --from-file clones.txt -o out/ --content-dir out/content
102
+ ```
103
+
104
+ With `-o out/` you get:
105
+
106
+ | file | one row per |
107
+ | ---- | ----------- |
108
+ | `repositories.csv` | repository, agentic or not, including failures |
109
+ | `revisions.csv` | change to a workflow file whose history is agentic at some point |
110
+ | `steps.csv` | agent invocation |
111
+ | `ghaw_manifests.csv` | revision of a GitHub Agentic Workflows source or compiled file |
112
+
113
+ Every column is documented in the
114
+ [output reference](https://github.com/unlv-evol/cai-miner/blob/main/docs/output.md).
115
+
116
+ ## Command-line reference
117
+
118
+ ```
119
+ cai-miner [options] [REPOSITORY ...]
120
+ ```
121
+
122
+ | option | effect |
123
+ | ------ | ------ |
124
+ | `-c`, `--config FILE` | detector catalogue (TOML); defaults to the bundled frozen catalogue |
125
+ | `--from-file FILE` | read clone paths from a file, one per line |
126
+ | `-o`, `--out-dir DIR` | write the four CSV files to `DIR` |
127
+ | `--content-dir DIR` | store each distinct workflow revision as `DIR/<sha256>.yml` |
128
+ | `--rev REV` | commit to start the history walk from (default `HEAD`) |
129
+ | `--since DATE` | ignore commits older than `DATE`, e.g. `2024-01-01` |
130
+ | `--include-weak` | let `job`, `url` and `env` evidence make a revision agentic |
131
+ | `--keep-all` | emit every workflow revision, not only agentic histories |
132
+ | `--no-prefetch` | disable the bulk blob prefetch on partial clones |
133
+ | `--repository OWNER/NAME` | name of the single repository given, instead of reading it from the clone's remote |
134
+ | `--fail-fast` | stop at the first repository that fails |
135
+ | `-q`, `--quiet` | suppress progress output |
136
+ | `--version` | print the version and exit |
137
+
138
+ `python -m cai_miner` is equivalent to `cai-miner`.
139
+
140
+ ## Detector catalogue
141
+
142
+ Agents and their patterns live in a TOML catalogue; adding an agent needs no
143
+ code changes:
144
+
145
+ ```toml
146
+ [agents.myagent]
147
+ display_name = "My Agent"
148
+ uses = ["myorg/my-agent-action"]
149
+ run = ["myagent --run"]
150
+ env = ["MYAGENT_API_KEY"]
151
+ ```
152
+
153
+ The bundled default is the catalogue GHAgentCI was mined with: a hand-written
154
+ catalogue drawn from vendor documentation, merged with one generated from the
155
+ GitHub Marketplace `ai-assisted` category. See the
156
+ [catalogue reference](https://github.com/unlv-evol/cai-miner/blob/main/docs/catalogue.md)
157
+ for the format, includes, aliases and overrides.
158
+
159
+ Files generated by [GitHub Agentic Workflows](https://github.com/github/gh-aw)
160
+ are detected from the compiler's own header, with no catalogue involved, and
161
+ their manifests are parsed in full; see
162
+ [gh-aw](https://github.com/unlv-evol/cai-miner/blob/main/docs/ghaw.md).
163
+
164
+ ## Using it from Python
165
+
166
+ ```python
167
+ from cai_miner.config import load_config
168
+ from cai_miner.detect import analyse
169
+ from cai_miner.extract import extract_repository
170
+
171
+ catalogue = load_config() # the bundled catalogue; or load_config("my.toml")
172
+
173
+ # Classify one workflow revision
174
+ facts = analyse(catalogue, open("ci.yml").read(), ".github/workflows/ci.yml")
175
+ print(facts.strong_agents)
176
+
177
+ # Mine one local clone
178
+ result = extract_repository("clones/vite", catalogue)
179
+ print(result.summary.n_agentic_files, len(result.steps))
180
+ ```
181
+
182
+ The command line is the stable interface; the Python modules may change
183
+ between minor versions before 1.0.
184
+
185
+ ## Reproducing GHAgentCI
186
+
187
+ The GHAgentCI dataset and its replication package are archived on Zenodo at
188
+ [doi:10.5281/zenodo.24088832](https://doi.org/10.5281/zenodo.24088832). This
189
+ repository also holds the scripts and validation material behind it; they are
190
+ not part of the installed package:
191
+
192
+ - [`docs/FULL_RUN.md`](https://github.com/unlv-evol/cai-miner/blob/main/docs/FULL_RUN.md): how the full mining run was set up, monitored and resumed;
193
+ - [`docs/DATASET.md`](https://github.com/unlv-evol/cai-miner/blob/main/docs/DATASET.md): the released tables, field by field;
194
+ - [`BENCHMARKS.md`](https://github.com/unlv-evol/cai-miner/blob/main/BENCHMARKS.md): throughput and clone-strategy measurements.
195
+
196
+ ## Citing
197
+
198
+ If you use cai-miner or GHAgentCI in research, please cite it; GitHub's
199
+ "Cite this repository" button reads
200
+ [`CITATION.cff`](https://github.com/unlv-evol/cai-miner/blob/main/CITATION.cff).
201
+
202
+ ## Contributing
203
+
204
+ Bug reports and pull requests are welcome. See
205
+ [CONTRIBUTING.md](https://github.com/unlv-evol/cai-miner/blob/main/CONTRIBUTING.md)
206
+ for the development setup.
207
+
208
+ ## License
209
+
210
+ [MIT](https://github.com/unlv-evol/cai-miner/blob/main/LICENSE)
@@ -0,0 +1,179 @@
1
+ # cai-miner
2
+
3
+ [![CI](https://github.com/unlv-evol/cai-miner/actions/workflows/ci.yml/badge.svg)](https://github.com/unlv-evol/cai-miner/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/cai-miner.svg)](https://pypi.org/project/cai-miner/)
5
+ [![Python](https://img.shields.io/pypi/pyversions/cai-miner.svg)](https://pypi.org/project/cai-miner/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/unlv-evol/cai-miner/blob/main/LICENSE)
7
+
8
+ **cai-miner** (Coding-Agent Invocations miner) mines the git history of GitHub
9
+ Actions workflow files and finds the **coding-agent invocations** inside them:
10
+ the steps that run Claude Code, Codex, Copilot, Gemini, Cursor, Aider and
11
+ similar agents as part of a repository's continuous integration.
12
+
13
+ For every workflow file that invokes an agent at some point, it emits the
14
+ file's whole history (before the agent arrived, while it was there, and after
15
+ it was removed), one row per agent invocation, and repository-level
16
+ denominators. It is the tool behind the **GHAgentCI** dataset.
17
+
18
+ ## Why content-based detection
19
+
20
+ Agent context files such as `CLAUDE.md` or `AGENTS.md` can be classified by
21
+ path, since the filename names the agent. An agentic CI workflow cannot: it is
22
+ an ordinary `.github/workflows/whatever.yml`, indistinguishable by name from a
23
+ build or lint workflow. cai-miner therefore parses every revision of every
24
+ workflow file, walks its jobs and steps, and matches each step against a
25
+ catalogue of agents.
26
+
27
+ Not every mention of an agent is an invocation; a workflow that sets
28
+ `ANTHROPIC_API_KEY` may just be feeding a test suite. Evidence is therefore
29
+ tiered:
30
+
31
+ | evidence | meaning | strength |
32
+ | -------- | ------- | -------- |
33
+ | `uses` | a step invokes a dedicated agent GitHub Action | strong |
34
+ | `run` | a step shell-invokes an agent CLI | strong |
35
+ | `path` | the workflow file has a reserved, agent-specific name | strong |
36
+ | `ghaw` | the file was compiled by GitHub Agentic Workflows | strong |
37
+ | `job` | a job carries a reserved, agent-specific id | weak |
38
+ | `url` | a step talks to an LLM inference endpoint | weak |
39
+ | `env` | an agent or LLM credential is bound at that scope | weak |
40
+
41
+ A revision counts as agentic only with strong evidence, unless you pass
42
+ `--include-weak`.
43
+
44
+ ## Installation
45
+
46
+ cai-miner needs Python 3.11 or newer and `git` 2.30 or newer on the `PATH`. Its
47
+ only Python dependency is PyYAML.
48
+
49
+ ```bash
50
+ uv tool install cai-miner # recommended: an isolated, global command
51
+ pipx install cai-miner # equivalent with pipx
52
+ pip install cai-miner # into the current environment
53
+ ```
54
+
55
+ Or run it once without installing: `uvx cai-miner --help`.
56
+
57
+ ## Quickstart
58
+
59
+ cai-miner works on local clones. A size-capped partial clone without a working
60
+ tree is the fastest way to get one (see [cloning](https://github.com/unlv-evol/cai-miner/blob/main/docs/cloning.md)):
61
+
62
+ ```bash
63
+ git clone --filter=blob:limit=64k --no-checkout --single-branch \
64
+ https://github.com/vitejs/vite.git clones/vite
65
+
66
+ # Agent invocations across the whole history, as CSV on stdout
67
+ cai-miner clones/vite
68
+
69
+ # Full outputs for many clones, plus every distinct workflow revision
70
+ cai-miner --from-file clones.txt -o out/ --content-dir out/content
71
+ ```
72
+
73
+ With `-o out/` you get:
74
+
75
+ | file | one row per |
76
+ | ---- | ----------- |
77
+ | `repositories.csv` | repository, agentic or not, including failures |
78
+ | `revisions.csv` | change to a workflow file whose history is agentic at some point |
79
+ | `steps.csv` | agent invocation |
80
+ | `ghaw_manifests.csv` | revision of a GitHub Agentic Workflows source or compiled file |
81
+
82
+ Every column is documented in the
83
+ [output reference](https://github.com/unlv-evol/cai-miner/blob/main/docs/output.md).
84
+
85
+ ## Command-line reference
86
+
87
+ ```
88
+ cai-miner [options] [REPOSITORY ...]
89
+ ```
90
+
91
+ | option | effect |
92
+ | ------ | ------ |
93
+ | `-c`, `--config FILE` | detector catalogue (TOML); defaults to the bundled frozen catalogue |
94
+ | `--from-file FILE` | read clone paths from a file, one per line |
95
+ | `-o`, `--out-dir DIR` | write the four CSV files to `DIR` |
96
+ | `--content-dir DIR` | store each distinct workflow revision as `DIR/<sha256>.yml` |
97
+ | `--rev REV` | commit to start the history walk from (default `HEAD`) |
98
+ | `--since DATE` | ignore commits older than `DATE`, e.g. `2024-01-01` |
99
+ | `--include-weak` | let `job`, `url` and `env` evidence make a revision agentic |
100
+ | `--keep-all` | emit every workflow revision, not only agentic histories |
101
+ | `--no-prefetch` | disable the bulk blob prefetch on partial clones |
102
+ | `--repository OWNER/NAME` | name of the single repository given, instead of reading it from the clone's remote |
103
+ | `--fail-fast` | stop at the first repository that fails |
104
+ | `-q`, `--quiet` | suppress progress output |
105
+ | `--version` | print the version and exit |
106
+
107
+ `python -m cai_miner` is equivalent to `cai-miner`.
108
+
109
+ ## Detector catalogue
110
+
111
+ Agents and their patterns live in a TOML catalogue; adding an agent needs no
112
+ code changes:
113
+
114
+ ```toml
115
+ [agents.myagent]
116
+ display_name = "My Agent"
117
+ uses = ["myorg/my-agent-action"]
118
+ run = ["myagent --run"]
119
+ env = ["MYAGENT_API_KEY"]
120
+ ```
121
+
122
+ The bundled default is the catalogue GHAgentCI was mined with: a hand-written
123
+ catalogue drawn from vendor documentation, merged with one generated from the
124
+ GitHub Marketplace `ai-assisted` category. See the
125
+ [catalogue reference](https://github.com/unlv-evol/cai-miner/blob/main/docs/catalogue.md)
126
+ for the format, includes, aliases and overrides.
127
+
128
+ Files generated by [GitHub Agentic Workflows](https://github.com/github/gh-aw)
129
+ are detected from the compiler's own header, with no catalogue involved, and
130
+ their manifests are parsed in full; see
131
+ [gh-aw](https://github.com/unlv-evol/cai-miner/blob/main/docs/ghaw.md).
132
+
133
+ ## Using it from Python
134
+
135
+ ```python
136
+ from cai_miner.config import load_config
137
+ from cai_miner.detect import analyse
138
+ from cai_miner.extract import extract_repository
139
+
140
+ catalogue = load_config() # the bundled catalogue; or load_config("my.toml")
141
+
142
+ # Classify one workflow revision
143
+ facts = analyse(catalogue, open("ci.yml").read(), ".github/workflows/ci.yml")
144
+ print(facts.strong_agents)
145
+
146
+ # Mine one local clone
147
+ result = extract_repository("clones/vite", catalogue)
148
+ print(result.summary.n_agentic_files, len(result.steps))
149
+ ```
150
+
151
+ The command line is the stable interface; the Python modules may change
152
+ between minor versions before 1.0.
153
+
154
+ ## Reproducing GHAgentCI
155
+
156
+ The GHAgentCI dataset and its replication package are archived on Zenodo at
157
+ [doi:10.5281/zenodo.24088832](https://doi.org/10.5281/zenodo.24088832). This
158
+ repository also holds the scripts and validation material behind it; they are
159
+ not part of the installed package:
160
+
161
+ - [`docs/FULL_RUN.md`](https://github.com/unlv-evol/cai-miner/blob/main/docs/FULL_RUN.md): how the full mining run was set up, monitored and resumed;
162
+ - [`docs/DATASET.md`](https://github.com/unlv-evol/cai-miner/blob/main/docs/DATASET.md): the released tables, field by field;
163
+ - [`BENCHMARKS.md`](https://github.com/unlv-evol/cai-miner/blob/main/BENCHMARKS.md): throughput and clone-strategy measurements.
164
+
165
+ ## Citing
166
+
167
+ If you use cai-miner or GHAgentCI in research, please cite it; GitHub's
168
+ "Cite this repository" button reads
169
+ [`CITATION.cff`](https://github.com/unlv-evol/cai-miner/blob/main/CITATION.cff).
170
+
171
+ ## Contributing
172
+
173
+ Bug reports and pull requests are welcome. See
174
+ [CONTRIBUTING.md](https://github.com/unlv-evol/cai-miner/blob/main/CONTRIBUTING.md)
175
+ for the development setup.
176
+
177
+ ## License
178
+
179
+ [MIT](https://github.com/unlv-evol/cai-miner/blob/main/LICENSE)
@@ -0,0 +1,109 @@
1
+ # Detector catalogue
2
+
3
+ Detection is driven by a TOML catalogue of agents and the patterns that
4
+ identify them. Three catalogues ship inside the package, in
5
+ `src/cai_miner/catalogues/`:
6
+
7
+ | file | what it is |
8
+ | ---- | ---------- |
9
+ | `catalogue.toml` | **the default.** The frozen catalogue GHAgentCI was mined with: `default.toml` and `marketplace.toml` merged. |
10
+ | `default.toml` | hand-written from vendor documentation: `run`, `url`, `env`, `path` and `job` patterns, plus the `[paths]`, `[tasks]` and `[exclude]` sections |
11
+ | `marketplace.toml` | generated from the GitHub Marketplace `ai-assisted` category: the long tail of `uses` patterns |
12
+
13
+ Pass `-c my.toml` to use your own. From Python, the bundled files are under
14
+ `cai_miner.config.CATALOGUES`.
15
+
16
+ ## Evidence kinds
17
+
18
+ | kind | matches | strength |
19
+ | ------ | ------------------------------------------------------- | -------- |
20
+ | `uses` | a step's `uses:` names a dedicated agent action | strong |
21
+ | `run` | a step's `run:` shell-invokes an agent CLI | strong |
22
+ | `path` | the workflow file has a reserved, agent-specific name | strong |
23
+ | `ghaw` | the file was generated by GitHub Agentic Workflows | strong |
24
+ | `job` | a job carries a reserved, agent-specific id | weak |
25
+ | `url` | a step talks to an LLM inference endpoint | weak |
26
+ | `env` | an agent or LLM credential is bound at that scope | weak |
27
+
28
+ A revision is agentic only if it carries strong evidence, unless
29
+ `--include-weak` is given. `ghaw` needs no pattern: the gh-aw compiler
30
+ identifies its own output (see [GitHub Agentic Workflows](ghaw.md)).
31
+
32
+ Why a filename can be strong evidence: GitHub's Copilot coding agent is wired
33
+ in by reserved filename. GitHub reads `.github/workflows/copilot-setup-steps.yml`
34
+ and runs the job of the same name, and neither carries a `uses:` or `run:` that
35
+ names Copilot. The reserved *file* is the contract GitHub honours, whereas the
36
+ reserved *job id* in some other file is a copied template GitHub never reads,
37
+ so only the former is strong.
38
+
39
+ `env` evidence is attributed **once, at the scope that declares it**: a step's
40
+ own `env:` to that step, a job's to the job, the workflow's to the workflow.
41
+ Folding outer scopes into each step would claim `actions/checkout` is an agent
42
+ invocation because the workflow exports `ANTHROPIC_API_KEY` at the top.
43
+
44
+ ## Matching
45
+
46
+ `uses` patterns match an action exactly: `owner/repo` matches `owner/repo@v1`
47
+ and `owner/repo/sub@v1`, but not `owner/repo-other` or `xowner/repo`. The other
48
+ kinds match as case-insensitive substrings.
49
+
50
+ ## Format
51
+
52
+ ```toml
53
+ # Which files are CI workflows at all.
54
+ [paths]
55
+ github_actions = [".github/workflows/*.yml", ".github/workflows/*.yaml"]
56
+
57
+ [agents.myagent]
58
+ display_name = "My Agent"
59
+ uses = ["myorg/my-agent-action"]
60
+ run = ["myagent --run"]
61
+ env = ["MYAGENT_API_KEY"]
62
+ url = ["api.myagent.example"]
63
+ path = [".github/workflows/myagent-setup.yml"]
64
+ job = ["myagent-setup"]
65
+ ```
66
+
67
+ Extending detection needs no code changes. Copy `default.toml` as a starting
68
+ point; it also shows the `[tasks]` and `[exclude]` sections.
69
+
70
+ ### Composing catalogues
71
+
72
+ A catalogue may `include` others, resolved relative to its own location:
73
+
74
+ ```toml
75
+ include = ["default.toml", "marketplace.toml"]
76
+
77
+ # Rename an agent group from an included file.
78
+ [aliases]
79
+ qodo = "pr_agent"
80
+
81
+ # Move one `uses` pattern to a different group.
82
+ [overrides]
83
+ "codota/tabnine-pr-agent" = "generic_ai"
84
+ ```
85
+
86
+ Patterns are unioned per agent group, and `[aliases]` and `[overrides]` apply
87
+ after merging. This is how `catalogue.toml` is built without editing either
88
+ source file, so the generated one can still be regenerated and diffed.
89
+
90
+ ## The frozen dataset catalogue
91
+
92
+ `catalogue.toml`, `default.toml` and `marketplace.toml` are frozen at the
93
+ versions that produced GHAgentCI, and a test checks their SHA-256 sums. The
94
+ dataset's validation sample only holds for the patterns that produced the
95
+ data, so a change to detection belongs in a new catalogue file, not in these.
96
+
97
+ ## Regenerating the Marketplace catalogue
98
+
99
+ `marketplace.toml` is produced by a script in the source repository (not part
100
+ of the installed package):
101
+
102
+ ```bash
103
+ uv run python scripts/build_catalogue.py -o new-marketplace.toml
104
+ ```
105
+
106
+ It enumerates the Marketplace `ai-assisted` category, resolves each listing to
107
+ its source repository, and groups repositories belonging to a known agent
108
+ vendor under that agent, with everything else under `generic_ai`. Vendor
109
+ grouping rules live in `_AGENT_RULES` in the script.
@@ -0,0 +1,60 @@
1
+ # Cloning repositories for cai-miner
2
+
3
+ `cai-miner` reads local clones; it never talks to the GitHub API. How you clone
4
+ decides how long a run takes and how much disk it needs. Measured numbers are
5
+ in [BENCHMARKS.md](../BENCHMARKS.md).
6
+
7
+ ## Recommended: a size-capped blob filter
8
+
9
+ ```bash
10
+ git clone --filter=blob:limit=64k --no-checkout --single-branch \
11
+ https://github.com/OWNER/NAME.git
12
+ ```
13
+
14
+ A size cap fetches everything `cai-miner` reads in a single server-built
15
+ packfile while leaving large blobs behind. `--no-checkout` skips the working
16
+ tree, which the tool does not need. Both caps below produce byte-identical
17
+ output; the choice is a time and bandwidth trade:
18
+
19
+ | repository | class | cap | total | disk |
20
+ | ---------- | ----- | --- | ----- | ---- |
21
+ | vite | ordinary | **64k** | **5 s** | **31 MB** |
22
+ | vite | | 1m | 7 s | 66 MB |
23
+ | langchain | large | **64k** | **18 s** | **108 MB** |
24
+ | langchain | | 1m | 33 s | 300 MB |
25
+ | godot | large | **64k** | **42 s** | **454 MB** |
26
+ | godot | | 1m | 71 s | 1176 MB |
27
+ | amplihack | gh-aw adopter | 64k | 41 s | 48 MB |
28
+ | amplihack | | **1m** | **16 s** | 196 MB |
29
+
30
+ `64k` wins everywhere except on gh-aw adopters, whose compiled workflows reach
31
+ 240 kB and so have to be backfilled, and a backfill costs a full fetch
32
+ negotiation per repository however few objects it needs. Since gh-aw adopters
33
+ are about 1% of repositories, prefer `1m` only for a gh-aw-heavy list.
34
+
35
+ A workflow file larger than the cap is not lost: `cai-miner` detects which
36
+ blobs are absent locally (without network access, by running `git cat-file`
37
+ under `GIT_NO_LAZY_FETCH`) and bulk-fetches exactly those. The blob-accounting
38
+ columns in `repositories.csv` make the outcome checkable.
39
+
40
+ ## Strategies to avoid
41
+
42
+ | strategy | vite | uv |
43
+ | -------- | ---- | -- |
44
+ | blobless (`--filter=blob:none`) + prefetch | 210 s | >300 s (timeout) |
45
+ | full clone, no filter | 13 s | 72 s |
46
+
47
+ On a blobless clone, `git cat-file` backfills missing blobs one network round
48
+ trip at a time, and requesting the object ids up front does not fix it:
49
+ `git fetch <oids>` costs server-side resolution against the whole repository,
50
+ roughly independent of how many ids you ask for. `cai-miner` still detects a
51
+ partial clone and prefetches in bulk as a fallback (disable with
52
+ `--no-prefetch`), but a `blob:limit` clone is faster and simpler.
53
+
54
+ ## Sizing a large run
55
+
56
+ With a capped clone, **extraction, not cloning, is the bottleneck** on large
57
+ repositories: most CPU time goes to YAML parsing. Extraction parallelises
58
+ across repositories (run several `cai-miner` processes on disjoint lists,
59
+ sharing one `--content-dir`), while clone bandwidth does not. Size a large run
60
+ on cores rather than network.