Documentation
¶
Overview ¶
Package parser extracts a flat node list from a typed-skill source file. It is the AST surface the agent IDE uses to render both the Slice 1 textual node list and the Slice 3 React Flow canvas. Code is canon: every node here corresponds to a real call site in the author's source on disk and click-to-`$EDITOR` is a one-line jump to that file:line.
The parser is read-only — it never mutates source. It is also deliberately strict about what it recognises: only the five graph primitives (tool, llm, parallel, handoff, approval) appear as nodes. Function bodies, types, imports, prompt strings, and control flow are not nodes; if a future slice ever needs them, it gets a separate extractor.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrUnsupportedLang = errors.New("parser: unsupported source extension")
ErrUnsupportedLang is returned when ParseFile is given a path with neither a .go nor .ts extension.
Functions ¶
This section is empty.
Types ¶
type Graph ¶
type Graph struct {
// Skill is the unprefixed skill name supplied by the caller.
Skill string `json:"skill"`
// Lang is the source flavor.
Lang Lang `json:"lang"`
// File is the parsed source file's path.
File string `json:"file"`
// Nodes is the ordered list of recognised call sites.
Nodes []Node `json:"nodes"`
// ParseError is non-empty when the source could not be parsed
// cleanly; the IDE surfaces this as a stale-graph banner so the
// last-good view stays visible until the author fixes the
// syntax.
ParseError string `json:"parse_error,omitempty"`
}
Graph is the parsed shape of one skill source file. Edges are implicit: each node points to its successor in declaration order. The frontend computes the edge list by zipping pairs.
func ParseFile ¶
ParseFile reads and parses a single source file. The skill name is the unprefixed identifier the IDE uses to key the resulting graph.
func ParseSkill ¶
ParseSkill parses every recognised typed-skill source under skillDir and returns a single combined Graph. When both `skill.go` and `skill.ts` are present the Go file wins (matches the registry's detectHandler precedence) so the IDE renders one canonical graph per skill.
type Lang ¶
type Lang string
Lang names the source flavor a node was extracted from. Drives per-flavor decisions in the IDE (e.g. "needs explicit `agent build` to refresh" for Go, "hot-reloads on save" for TS).
type Node ¶
type Node struct {
// ID is a stable identifier within a skill — `kind:index` so
// React Flow keys are deterministic across re-parses.
ID string `json:"id"`
// Kind is the recognised primitive (tool / llm / parallel /
// handoff / approval).
Kind NodeKind `json:"kind"`
// Label is the human-readable label rendered on the node. For
// `tool("server__name", ...)` this is the literal string; for
// `llm({model: "claude-..."})` it is the model name; for
// orchestration primitives it is a short summary.
Label string `json:"label"`
// File is the path to the source file (absolute when produced by
// ParseFile, relative to the skill root when produced by
// ParseSkill). The frontend joins it with the IDE root when it
// constructs the `editor://` link.
File string `json:"file"`
// Line is the 1-based source line of the call expression.
Line int `json:"line"`
// Col is the 1-based column of the call expression.
Col int `json:"col"`
// Detail is an optional second line of context the IDE renders
// in the node detail pane (e.g. the full first-argument string
// when truncated). Empty when no extra context is helpful.
Detail string `json:"detail,omitempty"`
}
Node is one call site recognised in a skill's source. The shape is identical across Go and TS so the IDE renders both flavors against the same component tree.