# Find Complexity Hotspots

> Detect advisory Python, JavaScript, TypeScript, Go, Java, bounded Kotlin/JVM, PHP, Ruby, Swift, Rust, and Dart function-complexity hotspots without changing production files. Preserves the Python stdlib AST scan and adds syntax-only family-local high-branch findings for bounded named functions, methods, and constructors.

- Skill: `khurrummahmood/find-complexity-hotspots` (Agent Skill, multi-file: 20 files)
- Install (CLI): `npx skillmds@latest add khurrummahmood/find-complexity-hotspots`
- Raw SKILL.md: https://api.skillmd.com/api/skills/khurrummahmood/find-complexity-hotspots/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: KhurrumMahmood (https://skillmd.com/u/khurrummahmood)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/khurrummahmood/find-complexity-hotspots

---


<!-- Native-parser compatibility subset: scans: [javascript, typescript, go, java] -->
<!-- TypeScript compatibility subset: scans: [python, javascript, typescript] -->

# /find-complexity-hotspots

## Kotlin/JVM 2.4.10 branch

Trigger this branch only for manifest-selected authored `.kt` functions. Keep
sibling `_kotlin`, read [`../_kotlin/GUIDE.md`](../_kotlin/GUIDE.md), and enter
through `scripts/run_kotlin.py`. Its frozen direct-body branch-keyword score is
advisory syntax evidence only; lambdas/local or inline functions, contracts,
resolved control flow, generated members, Java, Gradle variants, frameworks,
runtime cost, and refactor safety remain unresolved.

## C# 14 / .NET 10 branch

Use `scripts/run_csharp.py` with the sibling `_csharp` provider; run it with
`--help` for the exact CLI. It reports named methods whose direct Roslyn body
has a syntactic branch score of at least eight in the current compiled
manifest closure. The score is advisory source syntax, not runtime cost,
cognitive complexity, resolved control flow, or refactor safety.
Without the product-specific `csharp-project.json`, this branch retains
hash-bound authored-source findings as `partial` / `safe-defer-incomplete`
without claiming build membership, dependency resolution, generated inputs,
or native-test coverage. For a read-only real-repository scan, pass an external
`--output-dir` with `--no-host-write`.

## C++20 branch

Use `scripts/run_cpp.py` with the sibling `_cpp` provider; run the script with
`--help` for the exact CLI. It scores direct function bodies from a current
target-covering C++20 compile database, with compiler-owned headers and exact
namespace/signature/overload identity. The score says nothing about runtime
cost, ODR/ABI, specializations, dynamic dispatch, or external variants.
`--compile-database` accepts a standard CMake-style database outside the host;
`--no-host-write` requires only the report output to stay outside. A database
that omits other target translation units retains facts from covered units and
their owned headers as `partial` / `safe-defer-incomplete` rather than erasing
them or claiming a clean result.

## C17 branch

Use `scripts/run_c.py` with the sibling `_c-syntax` provider; run `python3
scripts/run_c.py --help` for the exact CLI. This external-library branch emits
a direct-function-body syntax score from one current C17 compile-command
snapshot. Macro meaning, runtime cost/control flow, performance, behavior, and
refactor safety remain unresolved.
Pass an external Meson/CMake compilation database with `--compile-database`
and external artifacts with `--no-host-write` when dogfooding a clean checkout.
Standard `command` or `arguments` rows and mixed C/C++ databases are accepted;
only selected C17 entries become C evidence.

## External syntax variants

For PHP, Ruby, or Swift, load the selected skill with its sibling provider and
read the matching on-demand guide before execution:

- [`../_php-syntax/GUIDE.md`](../_php-syntax/GUIDE.md)
- [`../_ruby-syntax/GUIDE.md`](../_ruby-syntax/GUIDE.md)
- [`../_swift-project-lexical/GUIDE.md`](../_swift-project-lexical/GUIDE.md)

These are frozen direct-body syntax scores and advisory leads. The guides own
the exact commands, nested-callable boundaries, native gates, and non-claims.
For Ruby complexity only, a missing gem lockfile or unavailable frozen bundle
does not erase source-bound Prism leads; the report remains `partial` /
`safe-defer-incomplete` and never claims a clean project result.
Swift complexity likewise accepts an external `--output-dir` with
`--no-host-write`. A dependency, plugin, or target-shape gate may preserve
hash-bound lexical leads under `partial` / `incomplete`; only a passed compiler
gate labels them compiler-validated.

## Dart v1

Dart v1 consumes the shared `_dart` D3 syntax snapshot and reports named
direct bodies at the frozen score threshold of 18. Nested closures and local
functions do not inflate their owners. The score is advisory syntax evidence,
not runtime or cognitive complexity.

```bash
SKILL_ROOT=".agents/skills/on-demand/find-complexity-hotspots"
python3 "${SKILL_ROOT}/scripts/run_dart.py" \
  --project-root "$PWD" --target lib --facts /tmp/dart-d3-facts.json \
  --output-dir "$PWD/reports/complexity-hotspots/dart"
```

For source-preserving dogfood, set `--output-dir` to a path outside the host
and add `--no-host-write`. A `partial/native_contract_unavailable` snapshot may
still publish hash-bound syntax leads, but its outcome remains `incomplete` and
must not be reported as a clean scan.

## Rust v1

Rust v1 reports advisory direct-body branch scores for named functions. It
excludes nested functions and braced closures and never infers runtime cost.
The copied closure must include sibling `_rust-syntax`; cfg, macro/build,
generated, and symlink uncertainty prevents a clean result. Locked/offline
native checks may reuse dependencies already present in the user's Cargo cache
but never fetch them. A missing cached dependency leaves source-bound syntax
leads visible with `partial` / `safe-defer-incomplete`; it is not a clean scan.

```bash
SKILL_ROOT=".agents/skills/on-demand/find-complexity-hotspots"
python3 "${SKILL_ROOT}/scripts/run_rust.py" \
  --project-root "$PWD" --target src \
  --output-dir "$PWD/reports/complexity-hotspots/rust"
```

Run a read-only SUSPECT audit. A finding is a lead worth reading, never a
proof that an optimization is safe or valuable.

## How success is judged

- The final report directory contains `detections.jsonl`, `report.md`, and
  `findings.json`, with `latest` pointing to that run. Go and Java reports also
  state `complete` or `partial` plus their explicit ambiguity or unsupported
  evidence. Do not claim a scan ran without these artifacts.
- Python findings preserve the six established bands. JavaScript, TypeScript,
  Go, and Java findings carry their exact `language`, native analyzer, function
  start/end lines, LOC, and branch score in both JSON artifacts; `report.md`
  prints the analyzer provenance.
- Use one verdict: `no-hotspots`, `measure-first`, `actionable-hotspot`,
  `safe-defer-incomplete`, or `scan-blocked`. Incomplete evidence must never be
  presented as `no-hotspots`. TypeScript findings are normally `measure-first`
  until native tests and realistic input sizes justify a change.
- This skill never edits source files or claims framework identity, API
  ownership, runtime cost, Java type resolution, or Kotlin/JVM-wide support.

## Scope

- **Target:** one or more explicit files, directories, or globs. There is no
  whole-repository default.
- **Python branch:** the existing stdlib AST detector remains intact: nested
  loops, membership scans, sort/repeated scans, Django QuerySet-like calls in
  loops, and high-branch functions. `--include-tests` affects this branch only.
- **JavaScript/TypeScript v1:** `.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, and `.tsx`
  function declarations, methods, block-bodied arrows and variable function
  expressions, and
  CommonJS/prototype or object-property function assignments. It counts only syntactically established counterparts of
  the existing branch invariant: conditionals, loop forms, try/catch, `with`,
  switch, `&&`/`||`, and ternaries. It does not infer data cost from these
  syntax facts.
- **JavaScript/TypeScript exclusions:** React/Node/ORM semantics, receiver or
  type claims, anonymous callback-only function expressions, expression-bodied arrows, declarations and
  overload signatures without a body, declarations (`.d.ts`), and generated,
  vendor, minified, bundle, test, spec, and fixture paths. These exclusions are
  deliberate even when `--include-tests` is present.
- **JavaScript/TypeScript prerequisite:** Node plus a `typescript` package. The
  parser prefers the target host's package when available and otherwise uses
  the pinned package installed at the external engineering-skills library root.
  The family-local Compiler API parser uses `createSourceFile`, not a tsconfig,
  Program, TypeChecker, shared parser, or fact platform. Missing both parser
  packages, missing Node, malformed parser output, or source syntax errors stop
  the run with exit code 2 instead of silently under-detecting.
- **Go v1:** `.go` named functions and receiver methods using the host Go
  toolchain's standard-library `go/parser` and `go/ast`. It counts `if`,
  `for`, `range`, `switch`, type-switch, `select`, `&&`, and `||` in the direct
  function body only. Nested function literals, imports, calls, interfaces,
  and type/package identity are outside the claim.
- **Go exclusions and ambiguity:** `_test.go`, vendor, generated/gen, fixture,
  build, and report paths are excluded even when directly targeted. Go's
  `Code generated ... DO NOT EDIT.` marker is excluded using `ast.IsGenerated`.
  Explicit `//go:build` or `// +build` files are withheld with
  `build-constraint-ambiguous`, and the final report is `partial`, never clean.
- **Go prerequisite:** a `go` executable on `PATH`, version **Go >= 1.22.0**.
  Missing or older Go, malformed eligible source, or malformed parser output
  stops the run with exit code 2; do not present a previous `latest` report as
  this run's result.
- **Java v1:** `.java` declared methods and constructors using the host JDK
  compiler tree API. It counts `if`, classic/enhanced `for`, `while`, `do`,
  switch statements/expressions, `catch`, ternaries, `&&`, and `||` in the
  direct method body. Nested lambdas and local/anonymous class bodies do not
  contribute to their enclosing method. Methods of local/anonymous classes,
  type resolution, call graphs, framework semantics, build configuration, and
  runtime cost are outside the claim.
- **Java exclusions and mixed source:** test (including Gradle
  `integrationTest` and `testFixtures`), vendor, generated, fixture,
  build/output, report, and symlink paths are excluded even when directly
  targeted. Generated headers and top-level type `@Generated` markers are withheld.
  A target containing only excluded Java source is `partial`, not a clean
  no-hotspot result; Markdown and JSON name the excluded paths.
  Eligible `.kt`/`.kts` files are inventoried as `kotlin_source_present`, make
  the Java result `partial`, and are never presented as Java or JVM support.
- **Java prerequisite:** both `java` and `javac` on `PATH` from **JDK >= 17.0.0**.
  The family-local source launcher batches all eligible `.java` files through
  the public compiler tree API. It does not invoke Maven/Gradle, resolve a
  project classpath, download a JAR, or import a shared analysis platform.
  Missing/old JDK, malformed eligible source, or malformed helper output stops
  the run with exit code 2.

## Installed command

Set `TARGET` to the requested source directory. Run this resolver verbatim from
the host root; it supports both a stock install and this source checkout.

<!-- installed-command:resolve:start -->
```bash
SKILL_ROOT=""
for SKILL_CANDIDATE in \
  ".agents/skills/find-complexity-hotspots" \
  ".claude/skills/find-complexity-hotspots"
do
  if [ -f "${SKILL_CANDIDATE}/SKILL.md" ]; then
    SKILL_ROOT="$(cd "${SKILL_CANDIDATE}" && pwd)"
    break
  fi
done
if [ -z "${SKILL_ROOT}" ]; then
  printf '%s\n' "find-complexity-hotspots is not installed in .agents/skills or .claude/skills" >&2
  exit 2
fi
if [ -x ".venv/bin/python" ]; then
  HOST_PYTHON="$(pwd)/.venv/bin/python"
else
  HOST_PYTHON="python3"
fi
```
<!-- installed-command:resolve:end -->

<!-- installed-command:run:start -->
```bash
: "${TARGET:?Set TARGET to a file, directory, or glob to audit}"
"${HOST_PYTHON}" "${SKILL_ROOT}/scripts/run.py" \
  --project-root "$(pwd)" \
  --skip-effectiveness-log \
  "${TARGET}"
```
<!-- installed-command:run:end -->

Use `--language typescript`, `--language go`, or `--language java` to make a
narrow native-parser contract explicit, or `--language python` to retain the
Python-only scan. The default is additive: it scans supported Python,
JavaScript, TypeScript, Go, and Java files found under `TARGET`.
`--skip-effectiveness-log` is retained for command compatibility; selected-skill
execution has no toolkit telemetry dependency.

For direct detector debugging, write only JSONL:

```bash
"${HOST_PYTHON}" "${SKILL_ROOT}/scripts/detect.py" \
  --project-root "$(pwd)" \
  --output /tmp/complexity-hotspots.jsonl \
  --language typescript \
  "${TARGET}"
```

## Finding buckets

- `django-query-in-loop`, `nested-loop`, `membership-scan-in-loop`,
  `sort-in-loop`, and `repeated-scan-in-loop` are Python-only heuristic leads.
  Preserve filters, authorization, ordering, duplicates, and data-size behavior
  before replacing a loop with a query, map, set, grouping, or batch.
- `high-branch-function` is structural. Python preserves its historical AST
  score. TypeScript, Go, and Java report the same threshold only from their narrow
  syntax lists above, never from calls, receivers, types, interfaces, or
  framework conventions.

## Summarize and act

Report in 10 lines or fewer: total findings and bucket counts; up to three
locations/symbols; the verdict; the `reports/find-complexity-hotspots/latest/`
report path; and one evidence-based next step. Do not optimize cold code or
small collections. For TypeScript, Go, or Java, state the score is syntactic
and name any unknown input size. For Go `partial`, name every build-constraint
ambiguity; for Java `partial`, name the unsupported Kotlin paths.

## Replay check

After changing this skill, run the Python oracle and native outcome suites:

```bash
python3 "${SKILL_ROOT}/scripts/smoke.py"
python3 -m pytest -q tests/test_find_complexity_hotspots_typescript.py
python3 -m pytest -q tests/test_find_complexity_hotspots_go.py
python3 -m pytest -q tests/test_find_complexity_hotspots_java.py
node --check "${SKILL_ROOT}/scripts/detect_typescript_complexity.mjs"
gofmt -d "${SKILL_ROOT}/scripts/detect_go_complexity.go"
java "${SKILL_ROOT}/scripts/detect_java_complexity.java" \
  --project-root "$(pwd)" \
  --file tests/fixtures/find-complexity-hotspots-java/src/main/java/example/CleanService.java
```

The locked TypeScript fixture runs `npm ci --offline --ignore-scripts`,
`npm run typecheck` (`tsc --noEmit`), and `npm test`. It proves positive,
clean, generated/vendor/minified/test/spec/declaration exclusions, syntax and
prerequisite failures, copied closure, and stock installation commands.

## When things go sideways

| Symptom | Action |
|---|---|
| No target path was supplied | Let argparse fail, then rerun with explicit paths. |
| TypeScript parser exits 2 | Stop. Install the host's pinned `typescript`, restore Node, or repair the syntax; do not present an incomplete TypeScript scan as clean. |
| Go parser exits 2 | Stop. Restore `go` on `PATH`, upgrade to Go >= 1.22.0, or repair the eligible syntax; do not present a prior report as the current scan. |
| Go report is partial | Read each `build-constraint-ambiguous` path with its intended build context. This detector does not evaluate tags or claim current-platform reachability. |
| Java parser exits 2 | Stop. Restore a complete JDK >= 17 on `PATH` or repair the eligible syntax; do not present a prior report as the current scan. |
| Java report is partial | Name each `kotlin_source_present` path. Route Kotlin separately; this Java detector does not provide JVM-wide coverage. |
| A high score is on cold/tiny data | Use `measure-first`; no optimization follows from syntax alone. |
| A likely ORM/React/Node/Java-framework issue is absent | This is expected: native-parser v1 intentionally has no framework semantics. Inspect it manually or use a future framework-specific workflow. |
| A direct detector run has JSONL but no report | Run `scripts/run.py` before presenting a verdict. |

