npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sf-agentpmd

v0.1.2

Published

SF CLI plugin: McCabe cyclomatic complexity and Agent LOC analysis for AgentScript (.agent) bundles.

Downloads

493

Readme

sf-agentpmd

SF CLI plugin that computes standard McCabe cyclomatic complexity for AgentScript (.agent) files, along with an inventory of declared and referenced agent actions.

The intent (per docs/agent-loc-categorization-skill-v2.md § 7) is the by-the-book number a SonarQube / PMD / Checkstyle run would produce — but applied to the AgentScript surface that those tools don't cover today.

Current scope (v2)

sf agentpmd analyze [--source-dir <dir|file>] [--apex-source <dir>] [--fail-on N]

If --source-dir is omitted, the plugin walks up from cwd looking for sfdx-project.json and uses its packageDirectories as the source roots. Run it from anywhere inside an sfdx project and it just works.

  • Walks every .agent file under the resolved source roots.

  • For each before_reasoning:, after_reasoning:, and reasoning.instructions: block, computes McCabe CC:

    CC = 1
       + count(if_statement)
       + count(elif_clause)
       + count(ternary_expression)
       + count(binary_expression where operator ∈ {and, or})
  • Reports CC per procedure, per scope (topic / start_agent / subagent), per file, and a total across files.

  • Collects all actions: declarations and classifies their target: URI (apex://, flow://, prompt://, …).

  • Counts how many times each declared action is referenced from reasoning.actions, reasoning.instructions, before_reasoning, after_reasoning, and transition statements.

  • For every apex://ClassName target, resolves the .cls file by walking up from the .agent location looking for a sibling classes/ directory (or honors --apex-source <dir>), parses it with @apexdevtools/apex-parser, and computes per-method McCabe CC for every method and constructor with a body:

    CC = 1
       + count(if)
       + count(for)         // includes enhanced-for
       + count(while)
       + count(do-while)
       + count(when arm)    // each switch `when X { ... }`; `when else` excluded
       + count(catch)
       + count(ternary ?:)
       + count(&&)
       + count(||)
  • Emits a CC by location rollup (AgentScript vs. Apex vs. Combined), matching the whitepaper § 7 framing.

Flags

| Flag | Purpose | | --- | --- | | -d, --source-dir <path> | Directory or single .agent file. Optional. Defaults to the packageDirectories of the nearest sfdx-project.json. | | -n, --api-name <X> | Filter to a specific bundle. Matches the bundle directory name or config.developer_name: inside the .agent. Repeat for multiple bundles. | | --apex-source <path> | Override directory for resolving apex:// targets. Default: walk up from each .agent looking for a classes/ sibling. | | --format <fmt> | Non-JSON output format: text (default), markdown, sarif, csv. Ignored when --json is set. | | --width <N> | Rule width for the text renderer. Default 60. | | --ascii | Force ASCII-only output in the text renderer (no emoji / box chars). Auto-enabled on non-TTY stdout. | | --no-color | Disable ANSI color. NO_COLOR env var also disables. | | --sarif-warning <N> / --sarif-error <N> | Override the SARIF level thresholds. Defaults 10 / 20. | | --fail-on <N> | Exit non-zero (code 2) if combined (agent + Apex) CC ≥ N. Useful in CI. | | --json | Machine-readable SF CLI envelope on stdout. Takes precedence over --format. |

Output formats at a glance

| Format | When to use | Surface | | --- | --- | --- | | text (default) | Terminal eyeballs. | Color-coded, palette-aligned (red/yellow/green/gray by CC band). Auto-degrades to ASCII on non-TTY. | | markdown | PR descriptions, gists, whitepaper appendices. | Mermaid xychart-beta bar chart at top (AgentScript red vs Apex green) + per-bundle and per-class tables. | | sarif | GitHub Code Scanning / IDE annotations / CI. | SARIF 2.1.0 with one result per procedure / per method. Level driven by complexity thresholds. | | csv | Spreadsheet pivots, posture-comparison matrices. | One row per procedure or Apex method. RFC-4180 quoted. | | --json | Machine consumers (e.g. another sf plugin). | SF CLI envelope around the full AnalysisReport. |

Example

$ sf agentpmd analyze -d ./force-app/main/default/aiAuthoringBundles
AgentForce PMD — Cyclomatic Complexity (McCabe)
════════════════════════════════════════════════════════════

📄 case_escalation_bot.agent   CC=31
────────────────────────────────────────────────────────────
  start_agent customer_verification   subtotal CC=8
    before_reasoning         CC=2   if=1
    after_reasoning          CC=5   if=3 and=1
    reasoning.instructions   CC=1   (base only)
  …

Roadmap

  • v3 — implement the four-category LOC rule from docs/agent-loc-categorization-skill-v2.md (Scaffolding, Deterministic Logic, Reasoning Logic, Conversation Surface) as a separate sub-command (sf agentpmd categorize-loc).
  • future — Flow incorporation (§ 9 of the whitepaper) once a CC analog for Flow elements is settled.

How it parses

We do not use heuristic regex scanners. Two real parsers do the work:

To resync the vendor copies after pulling new upstream commits:

./scripts/sync-vendor.sh

That copies the freshly-built dist/ from $AGENTSCRIPT_REPO/packages/{types,parser-javascript} into vendor/agentscript-{types,parser-javascript}/dist/.

Layout

src/
  commands/agentpmd/analyze.ts   # sf agentpmd analyze
  analyzer/
    parse.ts                     # AgentScript CST helpers
    complexity.ts                # AgentScript McCabe CC walker
    action-references.ts         # @actions.X declarations & references
    apex-parse.ts                # @apexdevtools/apex-parser wrappers
    apex-complexity.ts           # Apex McCabe CC walker
    apex-resolve.ts              # apex://ClassName → .cls path resolver
    apex-analyze.ts              # orchestrator for the Apex pass
    analyze.ts                   # file discovery + top-level orchestrator
    report.ts                    # text/json rendering (incl. § 7 split)
    types.ts                     # public types
  index.ts                       # programmatic entry
test/
  fixtures/                      # synthetic + gametwo fixtures
  analyzer/*.spec.ts             # vitest unit + integration tests
vendor/
  agentscript-types/             # vendored from agentscript monorepo
  agentscript-parser-javascript/
scripts/
  sync-vendor.sh
docs/
  agent-loc-categorization-skill-v2.md   # the categorization rule

Development

npm install
npm run build
npm test
node bin/dev.js agentpmd analyze --source-dir test/fixtures

The plugin uses ESM throughout and targets Node ≥ 20.

Claude Code skill

The plugin ships with a bundled Claude Code skill (at skill/ in the repo) that wraps the plugin from an adopter's point of view — discovery, install, upgrade, and output interpretation. It auto-triggers when a Claude session mentions sf agentpmd, "AgentScript cyclomatic complexity", or related phrases.

Activate the skill. After installing the plugin, run:

sf agentpmd install-skill

This recursively copies the bundled skill tree to ~/.claude/skills/agentforcepmd/. Restart Claude Code (or reload skills) to activate it.

Local-dev contributors can instead symlink the in-repo skill/ directory (it moved from .claude/skills/agentforcepmd/ to skill/) so edits show up live:

ln -sfn "$(pwd)/skill" ~/.claude/skills/agentforcepmd

The skill's SKILL.md indexes four reference pages:

  • references/command-structure.md — every flag, defaults, exit codes
  • references/install.md — both pre- and post-publication install paths
  • references/upgrade.md — refresh dance for a linked checkout, plus sf plugins update for the published case
  • references/output-formats.md — text / JSON / markdown / SARIF / CSV surface with examples, plus a "pick a format" cheat sheet