-
-
Notifications
You must be signed in to change notification settings - Fork 0
Output Formats
Synaptic builds one in-memory knowledge graph and can serialize it to many artifacts. The canonical artifact is graph.json (a NetworkX node-link document); everything else is derived from the same graph.
Two ways to produce artifacts:
-
synaptic extractwrites a full default set in one pass (see [Extraction]). -
synaptic export <format>regenerates a single artifact from an existinggraph.jsonwithout re-extracting, or pushes the graph live to a database. -
synaptic chartcreates a bounded architecture summary from an existinggraph.json.
For the visual/interactive artifacts (chart.html, graph.html, graph-3d.html, graph.svg, callflow.html, tree.html) see [Visualizations].
synaptic extract writes all of these into synaptic-out/:
graph.json graph.html GRAPH_REPORT.md
graph.graphml graph.cypher graph.dot
callflow.html tree.html graph.svg
graph-3d.html
--obsidian additionally writes synaptic-out/obsidian/ and --wiki writes synaptic-out/wiki/. Neither is produced by default.
graph.graphml, graph.cypher, graph.dot and graph-3d.html emit every node and
every edge with no aggregation, so their size tracks the graph exactly. Past 150,000
nodes they are skipped and extract says so, because at that scale they are large
enough that no tool in the chain will open them (a 379k-node graph produced a 342 MB
GraphML and a 259 MB graph-3d.html).
graph.json and graph.html are always written: graph.json is the canonical contract,
and graph.html aggregates by community above 5,000 nodes so it stays responsive.
synaptic export <format> [--graph <path>] [--out <path>] [--repo <tag>]
[--push <uri>] [--user <u>] [--password <p>]
export loads an existing graph.json, then re-emits one format from it. No re-extraction happens, so it is fast and deterministic.
Flags:
-
--graph <path>source graph. Default:synaptic-out/graph.json. -
--out <path>output file (single-file formats) or directory (obsidian/wiki). Default: alongside the source graph, using the conventional filename for that format. -
--repo <tag>scope to one federated member by itsrepotag before exporting (see [Workspaces-and-Federation]). -
--push <uri>forneo4j/falkordbonly: push live to a running database instead of writing the cypher script. Requires thepushbuild feature. -
--user <u>auth user for--pushto Neo4j (defaultneo4j). -
--password <p>auth password for--push(or setNEO4J_PASSWORD/FALKORDB_PASSWORD).
Verified from the command dispatch, export accepts exactly these formats (case-insensitive):
| Format | Output | Notes |
|---|---|---|
json |
graph.json |
Pretty-printed node-link JSON |
html |
graph.html |
Interactive 2D explorer (see [Visualizations]) |
svg |
graph.svg |
Static layout (see [Visualizations]) |
graphml |
graph.graphml |
Gephi / yEd / GraphML tools |
cypher |
graph.cypher |
Neo4j / FalkorDB import script |
dot |
graph.dot |
Graphviz DOT |
callflow (alias callflow-html) |
callflow.html |
Mermaid call-flow (see [Visualizations]) |
tree |
tree.html |
D3 file tree (see [Visualizations]) |
3d (alias force3d) |
graph-3d.html |
3D force graph (see [Visualizations]) |
obsidian |
obsidian/ directory |
Obsidian vault |
wiki |
wiki/ directory |
Markdown wiki |
report |
GRAPH_REPORT.md |
Analysis report (see [Analysis-and-Reports]) |
neo4j |
graph.cypher or live push |
See live push below |
falkordb |
graph.cypher or live push |
See live push below |
Any other value is rejected with an error listing the valid formats.
chart.html is deliberately a separate synaptic chart command rather than an export format because it is a bounded architecture summary with its own --max-communities control. It defaults beside the source graph.json, remains fully offline, and drills from communities into source-backed internal symbol graphs.
export json --repo X with no --out is refused, because its default output name (graph.json) would overwrite the source graph with a scoped subgraph. Pass --out <path> to write the scoped graph elsewhere. Other formats have distinct default names and are unaffected.
graph.json follows the NetworkX node_link_data(G, edges="links") shape. Top-level keys:
{
"directed": false,
"multigraph": false,
"graph": {},
"nodes": [ ... ],
"links": [ ... ],
"hyperedges": [],
"built_at_commit": "deadbeef"
}- Edges are under
links(notedges). On input, anedgeskey is accepted as an alias. -
hyperedgesis always present, even when empty. -
built_at_commitis omitted when unknown.
Required keys are always present; optional keys are omitted when unset. Any other keys round-trip through a flattened extra map (so re-importing is lossless).
{
"id": "auth",
"label": "auth.py",
"file_type": "code",
"source_file": "src/auth.py",
"source_location": "L42",
"community": 3,
"repo": "app",
"norm_label": "auth.py"
}-
idstable node identifier. -
labeldisplay name. -
file_typeone ofcode,document,paper,image,rationale,concept(lowercase). -
source_fileoriginating file path. -
source_locationoptional (e.g. a line marker); omitted when unset. -
communityoptional cluster id (integer); omitted when unset. -
repooptional federation tag; absent for single-repo graphs. -
kindoptional node kind (class,function,method,struct, ...); set for code nodes in supported languages, omitted otherwise. See [Extraction]. -
visibilityoptional declared visibility (public,private,protected,internal); omitted when unknown. -
spanoptional source range object (start_line,start_col,end_line,end_col); omitted when unknown. Lines-of-code isend_line - start_line + 1. -
norm_labellowercased search key, added by the JSON writer on export.
The kind (the node's NodeKind: table/column/view/function/class/… ) drives node shape and color-by-kind in the SVG, 2D, and 3D viewers, so the SQL and cross-language layers are visible — not just "code". SQL nodes also carry the facts the viewers surface on hover (dialect, data_type, pk, fk_target, rls_enabled, security_invoker). Non-code asset nodes carry asset_kind (e.g. stylesheet, data, image, font, media) for their own shapes; federated external-package stubs carry external_package: true.
{
"source": "a",
"target": "b",
"relation": "calls",
"confidence": "EXTRACTED",
"source_file": "src/a.py",
"source_location": "L10",
"confidence_score": 1.0,
"weight": 1.0,
"context": "...",
"sites": [
{ "source_file": "src/other.py", "source_location": "L22" }
],
"cross_repo": true
}-
source/targetendpoint node ids. -
relationrelationship name (e.g.calls,contains,method,imports). -
confidenceone ofEXTRACTED,INFERRED,AMBIGUOUS(uppercase). -
source_filewhere the relationship was found. -
confidence_scorenumeric score. The JSON writer defaults it from the confidence level when unset:EXTRACTED-> 1.0,INFERRED-> 0.5,AMBIGUOUS-> 0.2. -
weightdefaults to 1.0. -
source_location,contextoptional, omitted when unset. -
sitesoptional: additional distinct extraction locations for the same semantic edge. The primary location remains insource_file/source_location; federation repo-prefixes both the primary and every additional site. Context is part of semantic identity, so otherwise-equal context-bearing edges are not merged. -
cross_repoomitted when false;truemarks a federated cross-repo edge.
{ "id": "he1", "label": "auth cluster", "nodes": ["a", "b"] }Optional relation and confidence keys are omitted when unset.
GraphML for Gephi, yEd, or any GraphML consumer. The document declares <key>s and emits <node>/<edge> data. Attributes preserved:
- Node:
label,file_type,source_file,community(declared aslong;-1when unset). - Edge:
relation,confidence.
For federated graphs only, two extra attributes are declared and emitted: a node repo (string) and an edge cross_repo (boolean, written only on cross-repo edges). Single-repo GraphML is unchanged. When any node carries enrichment metadata, three node attributes are also declared and emitted: kind, visibility, and loc (long). Cypher's rich (live-push) form sets the same n.kind/n.visibility/n.loc. Internal _-prefixed extras are dropped. All text is XML-escaped.
A Cypher import script for Neo4j or FalkorDB, generated as ;-terminated statements: node MERGEs first, then edge MERGEs.
Both forms are idempotent on re-run. The MERGE key is the id alone, and label/confidence are applied with SET, so re-importing after a label or confidence change updates in place instead of duplicating. Node file type becomes the node label (capitalized, allowlisted; falls back to Entity), and the relation becomes the relationship type (uppercased, allowlisted; falls back to RELATES_TO).
MERGE (n:Code {id: 'a'}) SET n.label = 'A';
MATCH (a {id: 'a'}), (b {id: 'b'}) MERGE (a)-[r:CALLS]->(b) SET r.confidence = 'EXTRACTED';String values are escaped for single-quoted Cypher literals (drops control bytes; escapes \, ', newlines, CRs). Identifier-position tokens (node label, relationship type) are allowlisted to [A-Za-z0-9_] with a required leading letter, since Cypher cannot escape those positions.
The static script carries id + label on nodes only. The live push (see below) uses a richer form that also writes source_file and community onto nodes.
Graphviz DOT. Renders a digraph (with ->) when the graph is directed, otherwise a graph (with --). Layout hints rankdir=LR and node [shape=box] are emitted. Each node carries label and kind (the file type); each edge carries label (the relation).
graph Synaptic {
rankdir=LR;
node [shape=box];
"a" [label="A", kind="code"];
"a" -- "b" [label="calls"];
}Node ids and all attribute values are emitted as double-quoted DOT strings with ", \, and newlines escaped, so an arbitrary label cannot break the statement.
to_obsidian writes a directory (default synaptic-out/obsidian/) containing:
- One Markdown note per node, with YAML frontmatter (
id,file_type,community,source_file) and neighbors as[[wikilinks]]grouped by relation. Incoming edges are grouped under<relation> (in). - One
_Community-<id>.mdoverview note per community, with cohesion, a member list, a Dataview live query (LIST FROM "" WHERE community = N), and links to related communities by shared-edge count. -
.obsidian/graph.json, which colors the Obsidian graph view by community via a per-note frontmatter search.
Note filenames are sanitized from labels and deduped (colliding labels get a (N) suffix), and wikilinks target the actual deduped filename so they resolve. community_labels supply semantic community names; when empty, names fall back to Community N. The function returns the count of notes written.
to_wiki writes a directory (default synaptic-out/wiki/) of GitHub-wiki-style Markdown with [[wikilinks]]:
-
index.mdlisting communities and the top "key nodes" (highest degree). - One
community-<id>.mdarticle per community, with cohesion score, key concepts (highest-degree members), spanned source files, related communities by shared-edge count, and an audit trail (the EXTRACTED/INFERRED/AMBIGUOUS mix of the community's internal edges). - One page per "god node" (the top 10 highest-degree nodes overall), grouping neighbors by relation.
God-node filenames are deduped the same way as Obsidian notes. The function returns the count of files written.
A Markdown analysis report. export report recomputes communities and analysis from the loaded graph (these are not stored in graph.json) before writing. See [Analysis-and-Reports] for its contents.
export neo4j and export falkordb write graph.cypher by default. With --push <uri> and a Synaptic binary built with --features push, they stream the graph into a running database instead. Both use the richer (props + community) idempotent MERGE statements, so re-runs upsert and never duplicate.
synaptic export neo4j --push bolt://localhost:7687 --password <pw>
synaptic export falkordb --push falkordb://localhost:6379
Transports:
- Neo4j uses
cypher-shell(must be on PATH; speaks Bolt). The;-terminated script is piped to its stdin. The URI is a Bolt URL (e.g.bolt://localhost:7687). Auth:--user(defaultneo4j) and--passwordorNEO4J_PASSWORD. - FalkorDB uses the pure-Rust
redisclient, running eachMERGEthroughGRAPH.QUERY synaptic <stmt>. The URI acceptsfalkordb://,redis://,rediss://, a barehost:port, or a barehost(default port 6379). Auth password is optional, taken from--passwordorFALKORDB_PASSWORD, and is set as a connection field (never interpolated into a URL), so passwords containing@/:///%connect correctly.
On success each prints the number of statements pushed. Without the push feature, --push fails with a clear message. See [Ingestion] and [MCP-Server] for related integrations.
-
Building on Synaptic for consuming
graph.jsonas an API from any language (and building your own MCP server on it). - [Visualizations] for the interactive and static visual outputs.
- [Analysis-and-Reports] for GRAPH_REPORT.md.
- [Commands] for the full CLI reference.
- [Workspaces-and-Federation] for
--reposcoping and cross-repo graphs.
Getting started
Concepts
Using Synaptic
- Commands
- API Maintenance
- Extraction
- Querying
- Cross-Language Edges
- SQL Auditing
- Vulnerability Management
- Analysis and Reports
- Output Formats
- Visualizations
Integrations
Scaling
Reference