core

package
v0.4.5 Latest Latest
Warning

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

Go to latest
Published: Sep 25, 2025 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package core defines all the core functionalities to work with tasks.

Index

Constants

View Source
const (
	// TaskIDPrefix is the prefix used for task filenames.
	TaskIDPrefix = "T"
)

Variables

View Source
var ErrInvalid = errors.New("invalid value")
View Source
var ZeroTaskID = TaskID{/* contains filtered or unexported fields */}

Functions

func RecordChange

func RecordChange(task *Task, change string)

RecordChange adds a history entry to the task for the given change

func RecordConflictResolution added in v0.4.0

func RecordConflictResolution(task *Task, action, description string, metadata map[string]any)

RecordConflictResolution adds a history entry for conflict resolution actions

func RecordIDChange added in v0.4.0

func RecordIDChange(task Task, oldID, newID TaskID, reason string, metadata map[string]any)

RecordIDChange adds a specialized history entry for ID changes during conflict resolution

func RecordParentChange added in v0.4.0

func RecordParentChange(task *Task, oldParent, newParent TaskID, reason string)

RecordParentChange adds a history entry for parent reference changes

Types

type AcceptanceCriterion

type AcceptanceCriterion struct {
	Text    string `json:"text"`
	Checked bool   `json:"checked"`
	Index   int    `json:"index"`
}

AcceptanceCriterion represents a single item in the acceptance criteria list.

type ConflictDetector added in v0.4.0

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

ConflictDetector handles detection and resolution of ID conflicts

func NewConflictDetector added in v0.4.0

func NewConflictDetector(fs afero.Fs, tasksDir string) *ConflictDetector

NewConflictDetector creates a new conflict detector

func (*ConflictDetector) DetectConflicts added in v0.4.0

func (cd *ConflictDetector) DetectConflicts() ([]IDConflict, error)

DetectConflicts scans all task files and identifies ID conflicts

type ConflictResolver added in v0.4.0

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

ConflictResolver handles resolution of ID conflicts

func NewConflictResolver added in v0.4.0

func NewConflictResolver(detector *ConflictDetector, store *FileTaskStore) *ConflictResolver

NewConflictResolver creates a new conflict resolver

func (*ConflictResolver) CreateResolutionPlan added in v0.4.0

func (cr *ConflictResolver) CreateResolutionPlan(conflicts []IDConflict, strategy ResolutionStrategy) (*ResolutionPlan, error)

CreateResolutionPlan generates a plan to resolve the given conflicts

func (*ConflictResolver) ExecuteResolutionPlan added in v0.4.0

func (cr *ConflictResolver) ExecuteResolutionPlan(plan *ResolutionPlan, dryRun bool) ([]string, error)

ExecuteResolutionPlan executes the given resolution plan

func (*ConflictResolver) ExecuteResolutionPlanWithReferences added in v0.4.0

func (cr *ConflictResolver) ExecuteResolutionPlanWithReferences(plan *ResolutionPlan, dryRun bool) ([]string, error)

ExecuteResolutionPlanWithReferences executes a resolution plan and updates all references

type ConflictSummary added in v0.4.0

type ConflictSummary struct {
	TotalConflicts   int
	DuplicateIDs     int
	OrphanedChildren int
	InvalidHierarchy int
	ConflictsByType  map[ConflictType][]IDConflict
}

ConflictSummary provides a summary of detected conflicts

func SummarizeConflicts added in v0.4.0

func SummarizeConflicts(conflicts []IDConflict) ConflictSummary

SummarizeConflicts creates a summary of the provided conflicts

type ConflictType added in v0.4.0

type ConflictType int

ConflictType represents the type of ID conflict detected

const (
	ConflictTypeDuplicateID ConflictType = iota
	ConflictTypeInvalidHierarchy
	ConflictTypeOrphanedChild
)

func (ConflictType) String added in v0.4.0

func (ct ConflictType) String() string

String returns the string representation of ConflictType

type CreateTaskParams

type CreateTaskParams struct {
	Title        string   `json:"title"                  jsonschema:"Required. The title of the task."`
	Description  string   `json:"description"            jsonschema:"A detailed description of the task."`
	Priority     string   `json:"priority,omitempty"     jsonschema:"The priority of the task."`
	Parent       string   `json:"parent,omitempty"       jsonschema:"The ID of the parent task."`
	Assigned     []string `json:"assigned,omitempty"     jsonschema:"A list of names assigned."`
	Labels       []string `json:"labels,omitempty"       jsonschema:"A list of labels."`
	Dependencies []string `json:"dependencies,omitempty" jsonschema:"A list of task IDs that this task depends on."`
	AC           []string `json:"ac,omitempty"           jsonschema:"A list of acceptance criteria."`
	Plan         string   `json:"plan,omitempty"         jsonschema:"The implementation plan."`
	Notes        string   `json:"notes,omitempty"        jsonschema:"Additional notes."`
}

CreateTaskParams holds the parameters for creating a new task.

type EditTaskParams

type EditTaskParams struct {
	ID              string   `json:"id"                         jsonschema:"Required. The ID of the task to edit."`
	NewTitle        *string  `json:"new_title,omitempty"        jsonschema:"A new title for the task."`
	NewDescription  *string  `json:"new_description,omitempty"  jsonschema:"A new description for the task."`
	NewStatus       *string  `json:"new_status,omitempty"       jsonschema:"A new status (e.g., 'in-progress', 'done')."`
	NewPriority     *string  `json:"new_priority,omitempty"     jsonschema:"A new priority."`
	NewParent       *string  `json:"new_parent,omitempty"       jsonschema:"A new parent task ID."`
	AddAssigned     []string `json:"add_assigned,omitempty"     jsonschema:"A new list of assigned."`
	RemoveAssigned  []string `json:"remove_assigned,omitempty"  jsonschema:"A list of assigned to remove."`
	AddLabels       []string `json:"add_labels,omitempty"       jsonschema:"Add new list of labels."`
	RemoveLabels    []string `json:"remove_labels,omitempty"    jsonschema:"A list of labels to remove."`
	NewDependencies []string `json:"new_dependencies,omitempty" jsonschema:"A new list of dependencies (replaces the old list)."`
	NewNotes        *string  `json:"new_notes,omitempty"        jsonschema:"New implementation notes."`
	NewPlan         *string  `json:"new_plan,omitempty"         jsonschema:"New implementation plan."`
	AddAC           []string `json:"add_ac,omitempty"           jsonschema:"A list of new acceptance criteria to add."`
	CheckAC         []int    `json:"check_ac,omitempty"         jsonschema:"A list of 1-based indices of AC to check."`
	UncheckAC       []int    `json:"uncheck_ac,omitempty"       jsonschema:"A list of 1-based indices of AC to uncheck."`
	RemoveAC        []int    `json:"remove_ac,omitempty"        jsonschema:"A list of 1-based indices of AC to remove."`
}

EditTaskParams holds the parameters for editing a task.

type FileTaskStore

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

func NewFileTaskStore

func NewFileTaskStore(fs afero.Fs, tasksDir string) *FileTaskStore

func (*FileTaskStore) Archive

func (f *FileTaskStore) Archive(id TaskID) (string, error)

Archive moves a task to the archived directory and updates its status.

func (*FileTaskStore) Create

func (f *FileTaskStore) Create(params CreateTaskParams) (newTask Task, err error)

Create implements TaskStore.

func (*FileTaskStore) Get

func (f *FileTaskStore) Get(id string) (task Task, err error)

Get implements TaskStore.

func (*FileTaskStore) List

func (f *FileTaskStore) List(params ListTasksParams) (result ListResult, err error)

List implements TaskStore.

func (*FileTaskStore) Path

func (f *FileTaskStore) Path(t Task) string

func (*FileTaskStore) Update

func (f *FileTaskStore) Update(task *Task, params EditTaskParams) error

Update updates an existing task based on the provided parameters.

type Frontmatter

type Frontmatter struct {
	ID           string           `yaml:"id"`
	Title        string           `yaml:"title"`
	Status       string           `yaml:"status"`
	Assignee     MaybeStringArray `yaml:"assignee,omitempty"`
	Labels       MaybeStringArray `yaml:"labels,omitempty"`
	Dependencies MaybeStringArray `yaml:"dependencies,omitempty"`
	Parent       string           `yaml:"parent,omitempty"`
	Priority     string           `yaml:"priority,omitempty"`
	CreatedAt    time.Time        `yaml:"created_at"`
	UpdatedAt    time.Time        `yaml:"updated_at,omitempty"`
	History      []HistoryEntry   `yaml:"history,omitempty"`
}

type HistoryEntry

type HistoryEntry struct {
	Timestamp time.Time      `json:"timestamp"          yaml:"timestamp"`
	Change    string         `json:"change"             yaml:"change"`
	Type      string         `json:"type,omitempty"     yaml:"type,omitempty"`     // Type of change: "field_update", "id_change", "conflict_resolution", etc.
	Metadata  map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"` // Additional metadata about the change
}

HistoryEntry represents a single entry in the task's history.

type IDConflict added in v0.4.0

type IDConflict struct {
	Type        ConflictType
	ConflictID  TaskID
	Files       []string
	Tasks       []Task
	Description string
	DetectedAt  time.Time
}

IDConflict represents a detected conflict in task IDs

type ListResult added in v0.3.0

type ListResult struct {
	Tasks      []Task          `json:"tasks"`
	Pagination *PaginationInfo `json:"pagination,omitempty"`
}

ListResult contains the tasks and pagination metadata

func Paginate added in v0.4.1

func Paginate(tasks []Task, limit int, offset int) ListResult

Paginate applies pagination to a slice of tasks and returns a ListResult.

type ListTasksParams

type ListTasksParams struct {
	Parent        string   `json:"parent,omitempty"         jsonschema:"Filter tasks by a parent task ID."`
	Status        []string `json:"status,omitempty"         jsonschema:"Filter tasks by status."`
	Assigned      []string `json:"assigned,omitempty"       jsonschema:"Filter tasks by assignee."`
	Labels        []string `json:"labels,omitempty"         jsonschema:"Filter tasks by label."`
	Sort          []string `json:"sort,omitempty"           jsonschema:"Fields to sort by."`
	Priority      string   `json:"priority,omitempty"       jsonschema:"Filter tasks by priority."`
	Query         string   `json:"query,omitempty"          jsonschema:"Search query to filter tasks by."`
	Unassigned    bool     `json:"unassigned,omitempty"     jsonschema:"Filter tasks that have no one assigned."`
	DependedOn    bool     `json:"depended_on,omitempty"    jsonschema:"Filter tasks that other tasks depend on."`
	HasDependency bool     `json:"has_dependency,omitempty" jsonschema:"Filter tasks that have at least one dependency."`
	Reverse       bool     `json:"reverse,omitempty"        jsonschema:"Reverse the sort order."`
	// Pagination
	Limit  int `json:"limit,omitempty"  jsonschema:"Maximum number of tasks to return (0 means no limit)."`
	Offset int `json:"offset,omitempty" jsonschema:"Number of tasks to skip from the beginning."`
}

ListTasksParams holds the parameters for listing tasks.

type MaybeStringArray

type MaybeStringArray []string

MaybeStringArray is a custom type that can unmarshal from either a single string or an array of strings. It also marshals back to the same format, preserving the original structure. origin: https://carlosbecker.com/posts/go-custom-marshaling/

func MaybeStringArrayFromSlice added in v0.4.0

func MaybeStringArrayFromSlice(slice []string) MaybeStringArray

MaybeStringArrayFromSlice converts a string slice to MaybeStringArray

func (MaybeStringArray) MarshalJSON

func (a MaybeStringArray) MarshalJSON() ([]byte, error)

func (MaybeStringArray) MarshalYAML

func (a MaybeStringArray) MarshalYAML() (any, error)

func (*MaybeStringArray) ToSlice added in v0.1.1

func (a *MaybeStringArray) ToSlice() []string

func (*MaybeStringArray) UnmarshalJSON

func (a *MaybeStringArray) UnmarshalJSON(data []byte) error

func (*MaybeStringArray) UnmarshalYAML

func (a *MaybeStringArray) UnmarshalYAML(value *yaml.Node) error

type PaginationInfo added in v0.3.0

type PaginationInfo struct {
	TotalResults     int  `json:"total_results"`
	DisplayedResults int  `json:"displayed_results"`
	Offset           int  `json:"offset"`
	Limit            int  `json:"limit"`
	HasMore          bool `json:"has_more"`
}

PaginationInfo contains metadata about pagination results

type Priority

type Priority int
const (
	PriorityUnknown Priority = iota
	PriorityLow
	PriorityMedium
	PriorityHigh
	PriorityCritical
)

func ParsePriority

func ParsePriority(s string) (Priority, error)

func (Priority) MarshalJSON added in v0.2.5

func (p Priority) MarshalJSON() ([]byte, error)

func (Priority) MarshalYAML added in v0.2.5

func (p Priority) MarshalYAML() (any, error)

func (Priority) String

func (p Priority) String() string

func (*Priority) UnmarshalJSON added in v0.2.5

func (p *Priority) UnmarshalJSON(b []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*Priority) UnmarshalYAML added in v0.2.5

func (p *Priority) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML implements yaml.Unmarshaler.

type ReferenceUpdater added in v0.4.0

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

ReferenceUpdater handles updating references when task IDs change

func NewReferenceUpdater added in v0.4.0

func NewReferenceUpdater(detector *ConflictDetector, store *FileTaskStore) *ReferenceUpdater

NewReferenceUpdater creates a new reference updater

func (*ReferenceUpdater) FindTaskReferences added in v0.4.0

func (ru *ReferenceUpdater) FindTaskReferences(targetID TaskID) ([]Task, error)

FindTaskReferences finds all tasks that reference the given task ID

func (*ReferenceUpdater) UpdateReferences added in v0.4.0

func (ru *ReferenceUpdater) UpdateReferences(idChanges map[string]TaskID) error

UpdateReferences updates all references to changed task IDs

type ResolutionAction added in v0.4.0

type ResolutionAction struct {
	Type        string // "renumber", "update_parent", "delete"
	OriginalID  TaskID
	NewID       TaskID
	FilePath    string
	Description string
	Metadata    map[string]any // Additional metadata for the action
}

ResolutionAction represents an action to resolve a conflict

type ResolutionPlan added in v0.4.0

type ResolutionPlan struct {
	Actions   []ResolutionAction
	Summary   string
	Strategy  ResolutionStrategy
	CreatedAt time.Time
}

ResolutionPlan contains all actions needed to resolve conflicts

type ResolutionStrategy added in v0.4.0

type ResolutionStrategy int

ResolutionStrategy defines how conflicts should be resolved

const (
	ResolutionStrategyChronological ResolutionStrategy = iota // Keep older task, renumber newer
	ResolutionStrategyAutoRenumber                            // Automatically renumber conflicting IDs
	ResolutionStrategyManual                                  // Require manual resolution
)

type Status

type Status string

Status represents the state of a task.

const (
	StatusTodo       Status = "todo"
	StatusInProgress Status = "in-progress"
	StatusDone       Status = "done"
	StatusCancelled  Status = "cancelled"
	StatusArchived   Status = "archived"
	StatusRejected   Status = "rejected"
)

func ParseStatus

func ParseStatus(s string) (Status, error)

type Task

type Task struct {
	ID           TaskID           `json:"id"                     yaml:"id"`
	Title        string           `json:"title"                  yaml:"title"`
	Status       Status           `json:"status"                 yaml:"status"`
	Parent       TaskID           `json:"parent"                 yaml:"parent"`
	Assigned     MaybeStringArray `json:"assigned,omitempty"     yaml:"assigned,omitempty"`
	Labels       MaybeStringArray `json:"labels,omitempty"       yaml:"labels,omitempty"`
	Dependencies MaybeStringArray `json:"dependencies,omitempty" yaml:"dependencies,omitempty"`
	Priority     Priority         `json:"priority,omitempty"     yaml:"priority,omitempty"`
	CreatedAt    time.Time        `json:"created_at"             yaml:"created_at"`
	UpdatedAt    time.Time        `json:"updated_at,omitzero"    yaml:"updated_at,omitempty"`
	History      []HistoryEntry   `json:"history,omitempty"      yaml:"history,omitempty"`

	Description         string                `json:"description"`
	AcceptanceCriteria  []AcceptanceCriterion `json:"acceptance_criteria,omitempty"`
	ImplementationPlan  string                `json:"implementation_plan"`
	ImplementationNotes string                `json:"implementation_notes"`
}

Task represents a single task in the backlog. It includes metadata from the front matter and content from the markdown body. The task ID represents a hierarchical structure using dot notation (e.g., "1", "1.1", "1.2", "2"). The task name is derived from the ID and prefixed with "task-" (e.g., "T1", "T1.1").

func NewTask

func NewTask() Task

NewTask creates a new Task with default values.

func PaginateTasks added in v0.3.0

func PaginateTasks(tasks []Task, limit *int, offset *int) []Task

PaginateTasks applies pagination to a slice of tasks. If limit is nil or 0, returns all tasks. If offset is nil, defaults to 0.

func (*Task) Bytes

func (t *Task) Bytes() []byte

func (*Task) FileName

func (t *Task) FileName() string

FileName creates a filename from task ID and a slugified title.

func (*Task) GetConflictResolutionHistory added in v0.4.0

func (t *Task) GetConflictResolutionHistory() []HistoryEntry

GetConflictResolutionHistory returns all conflict resolution history entries for this task

func (*Task) GetIDChangeHistory added in v0.4.0

func (t *Task) GetIDChangeHistory() []HistoryEntry

GetIDChangeHistory returns all ID change history entries for this task

func (*Task) GetOriginalID added in v0.4.0

func (t *Task) GetOriginalID() (TaskID, bool)

GetOriginalID attempts to find the original ID of this task before any renaming

func (*Task) HasBeenRenamed added in v0.4.0

func (t *Task) HasBeenRenamed() bool

HasBeenRenamed checks if this task has ever had its ID changed

type TaskID

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

func (TaskID) Equals

func (t TaskID) Equals(other TaskID) bool

func (TaskID) HasSubTasks

func (t TaskID) HasSubTasks() bool

HasSubTasks returns true if the task ID has subtask segments (i.e., more than one segment).

func (TaskID) IsZero added in v0.4.0

func (t TaskID) IsZero() bool

IsZero checks if TaskID is zero value

func (TaskID) Less

func (t TaskID) Less(other TaskID) bool

func (TaskID) MarshalJSON

func (t TaskID) MarshalJSON() ([]byte, error)

func (TaskID) MarshalText

func (t TaskID) MarshalText() ([]byte, error)

func (TaskID) MarshalYAML

func (t TaskID) MarshalYAML() (any, error)

func (TaskID) Name

func (t TaskID) Name() string

Name returns the filename prefix for the task, e.g., "T1.02.03".

func (TaskID) NextSiblingID

func (t TaskID) NextSiblingID() TaskID

func (TaskID) NextSubTaskID

func (t TaskID) NextSubTaskID() TaskID

func (TaskID) Parent

func (t TaskID) Parent() *TaskID

func (TaskID) String

func (t TaskID) String() string

String returns the string representation of the TaskID (e.g., "1.02.03").

func (*TaskID) UnmarshalJSON

func (t *TaskID) UnmarshalJSON(data []byte) error

func (*TaskID) UnmarshalText

func (t *TaskID) UnmarshalText(text []byte) error

func (*TaskID) UnmarshalYAML

func (t *TaskID) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML implements yaml.Unmarshaler.

Jump to

Keyboard shortcuts

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