outline

package module
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 30, 2026 License: MIT Imports: 25 Imported by: 0

README

outline

Reduce a source tree to a structural skeleton suitable for feeding to an LLM. Function and method bodies are dropped; signatures, types, comments and imports are kept. Unsupported file types pass through unchanged.

Pure Go, no CGo. Parsing is done by gotreesitter, file selection respects .gitignore via git-pkgs/gitignore. Full API docs are on pkg.go.dev.

Installation

Add the library to your Go module:

go get github.com/git-pkgs/outline

For the CLI, see outline binary.

Usage

import "github.com/git-pkgs/outline"

r, err := outline.Pack(".", outline.Options{Compress: true})
if err != nil {
    return err
}
r.Markdown(os.Stdout)

Or per file:

src, _ := os.ReadFile("main.go")
out, ok := outline.Outline(src, "main.go")

A Go file like

func SayHello(name string) {
    fmt.Printf("Hello, %s!\n", name)
}

becomes

func SayHello(name string) {
⋮----

with the body elided and gaps marked by ⋮----.

API

Outline(src []byte, filename string) (string, bool) compresses one file. The second return is false if the language is not supported.

Imports(src []byte, filename string) ([]Import, bool) extracts module imports, their source-language form, named imports, local aliases, and one-based source lines. A statement containing both default and named imports returns one value for each form.

Refs(src []byte, filename string, receivers []string) ([]Ref, bool) extracts direct member accesses on the supplied receiver identifiers. This lets callers pass the local aliases returned by Imports without collecting unrelated member expressions from the file.

imports, ok := outline.Imports(src, "app.py")
if !ok {
    return
}

refs, _ := outline.Refs(src, "app.py", []string{"flask", "f"})

For both functions, false means the language is unsupported or parsing did not complete, including a parse timeout. A true result with an empty slice means the language is supported but the file contains no matches. Import and reference extraction currently cover Go, Ruby, Python, JavaScript, TypeScript/TSX, Rust, PHP, Elixir, Dart, Swift, Haskell, Perl, Lua, R, Julia, OCaml, Crystal, Nim, Zig, D, Java, Kotlin, and C#.

Pack(root string, opts Options) (*Result, error) walks root, applies .gitignore plus a built-in ignore list (vendored deps, build output, lockfiles), skips binaries and oversized files, and outlines what it can. Options lets you set size and file-count limits, extra ignore patterns, concurrency, and whether to compress.

Result carries []File and a rendered Tree string. Result.Markdown(w) and Result.XML(w) write the packed document.

Build(root string, opts Options) (*Graph, error) shares the Pack walker but keeps bin/ entrypoints and returns a directed code graph. Ruby files include .rb, .gemspec, and extensionless files with a Ruby shebang. Nodes are files, modules, declarations, and unresolved external call targets; each edge has a relation (contains, imports, loads, calls) and a confidence (extracted for facts read directly from one AST, inferred for name resolution). Call edges retain the receiver form, dispatch form, arguments, and byte span. Graph methods query the result: Def(name) looks up by node ID, bare name, or qualified name; Callers/Callees return one-hop call edges; Affected(seeds, opts) returns reverse-reachable evidence paths from a set of sinks; Path(from, to, opts) returns the shortest forward call chain; JSON(w) writes sorted output so repeated builds of unchanged input are byte-identical. Go and Python include cross-file call resolution. Ruby includes direct calls, same-file calls within the same class or module, distinct instance and singleton method names, unresolved dynamic receivers, subshells, and local require_relative load edges. Other supported languages contain file, symbol, module, and import structure with call edges omitted.

Tree(paths []string) string renders a box-drawing directory tree from a flat path list.

Supported(filename string) bool reports whether a file's extension maps to a language with an outlining query. SupportedSource(src, filename) also checks source-based detection such as Ruby shebangs.

SetParseTimeout(d time.Duration) overrides the per-file parse timeout (default 1s). Must be called before the first Outline or Pack call.

outline binary

go install github.com/git-pkgs/outline/cmd/outline@latest

outline graph [dir] builds the graph and prints a summary; -json writes it to stdout and -o file to disk. outline def <name>, outline callers <name>, outline callees <name>, outline affected <name>..., and outline path <from> <to> query it. -g file reads a saved graph instead of rebuilding; -inferred includes cross-file name-matched edges alongside extracted ones; -depth N caps traversal hops; -relations r,... selects which edge kinds to follow (default calls); -budget N caps output size in tokens. Flags precede positional arguments.

Seeds take the same forms as Def: Handler, Handler.process, or a full node ID. External targets use ext:<lang>:<module>:<name>, so tracing every declaration that reaches exec.Command from the testdata/cli-go fixture produces:

$ outline affected -inferred -dir testdata/cli-go ext:go:os/exec:Command
2 paths, 3 nodes
NODE Handler func main.go:9 exported=true sig=func Handler(name string) error
NODE os/exec.Command external exported=false sig=
NODE main func main.go:17 exported=false sig=func main()
EDGE Handler --calls[inferred]--> Run at main.go:14
NODE Run external exported=false sig=
EDGE Handler --calls[inferred]--> os/exec.Command at main.go:14
EDGE Handler --calls[inferred]--> Load at main.go:10
NODE Load func store/store.go:7 exported=true sig=func Load(name string) (Record, error)
EDGE main --calls[extracted]--> Handler at main.go:18

Languages

35 languages have body-stripping queries: Go, Ruby, Python, JavaScript, TypeScript/TSX, Rust, Java, C, C++, C#, PHP, Kotlin, Swift, Scala, Dart, Elixir, Erlang, Haskell, Clojure, Perl, Lua, R, Julia, OCaml, F#, Crystal, Nim, Zig, D, Groovy, HCL/Terraform, Starlark/Bazel, CMake, Bash and Make. gotreesitter ships ~200 grammars so adding a language means writing one .scm query file. cmd/outline-compare -dump <lang> prints the S-expression tree for stdin and is the easiest way to work out what to capture.

Performance

On an M1 Pro, outlining runs at ~6 MB/s per core and reaches ~36 MB/s across all eight via the parser pool. Packing a 600-file repo takes about 34ms; the Markdown render of that result is ~140µs. Almost all the time is in gotreesitter's full-parse path; chunk extraction and rendering barely register.

License

MIT.

Documentation

Index

Constants

View Source
const (
	KindFile     = "file"
	KindModule   = "module"
	KindExternal = "external"
	KindFunc     = "func"
	KindType     = "type"
	KindClass    = "class"
	KindConst    = "const"
	KindVar      = "var"
)

Node kinds.

View Source
const (
	RelContains   = "contains"
	RelImports    = "imports"
	RelLoads      = "loads"
	RelCalls      = "calls"
	RelReferences = "references"
	RelInherits   = "inherits"
	RelEmbeds     = "embeds"
	RelReexports  = "reexports"
)

Edge relations.

View Source
const (
	ConfExtracted = "extracted"
	ConfInferred  = "inferred"
)

Edge confidence.

View Source
const DefaultParseTimeout = time.Second

DefaultParseTimeout caps how long the parser will spend on a single file. Past this point the file is treated as unsupported and falls through as raw content. Pathological inputs (large table-driven test files, generated parser tables) can otherwise dominate runtime.

View Source
const SchemaVersion = 2

SchemaVersion is bumped whenever Node, Edge, or Graph change in a way a reader must understand.

View Source
const Separator = "⋮----"

Variables

View Source
var ToolVersion = "dev"

ToolVersion is stamped into every emitted graph.

Functions

func ExtID added in v0.2.3

func ExtID(lang, module, name string) string

ExtID returns the node ID for an unresolved external target.

func FileID added in v0.2.3

func FileID(path string) string

FileID returns the node ID for a repository-relative file path.

func ModID added in v0.2.3

func ModID(lang, module string) string

ModID returns the node ID for a module in a language.

func Outline

func Outline(src []byte, filename string) (string, bool)

Outline reduces source to a structural skeleton: declarations, signatures and comments are kept, function bodies are dropped. Returns the outline and true if the file's language is supported, otherwise "", false.

func SetParseTimeout

func SetParseTimeout(d time.Duration)

SetParseTimeout overrides the per-file parse timeout. Must be called before the first Outline or Pack call; later calls are ignored once a language pool has been created. A zero duration disables the timeout.

func Supported

func Supported(filename string) bool

Supported reports whether Outline can handle the given filename.

func SupportedSource added in v0.2.3

func SupportedSource(src []byte, filename string) bool

SupportedSource reports whether Outline can detect the language of source.

func SymID added in v0.2.3

func SymID(path string, start uint32) string

SymID returns the node ID for a declaration at a byte offset in a file.

func Tree

func Tree(paths []string) string

Tree renders a sorted list of slash-separated relative paths as a box-drawing directory tree. Directories are inferred from path segments and listed before files.

Types

type Argument added in v0.2.3

type Argument struct {
	Kind  string `json:"kind"`
	Text  string `json:"text"`
	Start uint32 `json:"start"`
	End   uint32 `json:"end"`
}

Argument is one source argument to a call.

type Call added in v0.2.3

type Call struct {
	Receiver     string       `json:"receiver,omitempty"`
	ReceiverKind ReceiverKind `json:"receiver_kind"`
	Name         string       `json:"name"`
	Dispatch     DispatchKind `json:"dispatch"`
	Arguments    []Argument   `json:"arguments,omitempty"`
	Line         int          `json:"line"`
	Start        uint32       `json:"start"`
	End          uint32       `json:"end"`
	In           int          `json:"-"`
}

Call is one call site. In refers to the innermost enclosing declaration during graph construction and is omitted from JSON.

type DispatchKind added in v0.2.3

type DispatchKind string

DispatchKind describes how a call reaches its target.

const (
	DispatchDirect   DispatchKind = "direct"
	DispatchSubshell DispatchKind = "subshell"
)

type Edge added in v0.2.3

type Edge struct {
	From      string `json:"from"`
	To        string `json:"to"`
	Rel       string `json:"rel"`
	Conf      string `json:"conf"`
	File      string `json:"file,omitempty"`
	Line      int    `json:"line,omitempty"`
	Operation string `json:"operation,omitempty"`
	Call      *Call  `json:"call,omitempty"`
}

Edge is one directed relationship between two nodes.

type File

type File struct {
	Path     string
	Content  string
	Language string
	Outlined bool
	Symbols  []Symbol // populated when Outlined is true
	Size     int64
	Skipped  string // reason content was omitted, e.g. "binary", "too-large"
}

File is one packed file.

type Graph added in v0.2.3

type Graph struct {
	SchemaVersion int      `json:"schema_version"`
	ToolVersion   string   `json:"tool_version"`
	SourceDigest  string   `json:"source_digest"`
	Complete      bool     `json:"complete"`
	Warnings      []string `json:"warnings,omitempty"`
	Nodes         []Node   `json:"nodes"`
	Edges         []Edge   `json:"edges"`
	// contains filtered or unexported fields
}

Graph is a whole-repository code graph.

func Build added in v0.2.3

func Build(root string, opts Options) (*Graph, error)

Build walks root, analyses every supported source file, resolves cross-file references for supported languages, and returns a Graph.

func (*Graph) Affected added in v0.2.3

func (g *Graph) Affected(seeds []string, opts TraverseOptions) []Path

Affected walks the graph in reverse from each seed and returns one evidence path per reached node. The default relation set is RelCalls, so with default options this is the transitive caller set.

func (*Graph) Callees added in v0.2.3

func (g *Graph) Callees(id string) []Edge

Callees returns outbound calls edges from id.

func (*Graph) Callers added in v0.2.3

func (g *Graph) Callers(id string) []Edge

Callers returns inbound calls edges to id.

func (*Graph) Def added in v0.2.3

func (g *Graph) Def(name string) []Node

Def returns nodes whose Name or Qualified exactly matches name, or whose ID is name.

func (*Graph) In added in v0.2.3

func (g *Graph) In(id string) []Edge

In returns edges arriving at id.

func (*Graph) JSON added in v0.2.3

func (g *Graph) JSON(w io.Writer) error

JSON writes the graph as sorted, indented JSON.

func (*Graph) Node added in v0.2.3

func (g *Graph) Node(id string) *Node

Node returns the node with the given ID, or nil.

func (*Graph) Out added in v0.2.3

func (g *Graph) Out(id string) []Edge

Out returns edges leaving id.

func (*Graph) Path added in v0.2.3

func (g *Graph) Path(from, to string, opts TraverseOptions) Path

Path returns the shortest forward edge chain from from to to under opts, or nil if none exists.

func (*Graph) Text added in v0.2.3

func (g *Graph) Text(w io.Writer, ids []string, budget int, allow func(Edge) bool) error

Text writes a budgeted line-oriented rendering of the seeds and their BFS neighbourhood, following only edges that pass allow (nil admits every edge). Every line is sanitised so untrusted source cannot inject terminal escapes or break the line protocol.

type Import added in v0.2.0

type Import struct {
	Module   string
	Kind     ImportKind
	Names    []Name
	Form     string
	Relative bool
	Line     int
}

Import is one source import form. A statement containing more than one form, such as a JavaScript default plus named import, produces one Import value for each form. Form and Relative retain language-specific loading details when they affect graph construction.

func Imports added in v0.2.0

func Imports(src []byte, filename string) ([]Import, bool)

Imports returns structured imports from one source file. The second return is false when the file's language or syntax tree is unsupported.

type ImportKind added in v0.2.0

type ImportKind string

ImportKind identifies the source-language form of an import.

const (
	// ImportNamed imports one or more named exports.
	ImportNamed ImportKind = "named"
	// ImportDefault imports a default export.
	ImportDefault ImportKind = "default"
	// ImportNamespace imports a module namespace.
	ImportNamespace ImportKind = "namespace"
	// ImportModule binds a module object using the language's module form.
	ImportModule ImportKind = "module"
	// ImportSideEffect loads a module without binding a local name.
	ImportSideEffect ImportKind = "side-effect"
	// ImportWildcard imports every exported name.
	ImportWildcard ImportKind = "wildcard"
)

type Name added in v0.2.0

type Name struct {
	Name  string
	Alias string
}

Name is one named import and its optional local alias. ImportDefault, ImportNamespace, and ImportModule use Alias for a local binding declared by the source syntax.

type Node added in v0.2.3

type Node struct {
	ID        string `json:"id"`
	Kind      string `json:"kind"`
	Name      string `json:"name"`
	Qualified string `json:"qualified,omitempty"`
	File      string `json:"file,omitempty"`
	Line      int    `json:"line,omitempty"`
	Start     int    `json:"start,omitempty"`
	End       int    `json:"end,omitempty"`
	Exported  bool   `json:"exported,omitempty"`
	Sig       string `json:"sig,omitempty"`
}

Node is one graph vertex. IDs are opaque and produced only by the id encoder helpers below.

type Options

type Options struct {
	// MaxFileSize is the per-file byte limit. Files larger than this are
	// listed in the tree but their content is omitted. Zero means 1MB.
	MaxFileSize int64
	// MaxFiles caps the number of files read. Zero means 10000.
	MaxFiles int
	// Compress applies tree-sitter outlining to supported source files.
	// When false, full file contents are kept.
	Compress bool
	// Ignore adds gitignore-syntax patterns on top of .gitignore and the
	// built-in defaults.
	Ignore []string
	// Concurrency is the number of files processed in parallel.
	// Zero means runtime.NumCPU().
	Concurrency int
	// Resolution supplies caller-provided source roots and package hints
	// for graph module resolution. Pack ignores it.
	Resolution ResolutionHints
}

Options configures Pack.

type PackageHint added in v0.2.3

type PackageHint struct {
	Ecosystem string
	Name      string
	Imports   []string
}

PackageHint maps an installed distribution to the import names it provides, for ecosystems where the two differ.

type Path added in v0.2.3

type Path []Edge

Path is an ordered chain of edges from a seed to a reached node.

type ReceiverKind added in v0.2.3

type ReceiverKind string

ReceiverKind describes the syntax used to select a call receiver.

const (
	ReceiverBare       ReceiverKind = "bare"
	ReceiverConstant   ReceiverKind = "constant"
	ReceiverLocal      ReceiverKind = "local"
	ReceiverSelf       ReceiverKind = "self"
	ReceiverExpression ReceiverKind = "expression"
)

type Ref added in v0.2.0

type Ref struct {
	Receiver string
	Member   string
	Line     int
}

Ref is a direct member access on a caller-supplied receiver.

func Refs added in v0.2.0

func Refs(src []byte, filename string, receivers []string) ([]Ref, bool)

Refs returns direct member accesses on the requested receiver identifiers. The second return is false when the file's language or syntax tree is unsupported.

type ResolutionHints added in v0.2.3

type ResolutionHints struct {
	SourceRoots []string
	Ecosystems  []string
	Packages    []PackageHint
}

ResolutionHints carries caller-supplied context that improves module resolution beyond what the repository files alone reveal.

type Result

type Result struct {
	Root      string
	Files     []File
	Tree      string
	Truncated bool // MaxFiles was hit
}

Result is the output of Pack.

func Pack

func Pack(root string, opts Options) (*Result, error)

Pack walks root, reads text files that survive gitignore and default filtering, optionally outlines them, and returns the collected result.

func (*Result) Markdown

func (r *Result) Markdown(w io.Writer) error

Markdown writes the result as a single markdown document: directory tree followed by one fenced code block per file.

func (*Result) XML

func (r *Result) XML(w io.Writer) error

XML writes the result in repomix-compatible <file path="...">...</file> form.

type Symbol added in v0.2.0

type Symbol struct {
	Name     string
	Kind     string // func, type, class, const, or var
	Line     int    // one-based source line
	Exported bool
}

Symbol is a top-level declaration captured while outlining a file.

type TraverseOptions added in v0.2.3

type TraverseOptions struct {
	// Depth caps hop distance. Zero means unbounded.
	Depth int
	// Relations restricts which edge relations are followed. Nil means
	// RelCalls only.
	Relations []string
	// IncludeInferred follows inferred-confidence edges as well as
	// extracted ones. Extracted edges are always followed.
	IncludeInferred bool
}

TraverseOptions filters graph traversal.

func (TraverseOptions) Allow added in v0.2.3

func (o TraverseOptions) Allow(e Edge) bool

Allow reports whether e passes the relation and confidence filter.

Directories

Path Synopsis
cmd
outline command
outline-compare command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL