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

pm-csv

v2026.6.10-1

Published

CSV importer and exporter for pm-cli

Readme

pm-csv

CSV importer and exporter for pm-cli.

Import pm items from a CSV file, export them back out, or wire up a programmatic csv-import importer — all with zero external runtime dependencies.


Installation

pm install github.com/unbraind/pm-csv --global

Or install per-project:

pm install github.com/unbraind/pm-csv --project

Commands

pm csv import <file>

Read a CSV file and create or update pm items.

pm csv import tasks.csv
pm csv import backlog.csv --delimiter ';'
pm csv import data.tsv --delimiter tab
pm csv import jira.csv --auto-map              # infer common aliases (summary->title, owner->assignee)
pm csv import jira.csv --map 'Summary=title,Owner=assignee'
pm csv import items.csv --key title         # idempotent re-import (no duplicates)
pm csv import legacy.csv --encoding latin1  # non-UTF-8 source
pm csv import sprint12.csv --source 'jira-export-2026-06'
pm csv import vendor.csv --strict       # fail before writing on bad row data
pm csv import items.csv --dry-run

Flags

| Flag | Type | Default | Description | |---|---|---|---| | --delimiter <char> | string | , | Field delimiter, or alias tab / comma / semicolon / pipe | | --map <col=field> | string | — | Remap a CSV header to a pm field (repeatable, comma-joined), e.g. --map 'Summary=title' | | --auto-map | boolean | false | Auto-map common third-party headers when unambiguous (e.g. summary -> title, owner -> assignee) | | --key <field> | string | — | Dedup key column: a re-import updates the matching item instead of creating a duplicate | | --encoding <enc> | string | utf-8 | Source file encoding: utf-8 | utf16le | latin1 | | --source <label> | string | — | Record an import-provenance label in the csv_source field of created/updated items | | --status <filter> | string | — | Import only rows whose (normalized) status matches; non-matching rows are skipped | | --type <type> | string | — | Import only rows whose type matches (case-insensitive) | | --priority <n> | integer | — | Import only rows whose integer priority equals this value | | --strict | boolean | false | Abort before writing if validation finds missing titles, unknown statuses, invalid/out-of-range priorities, or duplicate mapped columns | | --dry-run | boolean | false | Preview what would be imported without writing any data |

Strict import gate

Default imports remain lenient for messy spreadsheets: empty titles are skipped, unknown statuses fall back to open, and invalid priorities are ignored. Add --strict when the CSV is expected to be a production source of truth. In strict mode the importer runs the same parser as pm csv validate before any write, then aborts on row-level data issues or duplicate mapped columns so a bad file cannot partially mutate the pm store.

Row filtering on import

--status, --type and --priority filter the CSV rows before any items are created — non-matching rows are skipped, never written. They mirror the csv export filter semantics exactly (status is normalized through the same alias table, so --status open matches a row whose status cell is todo). Multiple criteria are ANDed. The result reports how many rows were filtered out:

pm csv import tasks.csv --status open               # import open rows only
pm csv import tasks.csv --type Feature --priority 1 # AND: Feature *and* priority 1
# → Imported 1, updated 0, skipped 5 (5 filtered out).

Required column: title

Optional columns: type, status, priority, tags, deadline, body, parent, assignee, sprint, release, blocked_by


pm csv validate <file>

Parse a CSV and report data-quality issues without importing. Exits non-zero (usage error) when there is a structural problem (no title column after --map or an empty file); otherwise exits 0 even when it reports row-level warnings.

pm csv validate tasks.csv
pm csv validate jira.csv --map 'Summary=title'
pm csv validate jira.csv --auto-map
pm csv validate data.tsv --delimiter tab --json

The report includes: row count, detected columns, mapped columns (after --map), whether the required title column is present, duplicate mapped columns, and counts of rows missing a title, rows with an unrecognized status, rows with a non-integer priority, and rows with a priority outside pm's 0..4 range.

--auto-map applies the same alias vocabulary as import, then validates against the effective mapped headers.

Flags

| Flag | Type | Default | Description | |---|---|---|---| | --delimiter <char> | string | , | Field delimiter, or alias tab / comma / semicolon / pipe | | --map <col=field> | string | — | Remap a CSV header to a pm field before validating | | --auto-map | boolean | false | Auto-map common third-party headers when unambiguous before validating | | --encoding <enc> | string | utf-8 | Source file encoding: utf-8 | utf16le | latin1 | | --json | boolean | false | Emit the report as JSON |


pm csv export

Export all pm items (or a filtered subset) to CSV. Without --output the CSV is returned in the command result object.

pm csv export
pm csv export --output items.csv
pm csv export --output backlog.csv --delimiter ';'
pm csv export --status open --output todos.csv
pm csv export --type Feature --output features.csv
pm csv export --excel --output for-excel.csv

Flags

| Flag | Type | Default | Description | |---|---|---|---| | --output <file> | string | — | Write CSV to this file path instead of returning it | | --delimiter <char> | string | , | Field delimiter, or alias tab / comma / semicolon / pipe | | --status <status> | string | — | Filter: open | in_progress | blocked | closed | canceled | draft | | --type <type> | string | — | Filter by item type | | --columns <list> | string | all | Comma-separated columns to export, in order (custom fields selectable when --all-fields is set) | | --all-fields | boolean | false | Discover custom item fields registered in the workspace schema and append them as columns | | --discover-fields | boolean | false | Alias for --all-fields | | --no-header | boolean | false | Omit the CSV header row | | --crlf | boolean | false | Use CRLF line endings (RFC-4180 / Excel) | | --excel | boolean | false | Excel-friendly output: CRLF line endings and a UTF-8 BOM prefix |

Export columns (fixed order): id, title, type, status, priority, tags, deadline, body, parent, assignee, sprint, release, blocked_by, csv_source, created_at, updated_at

Custom-field discovery (--all-fields)

By default only the built-in columns above are exported. --all-fields (alias --discover-fields) discovers any custom item fields registered in the workspace runtime schema and appends them as extra columns — the default column set is otherwise unchanged, so the flag is strictly additive.

Discovery reads the same inputs the SDK's resolveRuntimeFieldRegistry consumes (the workspace settings.json schema.fields plus the file it points at via schema.files.fields, default schema/fields.json). A standalone-installed extension only loads its own dist/, so the SDK function isn't importable at runtime; reading its inputs directly is the runtime-safe equivalent.

pm csv export --all-fields --output full.csv
# header gains your custom columns, e.g. …,updated_at,story_points,team

Programmatic importer: csv-import

Register the importer in your pm-cli config to automatically pull from a CSV file on every sync:

{
  "importers": [
    {
      "name": "csv-import",
      "config": {
        "file": "./data/items.csv",
        "delimiter": ","
      }
    }
  ]
}

Config options

| Key | Type | Required | Description | |---|---|---|---| | file | string | yes | Path to the CSV file to import | | delimiter | string | no (default ,) | CSV field delimiter (or alias tab/comma/semicolon/pipe) | | map | string | no | Header remap, e.g. Summary=title | | auto-map / autoMap | boolean | no (default false) | Auto-map common third-party headers when unambiguous | | key | string | no | Dedup key column for idempotent re-import | | encoding | string | no (default utf-8) | utf-8 | utf16le | latin1 | | source | string | no | Provenance label recorded in csv_source |


CSV Format

Import format

The first row must be a header row. Column names are case-insensitive. Column order does not matter. Only title is required.

title,type,status,priority,tags,deadline,body,parent,assignee,sprint,release,blocked_by
"Add login page",Feature,open,2,"auth,ui",2026-05-30,"Landing page with email+password login",,alice,Sprint-12,v1.0,
"Fix navbar bug",Issue,in_progress,1,"bug,ui",,"Navbar collapses on mobile Safari",,bob,Sprint-12,v1.0,
"Write API docs",Task,open,3,docs,,,,,Sprint-13,v1.1,Fix navbar bug

Column reference

| Column | Description | Notes | |---|---|---| | title | Item title | Required | | type | Item type | Any string, e.g. Feature, Issue, Task | | status | Item status | See status mapping below | | priority | Numeric priority | Integer | | tags | Comma-separated tags | Quote the field if tags contain commas | | deadline | Deadline | ISO 8601, e.g. 2026-05-30 (legacy due_date header accepted) | | body | Description / body text | Supports multiline when quoted | | parent | Parent item id | Maps to pm create --parent | | assignee | Assignee | Maps to pm create --assignee | | sprint | Sprint identifier | Maps to pm create --sprint | | release | Release identifier | Maps to pm create --release | | blocked_by | Blocked-by item id or reason | Maps to pm create --blocked-by (legacy blocked-by header accepted) |

All columns except title are optional. Round-tripping (export then import --key) is lossless for these fields.

Status mapping

The importer accepts common status strings and maps them to pm-cli statuses:

| Input values | pm-cli status | |---|---| | open, todo, new | open | | in_progress, wip, in progress, doing | in_progress | | blocked, on_hold, on hold | blocked | | closed, done, complete, completed | closed | | canceled, cancelled | canceled | | draft | draft |

Unrecognized values default to open.

Export format

Exports use the same CSV format and can be re-imported. An extra read-only csv_source column surfaces the import-provenance label (see --source); it is ignored on import.

id,title,type,status,priority,tags,deadline,body,parent,assignee,sprint,release,blocked_by,csv_source,created_at,updated_at
pm-abc123,Add login page,Feature,open,2,"auth,ui",2026-05-30,Landing page,,alice,Sprint-12,v1.0,,jira-export,2026-05-01T10:00:00Z,2026-05-09T12:00:00Z

Idempotent re-import (--key)

--key <field> makes re-imports update existing items instead of creating duplicates. The first import tags each created item with an internal csv-key:<value> provenance tag; a later import keyed on the same column finds and updates the matching item. Key matching is case-insensitive (pm folds tag case on storage). The internal csv-key: and csv-source: tags are stripped from exports so round-trips stay clean.

Provenance & the csv_source schema field (--source)

The extension registers an optional csv_source schema item field (via the schema capability). When you import with --source <label>, the label is recorded on each created/updated item and is surfaced back in the csv_source export column. Note: as of pm 2026.5.31 the CLI does not expose a scalar setter for extension-registered fields, so the value is persisted as an internal csv-source:<label> tag (stripped from the normal tags export column). On hosts whose SDK lacks registerItemFields, schema registration degrades to a no-op without breaking any other behavior.


CSV parsing rules

  • Fields containing the delimiter, double-quotes, or newlines must be wrapped in double-quotes.
  • Embedded double-quotes inside a quoted field are escaped by doubling them: "".
  • Multiline field values (newlines inside quotes) are fully supported.
  • Both \n (LF) and \r\n (CRLF) line endings are accepted on import.

Building

npm install
npm run build   # runs tsc → dist/

TypeScript 5, ES2022 target, NodeNext module resolution, strict mode. Zero runtime dependencies.


Exporter & column selection (added)

pm csv export and the native pm csv-export export both accept --columns to pick and order columns:

pm csv export --columns id,title,status --output todos.csv
pm csv-export export --columns title,priority      # native export pipeline

Valid columns: id, title, type, status, priority, tags, deadline, body, parent, assignee, sprint, release, blocked_by, csv_source, created_at, updated_at.

License

MIT

Release Automation

This package is release-ready for GitHub, npm, and Bun-compatible installs. CI runs type checking, build, production dependency audit, package packing, Bun install verification, and pm-changelog validation. The daily release workflow publishes only when commits exist after the latest release tag and uses pm-changelog to generate CHANGELOG.md and GitHub release notes.