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

@infona-ai/cli

v0.1.55

Published

Infona SDK and CLI — context graph platform for structured data

Readme

@infona-ai/cli

Node.js SDK and CLI for Infona — turn raw data into a queryable context graph (a knowledge graph you query in natural language).

Package: @infona-ai/cli. Primary binary: infona. Compatibility alias: onta (same entrypoint). Env vars: INFONA_* only (no ONTA_* fallback).

Quickstart

npx -y -p @infona-ai/cli infona
# or: npm install -g @infona-ai/cli && infona

First run with no config opens an interactive connect wizard (not a silent cloud login and not a silent force-local):

  Connect Infona
    1) Local open-access  (http://localhost:8000, tenant default)
    2) Browser sign-in    (hosted Infona cloud)
    3) API key            (paste key + optional URL)
  • Local probes the API, writes ~/.infona/config.json, and never opens a browser for open-access.
  • Browser is for hosted cloud only.
  • API key is for CI/headless or self-hosted with auth.

Re-run any time: infona init (confirms before overwriting saved credentials). Non-interactive local: infona init --local (probes localhost:8000, writes open-access config, no readline — safe for scripts). Re-writing the same local open-access config is idempotent; overwriting a different saved connection (e.g. cloud API key) requires a TTY confirm, or --force when non-interactive: infona init --local --force.

Then the interactive shell:

  /ingest <file>      Ingest a CSV/JSON/text file
  /ask <question>     Ask in natural language
  /kg list|switch|create|delete <name>
  /types [query]      Types in the active KG, with entity counts
  /type <name>        Drill into one type — attributes & relationships
  /enrich <Type> <attrs...>   Plan + run an enrichment job (interactive)
  /enrich watch <job_id>      Live progress for a running job
  /enrich jobs                List recent enrichment jobs
  /enrich review <job_id>     Walk through conflicts and accept/reject
  /status             Graph stats
  /login              Re-authenticate
  /quit

Bare lines (no leading /) auto-route to /ask. Full walkthrough at infona.ai/docs/quickstart.

Self-hosted / OSS repo mode

From the infona-oss checkout, after Neo4j + the API are up:

./scripts/oss_setup.sh     # health probe → write local config → best-effort CLI link
infona                     # bare; uses ~/.infona/config.json (no --local needed)

One-off flags (do not rewrite config):

infona --local                          # http://localhost:8000, tenant default
infona --no-login                       # assume open-access at INFONA_API_URL
INFONA_API_URL=http://my-host:8000 infona

Precedence: flags (one-off) > env (INFONA_API_URL / INFONA_API_KEY) > ~/.infona/config.json > connect wizard when empty.

When self-hosted, the prompt shows the host suffix: infona@localhost:8000 (kg) ▸.

Auto-enrichment

Fill and verify attributes on entities of a given type by looking them up in external sources, with a human review step before any write:

> /enrich LineItem brand manufacturer
Plan: enrich LineItem.brand, .manufacturer · tier: lite · policy: stage
Job queued: enr_xxxxxxxx · 12,450 entities
[████████████████████] filled 6,200 · verified 1,400 · conflicts 320
Status: review · 320 conflicts pending. Run /enrich review enr_xxxxxxxx

Use /enrich watch <job_id> for live progress, /enrich jobs to list recent jobs, and /enrich review <job_id> to walk through conflicts and accept/reject each one. The lite tier uses Wikidata only (free, no API key).

Install

npm install @infona-ai/cli        # or: npm install -g @infona-ai/cli

Requires Node 20+. The global install exposes the infona command (and the onta compatibility alias).

Browsing what got ingested

After ingest, look around before asking questions:

infona (mentors) [37,715] ▸ /types
  Type           Entities
  Mentor              988
  Skill               412
  Industry             38

infona (mentors) [37,715] ▸ /type Mentor
  Mentor  1,000 entities

  Attributes (6)
    .name           string      988  ( 99%)
    .level          string      714  ( 71%)
    ...

  Relationships (6)
    .title         → JobTitle    988  ( 99%) (+775 string)
    .skills        → Skill       987  ( 99%)
    ...

/types <query> filters by substring; /type <name> accepts case-insensitive prefix. Auto-attached system metadata (rdfs:label, ingested_at, source) is hidden by default — pass --system to see it. The (+775 string) annotation appears when the resolver produced both a literal value and a typed-entity link for the same column.

SDK

import { Client, InfonaError } from "@infona-ai/cli";

const client = new Client({ apiKey: process.env.INFONA_API_KEY });

await client.ingest("sales.csv", { kg: "sales" });
const result = await client.ask("What's the average deal size by region?", { kg: "sales" });
console.log(result.answer);

Constructor

new Client({
  apiKey?: string,    // env: INFONA_API_KEY
  baseUrl?: string,   // env: INFONA_API_URL (default: https://api.infona.ai)
  tenant?: string,    // env: INFONA_TENANT (default: demo-tenant)
})

Methods

  • ingest(pathOrText, { kg?, contentType? }) — auto-detects CSV by extension and uses the two-step schema/rows flow; otherwise sends raw content.
  • ask(question, { kg? }) — returns { answer, sparql?, ... }.
  • listKgs(), createKg(name, description?), deleteKg(name) — context-graph CRUD.
  • ontologyTypes() — list every type in the tenant ontology with attributes and parents.
  • ontologyResolve(ask, { knowledge_graph? }) — resolve a fuzzy natural-language ontology-evolution ask (no exact type/attribute/relationship names needed) against the current schema. Returns { applied, proposals, summary }; high-confidence changes land automatically, ambiguous/new-type ones come back as proposals.
  • ontologyApply(proposal) — confirm and commit a single ResolvedChange from ontologyResolve's proposals. Pass the object through unchanged; returns { applied, operations, summary }.
  • typeCounts(kg)[{ name, entity_count }] for the given KG, sorted desc. Powers /types.
  • typeUsage(kg, name, { includeSystem? }) — full breakdown for one type: attributes (with usage counts), relationships, and 3 sample entities. Powers /type. System predicates filtered by default.
  • exploreRecords(kg, type, { limit?, cursor? }) — one keyset-paginated page of entity instances ({ columns, rows, total, next_cursor }).
  • exploreTypeEdges(kg) — undirected type→type edges for an overview graph ([{ source, target, weight }]).
  • normalizeSuggest(kg, type), normalizeRules({ kg?, status? }), normalizeConfirmRule(id), normalizeRejectRule(id), normalizeApplyRule(id) — inferred-normalization rule lifecycle.
  • ontologyRecommend(body?) — recommend ontology relationships/changes for a KG.

All errors throw InfonaError (alias: InfonaError).

Raw / passthrough API (client.raw.*)

Every method above throws on a non-2xx status and some reshape the payload (e.g. listKgs() unwraps { kgs: [] }). When you instead want the backend Response verbatim — to forward it 1:1 (e.g. from a web proxy route) or to branch on status without a try/catch — use the raw namespace. Each raw method maps to one canonical operation with the path encoded inside the SDK, so callers pass no path string:

const client = new Client({ apiKey, tenant });

// Forward the backend response unchanged from a proxy:
const res = await client.raw.enrichJobs();          // GET …/enrich/jobs
return new Response(res.body, { status: res.status, headers: res.headers });

// A non-2xx is a Response, not a throw — and the body is never reshaped:
const r = await client.raw.enrichJob("missing");
if (r.status === 404) { /* … */ }

client.raw covers agent, ask, ingest (+ csv schema/rows), enrich jobs (create/list/get/conflicts/apply/cancel), ontology (types/resolve/recommend/apply), kgs (list/create/delete), explore (summary/records/type-edges/type-counts/search), search + grep (semantic instance search / index-free literal scan of one KG), normalize (suggest/rules GET+POST/confirm/reject/apply) and tenants (list/create/delete). Each returns Promise<Response> and only ever rejects on a network error or timeout (i.e. when there is no HTTP response to return).

One-shot CLI

For scripts and CI — every command is a single HTTP round-trip (use the infona bin, or npx -y -p @infona-ai/cli infona …):

# List / create / delete context graphs
infona kg list
infona kg create my-data --description "demo"
infona kg delete my-data

# Ingest data
infona ingest data.csv --kg my-data
infona ingest --text "Alice works at Acme" --kg my-data

# Ask questions
infona ask "How many companies?" --kg my-data
infona ask "Top 5 deals" --kg my-data --debug   # Cypher + latency breakdown

# Ontology + clear
infona ontology types
infona clear --kg my-data --yes

Environment

Prefer INFONA_* for new configs:

  • INFONA_API_KEY — required for headless / CI use; infona init (API key path) or infona login writes one to ~/.infona/config.json.
  • INFONA_API_URL — default https://api.infona.ai. OSS setup / local wizard sets http://localhost:8000.
  • INFONA_TENANT — default demo-tenant on cloud, default on localhost open-access.

Config file

~/.infona/config.json (mode 600). Example after ./scripts/oss_setup.sh or infona init --local:

{
  "apiUrl": "http://localhost:8000",
  "tenant": "default"
}

PDF ingest is not supported on any surface (CLI, API, MCP). Extract text or tables first; CSV is the best-supported path.

License

Apache-2.0. See LICENSE.