IReadOnlyList<string> Paths { get; }
Source
Gets absolute source-file paths in deterministic filename order.
Loads append-only release-note entries and inserts them into a stable living-note template.
Entries are individual Markdown files in a flat, filename-sorted directory. This avoids concurrent edits to the shared living-note template when independent work streams describe their release-facing changes. Each entry begins with an exact section directive and may add nested headings or ordinary Markdown, but cannot introduce a new top-level section. The supported section identifiers are declared by the template's composition markers, so consumer projects can use their own release-note structure without a code change. Callers use the composed content for rendering or release preparation; the checked-in template remains stable until its owning release workflow resets it.
Task<UnreleasedEntrySet> LoadAsync(string entriesDirectory, CancellationToken cancellationToken)
Loads and validates every entry file in a flat entries directory.
entriesDirectory
cancellationToken
Validated entries and their absolute source paths, ordered by filename.
UnreleasedEntryException
string Compose(string template, IEnumerable<UnreleasedEntry> entries, string destinationPath)
Inserts validated entries at the end of their designated top-level template sections.
template
entries
destinationPath
The deterministic composed release note.
UnreleasedEntryException
string RebaseRelativeLinkDestinations(string markdown, string entryPath, string destinationPath)
Rebases relative Markdown link destinations from an entry source into its composed release-note destination.
markdown
entryPath
destinationPath
Entry Markdown whose relative inline and reference link destinations resolve from the composed document.
Entry files live one directory below both releases/unreleased.md
and versioned release notes. The composer therefore preserves each destination's target while recalculating its relative path from the composed document. External, rooted, query-only, and fragment-only destinations remain unchanged. The transformation deliberately excludes inline, fenced, and indented code so examples retain their original bytes.
IReadOnlyList<MarkdownRange> FindCodeBlockRanges(string markdown)
Collects source-coordinate ranges for code blocks parsed from entry Markdown.
markdown
Half-open source ranges for every fenced or indented code block, including nested containers.
void AddCodeBlockRanges(ContainerBlock container, List<MarkdownRange> ranges)
Recursively adds code-block spans from a Markdown block container.
container
ranges
IReadOnlyList<MarkdownRange> FindInlineCodeRanges(string markdown)
Collects source-coordinate ranges delimited by inline-code backticks.
markdown
Half-open source ranges for matched inline-code delimiters and their contents.
string RewriteLinkDestinations(string markdown, string entryDirectory, string destinationDirectory, int sourceOffset, IReadOnlyList<MarkdownRange> inlineCodeRanges)
Rewrites eligible link destinations from an immutable source line.
markdown
entryDirectory
destinationDirectory
sourceOffset
inlineCodeRanges
The line with eligible destination spans rebased without moving source coordinates.
bool IsInInlineCodeRange(int position, IReadOnlyList<MarkdownRange> inlineCodeRanges)
Determines whether a source position belongs to an inline-code span.
position
inlineCodeRanges
true
when the position is preserved as inline code.
bool IsInMarkdownRange(int position, IReadOnlyList<MarkdownRange> ranges)
Determines whether a source position lies within any half-open Markdown range.
position
ranges
true
when the position is contained by a range.
bool IntersectsMarkdownRange(int start, int end, IReadOnlyList<MarkdownRange> ranges)
Determines whether a source line overlaps any half-open Markdown range.
start
end
ranges
true
when the line and a range share source content.
int CountRun(string value, int start, char character)
Counts consecutive occurrences of a character from a source position.
value
start
character
Number of consecutive matching characters.
bool IsEntryPath(string repositoryRelativePath)
Gets whether a repository-relative path can be an append-only unreleased entry.
repositoryRelativePath
true
when the path is a direct valid entry file.
string MarkerFor(string section)
Gets the exact marker used by the living-note template for a section.
section
Exact HTML comment marker.
IReadOnlyList<TemplateMarker> GetTemplateMarkers(string template)
Reads the unique composition markers declared by the living-note template.
template
Composition markers in their template order.
UnreleasedEntryException
Half-open source-coordinate range in an entry Markdown document.
Start
End
One validated append-only Markdown entry and its destination section.
Path
Section
Markdown
Validated entries together with the source files release preparation removes after archival.
Entries
Snapshots
IReadOnlyList<string> Paths { get; }
Source
Gets absolute source-file paths in deterministic filename order.
Captures one append-only entry source file and the bytes release preparation must revalidate before deletion.
Path
Sha256
Indicates an invalid append-only unreleased entry or living-note template marker shape.
Describes how a package documentation surface reaches the release narrative that applies to it.
A coordinated link is deliberately an alias rather than a version lookup. At release preparation time it resolves to releases/current.md
; the checked-in pointer in each exported docs tree then names that tree's immutable tagged note. Use an explicit link only when a package intentionally has a different release narrative.
Resolves and validates package-index release-link fields shared by package and release tooling.
bool TryResolve(string? releaseTrack, string? releaseNotesPath, out PackageReleaseLink? link, out string? error)
Resolves a package release link from package-index YAML values.
releaseTrack
release_track
YAML value.releaseNotesPath
release_notes_path
YAML value.link
error
true
when the fields describe a supported link and link
is non-null.
Rows without release_track
retain the historical explicit-path meaning when they declare a non-empty release_notes_path
, so old release manifests and archived package-index snapshots remain readable. Every row still needs one source. New coordinated rows must not also carry a versioned path: that combination makes it unclear whether a reader should follow the frozen alias or the mutable package-index value.
Selects the package release-link policy.