In gsd-build/get-shit-done, the five highest-priority hotspots all sit in the CLI execution layer — and every one of them is in the ‘fire’ quadrant, meaning structural complexity and active development are colliding right now. The top function, runCommand in get-shit-done/bin/gsd-tools.cjs, carries a cyclomatic complexity of 181, a max nesting depth of 15, fan-out of 108, and a risk score of 21.7 — making it a live regression risk, not a cleanup backlog item. Across 2,544 total functions in the repo, 118 are rated critical; five of those critical functions share the same cluster of god-function, deeply-nested, and exit-heavy patterns concentrated in the tool’s core orchestration and setup paths.
The table below ranks functions by activity-weighted risk — a score that multiplies structural complexity by recent commit frequency. A function that is both hard to understand (high cyclomatic complexity) and actively changing is a higher priority than one that is complex but untouched. CC = cyclomatic complexity (independent execution paths); ND = max nesting depth; FO = fan-out (distinct callees).
Top 5 Hotspots
| Function | File | Risk | CC | ND | FO |
|---|---|---|---|---|---|
runCommand | get-shit-done/bin/gsd-tools.cjs | 21.7 | 181 | 15 | 108 |
install | bin/install.js | 21.5 | 112 | 9 | 81 |
cmdInitManager | get-shit-done/bin/lib/init.cjs | 21.2 | 67 | 8 | 57 |
uninstall | bin/install.js | 20.8 | 112 | 8 | 34 |
cmdValidateHealth | get-shit-done/bin/lib/verify.cjs | 20.2 | 102 | 7 | 48 |
Hotspot Analysis
runCommand — get-shit-done/bin/gsd-tools.cjs
As the name and path suggest, runCommand is the central command dispatcher for the gsd CLI — the function that receives a user’s command and routes execution across the tool’s subsystems. Its cyclomatic complexity of 181 means there are 181 independent execution paths to reason about and test, its max nesting depth of 15 is well into extreme territory (four levels is already a refactoring signal), and its fan-out of 108 means it directly invokes 108 distinct functions — giving it one of the broadest coupling footprints in the codebase. With a recent activity score of 20.2 and a ‘fire’ quadrant classification, this function is both structurally the most dangerous in the repo and under active development right now, making every commit a live regression risk across a wide blast radius.
Recommendation: Before the next feature lands here, write characterization tests that exercise the highest-risk branches, then extract cohesive command-handling sub-functions to bring the CC below 30 and the nesting depth below 5. Audit the 108 fan-out callees to identify which can be grouped behind a narrower interface.
install — bin/install.js
The install function in bin/install.js almost certainly orchestrates the full toolchain installation sequence — detecting environments, writing configuration, and invoking downstream setup routines. Its cyclomatic complexity of 112 and max nesting depth of 9 indicate a function that has grown to absorb many conditional installation scenarios inline rather than delegating them, and its fan-out of 81 means changes here can ripple across a large portion of the setup subsystem. With a recent activity score of 20.2 and a ‘fire’ quadrant classification, it is being actively changed at the same time it carries extreme structural risk, and its exit-heavy pattern means test coverage across all exit paths is a significant burden.
Recommendation: Extract each major installation phase (environment detection, dependency resolution, config writing) into dedicated functions, then add targeted tests for each exit path before the next round of changes — the exit-heavy pattern makes untested paths a silent regression risk.
cmdInitManager — get-shit-done/bin/lib/init.cjs
Living in lib/init.cjs, cmdInitManager appears to handle the initialization command path — likely managing the setup state machine that runs when a user first configures gsd in a project. Its cyclomatic complexity of 67 and max nesting depth of 8 reveal a function encoding many branching initialization scenarios in a single body, and its fan-out of 57 makes it a hub that couples the init subsystem to a wide slice of the library. Its recent activity score of 20.11 and ‘fire’ quadrant status confirm this is actively changing, meaning each iteration on initialization behavior compounds the existing structural risk.
Recommendation: Decompose cmdInitManager by responsibility — separate environment-detection logic, configuration-writing steps, and user-prompt handling into individually testable units — to drive the cyclomatic complexity down and reduce the blast radius of future init-path changes.
uninstall — bin/install.js
uninstall shares its file with install, and the pairing is telling: both carry a cyclomatic complexity of 112, and both are in the ‘fire’ quadrant. The uninstall path presumably mirrors installation in reverse — detecting what was written, walking through dependent removals, and handling partial or failed states — which produces an almost identical branching surface. With a nesting depth of 8 and a risk score of 20.8, the function is slightly less coupled (fan-out of 34 versus install’s 81) but no less complex internally. Because both functions live in the same file and share structural patterns, they are natural candidates for a paired refactoring: shared phase-detection or environment-inspection logic can be extracted once and called by both.
Recommendation: Identify the conditional logic that appears in both install and uninstall and extract it into shared helpers — this reduces duplication and complexity in both functions simultaneously. Add exit-path tests before refactoring, as the exit-heavy pattern means the uninstall path has many silent failure modes.
cmdValidateHealth — get-shit-done/bin/lib/verify.cjs
cmdValidateHealth sits in the verify.cjs module and almost certainly runs the health-check command that confirms a gsd environment is correctly configured — validating installed tools, checking paths, and reporting on any setup issues. Its cyclomatic complexity of 102 and nesting depth of 7 suggest it encodes a wide range of environment states and validation conditions inline, and its fan-out of 48 means it touches a broad slice of the codebase to gather health signals. With a risk score of 20.2 and a ‘fire’ quadrant classification, it is actively changing at a time when its structural complexity already makes safe edits difficult.
Recommendation: Decompose validation into one function per concern — tool presence, path validity, config integrity — each returning a structured result. A top-level cmdValidateHealth that aggregates those results becomes a simple loop over validators, collapsing the current CC of 102 to near 5 and making each validation rule independently testable.
Codebase Risk Distribution
All five top hotspots share the same structural patterns (complex_branching, deeply_nested, exit_heavy, god_function, long_function), which is typical of the highest-risk functions in any large codebase — they accumulate every structural signal on the way to the top. More useful context is how the risk is distributed across all 2,544 analyzed functions:
| Band | Functions |
|---|---|
| Critical | 118 |
| High | 128 |
| Moderate | 1,396 |
| Low | 902 |
Hotspot patterns belong to two tiers — Tier 1 (structural): complex_branching, deeply_nested, exit_heavy, long_function, god_function. Tier 2 (relational/temporal): hub_function, cyclic_hub, middle_man, neighbor_risk, stale_complex, churn_magnet, shotgun_target, volatile_god.
Key Takeaways
runCommandinget-shit-done/bin/gsd-tools.cjshas a cyclomatic complexity of 181 and fan-out of 108 — write characterization tests covering its highest-risk branches before any further feature work lands in this function.- Both
installanduninstallinbin/install.jsshare a cyclomatic complexity of 112 and are both in the ‘fire’ quadrant; treating them as a paired refactoring target (extracting shared phase logic) would reduce duplication and structural risk simultaneously. - All five top hotspots carry the god-function and exit-heavy patterns — every new exit path added during active development increases the test-coverage gap; enforce a policy of adding branch-level tests with each PR touching these files.
Reproduce This Analysis
git clone https://github.com/gsd-build/get-shit-done
cd get-shit-done
git checkout 2205a855ef8b49761c1a12ed60206e5202f95093
hotspots analyze . --mode snapshot --explain-patterns --force
To run the same analysis on your own codebase, run hotspots analyze . --mode snapshot in any local git repo — no configuration required.
Hotspots highlights structural and activity risk — not “bad code.” Findings are a prioritization aid, not a bug predictor. Editorial policy →