Plu-Stan is a static analysis tool for Cardano smart contracts written in Plinth. This extension turns it into a review cockpit right inside VS Code and Cursor: catch security and performance anti-patterns before they ship, with a per-rule explanation of why each one matters — no manual CLI invocation required.
Features
- Review sessions — click ▶ Start Review to analyze your onchain modules and open a live findings workspace: a tree grouped by severity and rule (or by module), squiggles in the editor, and entries in the Problems panel
- Finding Detail panel — click any finding to see why it matters, a ✗ bad-example / ✓ good-example pair, concrete how-to-fix guidance, and a link to the full rule documentation
- Persistent dismissals — dismiss a finding you've judged not applicable (with an optional note); it's recorded in
.plustan/dismissals.jsonso the decision survives restarts and can be committed and shared with your team - Staleness tracking — editing a file marks its open findings as stale immediately, and saving an onchain module automatically re-runs analysis and reconciles what's fixed, what's new, and what's still open
- Status bar at a glance — live open/fixed counts for the active review session
- Onchain module explorer — tree view listing all modules annotated with
onchain-contract, auto-discovered from your workspace - One-shot commands —
Run Workspace/Run Modulefor a quick, session-free pass - Works in Cursor — fully compatible with the Cursor editor
Requirements
- The
plustanbinary built from input-output-hk/plu-stan. Extension 0.3.x requiresplustan>= 0.2.5.0; the extension checks this automatically via aplustan capabilitieshandshake and prompts you to update if there's a mismatch. - A Haskell workspace compiled with
.hie/.hiartifacts (Plu-Stan will trigger a build automatically if needed) - A GHC the extension ships a prebuilt binary for. The
plustanbinary reads.hiefiles, whose on-disk format is tied to the GHC major.minor series that produced them — patch releases within a series share the format, so one binary handles any patch of its series (e.g. a 9.6 build reads any 9.6.x project). The extension fetches the binary matching your project's GHC. If your project's GHC series isn't shipped, buildplustanwith that GHC and setplustan.binaryPath.
Getting Started
- Open your Plinth project in VS Code or Cursor.
- Open the Plu-Stan panel in the Activity Bar. If no binary is configured, you'll be offered a one-click download matched to your project's GHC (or run
Plu-Stan: Check for Updatesyourself). To point at a binary you built yourself, setplustan.binaryPath:{ "plustan.binaryPath": "/path/to/plustan" } - In the Findings view, click Start Review (▶), pick the modules to review (or accept all), and work the findings tree: click through to each issue, read the explanation, fix it or dismiss it.
- Click End Review when you're done — it stops auto re-runs and logs a fixed/open/dismissed summary.
Monorepo / multi-package projects: if your on-chain package lives in a subdirectory (e.g.
onchain/), pointplustan.hieDirat that package's.hiedirectory (e.g.onchain/.hie), or setplustan.projectDirto the package. Plu-Stan resolves each finding against the package that produced it, so either works.
Commands
| Command | Description |
|---|---|
Plu-Stan: Start Review |
Begin a review session over the whole workspace or chosen modules |
Plu-Stan: End Review |
Stop auto re-runs and summarize the session |
Plu-Stan: Toggle Findings Grouping |
Switch the Findings tree between severity/rule and module grouping |
Plu-Stan: Open Finding |
Jump to a finding's location in the editor |
Plu-Stan: Dismiss Finding |
Mark a finding as not applicable, with an optional note |
Plu-Stan: Restore Dismissed Finding |
Reopen a previously dismissed finding |
Plu-Stan: Run Workspace |
One-shot analysis of the full workspace (disabled during a review session) |
Plu-Stan: Run Module |
One-shot analysis of the selected onchain module (disabled during a review session) |
Plu-Stan: Refresh Onchain Modules |
Re-scan the workspace for onchain modules |
Plu-Stan: Clear Diagnostics |
Clear all Plu-Stan findings from the Problems panel |
Plu-Stan: Show Output |
Open the Plu-Stan output channel |
Plu-Stan: Open Settings |
Jump to Plu-Stan settings |
Plu-Stan: Check for Updates |
Download the plustan binary matching your project's GHC |
Settings
| Setting | Default | Description |
|---|---|---|
plustan.binaryPath |
"" |
Path to the plustan executable. Supports a leading ${workspaceFolder} token. Leave empty to let the extension manage a downloaded binary |
plustan.projectDir |
"" |
Directory Plu-Stan runs the analyzer in. Defaults to the workspace folder; usually only needed to point at a package subdirectory in a monorepo |
plustan.hieDir |
".hie" |
Directory containing .hie/.hi files. Relative to projectDir, or an absolute path |
plustan.extraArgs |
[] |
Additional CLI arguments appended to plustan analyze runs |
plustan.showOutputChannel |
true |
Automatically show the output channel when running commands |
.plustan/dismissals.json
Every dismissal is recorded in .plustan/dismissals.json at your workspace root, with a timestamp and your optional note. Commit it so the whole team sees the same set of accepted findings — and so a future CI check can hold the line on anything left open.
Rules
Plu-Stan checks for security and performance issues specific to Plinth on-chain code, including:
- Signature verification invariants (PLU-STAN-01)
- Unsafe
unsafeFromBuiltinDatausage (PLU-STAN-02) - Optional types in on-chain code (PLU-STAN-03)
- Credential-only equality comparisons (PLU-STAN-04)
- Inefficient higher-order list helpers (PLU-STAN-05)
- Multiple list traversals (PLU-STAN-06)
- Guard syntax inefficiency (PLU-STAN-07)
- Non-strict let bindings (PLU-STAN-08)
- Unsafe
valueOfcomparisons (PLU-STAN-09) - Unvalidated hashes from
BuiltinData(PLU-STAN-10) currencySymbolValueOfmisuse (PLU-STAN-11)- Validity interval / POSIX time misuse (PLU-STAN-12)
- Division before multiplication precision loss (PLU-STAN-16)
Each rule's finding comes with a plain-language explanation, a bad/good example pair, and a fix suggestion right in the Finding Detail panel. For full rule documentation see the plu-stan repository.