Skip to content

navigator.json

The browsable shape of a corpus: a tree of modules, types and members, plus one classified dependency row per base edge. Written by navigator.

Everything is an array index. Entity ids are opaque strings that never need to reach the renderer: a node is its position in nodes, a file its position in files. A reference that cannot be closed onto an index is dropped and counted in diagnostics.

Field names are those of NavigatorModel in packages/navigator/src/model.ts.

Top level

FieldTypeMeaning
kindstringalways codegraph.navigator/1
generatedBystringalways @codegraph/navigator
viewViewDescriptor{name, filters}
corpus{name, roots}
filesstring[]interned anchor paths
nodesNavNode[]preorder over the tree: a parent always precedes its children
rootsnumber[]tree roots, sorted (category, name, id)
depsDepRow[]sorted by (from, to, role, member, toMember, anchor)
reports{cycles: NavCycleReport[]}precomputed graph facts; absent only in artifacts written before the section existed
diagnostics{selfDeps, droppedDeps}

nodes[] — NavNode

FieldTypeMeaning
namestringdisplay name; an unnamed invocable (a constructor) shows its signature
kindstringthe entity kind, verbatim from the model
category"module" | "type" | "operation" | "attribute"from traits (TModule/TType/TInvocable/TStructural), never from kind
isStubboolean
parentnumbertree parent index; absent for a root
childrennumber[]preorder-consistent, sorted (category, name, id); empty, never absent
signaturestring
declaredTypenumberthe declared type of an attribute or operation, resolved to a node index
anchor[file, start, end]file is an index into files, lines 1-based inclusive
metrics{fanIn, fanOut, instability}present on types and modules that have a coupling row under the view; instability is Ce / (Ca + Ce) in [0,1], 0 by definition when Ca + Ce = 0

deps[] — DepRow

One base edge, attributed to the selectable nodes that own its endpoints. from and to are always type- or module-category nodes; member and toMember name the operation or attribute that actually carries each endpoint, when one does. A compound assignment (isRead && isWrite) emits BOTH a reads and a writes row — same anchor, both true.

FieldTypeMeaning
roleDepRolehow the row relates its endpoints; see below
from, tonumbernode indexes
membernumberthe member carrying the source endpoint
toMembernumberthe member carrying the target endpoint
detailstringhuman refinement of the role: parameter #2 (channel), local variable total
provenanceProvenance
anchor[file, start, end]

DepRole

The metamodel has no typeDeclaration edge kind — parameter, return, local-variable and field types are all reference edges stored on the member entity — so the role is recovered here from the source entity’s traits and its owner’s ordered parameters[] / localVariables[], never re-derived by a renderer.

import · extends · implements · embeds · usesTrait · includesFile · invokes · reads · writes · returnType · parameterType · localVariableType · fieldType · typeReference

reports.cycles[] — NavCycleReport

The analyzer’s cycle report re-addressed to node indexes. The renderer displays which dependency to attack and what cutting it costs; it never runs Tarjan itself.

FieldTypeMeaning
level"module" | "type"the analyzer’s fold: module over imports, type over every edge kind
componentsNavCycleComponent[]sorted by first member
tangleNavTangleSummary

NavCycleComponent:

FieldTypeMeaning
membersnumber[]node indexes, in the analyzer’s member order
edgesNavCycleEdge[]links BETWEEN members, sorted (from, to); folding self-loops excluded
weightnumbersum of edges counts — the base-edge weight of the cycle
feedbackWeightnumbersum of the feedback edges’ counts — the references the minimal cut severs
tangleMetricnumberfeedbackWeight / weight, in [0,1]

NavCycleEdge: {from, to, count, provenances, allDeclared, feedback} — count is the cost of cutting the link, allDeclared is true only when every aggregated base edge is a declared fact, feedback marks membership of the minimum feedback set.

NavTangleSummary: {feedbackEdgeCount, feedbackWeight, cyclicWeight, metric} — metric is feedbackWeight / cyclicWeight, and 0 (not NaN) on an acyclic graph.

diagnostics

FieldMeaning
selfDepsedges whose endpoints resolved to the SAME owner — internal cohesion, not a dependency
droppedDepsedges dropped because an endpoint had no owning node under the view

Excerpt

codegraph navigator fixtures/java/expected/model.jsonl — 137 nodes and 131 dependency rows, trimmed to one of each:

{
  "kind": "codegraph.navigator/1",
  "generatedBy": "@codegraph/navigator",
  "view": { "name": "all", "filters": [] },
  "corpus": { "name": "src", "roots": ["fixtures/java/src"] },
  "files": ["com/acme/order/adapter/LedgerAdapter.java", "com/acme/order/legacy/List.java"],
  "nodes": [
    { "name": "com.acme.order", "kind": "package", "category": "module", "isStub": false,
      "children": [1, 6, 13, 19, 21],
      "metrics": { "fanIn": 0, "fanOut": 5, "instability": 1 } },
    { "name": "trail", "kind": "attribute", "category": "attribute", "isStub": false,
      "parent": 2, "children": [], "declaredType": 135, "anchor": [0, 8, 8] }
  ],
  "roots": [0, 110, 112, 114, 123, 126, 128, 132, 135, 136],
  "deps": [
    { "role": "import", "from": 0, "to": 110, "provenance": "derived", "anchor": [11, 3, 3] },
    { "role": "parameterType", "from": 2, "to": 116, "member": 4,
      "detail": "parameter #1 (document)", "provenance": "declared", "anchor": [0, 11, 11] }
  ],
  "reports": {
    "cycles": [
      { "level": "module", "components": [],
        "tangle": { "feedbackEdgeCount": 0, "feedbackWeight": 0, "cyclicWeight": 0, "metric": 0 } }
    ]
  },
  "diagnostics": { "selfDeps": 45, "droppedDeps": 0 }
}

A type-level component from the same file:

{ "members": [21, 22],
  "edges": [
    { "from": 21, "to": 22, "count": 2, "provenances": ["declared"], "allDeclared": true, "feedback": false },
    { "from": 22, "to": 21, "count": 1, "provenances": ["declared"], "allDeclared": true, "feedback": true }
  ],
  "weight": 3, "feedbackWeight": 1, "tangleMetric": 0.3333333333333333 }

The design behind one classified row per base edge: The navigator.

Last updated on