trellis/links

Wiki-link parsing, reference resolution, backlink index, and cross-repository references.

Overview

The trellis/links subpath parses [[wiki-links]] from any text source — markdown, doc-comments, source files — and builds a bidirectional knowledge graph connecting all entities in your workspace.

import { parseFileRefs, RefIndex, resolveRef } from "trellis/links";

parseFileRefs

Extract all wiki-link references from a file's source:

const refs = parseFileRefs("src/engine.ts", source);
// WikiRef[] — { raw, target, kind, location }

WikiRef Shape

interface WikiRef {
  raw: string; // '[[issue:TRL-5]]'
  target: string; // 'issue:TRL-5'
  kind: RefKind; // 'issue' | 'file' | 'symbol' | 'milestone' | 'decision' | 'unknown'
  location: {
    file: string;
    line: number;
    column: number;
  };
}

Supported Reference Formats

FormatResolves To
[[auth.ts]]File entity
[[issue:TRL-5]]Issue entity
[[milestone:abc123]]Milestone entity
[[decision:d42]]Decision trace
[[MyClass]]Symbol / AST entity
[[@backend:lib:api-client]]Cross-repo entity

resolveRef

Resolve a parsed reference to a concrete entity in the graph:

const resolved = resolveRef(ref, context);
// ResolvedRef | null

interface ResolvedRef {
  entityId: string;
  entityType: string;
  label: string;
  url?: string; // Deep-link to docs/UI
}

RefIndex

The RefIndex maintains a bidirectional index of all references across the workspace — incoming and outgoing:

const index = new RefIndex();

// Index a file's references
index.indexFile("README.md", refs, context);

// Get all entities that reference a given entity
const incoming = index.getIncoming("issue:TRL-5");
// WikiRef[] — everything that links to TRL-5

// Get all entities referenced by a given file
const outgoing = index.getOutgoing("src/engine.ts");
// WikiRef[]

Cross-Repository References

// Link to an entity in another registered repo
index.addCrossRepoLink("frontend", "proj:app", "backend", "api:users");
// Creates: @frontend:proj:app --references--> @backend:api:users

// Query cross-repo incoming links
const refs = index.getCrossRepoIncoming("backend", "api:users");

Auto-indexing with TrellisVcsEngine

When using the full engine, the ref index is maintained automatically as files change:

import { TrellisVcsEngine } from "trellis";

const engine = new TrellisVcsEngine({ rootPath: "/my/project" });
await engine.start();

// Query the live ref index
const backlinks = engine.links.getIncoming("issue:TRL-5");

Querying the Knowledge Graph

Because links are stored as EAV graph edges, you can query them with EQL-S:

# Find all files that reference a specific issue
trellis query "find File where links issue:TRL-5"

# Find all issues referenced from the README
trellis query "find Issue where referencedFrom 'README.md'"