idea

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package idea parses and represents SpecScore Idea artifacts.

An Idea is a single markdown file under `spec/ideas/` (or `spec/ideas/archived/`) that captures a pre-spec, lintable one-pager: problem framing, recommended direction, MVP scope, exclusions, and dealbreaker assumptions. See `spec/features/idea/README.md` for the full artifact schema.

This package provides parsing utilities — the lint rules that enforce the schema live in `pkg/lint`.

Index

Constants

This section is empty.

Variables

View Source
var RequiredHeaderFields = []string{
	"Status",
	"Date",
	"Owner",
	"Promotes To",
	"Supersedes",
	"Related Ideas",
}

RequiredHeaderFields lists required **X:** fields in order.

View Source
var RequiredSections = []string{
	"Problem Statement",
	"Context",
	"Recommended Direction",
	"Alternatives Considered",
	"MVP Scope",
	"Not Doing (and Why)",
	"Key Assumptions to Validate",
	"SpecScore Integration",
	"Open Questions",
}

RequiredSections names the sections that every Idea MUST have, in order.

View Source
var ValidRelationships = map[string]bool{
	"depends_on":     true,
	"alternative_to": true,
	"extends":        true,
	"conflicts_with": true,
}

Valid relationship types for Related Ideas entries.

View Source
var ValidStatuses = map[string]bool{
	"Draft":        true,
	"Under Review": true,
	"Approved":     true,
	"Specified":    true,
	"Archived":     true,
}

Valid statuses for an Idea.

Functions

func FeatureSourceIdeas

func FeatureSourceIdeas(specRoot string) (map[string][]string, error)

FeatureSourceIdeas scans every `spec/features/**/README.md` and returns a map of feature slug -> []idea-slug based on the **Source Ideas:** header. Features without the field are omitted. Only top-level feature dirs are returned (filepath suffix: "features/<slug>/README.md").

func FindIdeaDirectories

func FindIdeaDirectories(specRoot string) ([]string, error)

FindIdeaDirectories returns directories that exist at `spec/ideas/<slug>/` (violation per REQ: single-file). Ignores the reserved `archived/` dir.

func Scaffold

func Scaffold(opts ScaffoldOptions) ([]byte, error)

Scaffold returns a lint-clean Idea file body for the given options. Every required section is emitted either with an HTML-comment prompt (the default) or with the supplied content.

func SortedStatuses

func SortedStatuses() []string

Sort returns a slice of statuses sorted alphabetically (helper for tests).

func ValidateSlug

func ValidateSlug(slug string) error

ValidateSlug returns nil if slug matches `[a-z0-9]+(-[a-z0-9]+)*`.

Types

type Discovered

type Discovered struct {
	Slug     string
	Path     string // absolute or relative path to the .md file
	Archived bool   // true if located under archived/
}

Discovered is a summary of an Idea file found during discovery.

func Discover

func Discover(specRoot string) ([]Discovered, error)

Discover walks `<specRoot>/ideas` and returns every idea file found. Returns ([], nil) if the directory does not exist.

type HeaderField

type HeaderField struct {
	Name  string
	Value string
	Line  int
}

HeaderField captures a single **Name:** value line.

type Idea

type Idea struct {
	Path           string
	Slug           string
	Title          string // full title line (without leading "# ")
	TitleName      string // name portion after "Idea: "
	TitleOK        bool   // true if title matches "# Idea: <Name>"
	TitleLine      int
	HasTitle       bool
	Fields         []HeaderField // in-order header fields encountered
	FieldByName    map[string]HeaderField
	Sections       []Section
	SectionByTitle map[string]*Section
	RawLines       []string
}

Idea is a parsed Idea artifact.

func Parse

func Parse(path string) (*Idea, error)

Parse reads an Idea file and returns its parsed representation. Parse is resilient — it returns a partial Idea even if the file is malformed (missing title, missing sections). Callers (lint rules) decide what is an error.

func (*Idea) ArchiveReason

func (i *Idea) ArchiveReason() string

ArchiveReason returns the Archive Reason value or "".

func (*Idea) PromotesTo

func (i *Idea) PromotesTo() []string

PromotesTo returns the parsed Promotes To slugs (comma-separated list). A value of "—" or "-" means empty.

func (*Idea) RelatedIdeas

func (i *Idea) RelatedIdeas() []string

RelatedIdeas returns the raw entries (un-split) from the Related Ideas field.

func (*Idea) Status

func (i *Idea) Status() string

Status returns the Status field value or "" if missing.

func (*Idea) Supersedes

func (i *Idea) Supersedes() []string

Supersedes returns the parsed Supersedes slugs.

type ScaffoldOptions

type ScaffoldOptions struct {
	Slug string
	// Title is the human-readable name after `# Idea: `. Defaults to
	// a title-cased version of the slug.
	Title string
	Owner string
	// Date in ISO-8601 (YYYY-MM-DD). Defaults to today's UTC date.
	Date string
	// Status defaults to "Draft".
	Status string

	// Section content. Empty strings leave the default prompt in place.
	HMW                  string // Problem Statement
	Context              string
	RecommendedDirection string
	Alternatives         []string // Each element is a bullet for Alternatives Considered.
	MVP                  string
	// NotDoing is a list of exclusions. When empty, a lint-clean default
	// list is emitted so the Not Doing section passes idea-not-doing-non-empty.
	NotDoing []string
	// Assumptions is an optional list of assumption-table rows.
	// Each row is {Tier, Assumption, HowToValidate}. When empty, a
	// lint-clean default table with one Must-be-true row is emitted.
	Assumptions [][3]string
	// SpecScore Integration overrides.
	NewFeatures  string
	Existing     string
	Dependencies string
	// OpenQuestions bullets (optional).
	OpenQuestions []string
}

ScaffoldOptions controls the content emitted by Scaffold. Any field left empty keeps the section's default HTML-comment prompt.

type Section

type Section struct {
	Title     string
	StartLine int
	EndLine   int
	Body      string
	Items     []string // lines starting with "- "
}

Section captures a single ## heading and its body.

type Table

type Table struct {
	Headers []string
	Rows    [][]string
}

Table captures a markdown pipe-table within a section.

func ParseTable

func ParseTable(body string) *Table

ParseTable extracts a markdown pipe-table from the given section body. Returns nil if no table is present. Only the first table is returned.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL