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

pi-redmine

v0.4.0

Published

Pi package that adds curated Redmine tools to the Pi coding agent via the Redmine REST API.

Readme

pi-redmine

A Pi package that adds curated Redmine tools to the Pi coding agent. It calls the Redmine REST API directly (no MCP server / Python process required).

Install

# from npm (Pi package gallery)
pi install npm:pi-redmine

# or from git
pi install git:github.com/meraks/pi-redmine

# try without installing
pi -e npm:pi-redmine
# or
pi -e git:github.com/meraks/pi-redmine

Source: https://github.com/meraks/pi-redmine

Configure

In Pi, run /redmine-config (interactive), or create ~/.pi/pi-redmine/config.json:

{
  "url": "https://redmine.example.com",
  "apiKey": "your_api_key"
}

Optional keys: username + password for basic auth (instead of apiKey).

A per-project override lives at ~/.pi/pi-redmine/projects/<key>/config.json (key = project basename + short hash of its absolute path). /redmine-config asks whether to save globally or for the current project only.

Precedence (highest first): .env in the project → project config file → global config file → environment variables:

export REDMINE_URL=https://redmine.example.com
export REDMINE_API_KEY=your_api_key          # preferred
# export REDMINE_USERNAME=you
# export REDMINE_PASSWORD=secret

A project's .env is the one source that a repository itself controls, so its REDMINE_URL is only honored when that same file also carries credentials (REDMINE_API_KEY, or REDMINE_USERNAME + REDMINE_PASSWORD). Without that rule, any repo you open could name a host and have your configured key sent to it.

TLS / self-signed Redmine

There is deliberately no "skip verification" switch: the only way to implement one is to disable certificate checks for the whole Node process, which would silently cover the LLM provider calls and every other extension too. To trust an internal or self-signed certificate, either install its CA or point Node at the PEM before starting Pi:

export NODE_EXTRA_CA_CERTS=/path/to/your-internal-ca.pem

Requests time out after 30s, accept cancellation, and never follow redirects (so the API key cannot be replayed to another host) — point REDMINE_URL at the final URL, not at a redirecting alias.

Tools

| Tool | Purpose | |------|---------| | redmine_list_projects | List visible projects | | redmine_get_project | Get a project (trackers + memberships) | | redmine_list_issues | Filter/list issues (standard + custom field filters) | | redmine_get_issue | Full issue detail (comments, relations, attachments) | | redmine_create_issue | Open a new issue (standard + custom fields) | | redmine_update_issue | Change fields / add a comment (standard + custom fields) | | redmine_list_time_entries | List logged time | | redmine_log_time | Log time against an issue/project | | redmine_get_wiki_page | Read a wiki page (title raw — spaces are fine, the tool URL-encodes it) | | redmine_update_wiki_page | Create/update a wiki page | | redmine_search | Site-wide search (issues defaults to true; pass issues: false to search only wiki pages/projects — at least one scope must be true) |

A /redmine command prints the current connection status; /redmine-config sets it interactively; /redmine-fields [project] discovers custom fields (see below).

Issue fields & filters

Standard fields accepted by redmine_create_issue / redmine_update_issue:

subject, description, tracker_id, priority_id, status_id, assigned_to_id, category_id, fixed_version_id, parent_issue_id, start_date, due_date, done_ratio, estimated_hours (create adds project_id).

Clearing a field must be explicit. Redmine represents "empty" as an empty string, which a typed field cannot express (and an accidentally empty value must not silently wipe a field), so pass the field names to clear:

redmine_update_issue(issue_id=123, clear=["assigned_to_id"])            # unassign
redmine_update_issue(issue_id=123, clear=["due_date", "start_date"])   # blank the dates

Clearable: assigned_to_id, category_id, fixed_version_id, parent_issue_id, due_date, start_date, description — anything else is rejected with the list of valid names. Sending "" to a field is ignored, not treated as a clear.

What Redmine does with an empty value (verified against a live instance; "required" means it answers 422):

| field | empty value | | |---|---|---| | assigned_to_id, category_id, fixed_version_id, parent_issue_id, due_date, start_date, description | clears the field | use clear | | subject, priority_id | 422 — required, cannot be empty | pass a real value | | tracker_id, status_id | accepted but silently ignored, nothing changes | pass a real id; redmine_get_project lists the trackers | | done_ratio | becomes 0 | its "empty" is 0, no clear needed | | a required custom field | 422 — required, cannot be empty | pass a real value | | a non-required custom field | cleared | goes through custom_fields: [{id, value: ""}], not clear |

"It succeeded but nothing changed": Redmine silently ignores fields that the project's tracker/workflow marks as not editable, and versions that are not shared with the project — the API still answers 201/204. If an update appears to have no effect (fixed_version_id and estimated_hours behave this way on some trackers), check that field's configuration in Redmine rather than assuming the tool failed.

Filtering with redmine_list_issues supports project_id, status_id, assigned_to_id, tracker_id, priority_id, category_id, fixed_version_id, parent_id, subject, sort, and custom-field filters via cf: [{id, value}]:

subject is a contains match: Redmine's own default operator for it is exact match, so the tool prefixes ~ unless you supply an operator yourself (e.g. =text for exact, !~text to exclude).

redmine_list_issues(project_id="my-project", cf=[{id:123, value:"..."}])

Custom-field ids come from /redmine-fields. Filtering uses each field's default operator (list = exact match, text = contains); != / empty / date-range filters need Redmine's advanced f[]/op[]/v[] syntax, which is not exposed here.

Custom fields are set via custom_fields: [{id, value}]. Redmine's custom-field definitions (format / tracker bindings) are admin-only via the API — a normal API key cannot list them. /redmine-fields works around this: it scans issues (read-only) and caches each field's id, name, and up to 5 sample values into ~/.pi/pi-redmine/config.json, which is usually enough to fill values on create/update:

/redmine-fields               # scan the newest 100 issues site-wide
/redmine-fields my-project  # scan issues in one project

redmine-fields only reads Redmine (a single GET /issues.json) and writes the local config cache — it never modifies Redmine data.

Develop

The extension is a single TypeScript module: extensions/redmine.ts. Pi loads .ts extensions directly, so no build step is needed. To try a local copy:

pi -e ./extensions/redmine.ts

npm test runs test/selfcheck.mjs — plain node:assert, no framework, no network: it points the tools at a local mock Redmine and checks config precedence, the .env rule, URL encoding, the search scope flags, the subject operator, and cancellation.

Then ask Pi something like "list my open Redmine issues" or "show issue 123".

Notes

  • Output is truncated to Pi's safe limits (~50KB / 2000 lines); refine queries if you hit the cap.
  • This package is intentionally a curated subset of Redmine. For the full surface, run redmine-mcp-server and bridge it from a separate extension.