# Means

> Query collections of Markdown documents with YAML frontmatter using the `means` CLI. Use when the user asks you to search, list, or inspect a directory of Markdown notes/docs (especially when frontmatter fields like `status`, `tags`, `title` are involved), or when `MEANS_DIR` is set in the environment. Output is JSON, so it's well-suited for programmatic use.

- Skill: `hmans/means` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add hmans/means`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hmans/means/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: hmans (https://skillmd.com/u/hmans)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/hmans/means

---


# means

`means` is a CLI for querying directories of Markdown files with YAML frontmatter. On every invocation it walks the target directory, parses frontmatter, and builds a fresh in-memory [Bleve](https://blevesearch.com/) index — no server, no config.

## Picking the directory

Every command needs to know which directory to work in.

- Prefer the `MEANS_DIR` env var if it is already set — don't override it.
- Otherwise pass `--dir <path>` explicitly. If neither is set, the command errors.

```sh
export MEANS_DIR=./notes
means list                    # uses $MEANS_DIR
means --dir ./other list      # explicit flag wins
```

## Commands

### `list` — enumerate documents

Prints a JSON array of `{ path, frontmatter }` for every Markdown file.

```sh
means list
means list --include-body    # also includes raw Markdown body
```

Use this when you need an overview of what's in the directory or want to scan frontmatter fields across all docs.

### `search` — Bleve query string search

Runs a [Bleve query string](https://blevesearch.com/docs/Query-String-Query/) across paths, frontmatter, and content. Returns `{ total, hits: [{ path, score, frontmatter }] }`.

```sh
means search rutabaga                                # free-text across all fields
means search 'status:draft'                           # match a frontmatter field
means search '+tags:overview +status:published'       # require both (AND)
means search '+status:draft -tags:archived'           # require draft, exclude archived
means search rutabaga --limit 5 --include-body
```

Query tips:
- Field syntax: `field:value`. Fields come from frontmatter keys plus `path` and `content`.
- Phrases: `"exact phrase"`.
- Combining terms: bare terms are OR-ed (any match scores). Prefix with `+` to require a term (AND) and `-` to exclude it. Bleve's query string does **not** treat the words `AND` / `OR` as operators — they get tokenized as content, so `status:draft AND priority:high` does not mean what it looks like.
- Default `--limit` is 20. Raise it with `--limit N` when you expect more hits.
- Add `--include-body` only when you actually need the full Markdown — otherwise the output stays compact.

## Typical flows

**"What's in this notes directory?"** → `means list` (or pipe through `jq` to pluck fields).

**"Find drafts tagged X."** → `means search '+status:draft +tags:X'`.

**"Which docs mention Foo?"** → `means search Foo` — then `means search Foo --include-body --limit 3` to read the relevant ones.

**Inspecting a single match:** once you have a path from `search`, read the file directly with the `Read` tool instead of re-running `means` with `--include-body`.

## Output handling

All output is JSON on stdout; errors go to stderr with a non-zero exit. Parse with `jq` when you need to extract fields:

```sh
means list | jq -r '.[].path'
means search 'status:draft' | jq '.hits[] | {path, title: .frontmatter.title}'
```

## What `means` does not do

- It does not write, create, update, or delete documents — it's read-only. To modify Markdown files, use normal file tools (`Edit`, `Write`).
- It does not persist an index between runs; every invocation re-scans the directory. That's fine for directories up to a few thousand docs.
- It is not a full-text editor, renderer, or git wrapper.

