dejared-mcp 1.1.0 → 1.2.1

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.
@@ -11,13 +11,13 @@
11
11
  {
12
12
  "name": "dejared",
13
13
  "source": "./",
14
- "description": "Explore, analyze, and decompile Java JAR files with structured workflows.",
15
- "version": "1.1.0",
14
+ "description": "Java decompiler and JAR analyzer. Decompile classes, search bytecode, and read resources embedded in JAR, WAR, EAR, and AAR archives.",
15
+ "version": "1.2.1",
16
16
  "author": {
17
17
  "name": "hqkh4nh"
18
18
  },
19
19
  "license": "MIT",
20
- "keywords": ["java", "jar", "decompiler", "bytecode", "reverse-engineering", "mcp"],
20
+ "keywords": ["java", "java-decompiler", "jar", "war", "aar", "decompiler", "decompile", "bytecode", "class-file", "cfr", "vineflower", "procyon", "reverse-engineering", "mcp"],
21
21
  "category": "development"
22
22
  }
23
23
  ]
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "dejared",
3
- "description": "Explore, analyze, and decompile Java JAR files with structured workflows.",
4
- "version": "1.1.0",
3
+ "description": "Java decompiler and JAR analyzer. Decompile classes, search bytecode, and read resources embedded in JAR, WAR, EAR, and AAR archives.",
4
+ "version": "1.2.1",
5
5
  "author": {
6
6
  "name": "hqkh4nh"
7
7
  },
8
8
  "repository": "https://github.com/hqkh4nh/dejared-mcp",
9
9
  "license": "MIT",
10
- "keywords": ["java", "jar", "decompiler", "bytecode", "reverse-engineering", "mcp"],
10
+ "keywords": ["java", "java-decompiler", "jar", "war", "aar", "decompiler", "decompile", "bytecode", "class-file", "cfr", "vineflower", "procyon", "reverse-engineering", "mcp"],
11
11
  "mcpServers": {
12
12
  "dejared": {
13
13
  "command": "npx",
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "dejared",
3
+ "version": "1.2.1",
4
+ "description": "Java decompiler and JAR analyzer. Decompile classes, search bytecode, and read resources embedded in JAR, WAR, EAR, and AAR archives.",
5
+ "author": {
6
+ "name": "hqkh4nh"
7
+ },
8
+ "homepage": "https://github.com/hqkh4nh/dejared-mcp",
9
+ "repository": "https://github.com/hqkh4nh/dejared-mcp",
10
+ "license": "MIT",
11
+ "keywords": ["java", "java-decompiler", "jar", "war", "aar", "decompiler", "decompile", "bytecode", "class-file", "cfr", "vineflower", "procyon", "reverse-engineering", "mcp"],
12
+ "skills": "./skills/",
13
+ "mcpServers": "./.mcp.json",
14
+ "interface": {
15
+ "displayName": "DeJared",
16
+ "shortDescription": "Decompile and search Java archives",
17
+ "longDescription": "Nine tools for navigating JAR, WAR, EAR, AAR, and Spring Boot fat-jars: list packages and resources, search classes and bytecode string literals, read embedded configs, extract class metadata via ASM, and decompile with CFR, Vineflower, or Procyon.",
18
+ "category": "Developer Tools"
19
+ }
20
+ }
package/README.md CHANGED
@@ -4,24 +4,28 @@
4
4
  [![npm downloads](https://img.shields.io/npm/dt/dejared-mcp?style=flat-square&color=cb3837&label=downloads)](https://www.npmjs.com/package/dejared-mcp)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue?style=flat-square)](LICENSE)
6
6
 
7
- # dejared-mcp
7
+ # dejared-mcp: Java decompiler MCP server
8
8
 
9
- A Model Context Protocol (MCP) server for exploring, analyzing, and decompiling Java JAR files.
10
- Designed for AI-powered development tools, dejared-mcp connects your IDE or CLI assistant
11
- to inspect package structures, search bytecode, and decompile classes
12
- using CFR, Vineflower, or Procyon.
9
+ dejared-mcp is a Java decompiler and JAR analyzer that speaks the Model Context
10
+ Protocol. It lets an AI coding agent (Claude Code, Codex, Cursor, VS Code)
11
+ open a `.jar`, `.war`, `.ear`, or `.aar`, list what is inside, search its
12
+ bytecode, and decompile any class back to Java source using CFR, Vineflower,
13
+ or Procyon.
13
14
 
15
+ [![Claude Code](https://img.shields.io/badge/Claude_Code-plugin-D97757?style=for-the-badge&logo=claude&logoColor=white)](#claude-code)
16
+ [![Codex](https://img.shields.io/badge/Codex-plugin-000000?style=for-the-badge&logo=openai&logoColor=white)](#codex)
14
17
  [![Install in VS Code](https://img.shields.io/badge/Install_in-VS_Code-0098FF?style=for-the-badge&logo=visualstudiocode&logoColor=white)](https://vscode.dev/redirect/mcp/install?name=dejared&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22dejared-mcp%22%5D%7D)
15
- [![Add to Cursor](https://img.shields.io/badge/Add_to-Cursor-000000?style=for-the-badge&logo=cursor&logoColor=white)](cursor://anysphere.cursor-deeplink/mcp/install?name=dejared&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImRlamFyZWQtbWNwIl19)
18
+ [![Add to Cursor](https://img.shields.io/badge/Add_to-Cursor-000000?style=for-the-badge&logo=cursor&logoColor=white)](https://cursor.com/install-mcp?name=dejared&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImRlamFyZWQtbWNwIl19)
16
19
 
17
20
  ## Table of Contents
18
21
 
19
22
  - [Overview](#overview)
20
23
  - [Prerequisites](#prerequisites)
21
24
  - [Quick Start](#quick-start)
25
+ - [Install as a plugin (recommended)](#install-as-a-plugin-recommended)
26
+ - [Install as an MCP server](#install-as-an-mcp-server)
22
27
  - [Features](#features)
23
28
  - [Decompiler Engines](#decompiler-engines)
24
- - [Installation and Configuration](#installation-and-configuration)
25
29
  - [Custom Java Path](#custom-java-path)
26
30
  - [Server Configuration](#server-configuration)
27
31
  - [How It Works](#how-it-works)
@@ -38,6 +42,12 @@ and deep analysis. AI assistants use these tools to navigate JAR file
38
42
  structures, search for classes and string literals in bytecode, and
39
43
  decompile `.class` files back to readable Java source code.
40
44
 
45
+ Reach for it whenever a dependency ships without sources: reading what a
46
+ third-party library actually does, recovering an `application.yml` or
47
+ `MANIFEST.MF` embedded in a JAR, following a stack trace into a library you
48
+ have no source for, or inspecting an obfuscated plugin or mod. It replaces
49
+ hand-running `jar tf`, `unzip`, `javap`, or a desktop decompiler.
50
+
41
51
  Any ZIP-based Java archive works: `.jar`, `.war`, `.ear`, `.aar`, and
42
52
  Spring Boot fat-jars.
43
53
 
@@ -52,66 +62,60 @@ transport.
52
62
 
53
63
  ## Quick Start
54
64
 
55
- Add the following to your MCP client configuration:
65
+ The best install is the plugin. One command pair gives your agent both halves:
66
+ the **nine MCP tools**, and the **`jar-analysis` skill** that tells it when to
67
+ reach for them instead of shelling out to `jar tf`, `unzip`, or `javap`.
56
68
 
57
- ```json
58
- {
59
- "mcpServers": {
60
- "dejared": {
61
- "command": "npx",
62
- "args": ["-y", "dejared-mcp"]
63
- }
64
- }
65
- }
69
+ ```bash
70
+ claude plugin marketplace add hqkh4nh/dejared-mcp
71
+ claude plugin install dejared@dejared-mcp-marketplace
66
72
  ```
67
73
 
68
- See [Installation and Configuration](#installation-and-configuration)
69
- for tool-specific instructions.
74
+ Codex carries the same bundle. See
75
+ [Install as a plugin](#install-as-a-plugin-recommended).
76
+ Every other client takes the [plain MCP config](#install-as-an-mcp-server).
70
77
 
71
- ## Features
78
+ ## Install as a plugin (recommended)
72
79
 
73
- ### Discovery
80
+ The MCP server on its own gives an agent nine tools. It does not tell the agent
81
+ *when* to use them, so most agents keep reaching for `jar tf`, `unzip -p`, and
82
+ `javap -p` out of habit and never touch the tools you installed.
74
83
 
75
- Browse and read JAR contents.
84
+ A plugin ships both parts together:
76
85
 
77
- | Tool | Description |
78
- |------|-------------|
79
- | `dejared_list_packages` | List all packages with class counts |
80
- | `dejared_list_classes` | List classes in a specific package |
81
- | `dejared_list_resources` | List non-class resource files |
82
- | `dejared_read_resource` | Read text resources (YAML, XML, properties, JSON, and others) |
83
-
84
- ### Hunting
86
+ | Part | What it does |
87
+ |------|--------------|
88
+ | MCP server | The nine tools listed under [Features](#features) |
89
+ | `jar-analysis` skill | Routes JAR questions to those tools, picks the cheap tool before the expensive one, and knows which decompiler to retry with |
85
90
 
86
- Search inside JAR files.
91
+ Two tools support that bundle today. Everything else is
92
+ [MCP-only](#install-as-an-mcp-server).
87
93
 
88
- | Tool | Description |
89
- |------|-------------|
90
- | `dejared_search_class` | Search classes by name |
91
- | `dejared_search_string` | Search string literals in bytecode (URLs, SQL, error messages) |
94
+ ### Claude Code
92
95
 
93
- ### Deep Analysis
96
+ ```bash
97
+ claude plugin marketplace add hqkh4nh/dejared-mcp
98
+ claude plugin install dejared@dejared-mcp-marketplace
99
+ ```
94
100
 
95
- Inspect metadata and decompile classes.
101
+ Inside a session, the same commands work as `/plugin marketplace add ...` and
102
+ `/plugin install ...`. If the install summary says `Run /reload-plugins to
103
+ activate`, run it.
96
104
 
97
- | Tool | Description |
98
- |------|-------------|
99
- | `dejared_get_metadata` | Extract class metadata via ASM (fast, no decompilation) |
100
- | `dejared_dump_package_metadata` | Batch metadata extraction for entire packages |
101
- | `dejared_decompile_class` | Decompile `.class` files to Java source code |
105
+ ### Codex
102
106
 
103
- ## Decompiler Engines
107
+ ```bash
108
+ codex plugin marketplace add hqkh4nh/dejared-mcp
109
+ codex plugin add dejared@dejared-mcp-marketplace
110
+ ```
104
111
 
105
- dejared-mcp supports three decompiler engines. The engine can be
106
- specified per request via the `dejared_decompile_class` tool.
112
+ Start a new session afterwards so the bundled skill and server load. Check with
113
+ `codex mcp list`. `dejared` should be listed as `enabled`.
107
114
 
108
- | Engine | Description |
109
- |--------|-------------|
110
- | **CFR** (default) | Reliable general-purpose decompiler |
111
- | **Vineflower** | Modern fork of FernFlower, handles newer Java features well |
112
- | **Procyon** | Alternative engine, can handle some edge cases better |
115
+ ## Install as an MCP server
113
116
 
114
- ## Installation and Configuration
117
+ For clients without a plugin system. You get the tools, but not the skill that
118
+ steers the agent toward them.
115
119
 
116
120
  Most clients accept this standard config:
117
121
 
@@ -126,6 +130,8 @@ Most clients accept this standard config:
126
130
  }
127
131
  ```
128
132
 
133
+ ### From the command line
134
+
129
135
  If your tool has a CLI, one line is enough:
130
136
 
131
137
  ```bash
@@ -154,10 +160,10 @@ Drop the standard config into the file for your tool:
154
160
  | JetBrains IDEs | Settings → Tools → AI Assistant → Model Context Protocol (MCP) |
155
161
  | Qodo Gen | Chat panel → Connect more tools → + Add new MCP |
156
162
 
157
- A few setups need more than the standard config — expand those below.
163
+ A few setups need more than the standard config. Expand those below.
158
164
 
159
165
  <details>
160
- <summary><strong>Codex</strong> — TOML instead of JSON</summary>
166
+ <summary><strong>Codex</strong>: TOML instead of JSON</summary>
161
167
 
162
168
  ```bash
163
169
  codex mcp add dejared -- npx -y dejared-mcp
@@ -181,7 +187,7 @@ DEJARED_JAVA_PATH = "/path/to/java"
181
187
  </details>
182
188
 
183
189
  <details>
184
- <summary><strong>VS Code (GitHub Copilot)</strong> — uses <code>servers</code>, not <code>mcpServers</code></summary>
190
+ <summary><strong>VS Code (GitHub Copilot)</strong>: uses <code>servers</code>, not <code>mcpServers</code></summary>
185
191
 
186
192
  Create or edit `.vscode/mcp.json`:
187
193
 
@@ -201,7 +207,7 @@ After saving, click **Start** above the server entry, then use Agent mode in Cop
201
207
  </details>
202
208
 
203
209
  <details>
204
- <summary><strong>opencode</strong> — command is an array</summary>
210
+ <summary><strong>opencode</strong>: command is an array</summary>
205
211
 
206
212
  Edit `~/.config/opencode/opencode.json`:
207
213
 
@@ -220,16 +226,6 @@ Edit `~/.config/opencode/opencode.json`:
220
226
 
221
227
  </details>
222
228
 
223
- <details>
224
- <summary><strong>Claude Code plugin</strong> — also installs the <code>/jar-analysis</code> skill</summary>
225
-
226
- ```bash
227
- claude plugin marketplace add hqkh4nh/dejared-mcp
228
- claude plugin install dejared@dejared-mcp-marketplace
229
- ```
230
-
231
- </details>
232
-
233
229
  <details>
234
230
  <summary><strong>Pure Java (no Node.js required)</strong></summary>
235
231
 
@@ -257,6 +253,49 @@ If you prefer to run the server JAR directly without Node.js:
257
253
 
258
254
  </details>
259
255
 
256
+ ## Features
257
+
258
+ ### Discovery
259
+
260
+ Browse and read JAR contents.
261
+
262
+ | Tool | Description |
263
+ |------|-------------|
264
+ | `dejared_list_packages` | List all packages with class counts |
265
+ | `dejared_list_classes` | List classes in a specific package |
266
+ | `dejared_list_resources` | List non-class resource files |
267
+ | `dejared_read_resource` | Read text resources (YAML, XML, properties, JSON, and others) |
268
+
269
+ ### Hunting
270
+
271
+ Search inside JAR files.
272
+
273
+ | Tool | Description |
274
+ |------|-------------|
275
+ | `dejared_search_class` | Search classes by name |
276
+ | `dejared_search_string` | Search string literals in bytecode (URLs, SQL, error messages) |
277
+
278
+ ### Deep Analysis
279
+
280
+ Inspect metadata and decompile classes.
281
+
282
+ | Tool | Description |
283
+ |------|-------------|
284
+ | `dejared_get_metadata` | Extract class metadata via ASM (fast, no decompilation) |
285
+ | `dejared_dump_package_metadata` | Batch metadata extraction for entire packages |
286
+ | `dejared_decompile_class` | Decompile `.class` files to Java source code |
287
+
288
+ ## Decompiler Engines
289
+
290
+ dejared-mcp supports three decompiler engines. The engine can be
291
+ specified per request via the `dejared_decompile_class` tool.
292
+
293
+ | Engine | Description |
294
+ |--------|-------------|
295
+ | **CFR** (default) | Reliable general-purpose decompiler |
296
+ | **Vineflower** | Modern fork of FernFlower, handles newer Java features well |
297
+ | **Procyon** | Alternative engine, can handle some edge cases better |
298
+
260
299
  ## Custom Java Path
261
300
 
262
301
  If Java is not in your system PATH, set the `DEJARED_JAVA_PATH` environment variable in your MCP config. This applies to all `npx`-based configurations:
@@ -324,7 +363,7 @@ Java 17 or later. A JRE is sufficient; you do not need a full JDK.
324
363
 
325
364
  Yes. Download the JAR from GitHub Releases and run it directly
326
365
  with `java -jar`. See the "Pure Java" section under
327
- [Installation and Configuration](#installation-and-configuration).
366
+ [Install as an MCP server](#install-as-an-mcp-server).
328
367
 
329
368
  ## Contributing
330
369
 
@@ -336,17 +375,25 @@ Contributions are welcome. Please follow these guidelines:
336
375
  4. Open a pull request against `master` with a description of what
337
376
  the change does and why.
338
377
 
378
+ Every manifest listed under [Project Structure](#project-structure) carries a
379
+ `version` field, and CI fails the build if any of them drifts from
380
+ `package.json`. Bump them together.
381
+
339
382
  ### Project Structure
340
383
 
341
384
  ```
342
385
  dejared-mcp/
343
- ├── bin/ # Node.js CLI entry point
344
- ├── lib/ # Node.js wrapper (JAR download and process management)
345
- ├── java-mcp/ # Java MCP server (Spring Boot, Gradle)
386
+ ├── bin/ # Node.js CLI entry point
387
+ ├── lib/ # Node.js wrapper (JAR download and process management)
388
+ ├── java-mcp/ # Java MCP server (Spring Boot, Gradle)
346
389
  │ └── src/
347
- ├── skills/ # Claude Code plugin skills
348
- ├── package.json # npm package manifest
349
- └── server.json # MCP Registry manifest
390
+ ├── skills/ # Agent skills, shared by every plugin manifest below
391
+ ├── .mcp.json # MCP server definition, shared the same way
392
+ ├── .claude-plugin/ # Claude Code plugin + marketplace manifests
393
+ ├── .codex-plugin/ # Codex plugin manifest
394
+ ├── .agents/plugins/ # Codex marketplace manifest
395
+ ├── package.json # npm package manifest
396
+ └── server.json # MCP Registry manifest
350
397
  ```
351
398
 
352
399
  ### Building from Source
package/lib/jar-runner.js CHANGED
@@ -133,7 +133,7 @@ async function ensureJar() {
133
133
  }
134
134
  }
135
135
 
136
- /** Entry point – resolves Java, ensures the JAR is cached, then spawns it. */
136
+ /** Entry point: resolves Java, ensures the JAR is cached, then spawns it. */
137
137
  async function run() {
138
138
  const javaPath = resolveJava();
139
139
  await ensureJar();
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "dejared-mcp",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "mcpName": "io.github.hqkh4nh/dejared",
5
- "description": "Explore, analyze, and decompile Java JAR files via MCP",
5
+ "description": "Java decompiler MCP server for AI coding agents. Explore, search, and decompile JAR, WAR, EAR, and AAR bytecode with CFR, Vineflower, or Procyon.",
6
6
  "bin": {
7
7
  "dejared-mcp": "bin/dejared-mcp.js"
8
8
  },
@@ -11,6 +11,7 @@
11
11
  "lib/",
12
12
  "skills/",
13
13
  ".claude-plugin/",
14
+ ".codex-plugin/",
14
15
  ".mcp.json",
15
16
  "README.md",
16
17
  "LICENSE"
@@ -23,11 +24,23 @@
23
24
  },
24
25
  "keywords": [
25
26
  "mcp",
27
+ "mcp-server",
28
+ "model-context-protocol",
26
29
  "java",
27
- "jar",
30
+ "java-decompiler",
28
31
  "decompiler",
32
+ "decompile",
33
+ "jar",
34
+ "war",
35
+ "aar",
36
+ "class-file",
29
37
  "bytecode",
30
- "reverse-engineering"
38
+ "cfr",
39
+ "vineflower",
40
+ "procyon",
41
+ "reverse-engineering",
42
+ "claude-code",
43
+ "codex"
31
44
  ],
32
45
  "engines": {
33
46
  "node": ">=20"
@@ -12,7 +12,7 @@ description: >
12
12
  `~/.m2/repository`, `~/.gradle/caches`, `build/libs/`, `target/`,
13
13
  `lib/`, and `libs/`. Prefer the dejared MCP tools over `jar tf`,
14
14
  `jar xf`, `unzip`, `javap -p`, `javap -c`, `javap -v`, or running a
15
- decompiler manually — even if the user doesn't explicitly ask for
15
+ decompiler manually, even if the user doesn't explicitly ask for
16
16
  "the dejared tools" or "decompilation".
17
17
  ---
18
18
 
@@ -20,7 +20,7 @@ description: >
20
20
 
21
21
  ## When This Skill Applies
22
22
 
23
- Reach for these tools — never the shell — whenever the task touches the **inside** of a Java artifact:
23
+ Reach for these tools, never the shell, whenever the task touches the **inside** of a Java artifact:
24
24
 
25
25
  | You would reach for... | Use this instead |
26
26
  |----------------------------------------------|--------------------------------------------------------|
@@ -52,8 +52,8 @@ Applies to `.jar`, `.war`, `.ear`, `.aar` and any artifact under `~/.m2/reposito
52
52
  ## Shared Rules
53
53
 
54
54
  - All tool calls require the **absolute path** to the JAR file.
55
- - Prefer these MCP tools over shelling out to jar/javap/unzip/strings or asking the user to decompile manually — structured output is faster and safer for the agent to consume.
56
- - Check metadata before decompiling — it often provides enough information without the cost of full decompilation.
55
+ - Prefer these MCP tools over shelling out to jar/javap/unzip/strings or asking the user to decompile manually. Structured output is faster and safer for the agent to consume.
56
+ - Check metadata before decompiling: it often provides enough information without the cost of full decompilation.
57
57
  - Default decompiler: CFR. If output is broken, try `vineflower` or `procyon`.
58
58
  - Report results in structured format.
59
59
 
@@ -61,21 +61,21 @@ Applies to `.jar`, `.war`, `.ear`, `.aar` and any artifact under `~/.m2/reposito
61
61
 
62
62
  ## Quick Use Cases
63
63
 
64
- **Quick Lookup** — find a class by name (`dejared_search_class`) or find a string in bytecode (`dejared_search_string`). One call, done.
64
+ **Quick Lookup**: find a class by name (`dejared_search_class`) or find a string in bytecode (`dejared_search_string`). One call, done.
65
65
 
66
- **Read Config** — `dejared_list_resources` to see what's in the JAR, then `dejared_read_resource` to read it (application.yml, pom.xml, logback.xml, etc.).
66
+ **Read Config**: `dejared_list_resources` to see what's in the JAR, then `dejared_read_resource` to read it (application.yml, pom.xml, logback.xml, etc.).
67
67
 
68
- **Get Signatures** — `dejared_get_metadata` for a single class, or `dejared_dump_package_metadata` for an entire package (accepts a list). Returns class hierarchy, annotations, fields, and method signatures without decompiling.
68
+ **Get Signatures**: `dejared_get_metadata` for a single class, or `dejared_dump_package_metadata` for an entire package (accepts a list). Returns class hierarchy, annotations, fields, and method signatures without decompiling.
69
69
 
70
70
  ---
71
71
 
72
72
  ## Workflows
73
73
 
74
- **Explore** — top-down JAR mapping:
74
+ **Explore**: top-down JAR mapping:
75
75
  `dejared_list_packages` → `dejared_list_classes` (use `recursive=true`) → `dejared_list_resources` → `dejared_read_resource` for configs → `dejared_dump_package_metadata` (batch all important packages in one call) → selective `dejared_decompile_class` only where method body logic is needed. If CFR output has issues, retry with `vineflower` or `procyon`.
76
76
 
77
- **Hunt** — search-driven investigation:
77
+ **Hunt**: search-driven investigation:
78
78
  Pick search tool (`dejared_search_class` or `dejared_search_string`) → triage results → `dejared_get_metadata` on promising matches → `dejared_decompile_class` only if needed.
79
79
 
80
- **Deep Analysis** — single class investigation:
80
+ **Deep Analysis**: single class investigation:
81
81
  `dejared_get_metadata` first → `dejared_decompile_class` (CFR default) → cross-reference with `dejared_search_class` or `dejared_dump_package_metadata` if needed. If CFR output has issues (broken lambdas, `goto` statements, missing method bodies), retry with `vineflower` (best for modern Java features like records, sealed classes, pattern matching) or `procyon` (handles some obfuscated/edge-case bytecode better).