OpenFindability
AGENTS.md4 starsChanged 10 days agoMITView on GitHub
Rules and orientation for any coding agent working in this repo. CLAUDE.md only imports this file, so this is the single place to edit. This file stays short on purpose. The depth (API quirks, storage shapes, dedupe keys, known limitations, why things are the way they are) lives in docs/reference/implementation-notes.md, grouped by topic. Read the section for the area you are about to change. OpenFindability is a local, self-hosted tool for deciding what to improve across the owner's web projects…
- Reads credentials
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,774 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repositoryOne other file it gives its agents.
- CLAUDE.mdCLAUDE.md
The file
We split this AGENTS.md into the rules it gives an agent
6 rules. About 0 are common, 0 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 30
Use pnpm. On Windows, pnpm's -- passthrough mis-quotes extra positional args: call npx tsx scripts/<name>.ts ...
- Very specific: line 97
Keep it simple. Prefer small server-side functions in lib/.
- Very specific: line 98
Never commit secrets or real project metrics.
- Very specific: line 102
Run pnpm run db:backup before a historical backfill or any risky change against the real database.
- Very specific: line 103
After editing lib/db/schema.ts, run pnpm run db:generate and commit the new drizzle/ files.
- Very specific: line 104
When asked to analyse a project, write a dated report under project/<slug>/reports/.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
Rules and orientation for any coding agent working in this repo. CLAUDE.md only imports this file, so this is the single place to edit.
This file stays short on purpose. The depth (API quirks, storage shapes, dedupe keys, known limitations, why things are the way they are) lives in docs/reference/implementation-notes.md, grouped by topic. Read the section for the area you are about to change.
Purpose
OpenFindability is a local, self-hosted tool for deciding what to improve across the owner's web projects and mobile apps: it pulls search, analytics, download and revenue data from the platforms into one SQLite file, derives SEO opportunities, and writes reports.
It is a single Next.js app in the repository root, with manual sync only. Do not introduce a monorepo, SaaS billing, auth, queues, a server process or cron scheduling unless explicitly requested.
Structure
app/: Next.js App Router pages and route handlers (home dashboard,project/[slug],api/sync,api/doctor).components/ui/: shadcn/ui primitives.components/charts/: client chart components that receive pre-computed props.lib/connectors/: one file per external API (GSC, GA4, Umami, Play Console, Play vitals, Play GCS stats, App Store Connect, RevenueCat, AdMob, AdSense, RespectASO).lib/sync.ts: orchestrates connectors and upserts their rows.lib/store.ts:readData/writeDataover SQLite.lib/db/schema.ts,lib/db/client.ts,drizzle/: Drizzle schema, connection, and committed migrations.lib/insights.ts,lib/report.ts,lib/analytics/: all aggregation, opportunity scoring and report rendering.lib/integrations/sheets-export.ts+integrations/google-sheets-gsc/: Google Sheets export and the Apps Script GSC collector.lib/release.ts: Android release pipeline.scripts/: CLI entry points, one perpnpm runcommand.mcp/server.ts: MCP server over the same data.tests/: offlinenode:testsuites, no live API calls.docs/guide/: how-to guides per connector and workflow.docs/reference/: implementation notes.docs/operations/: sensitive files, rollout notes.- Ignored by git:
data/(the database anddata/backups/),secrets/(credentials),project/<slug>/(private reports, context, notes),private-notes/.
Commands
Use pnpm. On Windows, pnpm's -- passthrough mis-quotes extra positional args: call npx tsx scripts/<name>.ts ... directly when passing them.
# Run and check
pnpm dev
pnpm typecheck
pnpm build
pnpm run test:gsc
pnpm run test:reliability
pnpm run test:integrations
pnpm run doctor # credentials, data freshness, failed syncs
# Sync (default 30-day window; `npx tsx scripts/sync.ts <source> <days>` for more)
pnpm run sync # every source except ASO
pnpm run sync:gsc | sync:ga4 | sync:umami | sync:play-console
pnpm run sync:ga4-landing # daily web landing/channel conversions
pnpm run audit:performance # bounded CrUX/PageSpeed preview; --apply to fetch
pnpm run intervention # list; add --apply saves, report compares before/after
pnpm run report:growth-evidence # --slug required
pnpm run test:growth-evidence
pnpm run sync:revenuecat | sync:admob | sync:adsense
pnpm run sync:play-vitals | sync:play-stats | sync:asc-analytics
pnpm run sync:aso # opt-in, needs local RespectASO
pnpm run sync:bing | sync:cloudflare-ai | sync:clarity
pnpm run discover:seo-geo # local mapping preview; --apply to save
pnpm run sync:warehouse # MotherDuck export preview; --apply to upload
pnpm run repair:analytics # preview GSC links + GA4 recovery; --apply after backup
pnpm run repair:play-metrics # recover distinct user/event CSV fields; --apply after backup
pnpm run report:seo-geo -- <slug>
pnpm run test:seo-geo
pnpm run sync:admob:backfill | sync:adsense:backfill | sync:play-stats:backfill | sync:asc-analytics:backfill
# Reports and exports
pnpm run report -- <slug> <gsc|aso|monetization|growth|asc|index|all>
pnpm run growth:summary
pnpm run store:status
pnpm run sheet:export -- --days 90 [--apply]
pnpm run audit:index [max-urls-per-site] [slug-or-property-filter]
pnpm run research:aso -- --slug <slug>
# Projects and account discovery
pnpm run project:add | project:update -- --slug <slug> [--field value ...]
pnpm run discover:apps
pnpm run gsc:sites | asc:apps | admob:apps | adsense:accounts
pnpm run admob:auth | adsense:auth # interactive OAuth, needs a browser
# Store listings and releases (all dry-run unless --apply)
pnpm run aso:pull-copy | aso:push-copy -- --slug <slug> --locale it
pnpm run play:pull-copy | play:push-copy -- --slug <slug> --language it-IT
pnpm run asc:experiments -- --slug <slug>
pnpm run release:status -- --slug <slug>
pnpm run release:android -- --slug <slug> [--path <flutter dir>] [--build] [--apply]
pnpm run release:ios-setup -- --path <app dir> [--apply] # reads the app folder, saves its iOS config
pnpm run release:ios -- --path <app dir> [--build [--unsigned]] [--apply] [--wait]
pnpm run release:ios-status -- --slug <slug>
pnpm run release:ios-cancel -- --slug <slug> --build-id <id> [--apply]
pnpm run release:ios-upload -- --slug <slug> --build-id <id> [--apply] [--wait] # retry only the upload
# Database
pnpm run db:backup # verified snapshot in data/backups/
pnpm run db:generate # after editing lib/db/schema.ts
pnpm run db:studio
pnpm run audit:secretsRules
- Keep it simple. Prefer small server-side functions in
lib/. - Never commit secrets or real project metrics. Credentials go in
secrets/(secrets/google/,secrets/appstoreconnect/,secrets/android/<slug>/) and.env. Update.env.examplewhen adding an env var. - Preserve
rawJsonon every imported record and log every connector run inconnectorRuns. - Aggregation lives in
lib/, never in client components: the data must stay usable from scripts, reports and agents without the web UI. - Anything that writes to an external platform (store listings, releases, the Google Sheet) is dry-run by default and only acts with
--apply. - Run
pnpm run db:backupbefore a historical backfill or any risky change against the real database. - After editing
lib/db/schema.ts, runpnpm run db:generateand commit the newdrizzle/files. Never renumber or edit a migration that may already be applied to a database. - When asked to analyse a project, write a dated report under
project/<slug>/reports/. Scratch notes go inprivate-notes/, notdocs/. - New UI primitives are ported shadcn components in
components/ui/, not hand-rolled CSS.
Data semantics that are easy to get wrong
- RevenueCat
revenueis a rolling 28-day window: never sum it across dates, use the latest snapshot.mrrandactiveSubscribersare point-in-time gauges. There is no backfill, history only builds from syncing regularly. - AdMob
revenueis a true daily total and is safe to sum. Mediation earnings (admobMediationMetrics) are the complete total; the network report is only a fallback for days without mediation data. Never add the two together, and never sum amounts in different or missing currencies. - GA4 users summed per day are not unique users for the period. GA4 and Umami stay separate.
- GSC detail rows are daily only when
rawJson._openfindability.grainis"day". Older rows are range aggregates dated with their end date: they stay in the database for audit but must not feed rankings, trends or opportunities (lib/gsc-detail.ts). GSC returns top rows, not an exhaustive query inventory. - App Store downloads count first-time downloads only. Rows before 2025-09-21 are inflated and cannot be re-fetched.
- Play installs come only from the monthly CSV export in Cloud Storage, and Play vitals lag about 5 days.
- Sync upserts by key, so re-running it is idempotent. ASO
appKeywordsis the one append-only table.
Documentation
- This file: rules, structure, commands. Change it only when one of those changes.
docs/reference/implementation-notes.md: add implementation detail for a new feature under the matching topic heading, in the same change that ships it. Describe how it works now; leave dates and history to git.docs/guide/: user-facing how-to for a connector or workflow. Start fromoperating-playbook.mdfor a full research-to-publish session.
Guides by area: GSC index audit gsc-index-audit.md · GA4 ga4-setup.md · Google Sheets and Apps Script google-sheets-live-setup.md · ASO aso-workflow.md · monetization monetization-workflow.md, admob-setup.md, adsense-setup.md · App Store Connect appstoreconnect-workflow.md · Android releases release-workflow.md · iOS releases codemagic-ios-release.md · MCP server mcp-server.md · credentials docs/operations/sensitive-files.md.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

