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

toro-cli

v0.1.0

Published

Le poste de pilotage de votre app, pour votre IA. Tickets, roadmap, features et journal — sur votre machine.

Readme

Toro

Le poste de pilotage des apps développées avec une IA : tickets, roadmap, features, composants et journal. L'interface les montre, l'API les écrit — et c'est la même porte pour les deux, avec la même clé.

Le problème qu'il traite : quand une IA développe, on voit le résultat mais jamais l'état. Ce qui reste, ce qui bloque, pourquoi telle chose est comme ça, et ce qu'elle a fait pendant la dernière heure.

Stack

| | | |---|---| | Front | React 19 + TypeScript + Vite 7 + Tailwind 4 | | API | Worker Cloudflare, TypeScript, aucun framework | | Base | D1 (SQLite) — locale en développement, distante en production | | Hébergement | Cloudflare Workers avec assets statiques |

Un seul processus sert les deux : @cloudflare/vite-plugin fait tourner le Worker dans le serveur de développement Vite, avec une D1 locale. Il n'y a donc rien à lancer à côté, et le code exécuté en local est celui qui partira.

Lancer en local

export PATH="$HOME/.local/bin:$PATH"
pnpm install
pnpm run db:local     # applique les migrations sur la D1 locale
pnpm dev              # http://localhost:5680

Au premier lancement, l'écran demande de créer la première clé d'API. Elle s'affiche une seule fois — l'API n'en garde que le SHA-256. C'est la même clé pour l'interface et pour l'IA.

pnpm run check type-vérifie le front et le Worker (tsc -b, trois projets).

Importer le coffre Obsidian

Le script lit ~/Documents/App creator/Projets/ et les dépôts de ~/Documents/Apps Claude/, puis écrit par l'API — il n'y a pas de chemin d'accès privilégié à la base.

TORO_TOKEN=toro_… node scripts/import-vault.mjs --projet Vibecoded
TORO_TOKEN=toro_… node scripts/import-vault.mjs --tout

Il faut désigner ce qu'on importe — sans --projet ni --tout, le script refuse et liste les projets du coffre. Un import est une écriture : le défaut « tout le coffre » avait rempli Toro de quatre projets que personne n'avait demandés.

Il est idempotent : relancé, il met à jour au lieu de dupliquer. Ce qu'il reprend :

| Source | Devient | |---|---| | _Index.md § « Le projet en une ligne » | le projet, son résumé, son URL de prod | | Gestion de projet.md | les tickets, avec leur identifiant d'origine (SOL-11) | | Features/<F>/<F>.md | la feature : statut, pourquoi, décisions, ce qu'on n'a pas fait | | CHANGELOG.md | les versions publiées | | <dépôt>/src/** | les composants réellement exportés, avec leur signature |

Le préfixe des tickets vient du backlog, jamais du nom : le coffre écrit FRG pour Forge, et des commits citent FRG-3.

L'API

Base : /api/v1. Tout demande Authorization: Bearer <clé>, sauf /health, /vocab et /setup. Les réponses sont en français, comme le vocabulaire.

Les deux routes qui portent l'essentiel :

# ce qu'on a le droit d'écrire — statuts, types, attentes, et leur sens
curl -s http://localhost:5680/api/v1/vocab

# le briefing complet d'un projet, en un appel
curl -s -H "Authorization: Bearer $TORO_TOKEN" \
  http://localhost:5680/api/v1/projects/solde/context

Le briefing rend l'état, les tickets dans l'ordre de priorité, le prochain non bloqué, ce qui attend Benjamin, les features avec leur statut, les dernières versions, le journal, et le vocabulaire. C'est ce qu'une IA lit en début de session au lieu de deviner.

Le reste : projects, tickets, features, components, milestones, releases, events, keys — en GET/POST/PATCH/DELETE. Plus deux routes particulières :

  • POST /tickets/:id/releasela charnière : le ticket quitte le backlog, son texte devient l'entrée de version, la feature liée passe en prod avec le numéro qui l'a livrée. Il n'y a jamais deux copies de « ce qui a été fait ».
  • GET /projects/:id/export.md — le backlog au format du coffre, tags Obsidian et [[liens]] compris. Le pont de retour vers les notes.

Le vocabulaire est contraint

Statuts de ticket à-faire · en-cours · en-test · à-releaser · released · abandonné, types tâche · bug · idée · dette, attentes benjamin · décision · plus-tard, statuts de feature en cours · en local · en test · à releaser · en prod · abandonnée.

Ils sont repris mot pour mot du coffre, et l'API refuse le reste — en CHECK dans la migration et en validation dans le Worker. C'est ce qui empêche une IA d'inventer un septième statut au fil des sessions.

Le journal

Chaque écriture par l'API pose un événement, avec le nom de la clé comme auteur. Une clé par outil, donc : « Claude Code », « Cursor »… C'est ce qui permet de lire le chemin et pas seulement le résultat.

Un scan de composants ne journalise pas ses centaines de lignes : le scanner pose un seul événement de synthèse.

Variables d'environnement

Aucune côté application. Les clés vivent en base, hachées. Le script d'import lit TORO_TOKEN et, éventuellement, TORO_URL (par défaut http://localhost:5680).

Déployer

Rien n'est déployé à ce jour. Avant le premier déploiement :

npx wrangler d1 create toro          # recopier database_id dans wrangler.jsonc
npx wrangler d1 migrations apply toro --remote
pnpm run deploy

L'API est ouverte en CORS (*) : c'est voulu, une IA qui appelle depuis ailleurs doit pouvoir le faire. La clé est le seul contrôle d'accès — il n'y a pas de comptes, et une clé donne tout. À savoir avant de mettre l'instance sur Internet.