Documentation
¶
Index ¶
- Constants
- func ChapterTarget(sagaID, chapterID string) string
- func EntrypointError(value string) string
- func FragmentTarget(sagaID, fragmentID string) string
- func LandmarkTarget(sagaID, fragmentID, landmarkID string) string
- func Load(root string) (*Saga, Validation, error)
- func PortabilityWarning(name string) string
- func PortablePathWarning(value string) string
- func SagaTarget(sagaID string) string
- func SectionTarget(sagaID, sectionID string) string
- func ValidAnnotationColor(value string) bool
- func ValidClaimKind(value string) bool
- func ValidID(value string) bool
- func ValidMarkdownAnchor(value string) bool
- func ValidMediaType(value string) bool
- func ValidVerificationMethod(value string) bool
- func ValidVerificationStatus(value string) bool
- func ValidateAnchor(anchor Anchor) error
- type AddedAnchor
- type Anchor
- type ChapterManifest
- type Claim
- type DiffFile
- type DiffReference
- type DiffReview
- type DiffSelector
- type Fragment
- type FragmentManifest
- type Issue
- type Landmark
- type LandmarkRegion
- type LandmarkSelector
- type Manifest
- type MarkdownHeading
- type Message
- type MessageManifest
- type NoteSelector
- type PR
- type Point
- type Review
- type Saga
- type Section
- type SectionManifest
- type Shape
- type Source
- type Suggestion
- type TextSelector
- type Thread
- type ThreadEvent
- type ThreadManifest
- type Validation
- type Verification
Constants ¶
const ( CurrentVersion = 2 SchemaURL = "https://changesaga.dev/schema/v2/saga.schema.json" )
const MaxNoteRunes = 2000
MaxNoteRunes bounds sticky note text so a single annotation stays a compact canvas note rather than an unbounded document; schema/v2 enforces the same limit as maxLength.
Variables ¶
This section is empty.
Functions ¶
func ChapterTarget ¶
func EntrypointError ¶
EntrypointError reports why a fragment entrypoint is unusable, or "" when it is a well-formed package-relative path.
The check is deliberately expressed in slash-path terms rather than through path/filepath. filepath.Clean rewrites "assets/app.js" to "assets\app.js" on Windows, so an OS-dependent normalization comparison would reject a portable nested entrypoint on exactly one platform. Backslashes are rejected outright because they are an ordinary filename byte on Unix and a separator on Windows, which would make one saga address two different files.
func FragmentTarget ¶
func LandmarkTarget ¶
func PortabilityWarning ¶
PortabilityWarning reports why a path component cannot exist on every platform Change Saga supports, or "" when the name is portable. It never produces errors: a saga that already contains such a name stays loadable on the platform that created it, but authors are told before publishing it.
func PortablePathWarning ¶
PortablePathWarning applies PortabilityWarning to every component of a slash path.
func SagaTarget ¶
func SectionTarget ¶
func ValidAnnotationColor ¶
func ValidClaimKind ¶ added in v0.0.2
func ValidMarkdownAnchor ¶
func ValidMediaType ¶
ValidMediaType reports whether a fragment media type is one the format defines. Engines render text/markdown, text/html, text/plain, image/svg+xml, and raster image/* fragments.
func ValidVerificationMethod ¶ added in v0.0.2
func ValidVerificationStatus ¶ added in v0.0.2
func ValidateAnchor ¶
Types ¶
type AddedAnchor ¶ added in v0.0.2
type AddedAnchor struct {
Line int `json:"line"`
Heading string `json:"heading"`
Anchor string `json:"anchor"`
}
AddedAnchor records one heading that gained a stable anchor.
func FixMarkdownHeadingAnchors ¶ added in v0.0.2
func FixMarkdownHeadingAnchors(content []byte, reserved map[string]bool) ([]byte, []AddedAnchor)
FixMarkdownHeadingAnchors appends " {#anchor}" to every heading that does not already declare one and returns the rewritten content. It is deliberately the narrowest possible edit: headings that already carry an anchor keep it, fenced code is skipped, and every other byte — including indentation, blank lines, and CRLF endings — is preserved. Nothing is renamed, so an anchor that a landmark or link already points at cannot move.
reserved names identifiers the generated anchors must avoid, which is how a non-heading landmark keeps its id from being claimed by a heading that would then conflict with it.
type Anchor ¶
type Anchor struct {
Type string `json:"type"`
Shapes []Shape `json:"shapes,omitempty"`
Text *TextSelector `json:"text,omitempty"`
Note *NoteSelector `json:"note,omitempty"`
Diff *DiffSelector `json:"diff,omitempty"`
Coordinate string `json:"coordinate_space,omitempty"`
}
type ChapterManifest ¶
type Claim ¶ added in v0.0.2
type Claim struct {
Path string `json:"-"`
Version int `json:"version"`
ID string `json:"id"`
Target string `json:"target"`
Kind string `json:"kind"`
Statement string `json:"statement"`
Evidence []string `json:"evidence"`
CreatedAt time.Time `json:"created_at"`
}
Claim is one falsifiable assertion made by the change author. Claims are deliberately independent records: adding a second claim never rewrites the first record and two authors do not contend on one aggregate manifest. Evidence here does not contribute to coverage; it points at exact code that an independent reviewer can inspect when testing the assertion.
type DiffFile ¶
type DiffFile struct {
Path string `json:"-"`
Version int `json:"version"`
Diffs []DiffReference `json:"diffs"`
}
type DiffReference ¶
type DiffReview ¶
type DiffSelector ¶
type DiffSelector struct {
URI string `json:"uri"`
}
type Fragment ¶
type Fragment struct {
Path string `json:"path"`
Directory string `json:"-"`
ID string `json:"id"`
Title string `json:"title,omitempty"`
MediaType string `json:"media_type"`
Entrypoint string `json:"entrypoint"`
Order int `json:"order,omitempty"`
Target string `json:"target"`
Diffs []DiffFile `json:"diffs,omitempty"`
Landmarks []Landmark `json:"landmarks,omitempty"`
Reviews []Review `json:"reviews,omitempty"`
}
type FragmentManifest ¶
type Landmark ¶
type Landmark struct {
Path string `json:"-"`
Directory string `json:"-"`
Version int `json:"version"`
ID string `json:"id"`
Label string `json:"label"`
Description string `json:"description,omitempty"`
Selector LandmarkSelector `json:"selector"`
Hotspot *LandmarkRegion `json:"hotspot,omitempty"`
Target string `json:"target"`
Diffs []DiffFile `json:"diffs,omitempty"`
}
type LandmarkRegion ¶
type LandmarkSelector ¶
type LandmarkSelector struct {
Type string `json:"type"`
ElementID string `json:"element_id,omitempty"`
HeadingID string `json:"heading_id,omitempty"`
Exact string `json:"exact,omitempty"`
Prefix string `json:"prefix,omitempty"`
Suffix string `json:"suffix,omitempty"`
X float64 `json:"x,omitempty"`
Y float64 `json:"y,omitempty"`
Width float64 `json:"width,omitempty"`
Height float64 `json:"height,omitempty"`
}
type MarkdownHeading ¶
MarkdownHeading describes the small heading subset supported by the reference renderer. Explicit anchors use: ## Heading {#stable-anchor}.
func MarkdownHeadings ¶
func MarkdownHeadings(source string) []MarkdownHeading
func ParseMarkdownHeading ¶
func ParseMarkdownHeading(line string) (MarkdownHeading, bool)
type MessageManifest ¶
type NoteSelector ¶
type PR ¶
PR uses a pointer for Number so an absent pull request number stays absent. schema/v2/saga.schema.json requires a positive number when the field is present; a plain int could not tell "unset" from an invalid literal 0.
type Saga ¶
type Saga struct {
Root string `json:"root"`
Manifest Manifest `json:"manifest"`
Section *Section `json:"section"`
Threads []*Thread `json:"threads,omitempty"`
DiffReviews []DiffReview `json:"diff_reviews,omitempty"`
Claims []Claim `json:"claims,omitempty"`
Verifications []Verification `json:"verifications,omitempty"`
}
type Section ¶
type Section struct {
Path string `json:"path"`
Kind string `json:"kind"`
ID string `json:"id"`
Title string `json:"title"`
Order int `json:"order,omitempty"`
Target string `json:"target"`
Children []*Section `json:"children,omitempty"`
Fragments []*Fragment `json:"fragments,omitempty"`
Diffs []DiffFile `json:"diffs,omitempty"`
Reviews []Review `json:"reviews,omitempty"`
}
type SectionManifest ¶
type Shape ¶
type Shape struct {
Type string `json:"type"`
X float64 `json:"x,omitempty"`
Y float64 `json:"y,omitempty"`
Width float64 `json:"width,omitempty"`
Height float64 `json:"height,omitempty"`
Points []Point `json:"points,omitempty"`
Color string `json:"color,omitempty"`
StrokeWidth float64 `json:"stroke_width,omitempty"`
}
type Suggestion ¶
type Suggestion struct {
Replacement string `json:"replacement"`
}
type TextSelector ¶
type Thread ¶
type Thread struct {
Version int `json:"version"`
ID string `json:"id"`
Target string `json:"target"`
Anchor Anchor `json:"anchor"`
Kind string `json:"kind,omitempty"`
Suggestion *Suggestion `json:"suggestion,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
CreatedAt time.Time `json:"created_at"`
Directory string `json:"-"`
AttributionDetail string `json:"-"`
Messages []*Message `json:"messages,omitempty"`
Events []ThreadEvent `json:"events,omitempty"`
State string `json:"state"`
}
type ThreadEvent ¶
type ThreadManifest ¶
type ThreadManifest struct {
Version int `json:"version"`
ID string `json:"id"`
Target string `json:"target"`
Anchor Anchor `json:"anchor"`
Kind string `json:"kind,omitempty"`
Suggestion *Suggestion `json:"suggestion,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
type Validation ¶
type Verification ¶ added in v0.0.2
type Verification struct {
Path string `json:"-"`
Version int `json:"version"`
ID string `json:"id"`
Claim string `json:"claim"`
Status string `json:"status"`
Method string `json:"method,omitempty"`
Summary string `json:"summary"`
Command string `json:"command,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
Verification is an append-only result for one claim. The latest result is useful for navigation, but the complete history remains committed as separate files so a later result never erases the earlier one.