where-are-we
The first question in an unfamiliar repository — answered in seconds, without a model.
Any codebase. Any language. Any agent.
An agent opening a repository it has never seen spends its first forty tool calls on the same questions. Where do the tests live. What may a step call. How is a scenario launched. Which environment variables must be set. What does the product actually expose.
At roughly a minute per turn that is half an hour, in every session, for answers that are identical every time and derivable without a model.
where-are-we derives them by walking the tree, and writes them where the agent
will read them.
pip install git+https://github.com/ngavrish/where-are-we
where-are-we --repo ~/work/my-suite --product ~/work/my-app/src --out /tmp/map
framework map: 66 step modules, 1446 steps, 182 features, 1889 scenarios -> /tmp/map/framework_map.md
What you get
| file | what it is | typical size |
|---|---|---|
framework_map_brief.md |
the digest to put in a prompt | ~40 KB |
framework_map.md |
the full map: every step phrase, every scenario with its line number | ~135 KB |
framework_map.json |
the same as data, for tooling | — |
Or straight into the file your harness already reads:
where-are-we --repo . --agent-file AGENTS.md # also CLAUDE.md, .cursorrules, …
The map is written between markers. Whatever else lives in that file survives.
What it finds
Whatever the repository is. A service, a library, a monorepo, a test suite — it is read the same way: what it is made of, where it starts, what it serves, what it exposes, and how its parts depend on each other.
|
Any codebase
Shape of a test suite
Facts you would otherwise grep for
|
The product under test
Contracts
The state of the suite itself
|
Frameworks
behave · pytest · jest · playwright · cypress · robot · JUnit · TestNG · Cucumber-JVM (Java · Kotlin · Scala) · cucumber-js (TypeScript · JavaScript) · cucumber-ruby · rspec · go test · xUnit · NUnit · SpecFlow · PHPUnit · Behat · Rust · XCTest · karate · gauge · k6 · gatling
Detection is by shape, not by directory name: a page object is a class that owns selectors — wherever it lives, whatever the team calls it. Run it on a repository before you know what is in it.
When the repository knows better
Autodetection gets the shape right and the vocabulary wrong. A repository states its own, and what it states wins:
where-are-we --repo . --init # writes a starter manifest from what was detected
{
"name": "billing-e2e",
"purpose": "End-to-end tests for the billing portal.",
"layers": {
"steps": "steps/*.py — steps own no selectors, they call page objects"
},
"product_src": ["../billing-web/src"],
"conventions": ["After a fix, re-run only what failed."]
}
.framework-map.json at the root, or the same block fenced as
```framework-map inside README.md.
Directories can explain themselves too:
wawe-readmes --repo . # a README in every content directory that lacks one,
# derived from what is in it, with one TODO line for a human
The map reads them back.
Keeping it current
A map is worth rebuilding when the thing it describes has moved. The commit and
the newest file in the tree are recorded with it, so running the command on
every checkout costs a stat walk and nothing else. --force rebuilds regardless.
where-are-we --repo . --install-hook git # post-checkout, post-merge, post-commit
where-are-we --repo . --install-hook agent # SessionStart, before the first turn
Options
--repo PATH the test repository to index
--product PATH,… source roots of the application under test
--out DIR where the three files land
--agent-file FILE also write the brief into AGENTS.md / CLAUDE.md / .cursorrules
--rules PATH a corpus of rules to list by name
--runs-api URL a runs database, to carry what earlier runs concluded
--init write a starter .framework-map.json
--install-hook git|agent
--force rebuild even when nothing moved
--only "routes,data model" keep only these sections in the brief
--skip "coverage,history" drop these
--max-lines N cap the brief; the full map is untouched
--diff what changed since the map already in --out
--quiet no summary line
Why it exists
It was built for an agentic QA pipeline where seven branches ran at once and
each one opened the same way: forty greps to find where the steps live, which
page object owns the portal, how the driver is built, what environment.py
does. Identical in every branch, identical every run, and derivable without a
model — three runs died at their deadline with the branches still reading.
Nothing about it turned out to be specific to that pipeline, or to that agent, or to Python. So it lives here.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file where_are_we-0.1.0.tar.gz.
File metadata
- Download URL: where_are_we-0.1.0.tar.gz
- Upload date:
- Size: 42.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a87de39f3b1224668ae0afb76d76354334eb6af237caa976faff51c140f188ec
|
|
| MD5 |
8686baef47422601c782c13ef42c7953
|
|
| BLAKE2b-256 |
5dd75917743ca9284eb8ba106800c7cf495445f06dd85521b302409a80969d52
|
File details
Details for the file where_are_we-0.1.0-py3-none-any.whl.
File metadata
- Download URL: where_are_we-0.1.0-py3-none-any.whl
- Upload date:
- Size: 40.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5c6f8e9644e82a45fbda8ee5313aa7dbea5e0c5ecd22371d6a609a4105e876e
|
|
| MD5 |
091f0ed3bfc9e3f910304c4781d8c2ee
|
|
| BLAKE2b-256 |
4cd129e3937ce368f839d890b127a4f5273f6a80b792238c02cc4e3a2ee7f9c9
|