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

@markdownai/parser

v1.4.0

Published

Pure AST production for MarkdownAI documents. Reads `.md` source, returns a typed tree. No execution, no IO.

Readme

@markdownai/parser

Pure AST production for MarkdownAI documents. Reads .md source, returns a typed tree. No execution, no IO.

Root README · Spec v2.0 · Engine · GitHub

Install

npm install @markdownai/parser

What changed in v2

  • Three directive forms unified under one grammar: self-closing (@name ... /), block-with-attrs (@name + indented attrs + @name-end), block-with-attrs+body (same, with body after a blank line or >). Full grammar in the spec.
  • Close tags carry the directive name. @phase-end, @if-end, @foreach-end. Bare @end, @endif, @endswitch are no longer accepted.
  • @on-complete <phase> / replaces v1's @on complete -> X arrow transitions.
  • Nested same-name blocks are supported. The parser depth-tracks @if inside @if, etc.
  • block: bool on ParseModule is gone. Every directive uses the same shape; the parser figures out form 1 vs 2 vs 3 from the opener line.
  • DirectiveInput is the new input record passed to each directive's parse():
interface DirectiveInput {
  positional: string         // first token after the directive name
  attrs: Record<string, string>
  flags: string[]            // bare-name tokens (no `=`)
  body: string[]             // raw body lines, empty for forms 1/2
  isSelfClosed: boolean      // true when opener ended with ` /`
  line: number               // 1-based opener line
  rawArgs: string            // verbatim opener text after the name
}

Worked example

import { parse } from '@markdownai/parser'

const ast = parse(`@markdownai v2.0

@phase setup
  required=true
>
  @touch path="src/foo.ts" /
  @on-complete build /
@phase-end
`)

// ast.header.version === "2.0"
// ast.nodes[0] === {
//   type: 'PhaseNode',
//   name: 'setup',
//   attrs: { required: 'true' },
//   body: [
//     { type: 'TouchNode', path: 'src/foo.ts', ... },
//     { type: 'OnCompleteNode', target: 'build', ... },
//   ],
//   line: 3,
// }

API

  • parse(source: string, options?: ParseOptions): ParseResult - returns { header, nodes } or throws ParseError.
  • ParseError - has message, sourceLine, filePath.
  • scanInterpolations(source) - returns {{ }} expressions without a full parse.
  • scanShellInlines(source) - returns !`...` expressions.
  • getAvailableDirectives() - registry of every registered directive.

All AST node types are exported under MarkdownAIDocument, PhaseNode, DefineNode, ConditionalNode, etc. The full set lives in src/types.ts. New as of 1.3.0: TemplateNode (@template single-line directive with optional data= and as= bindings) and DataNode (@data block whose body is DataAssignEntry/DataSpreadEntry records). @data is also registered as a verbatim-body directive, so its key = expression body lines reach the directive parser without quote-stripping or attr-extraction.

Migration from v1

Mechanical rewrite via the bundled script:

node packages/parser/scripts/migrate-v1-to-v2.mjs <file> --in-place

The script is idempotent. Re-running on a v2 file is a no-op. It handles bare @end rewrites, arrow-transition rewrites, multi-line attrs for inline directives, and the as=row shorthand. Run --dry-run first if you want to see the diff.

What this package does not do

Execute directives. Read files. Make HTTP requests. Resolve macros. All of that lives in @markdownai/engine.

License

MIT.