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

@ngdtrung/video-tools

v0.0.1

Published

Agent skills for educational video production, plus a Pi extension that lets agents talk to you on Telegram (approvals, questions, and direct instructions).

Readme

video-tools

Agent skills for educational video production, plus a Pi extension that lets agents talk to you on Telegram (approvals, questions, and direct instructions).

extensions/pi/telegram-approval.ts        Pi extension: approvals + ask_user + agent mailbox
                                          (also the inbox daemon: run with --telegram-inboxd)
extensions/pi/telegram-approval.test.ts
extensions/pi/telegram-inboxd.test.ts
skills/                                   Agent skills (SKILL.md format)

Telegram extension

One bot, one chat, many agents. Agents ask for approval or free-form answers; you can also send instructions to a running agent at any time.

Setup

  1. Create a bot via @BotFather → /newbot → copy the token.

  2. Get your chat id: message your bot, then open https://api.telegram.org/bot<TOKEN>/getUpdates and read chat.id.

  3. Export env vars (put in your shell profile):

    export TELEGRAM_BOT_TOKEN="123456:ABC..."
    export TELEGRAM_CHAT_ID="123456789"
  4. Install the extension — two options:

    pi install (recommended) — the repo is a pi package (pi manifest in package.json declares the extension + all skills):

    pi install npm:@ngdtrung/video-tools                  # from npm (recommended)
    pi install git:github.com/ductrung-nguyen/video-tools # or straight from GitHub
    pi install /path/to/video-tools                       # or a local clone

    Add -l to install into project settings (.pi/settings.json) instead of user settings. Manage with pi list / pi remove / pi config.

    Manual symlink — if you want live repo edits:

    git clone [email protected]:ductrung-nguyen/video-tools.git
    cd video-tools
    mkdir -p ~/.pi/agent/extensions
    ln -sfn "$(pwd)/extensions/pi/telegram-approval.ts" \
           ~/.pi/agent/extensions/telegram-approval.ts

    One file is all you need: the extension spawns itself as the inbox daemon (--telegram-inboxd flag), so there is no second file to install.

  5. Start pi — a 🟢 [agent:name] online card appears in your chat.

Talking to agents

| You send | What happens | |---|---| | Reply to an agent's card | Instruction injected into that agent | | @name do X | Instruction to agent name | | !do X (or @name !do X) | Interrupt/steer the current turn | | /msg @name text | Same as @name (autocomplete-friendly) | | /steer @name text | Same as ! prefix | | /agents or /start | Live roster (also on the persistent keyboard) | | 💬 Message / ⚡ Interrupt buttons on a card | Bot prompts you; reply to the prompt | | #XXXXXX text | Answer a specific pending request by tag | | Bare text | Only routed when exactly one agent awaits your input |

Approval requests (request_approval tool) show ✅ Approve / ❌ Reject / 💬 Other buttons; Reject/Other then ask for a reason — reply to that prompt. ask_user posts a question with optional quick-reply buttons; free text works too (reply, #TAG, or bare text when unambiguous).

The inbox daemon

telegram-inboxd keeps the Telegram inbox warm and answers /agents even when no agent is running. It is managed automatically:

  • session_start spawns it if absent (pidfile-guarded, single instance)
  • session_shutdown stops it when the last agent session ends

| Env var | Effect | |---|---| | TELEGRAM_INBOXD=keep | Never stop it — always-on listener (recommended) | | TELEGRAM_INBOXD=off | Never auto-spawn | | TELEGRAM_AGENT_NAME=… | Stable agent name instead of name-xxxx | | TELEGRAM_STATE_DIR=… | Override inbox location (default $TMPDIR/pi-telegram-approval) |

Standalone run: npm run inboxd (or under systemd --user / tmux / nohup).

How routing works (why it's safe with many agents)

Telegram getUpdates is single-consumer — polling with an offset deletes updates server-side. All agent processes therefore share one on-disk inbox ($TMPDIR/pi-telegram-approval/inbox-<bot>-<chat>.json): only the process holding a mkdir lock polls Telegram and stores every update; each agent then claims only entries tagged with its request id (#XXXXXX) or agent name (@name, [agent:name]). Ambiguous bare text is never stolen — it's marked bareRejected and must be re-sent as a reply or with a tag.

Tests

npm test    # 8 tests: approvals, anti-steal routing, mailbox, ask_user, daemon

Skills

Four skills in skills/, each a standard SKILL.md bundle:

| Skill | Purpose | Extra requirements | |---|---|---| | teaching-video-studio | End-to-end educational video production (research → script → HyperFrames → voice → QA) | HyperFrames skills for rendering | | language-learning-video-studio | Longitudinal language-learning video series with course memory | Same | | video-catalog | SQLite catalog of produced videos (dedup, backlinks, publish queue) | sqlite3 with FTS5 | | minimax-tts | MiniMax Speech 2.8 text-to-speech CLI | pip install requests, MINIMAX_API_KEY |

Skills are discovered from ~/.agents/skills/ (omp) and ~/.pi/agent/skills/ (pi). pi install already registers all skills via the package manifest; for omp — or pi without the package — copy the skill into ~/.agents/skills/, then symlink into pi:

REPO_DIR=$(pwd)   # run inside your video-tools clone

# canonical copy for omp
cp -r "$REPO_DIR/skills/<name>" ~/.agents/skills/

# symlink for pi
ln -sfn ~/.agents/skills/<name> ~/.pi/agent/skills/<name>

Or symlink the repo directly if you want live edits:

ln -sfn "$REPO_DIR/skills/<name>" ~/.agents/skills/<name>
ln -sfn ~/.agents/skills/<name> ~/.pi/agent/skills/<name>

Repeat per skill. The agent picks them up on next session start.