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

@kaynooo/forgejo-tools

v0.9.0

Published

ft: Forgejo CI runs, logs, releases and issue checklists from the terminal, through tea.

Readme

ft

Forgejo tools for the terminal: CI runs and their failures, releases, issue checklists and issue claims between Claude Code sessions.

bun install -g @kaynooo/forgejo-tools

Needs tea logged in to the Forgejo instance (tea login add). Every call goes through tea api, so ft has no token of its own: tea owns the login and finds the repository from origin. Run ft from the repository, or pass --repo owner/name to the commands that take it.

Commands

| Command | What it does | | --- | --- | | ft runs | recent runs with workflow, ref, duration and age (-n, --sha, -w test.yml, --json) | | ft ci [ref] | waits for the push runs covering a commit on the default branch and prints each failed test's output | | ft watch | waits for the runs in progress, or --after <id> those newer than a run | | ft logs <run> | what the failed jobs of a run say went wrong, -j <name or id> picks a job, --full for whole logs | | ft release <level> | waits for the runs on HEAD, pushing it first when origin lacks it, then bun pm version, one atomic push of branch and tag, and waits for the runs and the registry; -p <folder> releases one workspace package as <folder>-v<version> | | ft board | open issues: available, taken by a live session, or claimed with no live session here, each claim with its boxes left and a stale one with its latest note (-q <regex> on titles, --state available\|taken\|away, -L, -m <milestone>, --json) | | ft digest | one screen for a session starting cold: the issues this session holds with their boxes left, claims no live session answers to, red or running CI on the default branch, unpushed commits, dirty files and TODO comments naming a closed issue (needs todo-scan on the PATH; empty sections left out, --json) | | ft take <n>... / ft drop <n>... | claims or gives back issues for the calling Claude Code session, --lane as lane-<s>-<n> | | ft issue <n>... | an issue's state, claim and description, its checklist boxes numbered in place (-c comments, -t only the boxes left, -b only the raw description to edit, --json) | | ft new -t <title> | creates an issue and prints its number and url; -F <file> (-F - for stdin) is the description, -L a,b the labels and -m <milestone> the milestone, refused before anything is created when the repository lacks one | | ft edit <n> | replaces the title (-t) and/or the description (-F <file>, -F - for stdin); --append adds the -F text after the description instead, --add-box <text> (repeatable) an unticked box after the last one, -m <milestone> moves it to a milestone and -m '' takes it out | | ft tick <n> <box>... | ticks boxes by number or text, --undo unticks, -m <text> or -F <file> comments too; --closed ticks instead every - [ ] #<n> line of a release plan whose issue is closed | | ft comment <n> [text] | comments on an issue, from -F <file> or stdin when no text is given, so a heredoc needs no escaping | | ft fixed <n> [sha]... | comments Fixed in <a>, <b> and <c>: <subject> and closes; with no sha it takes the commits on origin's default branch naming #<n> and says which; refuses while boxes are left unless --tick ticks them first; then ticks its - [ ] #<n> line in every open issue listing it, and names those | | ft close <n>... [-m reason] | closes issues no commit fixed (a duplicate, one dropped), posting the reason first; ft reopen reopens them the same way | | ft label <n> [+]a -b | adds the labels named bare or with +, removes those named with -, refusing one the repository lacks, and prints the issue's labels | | ft plan add <plan> <n>... / ft plan carry <from> <to> | adds - [ ] #<n> <title> lines to a release plan's checklist, or copies one plan's unticked #<n> lines into the next, both under --section "Bugs:" (created when missing) and skipping issues already listed | | ft milestones | lists the milestones (--state open\|closed\|all, --json) with the issues open and closed in each, the progress and the due date | | ft milestone <title\|id> | shows a milestone's open issues as ft board does (available, taken, claimed by one gone); ft milestone new <title> [-d text] [--due YYYY-MM-DD] creates one through the API, sending no due_on unless --due is given, never a zero date; ft milestone close <m> refuses while issues are open in it, naming them, unless --force | | ft remote [--fix] | switches an origin using an ssh alias (forgejo:owner/repo) to git@<host>:owner/repo.git, which tea matches; the host comes from --host or remoteHost in ~/.config/ft/config.json ({"remoteHost": "git.example.com"}), and with neither it checks nothing |

ft <command> --help lists each command's options. Waiting commands show one line per run with how long it has been waiting or running (● running for 1m 12s), redrawn in place on a terminal and left at its last status with the time it took (✓ success in 3m 2s), and a line per status change in a log or a pipe; they exit 0 when the runs pass, 1 when one fails, 2 on a timeout, a stalled queue or bad usage; the other commands exit 0 when done, 1 when Forgejo refuses or a check fails, 2 on a usage error.

CI

ft ci follows every workflow a push starts. A run that was cancelled leaves the commit to the next push's runs, and so does one whose --job was skipped, as a workflow skipping its tests when a newer push is queued does; a tagged release commit whose tests were skipped passes, its tag's workflow testing it.

ft ci --workflow test.yml --job test   # kayjs: the test job is skipped when a newer push supersedes it

With an admin login, a queued run is checked against the runners: a job whose runs-on labels no online runner carries fails at once, and a queue no runner works on for 3 minutes fails with the reason.

Releases

ft release patch|minor|major releases from the default branch. It first pushes any commits origin lacks and waits for their runs, so failing tests stop it before a tag exists that would never publish; a push starting no run within 3 minutes lets it go on. A refused push drops the bump commit and tag. A repo with its own bump script runs it, then ft release --tagged. In a monorepo, ft release patch -p ft bumps packages/ft alone, refreshes bun.lock, and commits and tags it ft-v<version>, so each package releases on its own. --dry-run makes the same checks, then prints the bump (1.0.0 -> 1.1.0), the tag, whether HEAD is pushed first, the pushes and the runs and registry it would wait for, and changes nothing. Once released, an open milestone titled like the version (1.2.0, v1.2.0 or the tag) has its closed issues listed and is closed; a failure there only warns.

Issue claims

Sessions claim an issue with a Taken by session <name>. comment and give it back with Released by session <name>.. ft board checks each claim against the Claude Code sessions running on this machine (~/.claude/sessions and ~/.claude-accounts/*/sessions, pid and start time). A lane's claim (lane-<n>-<issue>) is held while the session named *-<n> runs: ft take 12 13 --lane from session kayjs-60 claims them as lane-60-12 and lane-60-13, and a session can pass its own claim to one of its lanes. A claim no session here answers to may come from another machine, so ft take only takes it over with --take-stale.