Documentation
¶
Index ¶
- Variables
- func ExtractLevel(tags []string) string
- func IndexCacheAge(cacheDir string) time.Duration
- func LoadProgress(dataDir string) (map[string]TutorialProgress, error)
- func ResolveImageURLs(content, repo, branch, slug string) string
- func ResolveImageURLsKeepMarkdown(content, repo, branch, slug string) string
- func SaveContent(cacheDir string, tut *Tutorial) error
- func SaveIndex(cacheDir string, index []TutorialMeta) error
- func SaveProgress(dataDir string, progress map[string]TutorialProgress) error
- func SaveRepoInfo(cacheDir string, repos []RepoInfo) error
- func UpdateProgress(dataDir, slug string, currentStep, totalSteps int, markDone bool) error
- type Client
- type ClientConfig
- type CommandAnnotation
- type FetchedImage
- type FileCreateAnnotation
- type ImageRef
- type RepoInfo
- type StepAnnotations
- type Tutorial
- type TutorialMeta
- func Enrich(index []TutorialMeta, userAgent string) []TutorialMeta
- func EnrichWithURL(index []TutorialMeta, userAgent, baseURL string) []TutorialMeta
- func FilterByLevel(index []TutorialMeta, level string) []TutorialMeta
- func FilterByTags(index []TutorialMeta, tags []string) []TutorialMeta
- func FindBySlug(index []TutorialMeta, slug string) *TutorialMeta
- func LoadIndex(cacheDir string) ([]TutorialMeta, error)
- func ParseFrontmatterOnly(md, slug, repo string) (*TutorialMeta, error)
- func Search(index []TutorialMeta, query string) []TutorialMeta
- type TutorialProgress
- type TutorialStep
- type VerificationAnnotation
Constants ¶
This section is empty.
Variables ¶
ErrRepoUnavailable is returned when a GitHub API request returns 403 or 404.
Functions ¶
func ExtractLevel ¶
ExtractLevel derives the experience level from tutorial tags.
func IndexCacheAge ¶
IndexCacheAge returns the age of the index cache file, or a negative duration if missing.
func LoadProgress ¶
func LoadProgress(dataDir string) (map[string]TutorialProgress, error)
LoadProgress reads all tutorial progress from the data directory.
func ResolveImageURLs ¶
ResolveImageURLs replaces relative image paths with full GitHub raw content URLs rendered as markdown links so glamour doesn't word-wrap the URL.
func ResolveImageURLsKeepMarkdown ¶
ResolveImageURLsKeepMarkdown resolves relative image paths to full GitHub raw URLs but preserves the  markdown image syntax. Use this for MCP responses where the agent should see image markdown, not link markdown.
func SaveContent ¶
SaveContent writes a parsed tutorial to the content cache.
func SaveIndex ¶
func SaveIndex(cacheDir string, index []TutorialMeta) error
SaveIndex writes the tutorial index to the cache.
func SaveProgress ¶
func SaveProgress(dataDir string, progress map[string]TutorialProgress) error
SaveProgress writes all tutorial progress to the data directory.
func SaveRepoInfo ¶
SaveRepoInfo writes cached repo metadata.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client handles GitHub API interactions for tutorials.
func NewClient ¶
func NewClient(cfg ClientConfig) *Client
NewClient creates a new tutorial GitHub client.
func (*Client) FetchDefaultBranch ¶
FetchDefaultBranch returns the default branch for a repo.
func (*Client) FetchRawMarkdown ¶
FetchRawMarkdown fetches the raw markdown content for a tutorial.
func (*Client) FetchRepoList ¶
FetchRepoList fetches the list of tutorial repo names.
type ClientConfig ¶
type ClientConfig struct {
RepoListURL string
APIBaseURL string
RawBaseURL string
Token string
UserAgent string
}
ClientConfig allows overriding base URLs for testing.
type CommandAnnotation ¶
type FetchedImage ¶
type FetchedImage struct {
Alt string `json:"alt"`
URL string `json:"url"`
Data string `json:"data"`
MIMEType string `json:"mime_type"`
}
FetchedImage holds base64-encoded image data ready for MCP ImageContent.
func FetchImage ¶
func FetchImage(rawURL, cacheDir, slug string) (*FetchedImage, error)
FetchImage downloads an image from url, caches it locally, and returns the base64-encoded data with MIME type. Returns cached data on subsequent calls.
func FetchStepImages ¶
func FetchStepImages(refs []ImageRef, cacheDir, slug string) []FetchedImage
FetchStepImages fetches all images from the given refs, skipping any that fail.
type FileCreateAnnotation ¶
type ImageRef ¶
type ImageRef struct {
Alt string `json:"alt"`
OriginalPath string `json:"original_path"`
URL string `json:"url"`
}
ImageRef represents a parsed image reference from tutorial markdown.
func ExtractImageRefs ¶
ExtractImageRefs finds all markdown image references and resolves relative paths to full GitHub raw URLs. Absolute URLs and path traversals are left as-is.
type RepoInfo ¶
type RepoInfo struct {
Name string `json:"name"`
DefaultBranch string `json:"default_branch"`
TreeSHA string `json:"tree_sha,omitempty"`
}
RepoInfo stores cached metadata about a sap-tutorials repo.
func LoadRepoInfo ¶
LoadRepoInfo reads cached repo metadata.
type StepAnnotations ¶
type StepAnnotations struct {
Commands []CommandAnnotation `json:"commands,omitempty"`
FileCreates []FileCreateAnnotation `json:"file_creates,omitempty"`
Verifications []VerificationAnnotation `json:"verifications,omitempty"`
PrerequisiteTools []string `json:"prerequisite_tools,omitempty"`
}
func AnnotateStep ¶
func AnnotateStep(md string) StepAnnotations
type Tutorial ¶
type Tutorial struct {
TutorialMeta
Prerequisites string `json:"prerequisites,omitempty"`
YouWillLearn []string `json:"you_will_learn,omitempty"`
Steps []TutorialStep `json:"steps"`
}
Tutorial is a fully parsed tutorial with step content.
func LoadContent ¶
LoadContent reads a parsed tutorial from the content cache.
type TutorialMeta ¶
type TutorialMeta struct {
Slug string `json:"slug"`
Title string `json:"title"`
Description string `json:"description"`
Time int `json:"time"`
Level string `json:"level"`
Tags []string `json:"tags"`
PrimaryTag string `json:"primary_tag"`
Author string `json:"author,omitempty"`
Repo string `json:"repo"`
URL string `json:"url"`
Parser string `json:"parser"`
}
TutorialMeta is a resolved tutorial in the full index (cached from GitHub).
func Enrich ¶
func Enrich(index []TutorialMeta, userAgent string) []TutorialMeta
Enrich attempts to augment the index with data from developers.sap.com. Returns the original index unchanged if the API is unavailable (403, timeout, etc.).
func EnrichWithURL ¶
func EnrichWithURL(index []TutorialMeta, userAgent, baseURL string) []TutorialMeta
EnrichWithURL is the testable variant of Enrich with a custom base URL.
func FilterByLevel ¶
func FilterByLevel(index []TutorialMeta, level string) []TutorialMeta
FilterByLevel returns tutorials matching the given level.
func FilterByTags ¶
func FilterByTags(index []TutorialMeta, tags []string) []TutorialMeta
FilterByTags returns tutorials with at least one tag matching (OR, case-insensitive, substring).
func FindBySlug ¶
func FindBySlug(index []TutorialMeta, slug string) *TutorialMeta
FindBySlug returns the first tutorial matching slug, or nil.
func LoadIndex ¶
func LoadIndex(cacheDir string) ([]TutorialMeta, error)
LoadIndex reads the tutorial index from the cache and deduplicates by slug.
func ParseFrontmatterOnly ¶
func ParseFrontmatterOnly(md, slug, repo string) (*TutorialMeta, error)
ParseFrontmatterOnly extracts metadata without parsing steps.
func Search ¶
func Search(index []TutorialMeta, query string) []TutorialMeta
Search returns tutorials matching query against title, description, slug, and tags. Multi-word queries use AND semantics: every word must appear somewhere in the combined text. Results are ranked: title matches first, then others.
type TutorialProgress ¶
type TutorialProgress struct {
Slug string `json:"slug"`
CurrentStep int `json:"current_step"`
CompletedSteps []int `json:"completed_steps"`
TotalSteps int `json:"total_steps"`
StartedAt time.Time `json:"started_at"`
LastAccessed time.Time `json:"last_accessed"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
}
TutorialProgress tracks a user's position within a tutorial.
func GetProgress ¶
func GetProgress(dataDir, slug string) (*TutorialProgress, error)
GetProgress returns progress for a single tutorial, or nil if not started.
func MergeCompletedSteps ¶
func MergeCompletedSteps(dataDir, slug string, completedSteps []int, currentStep, totalSteps int) (*TutorialProgress, error)
MergeCompletedSteps merges a batch of completed step indices into the stored progress for a tutorial. Steps are deduplicated and sorted. currentStep is set explicitly if > 0, otherwise inferred from the last completed step. If all steps are completed, CompletedAt is stamped.
type TutorialStep ¶
type TutorialStep struct {
Number int `json:"number"`
Title string `json:"title"`
Content string `json:"content"`
}
TutorialStep is a single step within a tutorial.