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

@sinoia/edifice-tools

v0.3.0

Published

CLI pour piloter Édifice (intégration & gestion) — LLM-friendly, calqué sur @sinoia/hubdoc-tools. CLI scopée de l'écosystème Synapse.

Readme

@sinoia/edifice-tools (edi)

CLI pour piloter Édifice — d'abord pour l'intégration (monter des jeux de test, dérouler les flux bannette / e-invoicing / GED), puis pour des actions de gestion.

Calqué sur @sinoia/hubdoc-tools (le CLI domaine de la GED), pas sur ch (l'ops/infra CorexHub). Conçu pour être LLM-friendly (--json, erreurs sur stderr, whoami) : c'est une CLI scopée de l'écosystème Synapse — montée dans les sandboxes d'agents Claude Code, qui lisent le token délégué via EDIFICE_API_TOKEN.

Spécification : edifice#465.

Installation (dev)

npm install
npm run build          # → dist/cli.js (bundle esbuild auto-suffisant)
node dist/cli.js --help
# ou en dev, sans build :
npm run dev -- --help

Authentification

Édifice n'expose pas de device-flow OIDC (authorization_code+PKCE seulement) ; le CLI s'authentifie via POST /api/Auth/LogIn → JWT (7 jours).

# Interactif (humain) : demande base URL, login, mot de passe masqué
edi login

# Scripté
edi login --api-url https://spirit-rec.edifice… --login user --password ****

# Agent / CI : fournir un token déjà minté
export EDIFICE_API_TOKEN=eyJ…
export EDIFICE_API_URL=https://…
edi whoami --json

Résolution du token : EDIFICE_API_TOKEN (env) → config (~/.edifice-config.json, 0600). Le keychain s'insérera entre les deux ultérieurement.

Commandes

| Commande | Rôle | |----------|------| | edi login | Auth interactive/scriptée → stocke le JWT | | edi token set <jwt> | Enregistre un JWT déjà obtenu | | edi whoami | Décode le JWT (Id/Email/Roles/exp), source du token, vérif serveur | | edi banks list | Démo API v2 typée (GET /api/v2/banks) — patron des commandes v2 |

Commercialisation (lecture seule) — agent « Assistant commercial »

Bloc taillé pour l'agent IA de reporting commercial Spirit (rythme de vente, alertes sur les dates clés, dialogue pricing). Uniquement des GET → utilisable sous --read-only.

| Commande | Endpoint | Ce qu'on y lit | |----------|----------|----------------| | edi projects list --launched-only [--status-id --parent-id --all] | v2 /api/v2/projects | programmes + dateLancementCommercialReelle ; --launched-only = lancés commercialement | | edi projects show <id> | v2 /api/v2/projects/{id} | fiche programme | | edi projects schedule <id> | /api/ProvisionalSchedules/GetAsyncByProjectId/{id} | dates clés projetées en dateInitiale / dateRecalee / dateReelle | | edi projects price-grids <id> [--lots] [--grid-id] | v2 /api/v2/projects/{id}/price-grids | grilles ; --lots → une ligne par lot (prix, surface, typologie, saleStatusTag) | | edi projects commercial <id> [--plan-fi-id] | /api/EtatCommercialisation/ventes/{id} | CA en stock / réservé / acté + % | | edi projects margin <id> | /api/FinancialPlans/GetAllByProject/{id} | plans financiers + marge nette (netMargin, /CA) | | edi projects contacts <id> | /api/ContactProjectPeoples/GetAsyncByProjectId/{id} | intervenants → destinataire de la fiche action | | edi projects forecast <id> [--prevision-id] [--list-previsions] | /api/Tresorerie/Projet/{id} + /api/Tresorerie/Ventes/{idPrevision} | écoulement prévu vs réel (ecoulement, lotsActes, reel) | | edi dashboard vision-globale [--all] [--position] | /api/TableauDeBord/VisionGlobaleProjet/AllerALaPosition/{position} | vue multi-programmes : lots, avancement, acté/réservé/stock, CA, marge nette HT, prix de revient, dates clés — la source la plus dense pour le rapport hebdo | | edi dashboard vision-globale-total | …/VisionGlobaleProjet/Total | taille du périmètre visible | | edi sales list --project-id --status-id [--all] | v2 /api/v2/sales | ventes du programme (reservationDate, saleDate) → rythme réalisé | | edi sales lots --sale-id <id> | v2 /api/v2/sales/{id}/lots | lots d'une vente | | edi sales statuses | /api/SaleStatus | référentiel En stock / Réservé / Acté / Option / Désisté… |

Toutes ces commandes acceptent --raw (charge utile serveur intacte, sans projection) et --json.

Points d'attention (côté API, pas côté CLI) :

  • dashboard vision-globale est borné par le serveur au périmètre visible du porteur du token, aux projets racines (parentId = null) et aux statuts En cours / Prospection. Le paramètre recherche de l'endpoint est appliqué après la pagination côté serveur : il n'est volontairement pas exposé.
  • projects forecast suppose qu'une prévision de trésorerie existe et soit tenue à jour sur le programme — c'est aujourd'hui la seule source du rythme de vente prévisionnel.

Appels de fonds en masse (« paquet ADF »)

Le cycle Édifice de l'appel de fonds lié à l'avancement du chantier. Les quatre dernières commandes écrivent — elles sont refusées sous --read-only.

| Commande | Endpoint | Rôle | |----------|----------|------| | edi adf planning | /api/AppelDeFonds/AGrouper | échéances mûres par programme × catalogue : stade, datePrevisionnelle, appelsALancer, et l'idParametreEcheance à regrouper | | edi adf packets | /PaquetADFALancer | paquets prêts à lancer | | edi adf packet <id> [--buyers] | /DetailDuPaquetALancer/{id} | détail ; --buyersune ligne par acquéreur (acquereur, idVente, pourcentage, montantTTC) | | edi adf history [--packet-id] | /Historique, /HistoriqueParPaquet/{id} | ce qui est réellement parti : appels réussis / manquants | | edi adf unpaid | /Impaye | appels de fonds impayés | | edi adf create --libelle --echeances | POST /api/AppelDeFonds | crée un paquet (statut « En attente ») | | edi adf update <id> --echeances | PATCH /api/AppelDeFonds/{id} | recompose un paquet | | edi adf launch <id> | POST /Lancer/{id} | lancement en masse, irréversible | | edi adf cancel <id> | PATCH /Annule/{id} | annule un paquet non lancé |

Contraintes serveur sur create : --libelle obligatoire (60 caractères max), --echeances non vide, et toutes les échéances doivent appartenir au même projet. launch exige la permission Corex AppelDeFond et rend { cptOK, cptKo, warnings } : un 200 ne suffit pas à conclure que tout est parti — c'est cptKo et warnings qu'il faut lire.

Mode lecture seule

--read-only (ou EDIFICE_READ_ONLY=1) refuse localement, avant l'envoi, toute requête qui n'est pas GET/HEAD — axios legacy, client v2 typé et multipart compris :

edi --read-only --json dashboard vision-globale --all      # ok
edi --read-only sales create --data @vente.json            # ✗ read_only, exit 1

C'est un garde-fou client : il rend l'écriture impossible par accident (ou par dérive d'un LLM) sans changer de token. Il ne remplace pas un token à scope restreint côté Édifice.

Intégration / seeding (T2, socle — ordre DevDataSeeder)

| Commande | Endpoint | |----------|----------| | edi orgs list / orgs create | v2 typé (/api/v2/organizational-units) — --name/--parent-id/--data | | edi roles list | legacy GET /api/Role/AllEnabled (roleIds) | | edi users list / users create | legacy /api/User — create : --data (UserToAdd), appelant Administrateur | | edi projects list / projects create | list = v2 ; create = legacy POST /api/Projects (--data) | | edi providers list / providers create | legacy /api/Providers (list : --search <nom>) | | edi orders create / list / validate / sign | engagements, legacy /api/Orders (create --project-id --data, sign --date) | | edi amendments create | avenant, legacy POST /api/Amendments/{engagementId} (--data) | | edi providers rib | RIB fournisseur — multipart (--data + --file justificatif) | | edi ged upload\|upload-order\|upload-reservation | dépôt GED — multipart (--file + scope) | | edi buyers list\|create | acquéreurs — v2 typé | | edi sales list\|create\|funds-call | ventes + appel de fonds — v2 typé |

Bannette (intake e-invoice + workflow)

| Commande | Rôle | |----------|------| | edi bannette list / show <id> / workflow <id> | consultation | | edi bannette invoice create --data [--file] | multipart — crée une facture et l'entre en bannette | | edi bannette invoice update <id> --data [--file] | multipart | | edi bannette save-presaisie\|validate-presaisie\|discard-presaisie <id> --data | pré-saisie | | edi bannette transition <id> <action> [--data] | workflow générique (validate-n1/n2, approve, refuse, suspend, resume, dispute, reassign, confirm-not-duplicate) | | edi bannette bap-token <id> / emit-bap <id> --data | émission du BAP | | edi bannette change-engagement <id> --type --data | rattachement |

Brique multipart (src/util/multipart.ts) : aplatit le JSON en champs form ASP.NET (items[0].name=…) + fichier, via fetch. Réutilisable pour le RIB fournisseur et l'upload GED (encore à câbler).

Seed — scénarios end-to-end

# Monte toute la chaîne : projet → tiers → engagement signé → facture bannette → BAP
edi seed bannette-vefa --data @scenario.json          # exécute
edi seed bannette-vefa --dry-run --json               # imprime le plan (10 étapes, ids threadés)
edi seed bannette-vefa --project-id 12 --data @…      # réutilise un projet existant

Data-driven : --data fournit le corps par étape ({ project, provider, order, signature, invoice, transitions, bap }) ; l'orchestrateur enchaîne + injecte les ids (projet→engagement→facture) + déroule le workflow (validate-n1→n2→approve→BAP). En cas d'échec, renvoie created (partiel).

Chaque create accepte --data '<json>' ou --data @fichier.json (corps complet, robuste pour le seeding) ; les retours sont « flatten-at-root » (.id en racine).

Global : --json (sortie machine), --read-only (refuse toute écriture), -v/--version.

Client API (T1)

  • v2 (typé) : ctx.v2 = client openapi-fetch généré depuis ../edifice-mono/api/specifications/api-v2-openapi.yaml (types src/api/v2.ts, commité). Régénérer : npm run generate:api (pure Node, pas de Java).
  • legacy (escape hatch) : ctx.axios pour les endpoints hors v2 (bannette, orders, GED, e-invoice…).

Les deux portent le Bearer + la base URL résolus par buildApiContext().

Feuille de route

  • T0 (ce squelette) : auth + whoami.
  • T1 : client typé généré depuis specifications/api-v2-openapi.yaml (+ /swagger legacy).
  • T2 : intégration/seeding (ordre DevDataSeeder) — orgs/users/projects/orders/bannette/…
  • T3 : skills Claude Code embarqués (edifice-auth, edifice-seed) + insertion Synapse.
  • T4 : gestion (SEPA, mise en paiement, déversement compta).