JSON envelopes
nci --format json returns the same envelope on every nci query subcommand. nci sql --format json returns a raw row array with no envelope — it’s closer to the sqlite3 CLI’s output mode. This page documents both shapes, plus the data payload by subcommand.
The nci query envelope
type QueryEnvelope<TData> = | { ok: true; data: TData; meta: QueryMeta } | { ok: false; error: string };
QueryMeta always includes envelopeVersion (currently 1) and query (the subcommand name). Other keys are subcommand-specific — for example active_package adds activePackageResolution, and evidence adds limit / truncation fields. Treat nci query … --format json output as the source of truth.
ok: true— non-emptydatapayload below, plusmetaas above. Exit code0.ok: false— non-zero exit code.erroris one human-readable string (stderr usually repeats the same text for plain mode).
Some subcommands return data shapes whose “not found” case is null-valued rather than the failure envelope. query show, query snippet, and query overloads exit with EXIT_QUERY_NOT_FOUND = 2 and return { ok: true, data: { symbol: null } } (or the equivalent for snippet / symbols: [] for overloads). Those responses may also include a top-level string hint alongside data and meta. Read Exit codes for the matrix.
data shapes by subcommand
| Subcommand | data payload |
|---|---|
find | { symbols: SymbolHit[] } |
symbol | { symbols: SymbolHit[] } |
show | { symbol: SymbolRow | null } |
snippet | { snippet: SnippetRow | null } |
overloads | { symbols: SymbolHit[] } |
packages | { packages: PackageRow[] } |
package_versions | { versions: string[] } |
package_deps | { dependencies: string[] } |
source_packages | { source_packages: string[] } |
active_package | { resolutions: ActivePackageRow[] } |
symbols | { symbols: SymbolRow[], page: { offset, limit, returned } } |
evidence | { symbols: SymbolHit[], snippets: Record<string, string> } |
SymbolHit, SymbolRow, and SnippetRow carry the columns documented at Symbol graph model — id, name, kind_name, signature, js_doc, source_package_name, etc. The exact field set per subcommand is what nci query <sub> --format json prints; treat that output as the source of truth.
nci sql output
nci sql --format json returns a raw JSON array of row objects:
[ { "name": "zod", "version": "3.23.8" }, { "name": "react", "version": "19.0.0" } ]
--format jsonl returns one row object per line. --format plain returns tab-separated values. There is no ok / data envelope on nci sql — the row array (or empty array) is the entire payload.
--max-rows N causes the command to fail (exit 1) if the result set would exceed N. It applies to nci sql only, never to nci query.
Where each shape lives
- The
nci queryenvelope is generated inpackages/nci-engine/src/cli.rs. - The
--format jsonSQL output usesserde_json::Valuemapping per row. - The MCP server (
packages/nci-mcp) forwards both shapes verbatim —nci_queryreturns the envelope,nci_sqlreturns the row array.