Add GSP links field and link inspection

This commit is contained in:
2026-05-07 10:41:38 +08:00
parent 0c5254eb1b
commit 27e71d8c51
18 changed files with 448 additions and 17 deletions

View File

@@ -24,6 +24,7 @@ type Unit struct {
With Relations `json:"with,omitempty" yaml:"with"`
Refines string `json:"refines,omitempty" yaml:"refines"`
Type string `json:"type,omitempty" yaml:"type"`
Links Links `json:"links,omitempty" yaml:"links"`
File string `json:"file,omitempty" yaml:"-"`
}
@@ -67,6 +68,55 @@ func (r *Relations) UnmarshalYAML(value *yaml.Node) error {
return nil
}
type Link struct {
Path string `json:"path" yaml:"path"`
Role string `json:"role,omitempty" yaml:"role"`
Context string `json:"context,omitempty" yaml:"context"`
}
type Links []Link
func (l *Links) UnmarshalYAML(value *yaml.Node) error {
if value.Kind == 0 || value.Tag == "!!null" {
*l = nil
return nil
}
switch value.Kind {
case yaml.ScalarNode:
if value.Value == "" {
return fmt.Errorf("links item cannot be empty")
}
*l = Links{{Path: value.Value}}
return nil
case yaml.SequenceNode:
out := make([]Link, 0, len(value.Content))
for _, item := range value.Content {
switch item.Kind {
case yaml.ScalarNode:
if item.Value == "" {
return fmt.Errorf("links item cannot be empty")
}
out = append(out, Link{Path: item.Value})
case yaml.MappingNode:
var link Link
if err := item.Decode(&link); err != nil {
return err
}
if link.Path == "" {
return fmt.Errorf("links object item requires path")
}
out = append(out, link)
default:
return fmt.Errorf("links item must be a string or object")
}
}
*l = out
return nil
default:
return fmt.Errorf("links must be a string or list")
}
}
type Issue struct {
Level string `json:"level"`
Code string `json:"code"`
@@ -112,6 +162,7 @@ type IndexEntry struct {
Resolution string `json:"resolution,omitempty"`
With []string `json:"with,omitempty"`
Refines string `json:"refines,omitempty"`
Links []string `json:"links,omitempty"`
}
type FlattenResult struct {
@@ -130,16 +181,17 @@ type TraceResult struct {
}
type PackResult struct {
Entry string `json:"entry"`
Intent string `json:"intent,omitempty"`
Stage string `json:"stage,omitempty"`
Depth int `json:"depth"`
Budget int `json:"budget,omitempty"`
Truncated bool `json:"truncated"`
Units []*Unit `json:"units"`
Summary Summary `json:"summary"`
ApproxChars int `json:"approxChars"`
Warnings []Issue `json:"warnings,omitempty"`
Entry string `json:"entry"`
Intent string `json:"intent,omitempty"`
Stage string `json:"stage,omitempty"`
Depth int `json:"depth"`
Budget int `json:"budget,omitempty"`
Truncated bool `json:"truncated"`
Units []*Unit `json:"units"`
Links []ResolvedLink `json:"links,omitempty"`
Summary Summary `json:"summary"`
ApproxChars int `json:"approxChars"`
Warnings []Issue `json:"warnings,omitempty"`
}
type Summary struct {
@@ -148,6 +200,34 @@ type Summary struct {
MaxResolution string `json:"maxResolution,omitempty"`
TypeCounts map[string]int `json:"typeCounts,omitempty"`
MissingCount int `json:"missingCount,omitempty"`
LinkCount int `json:"linkCount,omitempty"`
}
type LinkResult struct {
Entry string `json:"entry"`
Depth int `json:"depth"`
Links []ResolvedLink `json:"links,omitempty"`
Summary LinkSummary `json:"summary"`
Warnings []Issue `json:"warnings,omitempty"`
}
type LinkSummary struct {
Total int `json:"total"`
ByKind map[string]int `json:"byKind,omitempty"`
ByRole map[string]int `json:"byRole,omitempty"`
ByState map[string]int `json:"byState,omitempty"`
}
type ResolvedLink struct {
Owner string `json:"owner"`
Title string `json:"title,omitempty"`
Path string `json:"path"`
Role string `json:"role"`
Kind string `json:"kind"`
Status string `json:"status"`
Exists bool `json:"exists,omitempty"`
Context string `json:"context,omitempty"`
File string `json:"file,omitempty"`
}
type ImpactResult struct {