codingcontext

package
v0.0.38 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2026 License: MIT Imports: 19 Imported by: 0

README

codingcontext

Go package for dynamically assembling context for AI coding agents.

Installation

go get github.com/kitproj/coding-context-cli/pkg/codingcontext

Usage

Basic Example
package main

import (
    "context"
    "fmt"
    "log/slog"
    "os"

    "github.com/kitproj/coding-context-cli/pkg/codingcontext"
    "github.com/kitproj/coding-context-cli/pkg/codingcontext/taskparser"
)

func main() {
    // Create a new context with options
    ctx := codingcontext.New(
        codingcontext.WithSearchPaths("file://.", "file://"+os.Getenv("HOME")),
        codingcontext.WithParams(taskparser.Params{
            "issue_number": []string{"123"},
            "feature":      []string{"authentication"},
        }),
        codingcontext.WithLogger(slog.New(slog.NewTextHandler(os.Stderr, nil))),
    )

    // Run a task and get the result
    result, err := ctx.Run(context.Background(), "my-task")
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(1)
    }

    // Access the assembled context
    for _, rule := range result.Rules {
        fmt.Println(rule.Content)
    }
    fmt.Println(result.Task.Content)
}
Advanced Example
package main

import (
    "context"
    "fmt"
    "log/slog"
    "os"

    "github.com/kitproj/coding-context-cli/pkg/codingcontext"
    "github.com/kitproj/coding-context-cli/pkg/codingcontext/selectors"
    "github.com/kitproj/coding-context-cli/pkg/codingcontext/taskparser"
)

func main() {
    // Create selectors for filtering rules
    sel := make(selectors.Selectors)
    sel.SetValue("language", "go")
    sel.SetValue("stage", "implementation")

    // Create context with all options
    ctx := codingcontext.New(
        codingcontext.WithSearchPaths(
            "file://.",
            "git::https://github.com/org/repo//path/to/rules",
        ),
        codingcontext.WithParams(taskparser.Params{
            "issue_number": []string{"123"},
        }),
        codingcontext.WithSelectors(sel),
        codingcontext.WithAgent(codingcontext.AgentCursor),
        codingcontext.WithResume(false),
        codingcontext.WithBootstrap(true),
        codingcontext.WithUserPrompt("Additional context or instructions"),
        codingcontext.WithManifestURL("https://example.com/manifest.txt"),
        codingcontext.WithLogger(slog.New(slog.NewTextHandler(os.Stderr, nil))),
    )

    // Run the task and get the result
    result, err := ctx.Run(context.Background(), "implement-feature")
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(1)
    }

    // Process the result
    fmt.Printf("Task: %s\n", result.Task.Content)
    fmt.Printf("Rules found: %d\n", len(result.Rules))
    fmt.Printf("Total tokens: %d\n", result.Tokens)
    fmt.Printf("Agent: %s\n", result.Agent)
    
    // Access task metadata using typed fields
    if len(result.Task.FrontMatter.Languages) > 0 {
        fmt.Printf("Languages: %v\n", result.Task.FrontMatter.Languages)
    }
    
    // You can also access any frontmatter field via the Content map
    if customField, ok := result.Task.FrontMatter.Content["custom_field"]; ok {
        fmt.Printf("Custom field: %v\n", customField)
    }
    
    // Access MCP server configurations
    mcpServers := result.MCPServers()
    for id, config := range mcpServers {
        fmt.Printf("MCP Server %s: %s\n", id, config.Command)
    }
}

API Reference

Types
Context

The main type for assembling context.

Result

Result holds the assembled context from running a task:

  • Rules []Markdown[RuleFrontMatter] - List of included rule files
  • Task Markdown[TaskFrontMatter] - Task file with frontmatter and content
  • Tokens int - Total estimated token count
  • Agent Agent - The agent used (from task frontmatter or option)

Methods:

  • MCPServers() map[string]MCPServerConfig - Returns all MCP server configurations from rules as a map from rule ID to configuration
Markdown[T]

Represents a markdown file with frontmatter and content (generic type):

  • FrontMatter T - Parsed YAML frontmatter (type depends on usage)
  • Content string - Expanded content of the markdown
  • Tokens int - Estimated token count

Type aliases:

  • TaskMarkdown = Markdown[TaskFrontMatter]
  • RuleMarkdown = Markdown[RuleFrontMatter]
TaskFrontMatter

Frontmatter structure for task files with fields:

  • Agent string - Default agent if not specified via option
  • Languages []string - Programming languages for filtering rules
  • Model string - AI model identifier (metadata only)
  • SingleShot bool - Whether task runs once or multiple times (metadata only)
  • Timeout string - Task timeout in time.Duration format (metadata only)
  • MCPServers MCPServerConfigs - MCP server configurations (metadata only)
  • Resume bool - Whether this task should be resumed
  • Selectors map[string]any - Additional custom selectors for filtering rules
  • ExpandParams *bool - Controls parameter expansion (defaults to true)
  • Content map[string]any - All frontmatter fields as map (from BaseFrontMatter)
RuleFrontMatter

Frontmatter structure for rule files with fields:

  • TaskNames []string - Which task(s) this rule applies to
  • Languages []string - Which programming language(s) this rule applies to
  • Agent string - Which AI agent this rule is intended for
  • MCPServers MCPServerConfigs - MCP server configurations (metadata only)
  • RuleName string - Optional identifier for the rule file
  • ExpandParams *bool - Controls parameter expansion (defaults to true)
  • Content map[string]any - All frontmatter fields as map (from BaseFrontMatter)
CommandFrontMatter

Frontmatter structure for command files with fields:

  • ExpandParams *bool - Controls parameter expansion (defaults to true)
  • Content map[string]any - All frontmatter fields as map (from BaseFrontMatter)
BaseFrontMatter

Base frontmatter structure that other frontmatter types embed:

  • Content map[string]any - All frontmatter fields as a map for selector matching
Agent

Type representing an AI coding agent (string type).

Constants:

  • AgentCursor - Cursor AI (cursor.sh)
  • AgentOpenCode - OpenCode.ai agent
  • AgentCopilot - GitHub Copilot
  • AgentClaude - Anthropic Claude AI
  • AgentGemini - Google Gemini AI
  • AgentAugment - Augment Code assistant
  • AgentWindsurf - Codeium Windsurf
  • AgentCodex - Codex AI agent

Methods:

  • String() string - Returns string representation
  • PathPatterns() []string - Returns path patterns for this agent
  • MatchesPath(path string) bool - Checks if path matches agent patterns
  • ShouldExcludePath(path string) bool - Returns true if path should be excluded
  • IsSet() bool - Returns true if agent is set (non-empty)
  • UserRulePath() string - Returns user-level rules path for agent
MCPServerConfig

Configuration for MCP (Model Context Protocol) servers:

  • Type TransportType - Connection protocol ("stdio", "sse", "http")
  • Command string - Executable to run (for stdio type)
  • Args []string - Command arguments
  • Env map[string]string - Environment variables
  • URL string - Endpoint URL (for http/sse types)
  • Headers map[string]string - Custom HTTP headers
MCPServerConfigs

Type alias: map[string]MCPServerConfig - Maps server names to configurations

TransportType

Type representing MCP transport protocol (string type):

Constants:

  • TransportTypeStdio - Local process communication
  • TransportTypeSSE - Server-Sent Events (remote)
  • TransportTypeHTTP - Standard HTTP/POST
Params

Map of parameter key-value pairs for template substitution: map[string][]string

Methods:

  • String() string - Returns string representation
  • Set(value string) error - Parses and sets key=value pair (implements flag.Value)
  • Value(key string) string - Returns the first value for the given key
  • Lookup(key string) (string, bool) - Returns the first value and whether the key exists
  • Values(key string) []string - Returns all values for the given key
Selectors

Map structure for filtering rules based on frontmatter metadata: map[string]map[string]bool

Methods:

  • String() string - Returns string representation
  • Set(value string) error - Parses and sets key=value pair (implements flag.Value)
  • SetValue(key, value string) - Sets a value for a key
  • GetValue(key, value string) bool - Checks if value exists for key
  • MatchesIncludes(frontmatter BaseFrontMatter) bool - Tests if frontmatter matches selectors
Task Parser Types

Types for parsing task content with slash commands:

  • Task - Slice of Block elements representing parsed task content
  • Block - Contains either Text or SlashCommand
  • SlashCommand - Parsed slash command with name and arguments
  • Text - Text content (slice of TextLine)
  • TextLine - Single line of text content
  • Input - Top-level wrapper type for parsing
  • Argument - Slash command argument (can be positional or named key=value)

Methods:

  • (*SlashCommand) Params() taskparser.Params - Returns parsed parameters as map
  • (*Text) Content() string - Returns text content as string
  • Various String() methods for formatting each type
Constants
FreeTextTaskName

Constant: "free-text" - Task name used for free-text prompts

FreeTextParamName

Constant: "text" - Parameter name for text content in free-text tasks

Functions
New(opts ...Option) *Context

Creates a new Context with the given options.

Options:

  • WithSearchPaths(paths ...string) - Add search paths (supports go-getter URLs)
  • WithParams(params taskparser.Params) - Set parameters for substitution (import taskparser package)
  • WithSelectors(selectors selectors.Selectors) - Set selectors for filtering rules (import selectors package)
  • WithAgent(agent Agent) - Set target agent (excludes that agent's own rules)
  • WithResume(resume bool) - Set resume selector to "true" (for filtering tasks by frontmatter resume field)
  • WithBootstrap(doBootstrap bool) - Control whether to discover rules, skills, and run bootstrap scripts (default: true)
  • WithUserPrompt(userPrompt string) - Set user prompt to append to task
  • WithManifestURL(manifestURL string) - Set manifest URL for additional search paths
  • WithLogger(logger *slog.Logger) - Set logger
(*Context) Run(ctx context.Context, taskName string) (*Result, error)

Executes the context assembly for the given task name and returns the assembled result structure with rule and task markdown files (including frontmatter and content).

markdown.ParseMarkdownFile[T any](path string, frontmatter *T) (Markdown[T], error)

Parses a markdown file into frontmatter and content. Generic function that works with any frontmatter type. Import from github.com/kitproj/coding-context-cli/pkg/codingcontext/markdown.

taskparser.ParseTask(text string) (Task, error)

Parses task text content into blocks of text and slash commands. Import from github.com/kitproj/coding-context-cli/pkg/codingcontext/taskparser.

taskparser.ParseParams(s string) (taskparser.Params, error)

Parses a string containing key=value pairs with quoted values.

Examples:

import "github.com/kitproj/coding-context-cli/pkg/codingcontext/taskparser"

// Parse quoted key-value pairs
params, _ := taskparser.ParseParams(`key1="value1" key2="value2"`)
// Result: taskparser.Params{"key1": []string{"value1"}, "key2": []string{"value2"}}

// Parse with spaces in values
params, _ = taskparser.ParseParams(`key1="value with spaces" key2="value2"`)
// Result: taskparser.Params{"key1": []string{"value with spaces"}, "key2": []string{"value2"}}

// Parse with escaped quotes
params, _ = taskparser.ParseParams(`key1="value with \"escaped\" quotes"`)
// Result: taskparser.Params{"key1": []string{"value with \"escaped\" quotes"}}
ParseAgent(s string) (Agent, error)

Parses a string into an Agent type. Returns error if agent is not supported.

See Also

Documentation

Overview

Package codingcontext provides context assembly for AI coding agents.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrTaskNotFound is returned when the requested task file cannot be found.
	ErrTaskNotFound = errors.New("task not found")
	// ErrCommandNotFound is returned when a referenced command file cannot be found.
	ErrCommandNotFound = errors.New("command not found")
	// ErrSkillMissingName is returned when a skill's frontmatter lacks the required name field.
	ErrSkillMissingName = errors.New("skill missing required 'name' field")
	// ErrSkillNameLength is returned when a skill's name exceeds the maximum length.
	ErrSkillNameLength = errors.New("skill 'name' field must be 1-64 characters")
	// ErrSkillMissingDesc is returned when a skill's frontmatter lacks the required description field.
	ErrSkillMissingDesc = errors.New("skill missing required 'description' field")
	// ErrSkillDescriptionLength is returned when a skill's description exceeds the maximum length.
	ErrSkillDescriptionLength = errors.New("skill 'description' field must be 1-1024 characters")

	// ErrInvalidTaskNameNamespace is returned when the task name has an empty namespace.
	ErrInvalidTaskNameNamespace = errors.New("namespace must not be empty")
	// ErrInvalidTaskNameBase is returned when the task name has an empty base name.
	ErrInvalidTaskNameBase = errors.New("task base name must not be empty")
	// ErrInvalidTaskNameDepth is returned when the task name has more than one level of namespacing.
	ErrInvalidTaskNameDepth = errors.New("only one level of namespacing is supported (expected \"namespace/task\")")
)
View Source
var ErrUnknownAgent = errors.New("unknown agent")

ErrUnknownAgent is returned when parsing an unknown or unsupported agent name.

Functions

This section is empty.

Types

type Agent added in v0.0.17

type Agent string

Agent represents an AI coding agent.

const (
	AgentCursor   Agent = "cursor"
	AgentOpenCode Agent = "opencode"
	AgentCopilot  Agent = "copilot"
	AgentClaude   Agent = "claude"
	AgentGemini   Agent = "gemini"
	AgentAugment  Agent = "augment"
	AgentWindsurf Agent = "windsurf"
	AgentCodex    Agent = "codex"
)

Supported agents.

func ParseAgent added in v0.0.17

func ParseAgent(s string) (Agent, error)

ParseAgent parses a string into an Agent type.

func (*Agent) IsSet added in v0.0.18

func (a *Agent) IsSet() bool

IsSet returns true if an agent has been specified (non-empty).

func (*Agent) MatchesPath added in v0.0.17

func (a *Agent) MatchesPath(path string) bool

MatchesPath returns true if the given path matches any of the agent's patterns.

func (*Agent) PathPatterns added in v0.0.17

func (a *Agent) PathPatterns() []string

PathPatterns returns the path patterns associated with this agent.

func (*Agent) Set added in v0.0.18

func (a *Agent) Set(value string) error

Set implements the flag.Value interface for Agent.

func (*Agent) ShouldExcludePath added in v0.0.18

func (a *Agent) ShouldExcludePath(path string) bool

ShouldExcludePath returns true if the given path should be excluded based on this agent Empty agent means no exclusion.

func (*Agent) String added in v0.0.17

func (a *Agent) String() string

String returns the string representation of the agent.

func (*Agent) UserRulePath added in v0.0.24

func (a *Agent) UserRulePath() string

UserRulePath returns the primary user-level rules path for this agent relative to home directory. Returns an empty string if the agent is not set. The path is relative and should be joined with the home directory.

type Context

type Context struct {
	// contains filtered or unexported fields
}

Context holds the configuration and state for assembling coding context.

func New

func New(opts ...Option) *Context

New creates a new Context with the given options.

func (*Context) Lint added in v0.0.38

func (cc *Context) Lint(ctx context.Context, taskName string) (*LintResult, error)

Lint runs context assembly in dry-run mode and returns validation results. It skips bootstrap script execution and shell command expansion (!`cmd`), but otherwise performs the same file loading, parsing, and selector matching as Run(). Fatal errors (e.g. task not found) are returned as errors; structural problems are collected in LintResult.Errors.

func (*Context) ListTasks added in v0.0.38

func (cc *Context) ListTasks(ctx context.Context) ([]DiscoveredTask, error)

ListTasks enumerates all available tasks from the configured search paths without running any of them. It resolves remote directories (same as Run) and scans both global (.agents/tasks/) and namespace-specific (.agents/namespaces/<ns>/tasks/) task directories.

If the same task name appears in multiple search paths the first occurrence wins (consistent with how Run/Lint resolve tasks).

func (*Context) Run

func (cc *Context) Run(ctx context.Context, taskName string) (*Result, error)

Run executes the context assembly for the given taskName and returns the assembled result. The taskName is looked up in task search paths and its content is parsed into blocks. If the taskName cannot be found as a task file, an error is returned.

type DiscoveredTask added in v0.0.38

type DiscoveredTask struct {
	// Name is the task name as passed to Lint or Run (e.g. "my-task" or "myteam/my-task").
	Name string
	// Path is the absolute path to the task markdown file.
	Path string
	// Namespace is the namespace prefix; empty for global tasks.
	Namespace string
}

DiscoveredTask represents a task found during enumeration of search paths.

type LintError added in v0.0.38

type LintError struct {
	Path    string // May be empty
	Kind    LintErrorKind
	Message string
	Line    int // 1-indexed; 0 means unknown (only set for parse errors)
	Column  int // 1-indexed; 0 means unknown (only set for parse errors)
}

LintError records a non-fatal structural problem found during linting.

type LintErrorKind added in v0.0.38

type LintErrorKind string

LintErrorKind identifies the category of a structural problem.

const (
	LintErrorKindParse           LintErrorKind = "parse"
	LintErrorKindMissingCommand  LintErrorKind = "missing-command"
	LintErrorKindSkillValidation LintErrorKind = "skill-validation"
	LintErrorKindSelectorNoMatch LintErrorKind = "selector-no-match"
)

Valid LintErrorKind values.

type LintResult added in v0.0.38

type LintResult struct {
	*Result

	LoadedFiles []LoadedFile
	Errors      []LintError
}

LintResult is returned by Lint(). It embeds the assembled Result plus tracking data collected during the dry run.

type LoadedFile added in v0.0.38

type LoadedFile struct {
	Path string
	Kind LoadedFileKind
}

LoadedFile records a file accessed during context assembly.

type LoadedFileKind added in v0.0.38

type LoadedFileKind string

LoadedFileKind identifies the role of a file loaded during context assembly.

const (
	LoadedFileKindTask      LoadedFileKind = "task"
	LoadedFileKindRule      LoadedFileKind = "rule"
	LoadedFileKindCommand   LoadedFileKind = "command"
	LoadedFileKindSkill     LoadedFileKind = "skill"
	LoadedFileKindPathRef   LoadedFileKind = "path-ref"
	LoadedFileKindBootstrap LoadedFileKind = "bootstrap"
)

Valid LoadedFileKind values.

type Option

type Option func(*Context)

Option is a functional option for configuring a Context.

func WithAgent added in v0.0.17

func WithAgent(agent Agent) Option

WithAgent sets the target agent, which excludes that agent's own rules.

func WithBootstrap added in v0.0.36

func WithBootstrap(doBootstrap bool) Option

WithBootstrap controls whether to discover rules, skills, and run bootstrap scripts. When set to false, rule discovery, skill discovery, and bootstrap script execution are skipped.

func WithLint added in v0.0.38

func WithLint(lint bool) Option

WithLint enables lint mode: skips bootstrap script execution and shell command expansion (!`cmd`). File access is tracked and non-fatal structural errors are collected in LintResult. Use Lint() instead of Run() to retrieve results.

func WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger sets the logger.

func WithManifestURL added in v0.0.20

func WithManifestURL(manifestURL string) Option

WithManifestURL sets the manifest URL.

func WithParams

func WithParams(params taskparser.Params) Option

WithParams sets the parameters.

func WithResume

func WithResume(resume bool) Option

WithResume sets the resume selector to "true", which can be used to filter tasks by their frontmatter resume field. This does not affect rule/skill discovery or bootstrap scripts.

func WithSearchPaths added in v0.0.20

func WithSearchPaths(paths ...string) Option

WithSearchPaths adds one or more search paths.

func WithSelectors

func WithSelectors(selectors selectors.Selectors) Option

WithSelectors sets the selectors.

func WithUserPrompt added in v0.0.24

func WithUserPrompt(userPrompt string) Option

WithUserPrompt sets the user prompt to append to the task.

type Result

type Result struct {
	Name      string                                        // Name of the task
	Namespace string                                        // Active namespace (e.g. "myteam" from "myteam/fix-bug"), empty if none
	Rules     []markdown.Markdown[markdown.RuleFrontMatter] // List of included rule files
	Task      markdown.Markdown[markdown.TaskFrontMatter]   // Task file with frontmatter and content
	Skills    skills.AvailableSkills                        // List of discovered skills (metadata only)
	Tokens    int                                           // Total token count
	Agent     Agent                                         // The agent used (from task or -a flag)
	Prompt    string                                        // Combined prompt: all rules and task content
}

Result holds the assembled context from running a task.

func (*Result) MCPServers added in v0.0.18

func (r *Result) MCPServers() map[string]mcp.MCPServerConfig

MCPServers returns all MCP server configurations from rules as a map. Each rule can specify one MCP server configuration. Returns a map from rule ID to MCP server configuration. Empty/zero-value MCP server configurations are filtered out. The rule ID is automatically set to the filename (without extension) if not explicitly provided in the frontmatter.

Directories

Path Synopsis
Package markdown provides parsing and structs for markdown frontmatter.
Package markdown provides parsing and structs for markdown frontmatter.
Package mcp provides types for MCP (Model Context Protocol) server configuration.
Package mcp provides types for MCP (Model Context Protocol) server configuration.
Package selectors provides selector parsing and matching for rule/skill frontmatter.
Package selectors provides selector parsing and matching for rule/skill frontmatter.
Package skills provides types and serialization for agent skills.
Package skills provides types and serialization for agent skills.
Package taskparser provides parsing and expansion for task content and parameters.
Package taskparser provides parsing and expansion for task content and parameters.
Package tokencount provides token estimation for LLM text.
Package tokencount provides token estimation for LLM text.

Jump to

Keyboard shortcuts

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