# Findev App Modernization: Code Inventory Prompt

Version 2.0, October 2026. Source: https://fin.dev/app-modernization/estimate

This file is written for an AI agent. A person gives it to you together with access to a repository inside their network. Your task is to count the code in that repository by the rules below and to return one JSON object. You do not calculate a price and you do not send anything anywhere: the person pastes your JSON into the estimate form on fin.dev, and Findev calculates the range there.

## 1. Instructions for the agent

1. Locate the repository root: the repository the user points you to (a local checkout or any directory with the source tree). If the user has not named one, ask for the path.
2. List the files and their sizes in bytes with shell commands (for example `git ls-files` and the file sizes on disk, or `find`, or PowerShell `Get-ChildItem`). Do not open file contents and do not estimate by eye: count with commands or with a short script, because the figures must be exact.
3. Apply the rules of section 2 exactly as written, without changing any value, rule or name.
4. Check your method on the worked examples in section 4: apply your counting to the example files and confirm that you get the stated JSON. If an example does not reproduce, fix your method before you count the repository.
5. Reply with the JSON object of section 3 in one code block. Never include file names, paths, code or the repository name in the reply. If you could not count a part of the tree, say so in one line below the block instead of guessing.
6. Tell the user to paste the JSON into the estimate form at https://fin.dev/app-modernization/estimate, in the tab for their own AI agent.

## 2. What to count

### 2.1 Files considered

Every regular file under the repository root. In a git repository use the files that git tracks (`git ls-files`), otherwise every file under the root. Do not follow symbolic links. Paths are relative to the root with `/` as the separator. All name and path comparisons below are case-insensitive. The size of a file is its size in bytes.

### 2.2 Excluded files

Excluded before any counting (they add no code, no tests and no docs):
- Paths containing a directory named `node_modules`, `vendor`, `third_party`, `dist`, `build`, `out`, `target`, `.git`, `bower_components`, `.venv` or `venv`.
- Minified or generated files: `*.min.js`, `*.min.css`, `*.bundle.js`, `*.bundle.css`, `*.generated.*`, `*.designer.*`, `*_pb2.py`, `*.pb.go`. In `*.generated.*` and `*.designer.*` the last part is an extension made of letters only.

The files that remain are the counted files. Everything below applies to the counted files only.

### 2.3 Language of a file

The extension of a file is the text after the last dot of its file name, in lower case. A file name without a dot has no extension. Use this table:

| Language | Extensions |
|---|---|
| Java | .java |
| .NET / C# | .cs |
| Python | .py |
| JavaScript | .js, .jsx, .ts, .tsx, .mjs, .cjs |
| C++ | .cpp, .cc, .cxx, .hpp, .hh |
| C | .c, .h |
| kdb+/q | .q, .k |
| SQL / stored procs | .sql, .pls, .plsql, .prc |
| COBOL | .cob, .cbl, .cpy |
| Other | .go, .rb, .php, .scala, .kt, .rs, .swift, .m, .pl, .r, .groovy, .f, .f90, .pas, .ada, .erl, .ex |

A file with any other extension has no language. It adds no code, but it still counts for section 2.4. A `.h` file belongs to C++ when at least one counted file has the extension `.cpp`, `.cc`, `.cxx`, `.hpp` or `.hh`; otherwise it belongs to C.

### 2.4 Test files and doc files

Among all counted files, whatever their extension:
- A test file has a directory named `test`, `tests`, `spec` or `__tests__` in its path, or its file name consists of a stem ending in `.test`, `_test`, `.spec` or `_spec`, a dot, and an extension made of letters only (for example `a_test.py`, `b.spec.ts`; not `test.js`).
- A doc file has a directory named `readme`, `doc` or `docs` in its path, or a path segment (a directory name or the file name) that starts with `readme.`, `doc.` or `docs.` (for example `README.md`, `docs/index.md`; not `README` without a dot, not `readme_old.md`, not `documents/a.md`).

### 2.5 What to total

- For each language: `files` is the number of counted files of that language, `bytes` is the sum of their sizes.
- `test_files` is the number of test files and `doc_files` is the number of doc files among all counted files.

## 3. Output format

One JSON object:

```json
{"v":1,"languages":{"Java":{"files":412,"bytes":18230400},"Python":{"files":30,"bytes":640000}},"test_files":57,"doc_files":4}
```

- `v` is always `1`.
- Language names are exactly the names in the first column of the table in section 2.3. Include only languages with at least one counted file.
- `files`, `bytes`, `test_files` and `doc_files` are whole numbers. `bytes` are bytes, not lines of code: do not convert them.
- No other keys, no file names, no comments.

## 4. Worked examples (use them to check your method)

Example 1

| Path | Size |
|---|---|
| README.md | 10 |
| src/Core.java | 2300000 |
| test/CoreTest.java | 100000 |
| db/schema.sql | 200000 |

```json
{"v":1,"languages":{"Java":{"files":2,"bytes":2400000},"SQL / stored procs":{"files":1,"bytes":200000}},"test_files":1,"doc_files":1}
```

Example 2

| Path | Size |
|---|---|
| src/engine.cpp | 4000000 |
| src/engine.h | 400000 |
| vendor/lib/big.cpp | 9000000 |
| web/app.min.js | 5000000 |

```json
{"v":1,"languages":{"C++":{"files":2,"bytes":4400000}},"test_files":0,"doc_files":0}
```

Example 3

| Path | Size |
|---|---|
| Src/Main.JAVA | 800000 |
| q | 500000 |
| docs/index.md | 1 |
| README | 1 |
| README.md | 1 |
| lib/a.h | 100 |
| app_test.py | 2000 |
| test.js | 50 |
| build/out.java | 999 |

```json
{"v":1,"languages":{"Java":{"files":1,"bytes":800000},"C":{"files":1,"bytes":100},"Python":{"files":1,"bytes":2000},"JavaScript":{"files":1,"bytes":50}},"test_files":1,"doc_files":2}
```

## 5. Limits

- The extension map is coarse: `.m`, `.pl`, `.r` and `.f` are ambiguous and count as Other, and TypeScript counts as JavaScript.
- Bytes are not lines. Findev converts them on its side, so do not try to.
- This file contains no prices and no model. The result is a first-pass range from source-tree signals only, a conversation starter and not a quote.
- For a scoped, fixed-price roadmap for your system, book a short session through https://fin.dev/app-modernization/estimate.
