setup

package
v0.7.1 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

AllRecipes is the default wizard selection order.

Functions

func BeginMarker

func BeginMarker(recipe Recipe, version, contentHash string) string

BeginMarker builds the opening HTML comment for a pine section.

func ContentHash

func ContentHash(body string) string

ContentHash returns a short hex digest of the section body for staleness checks.

func ExtractSection

func ExtractSection(content string) (body string, meta string, found bool)

ExtractSection returns the pine-managed body, marker metadata, and whether it was found.

func HasPine

func HasPine(start string) bool

HasPine reports whether a .pine directory exists at or above start.

func InstallClaudeHook added in v0.3.0

func InstallClaudeHook(root string) (string, error)

InstallClaudeHook idempotently inserts Pine's learn-reminder Stop hook into .claude/settings.json, preserving every other setting and hook. Returns "installed" (added or updated) or "current" (already present and identical).

func InstallCodexHook added in v0.4.0

func InstallCodexHook(root string) (string, error)

InstallCodexHook idempotently installs Pine's learn-reminder Stop hook into .codex/hooks.json and writes the companion script.

func InstallCursorHook added in v0.4.0

func InstallCursorHook(root string) (string, error)

InstallCursorHook idempotently installs Pine's sessionStart learn-reminder into .cursor/hooks.json and writes the companion script.

func InstallSkillFile added in v0.3.0

func InstallSkillFile(root string, info RecipeInfo, opts RenderOptions) (string, error)

InstallSkillFile writes the Pine SKILL.md into an agent's skills directory. The file is wholly Pine-owned: it is (re)written only when its content differs from the current template, so re-running setup after a Pine upgrade refreshes it while an unchanged run is a no-op.

func IsInteractive

func IsInteractive(r io.Reader) bool

IsInteractive reports whether r is a terminal (wizard can prompt).

func MergeFile

func MergeFile(path, markedSection string) error

MergeFile writes or updates the pine section in path.

func RemoveClaudeHook added in v0.3.0

func RemoveClaudeHook(root string) (bool, error)

RemoveClaudeHook strips Pine's learn-reminder hook from .claude/settings.json, leaving other settings intact. Returns whether a hook was removed.

func RemoveCodexHook added in v0.4.0

func RemoveCodexHook(root string) (bool, error)

RemoveCodexHook strips Pine's Codex learn-reminder hook and script.

func RemoveCursorHook added in v0.4.0

func RemoveCursorHook(root string) (bool, error)

RemoveCursorHook strips Pine's Cursor learn-reminder hook and script.

func RemoveSection

func RemoveSection(path string) (bool, error)

RemoveSection deletes the pine block from path. Returns whether a section existed.

func RemoveSkillFile added in v0.3.0

func RemoveSkillFile(root string, info RecipeInfo) (bool, error)

RemoveSkillFile deletes a previously installed SKILL.md (and its now-empty directory, best-effort). Returns whether a file was removed.

func RenderSection

func RenderSection(recipe Recipe, version string, opts RenderOptions) (string, error)

RenderSection builds the marked pine section for one recipe.

func RenderSkill added in v0.3.0

func RenderSkill(opts RenderOptions) string

RenderSkill builds the standalone SKILL.md content Pine installs into an agent's skills directory. Unlike RenderSection it is not marker-wrapped — the file is wholly Pine-owned and rewritten when the template changes.

func RepoRoot

func RepoRoot(start string) (string, error)

RepoRoot resolves the repository root from a starting directory. When no .git directory is found, the starting directory is used as the project root.

func StdinIsInteractive

func StdinIsInteractive() bool

StdinIsInteractive is a convenience wrapper for os.Stdin.

Types

type HookKind added in v0.4.0

type HookKind string

HookKind identifies which agent hook config Pine manages for a recipe.

const (
	HookKindNone   HookKind = ""
	HookKindClaude HookKind = "claude"
	HookKindCodex  HookKind = "codex"
	HookKindCursor HookKind = "cursor"
)

type InstallStatus

type InstallStatus string

InstallStatus reports whether a recipe section is present and current.

const (
	StatusMissing InstallStatus = "missing"
	StatusStale   InstallStatus = "stale"
	StatusCurrent InstallStatus = "current"
)

func CheckClaudeHook added in v0.3.0

func CheckClaudeHook(root string) InstallStatus

CheckClaudeHook reports whether Pine's hook is present and current.

func CheckCodexHook added in v0.4.0

func CheckCodexHook(root string) InstallStatus

CheckCodexHook reports whether Pine's Codex hook is present and current.

func CheckCursorHook added in v0.4.0

func CheckCursorHook(root string) InstallStatus

CheckCursorHook reports whether Pine's Cursor hook is present and current.

func CheckFile

func CheckFile(path string, expectedBody string, recipe Recipe, version string) InstallStatus

CheckFile compares the on-disk section to the expected rendered body.

func CheckSkillFile added in v0.3.0

func CheckSkillFile(root string, info RecipeInfo, opts RenderOptions) InstallStatus

CheckSkillFile reports whether the installed SKILL.md matches the current template.

type Recipe

type Recipe string

Recipe names a target agent integration.

const (
	RecipeAgents Recipe = "agents"
	RecipeClaude Recipe = "claude"
	RecipeGemini Recipe = "gemini"
	RecipeCursor Recipe = "cursor"
)

type RecipeInfo

type RecipeInfo struct {
	Name        Recipe
	File        string
	Label       string
	Description string
	Header      string
	// SkillFile is the repo-relative path where this agent looks for a skill
	// file, or "" when the agent has no skill convention. When set, `pine setup`
	// installs the Pine SKILL.md there in addition to merging the markdown block.
	SkillFile string
	// HookKind is the session-hook target for this recipe, or HookKindNone.
	HookKind HookKind
	// SectionRecipe, when set, is the recipe id used in the AGENTS.md/CLAUDE.md
	// section marker. Cursor shares AGENTS.md with Codex, so it renders and
	// checks as RecipeAgents while still owning only the Cursor hook on remove.
	SectionRecipe Recipe
}

RecipeInfo describes one agent integration bundle.

func Lookup

func Lookup(name Recipe) (RecipeInfo, bool)

Lookup returns recipe metadata or false.

func Registry

func Registry() []RecipeInfo

Registry returns metadata for every built-in recipe.

func (RecipeInfo) InstructionRecipe added in v0.5.0

func (info RecipeInfo) InstructionRecipe() Recipe

InstructionRecipe is the recipe id used when rendering/checking the instruction file section.

func (RecipeInfo) OwnsInstruction added in v0.5.0

func (info RecipeInfo) OwnsInstruction() bool

OwnsInstructionReports whether this recipe owns the instruction file / skill for install-remove. Shared consumers (Cursor → AGENTS.md) do not.

type RenderOptions

type RenderOptions struct {
	// BoardColumns is a comma-separated list of kanban statuses, e.g. "todo, doing, done".
	// When empty, the board-columns line is omitted.
	BoardColumns string
}

RenderOptions supplies dynamic fragments when rendering agent instructions.

type Runner

type Runner struct {
	Root    string // repository root (parent of .pine)
	Version string
	Opts    RenderOptions
	Out     io.Writer
	In      io.Reader

	// Confirm, when set, replaces the interactive Yes/No prompt (tests inject fakes).
	Confirm func(title, description string, defaultYes bool) (bool, error)
	// PickRecipes, when set, replaces the interactive multi-select (tests inject fakes).
	PickRecipes func(infos []RecipeInfo) ([]Recipe, error)
	// MultiSelect, when set, replaces tui.MultiSelectIO inside the default pickRecipes path.
	MultiSelect func(title string, choices []tui.Choice) ([]string, error)
}

Runner performs setup operations against a repository root.

func (*Runner) Check

func (r *Runner) Check(recipes []Recipe) error

Check reports install status for each recipe.

func (*Runner) Install

func (r *Runner) Install(recipes []Recipe) error

Install writes or updates sections for the given recipes.

func (*Runner) List

func (r *Runner) List()

List prints available recipes.

func (*Runner) Print

func (r *Runner) Print(recipes []Recipe) error

Print writes rendered sections to Out.

func (*Runner) Remove

func (r *Runner) Remove(recipes []Recipe) error

Remove strips pine sections for the given recipes.

func (*Runner) Wizard

func (r *Runner) Wizard(hasPine bool) ([]Recipe, error)

Wizard runs the interactive multi-select and returns chosen recipes.

Jump to

Keyboard shortcuts

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