energy-state-analyzer 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.esaignore +1 -1
- package/.vscodeignore +9 -3
- package/AGENTS.md +85 -69
- package/CHANGELOG.md +17 -1
- package/README.md +21 -5
- package/action.yml +3 -3
- package/dist/498894f52e4b9dcbc99d.wasm +0 -0
- package/dist/cli.js +1 -1
- package/dist/web-tree-sitter.wasm +0 -0
- package/docs/architecture.md +61 -0
- package/docs/cli.md +4 -1
- package/docs/detectors/magic-numbers.md +7 -1
- package/docs/detectors/magic-strings.md +1 -1
- package/docs/detectors/suppression.md +1 -1
- package/docs/fable-rewrite-plan.md +97 -0
- package/package.json +15 -21
- package/.prettierignore +0 -7
- package/dist/cli.js.map +0 -1
package/.esaignore
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Paths the energy-state analyzer itself should not scan.
|
|
2
2
|
# One pattern per line — a literal path/directory (also matches at any depth if it has no
|
|
3
|
-
# '/'), or a single '*' basename glob. See src/
|
|
3
|
+
# '/'), or a single '*' basename glob. See src/Core/Esaignore.fs for the exact rules.
|
|
4
4
|
|
|
5
5
|
# Deliberately bad/deeply-nested code used only to exercise the detectors themselves.
|
|
6
6
|
src/test/fixtures
|
package/.vscodeignore
CHANGED
|
@@ -3,14 +3,20 @@
|
|
|
3
3
|
out/**
|
|
4
4
|
node_modules/**
|
|
5
5
|
src/**
|
|
6
|
+
tests/**
|
|
7
|
+
cli/**
|
|
8
|
+
fable-out/**
|
|
9
|
+
fable-tests/**
|
|
6
10
|
.gitignore
|
|
7
11
|
.yarnrc
|
|
8
12
|
webpack.config.js
|
|
9
13
|
vsc-extension-quickstart.md
|
|
10
|
-
**/tsconfig.json
|
|
11
|
-
**/eslint.config.mjs
|
|
12
14
|
**/*.map
|
|
13
|
-
**/*.
|
|
15
|
+
**/*.fs
|
|
16
|
+
**/*.fsproj
|
|
17
|
+
**/bin/**
|
|
18
|
+
**/obj/**
|
|
19
|
+
**/fable_modules/**
|
|
14
20
|
**/.vscode-test.*
|
|
15
21
|
.claude/**
|
|
16
22
|
CLAUDE.md
|
package/AGENTS.md
CHANGED
|
@@ -1,84 +1,100 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Project overview
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Energy State Analyzer is a VS Code extension and CLI that analyze Python, F#, TypeScript, and
|
|
6
|
+
Kotlin through `web-tree-sitter` grammars in `grammars/`. Product source is F# and is compiled
|
|
7
|
+
by Fable 5 to JavaScript before webpack packages the extension and CLI.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
See `energy-state.md` for the original design rationale and `docs/fable-rewrite-plan.md` for the
|
|
10
|
+
completed migration and current build graph.
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
## Build commands
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Commands are wrapped in a `Justfile`; run `just --list` to see all of them. Prefer these over calling `npm run` directly.
|
|
14
|
+
Prefer `Justfile` recipes:
|
|
14
15
|
|
|
15
16
|
```bash
|
|
16
17
|
just install # npm install
|
|
17
|
-
just
|
|
18
|
-
just
|
|
19
|
-
just
|
|
20
|
-
just
|
|
21
|
-
just format
|
|
22
|
-
just
|
|
23
|
-
just
|
|
24
|
-
just
|
|
25
|
-
just
|
|
18
|
+
just fable # F# -> Fable JavaScript in fable-out/
|
|
19
|
+
just build # Fable + webpack development bundles
|
|
20
|
+
just watch # Fable and webpack watchers
|
|
21
|
+
just lint # Fantomas check over F# source and tests
|
|
22
|
+
just format # Format F# source and tests
|
|
23
|
+
just format-check # CI formatting check
|
|
24
|
+
just analyze # Build, then run the F# CLI against src/ or supplied paths
|
|
25
|
+
just test # Fable Scriptorium suite under Node
|
|
26
|
+
just pack # Production bundles + .vsix
|
|
27
|
+
just clean # Generated outputs and packages
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
Fable commands use `--lang javascript --noCache`. Fable emits ESM, so test output receives a
|
|
31
|
+
`{"type":"module"}` shim. Webpack consumes those ESM files and preserves the public CommonJS
|
|
32
|
+
contracts: `dist/extension.js`, `dist/cli.js`, and the CLI shebang.
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
Press `F5` to launch an Extension Development Host; `.vscode/tasks.json` runs the Fable and
|
|
35
|
+
webpack watch pipeline.
|
|
33
36
|
|
|
34
37
|
## Architecture
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
39
|
+
Keep every F# file at or below 12 functions and 10 import sources. `src/EnergyState.fsproj` has
|
|
40
|
+
`EnableDefaultCompileItems=false` behavior, so add every new `.fs` file explicitly in dependency
|
|
41
|
+
order.
|
|
42
|
+
|
|
43
|
+
- **`src/Core/`**: host-independent synchronous detector pipeline, tree-sitter facade,
|
|
44
|
+
suppression, scanning, and report rendering. `Analyze.fs` is the one detector composition
|
|
45
|
+
point shared by extension and CLI.
|
|
46
|
+
- **`src/Languages/`**: grammar-specific `LanguageAdapter` records for the four supported
|
|
47
|
+
analyzed languages.
|
|
48
|
+
- **`src/Extension/`**: VS Code Fable facade, configuration boundary, grammar cache, analysis
|
|
49
|
+
orchestration, editor/Problems presentation, and `Extension.fs` composition root. The narrow
|
|
50
|
+
VS Code bindings (`Host`, `Document`, `Workspace`, `Presentation`, `Diagnostics`,
|
|
51
|
+
`DiagnosticValues`, `Identity`) live in the `src/Extension/Vscode/` subfolder with their
|
|
52
|
+
`Vscode*` prefix dropped from both path and module name. `DecorationModel.fs`,
|
|
53
|
+
`DiagnosticModel.fs`, and `ConfigurationValues.fs` remain pure and have direct Scriptorium
|
|
54
|
+
coverage.
|
|
55
|
+
- **`src/Cli*.fs` and `cli/Main.fs`**: CLI argument parsing, modes, runtime, narrow Node
|
|
56
|
+
bindings, and Fable entry point. Scan, legacy single-file, `--report`, `--base-ref`, and
|
|
57
|
+
thresholds share the Core pipeline.
|
|
58
|
+
- **`tests/`**: F# Scriptorium suites. `src/test/fixtures/` is retained only as multi-language
|
|
59
|
+
analyzer input, including `.ts` fixtures; it is not TypeScript product or test code.
|
|
60
|
+
|
|
61
|
+
The extension composition root owns lifecycle state, grammar caches, decorations, diagnostics,
|
|
62
|
+
commands, and editor/document/configuration event subscriptions. Presentation never leaks into
|
|
63
|
+
`Core/`; `Core/TreeSitter.fs` is the only web-tree-sitter facade.
|
|
64
|
+
|
|
65
|
+
`EnergyViolation` is the DU/record model in `src/Core/Violation.fs`. Add a new detector by adding
|
|
66
|
+
its `Detector` to `Core/Analyze.fs`, and add a `ViolationType` case plus special presentation
|
|
67
|
+
mapping only when required.
|
|
68
|
+
|
|
69
|
+
## Build and packaging
|
|
70
|
+
|
|
71
|
+
`npm run fable` writes generated JavaScript and `fable_modules` to ignored `fable-out/`. It first
|
|
72
|
+
compiles the library project for the extension entry, then the CLI project for `Main.js`.
|
|
73
|
+
`webpack.config.js` consumes only generated `.js`, treats `vscode` as an external, bundles
|
|
74
|
+
`web-tree-sitter`, copies its WASM, and emits the fixed output names. Do not add `ts-loader`,
|
|
75
|
+
`tsconfig.json`, or TypeScript product tooling back.
|
|
76
|
+
|
|
77
|
+
The `.vsix` and npm package ship transpiled bundles, grammar WASMs, and metadata only. Keep F#
|
|
78
|
+
sources, tests, `fable-out/`, `fable_modules/`, `bin/`, `obj/`, and maps excluded by ignore files.
|
|
79
|
+
|
|
80
|
+
## Before committing or opening a PR
|
|
81
|
+
|
|
82
|
+
Run `just format`, `just lint`, and `just analyze`. Triage every analyzer finding:
|
|
83
|
+
|
|
84
|
+
- **Real violation**: fix it.
|
|
85
|
+
- **Wrong implementation**: add a fixture and integration test, then fix the detector.
|
|
86
|
+
- **Wrong threshold**: adjust the detector/configuration threshold with a boundary test.
|
|
87
|
+
- **Legitimate exception**: use a reasoned `esa-ignore` directive; stale directives remain
|
|
88
|
+
findings.
|
|
89
|
+
|
|
90
|
+
Do not suppress a finding merely to make a check pass. If a required cleanup is unrelated to the
|
|
91
|
+
behavior change, land it separately rather than mixing it into the behavioral change.
|
|
92
|
+
|
|
93
|
+
## Releasing and decision comments
|
|
94
|
+
|
|
95
|
+
ShipIt release automation is described in `RELEASING.md`. Use Conventional Commit subjects; do
|
|
96
|
+
not hand-edit generated changelog entries or package versions.
|
|
97
|
+
|
|
98
|
+
This repository uses Agent Decision Comments. Read `AGENT_DECISION_COMMENTS.md` before modifying
|
|
99
|
+
governed code, preserve active `decision:` and `invariant:` comments, and add one for a
|
|
100
|
+
non-obvious durable design choice.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
last_commit_released:
|
|
2
|
+
last_commit_released: 01777cc27c9c08136661a2f1e21409cdf94f05ce
|
|
3
3
|
name: energy-state-analyzer
|
|
4
4
|
updaters:
|
|
5
5
|
- command: npm version {version} --no-git-tag-version --allow-same-version
|
|
@@ -11,6 +11,22 @@ All notable changes to the "energy-state-analyzer" extension are generated by
|
|
|
11
11
|
[EasyBuild.ShipIt](https://github.com/easybuild-org/EasyBuild.ShipIt) from
|
|
12
12
|
[Conventional Commits](https://www.conventionalcommits.org/).
|
|
13
13
|
|
|
14
|
+
## 0.8.0 - 2026-08-31
|
|
15
|
+
|
|
16
|
+
### 🚀 Features
|
|
17
|
+
|
|
18
|
+
* Rewrite analyzer in F# for Fable (#46) ([8aaf666](https://github.com/cardamomcode/energy-state-analyzer/commit/8aaf6666c537b9f1655175805128749e56b8d933))
|
|
19
|
+
* *(core)* Calculate McCabe cyclomatic complexity (#55) ([9a42b6a](https://github.com/cardamomcode/energy-state-analyzer/commit/9a42b6a68cf94c7583c1d1a8282ddffa961275c7))
|
|
20
|
+
* *(core)* Add include-test-files toggle for magic detectors (#57) ([271e15c](https://github.com/cardamomcode/energy-state-analyzer/commit/271e15c8a914f550a5079789750a71caba34181d))
|
|
21
|
+
* *(extension)* Split src/extension.ts by domain (#30) (#42) ([b9f1ba3](https://github.com/cardamomcode/energy-state-analyzer/commit/b9f1ba37d93cbfd34275814a7bdbfb591cd9ae06))
|
|
22
|
+
|
|
23
|
+
### 🐞 Bug Fixes
|
|
24
|
+
|
|
25
|
+
* *(extension)* Construct VS Code diagnostics correctly (#54) ([c9b2f3f](https://github.com/cardamomcode/energy-state-analyzer/commit/c9b2f3f4a8c1c6550776bc1b1b8c611483fba7b3))
|
|
26
|
+
* *(suppressions)* Anchor esa-ignore directive regex so prose isn't matched (#45) ([c99b26a](https://github.com/cardamomcode/energy-state-analyzer/commit/c99b26ae425f16c16460b42d474dd52934f3610d))
|
|
27
|
+
|
|
28
|
+
<strong><small>[View changes on Github](https://github.com/cardamomcode/energy-state-analyzer/compare/5d63923aba3248095bda4074aff14bb133f4f65b..01777cc27c9c08136661a2f1e21409cdf94f05ce)</small></strong>
|
|
29
|
+
|
|
14
30
|
## 0.7.0 - 2026-08-28
|
|
15
31
|
|
|
16
32
|
### 🚀 Features
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Energy State Analyzer
|
|
2
2
|
|
|
3
|
-
Visualizes "energy states" in Python, F#, and
|
|
3
|
+
Visualizes "energy states" in Python, F#, TypeScript, and Kotlin code as you edit: parts of a file that are complex, deeply nested, or otherwise harder to understand and maintain get highlighted with colored gutter icons, inline decorations, and entries in the Problems panel.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
Real-time analysis of the active Python, F#, or
|
|
7
|
+
Real-time analysis of the active Python, F#, TypeScript, or Kotlin file, re-run on every edit and on editor focus change, via these detectors (see [docs/detectors](docs/detectors/README.md) for full detail on each):
|
|
8
8
|
|
|
9
9
|
- [Cyclomatic complexity](docs/detectors/cyclomatic-complexity.md), too many independent execution paths.
|
|
10
10
|
- [Cognitive complexity](docs/detectors/cognitive-complexity.md), too hard to read due to nesting.
|
|
@@ -36,14 +36,31 @@ The name is a deliberate analogy to thermodynamics: a function's "energy" is its
|
|
|
36
36
|
The same detectors also run headlessly, without VS Code, useful for CI or for an AI coding agent that wants to check the complexity of code it just generated and keep refactoring until it's clean:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
npx energy-state-analyzer path/to/file.py # or .fs / .fsx / .ts
|
|
39
|
+
npx energy-state-analyzer path/to/file.py # or .fs / .fsx / .ts / .kt
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
See [docs/cli.md](docs/cli.md) for scanning a whole repo, aggregated markdown/JSON/human reports, and diffing a PR against a base branch.
|
|
43
43
|
|
|
44
44
|
## Requirements
|
|
45
45
|
|
|
46
|
-
The extension activates automatically when you open a Python, F#, or
|
|
46
|
+
The extension activates automatically when you open a Python, F#, TypeScript, or Kotlin file; it bundles its own grammars for parsing (via `web-tree-sitter`), so no external tools are required. F# files only get a `fsharp` language ID (and so trigger analysis) if you have an F# language extension installed (e.g. [Ionide](https://ionide.io/)), VS Code otherwise treats `.fs` files as plain text.
|
|
47
|
+
|
|
48
|
+
## Development
|
|
49
|
+
|
|
50
|
+
Product and test sources are F#. Install the pinned .NET tools (Fable and Fantomas) and npm
|
|
51
|
+
dependencies, then use the wrapped commands:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
just setup
|
|
55
|
+
just install
|
|
56
|
+
just build
|
|
57
|
+
just test
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Fable emits JavaScript with `--lang javascript --noCache` into ignored `fable-out/`; webpack then
|
|
61
|
+
creates `dist/extension.js` and `dist/cli.js`. `just lint` checks F# formatting, `just format`
|
|
62
|
+
formats it, and `just analyze` runs the built F# CLI against the production F# source. Press `F5`
|
|
63
|
+
for the Extension Development Host.
|
|
47
64
|
|
|
48
65
|
## Extension Settings
|
|
49
66
|
|
|
@@ -73,6 +90,5 @@ To exclude files/folders (e.g. test fixtures, generated code) from both the exte
|
|
|
73
90
|
|
|
74
91
|
## Known Issues
|
|
75
92
|
|
|
76
|
-
- Nesting depth and parameter count thresholds are not yet configurable via VS Code settings, only cyclomatic complexity, cognitive complexity, the large-function coherence check, the match-opportunity branch count, and the magic-number/magic-string detectors are.
|
|
77
93
|
- TypeScript arrow functions aren't analyzed by complexity/parameter-count/coherence (same limitation Python already has for `lambda`), only named `function` declarations and class methods are.
|
|
78
94
|
- Several detectors have per-language gaps beyond the above, see the "Known limitations" section of the relevant [detector doc](docs/detectors/README.md).
|
package/action.yml
CHANGED
|
@@ -7,7 +7,7 @@ branding:
|
|
|
7
7
|
|
|
8
8
|
# Requires the caller's checkout step to use `fetch-depth: 0` when base-ref is
|
|
9
9
|
# set, so both the head and base commits are present locally for `git diff`/
|
|
10
|
-
# `git show` (see src/
|
|
10
|
+
# `git show` (see src/CliModes.fs's changedFilesFromGit/readAtRef).
|
|
11
11
|
|
|
12
12
|
inputs:
|
|
13
13
|
path:
|
|
@@ -51,7 +51,7 @@ runs:
|
|
|
51
51
|
using: composite
|
|
52
52
|
steps:
|
|
53
53
|
- name: Setup Node
|
|
54
|
-
uses: actions/setup-node@
|
|
54
|
+
uses: actions/setup-node@v7
|
|
55
55
|
with:
|
|
56
56
|
node-version: 22
|
|
57
57
|
|
|
@@ -76,7 +76,7 @@ runs:
|
|
|
76
76
|
|
|
77
77
|
- name: Comment on PR
|
|
78
78
|
if: ${{ inputs.post-comment == 'true' && github.event_name == 'pull_request' }}
|
|
79
|
-
uses: marocchino/sticky-pull-request-comment@
|
|
79
|
+
uses: marocchino/sticky-pull-request-comment@v3
|
|
80
80
|
with:
|
|
81
81
|
header: ${{ inputs.comment-header }}
|
|
82
82
|
path: ${{ steps.run.outputs.report-path }}
|
|
Binary file
|