241 lines
6.2 KiB
TypeScript
241 lines
6.2 KiB
TypeScript
export type TaskStatus = string;
|
|
|
|
/** Records when a task transitioned to a specific status */
|
|
export interface StatusHistoryEntry {
|
|
status: string;
|
|
timestamp: string; // ISO format: "YYYY-MM-DD HH:mm"
|
|
}
|
|
|
|
// Structured Acceptance Criterion (domain-level)
|
|
export interface AcceptanceCriterion {
|
|
index: number; // 1-based
|
|
text: string;
|
|
checked: boolean;
|
|
}
|
|
|
|
export interface AcceptanceCriterionInput {
|
|
text: string;
|
|
checked?: boolean;
|
|
}
|
|
|
|
export interface Task {
|
|
id: string;
|
|
title: string;
|
|
status: TaskStatus;
|
|
assignee: string[];
|
|
reporter?: string;
|
|
createdDate: string;
|
|
updatedDate?: string;
|
|
labels: string[];
|
|
milestone?: string;
|
|
dependencies: string[];
|
|
readonly rawContent?: string; // Raw markdown content without frontmatter (read-only: do not modify directly)
|
|
description?: string;
|
|
implementationPlan?: string;
|
|
implementationNotes?: string;
|
|
/** Structured acceptance criteria parsed from body (checked state + text + index) */
|
|
acceptanceCriteriaItems?: AcceptanceCriterion[];
|
|
parentTaskId?: string;
|
|
subtasks?: string[];
|
|
priority?: "high" | "medium" | "low";
|
|
branch?: string;
|
|
ordinal?: number;
|
|
filePath?: string;
|
|
// Metadata fields
|
|
lastModified?: Date;
|
|
source?: "local" | "remote" | "completed" | "local-branch";
|
|
/** Optional per-task callback command to run on status change (overrides global config) */
|
|
onStatusChange?: string;
|
|
/** History of status transitions with timestamps for velocity tracking */
|
|
statusHistory?: StatusHistoryEntry[];
|
|
/** Flag to mark task for "Do Today" daily focus list */
|
|
doToday?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Check if a task is locally editable (not from a remote or other local branch)
|
|
*/
|
|
export function isLocalEditableTask(task: Task): boolean {
|
|
return task.source === undefined || task.source === "local" || task.source === "completed";
|
|
}
|
|
|
|
export interface TaskCreateInput {
|
|
title: string;
|
|
description?: string;
|
|
status?: TaskStatus;
|
|
priority?: "high" | "medium" | "low";
|
|
labels?: string[];
|
|
assignee?: string[];
|
|
dependencies?: string[];
|
|
parentTaskId?: string;
|
|
implementationPlan?: string;
|
|
implementationNotes?: string;
|
|
acceptanceCriteria?: AcceptanceCriterionInput[];
|
|
rawContent?: string;
|
|
}
|
|
|
|
export interface TaskUpdateInput {
|
|
title?: string;
|
|
description?: string;
|
|
status?: TaskStatus;
|
|
priority?: "high" | "medium" | "low";
|
|
labels?: string[];
|
|
addLabels?: string[];
|
|
removeLabels?: string[];
|
|
assignee?: string[];
|
|
ordinal?: number;
|
|
dependencies?: string[];
|
|
addDependencies?: string[];
|
|
removeDependencies?: string[];
|
|
implementationPlan?: string;
|
|
appendImplementationPlan?: string[];
|
|
clearImplementationPlan?: boolean;
|
|
implementationNotes?: string;
|
|
appendImplementationNotes?: string[];
|
|
clearImplementationNotes?: boolean;
|
|
acceptanceCriteria?: AcceptanceCriterionInput[];
|
|
addAcceptanceCriteria?: Array<AcceptanceCriterionInput | string>;
|
|
removeAcceptanceCriteria?: number[];
|
|
checkAcceptanceCriteria?: number[];
|
|
uncheckAcceptanceCriteria?: number[];
|
|
rawContent?: string;
|
|
doToday?: boolean;
|
|
}
|
|
|
|
export interface TaskListFilter {
|
|
status?: string;
|
|
assignee?: string;
|
|
priority?: "high" | "medium" | "low";
|
|
parentTaskId?: string;
|
|
}
|
|
|
|
export interface Decision {
|
|
id: string;
|
|
title: string;
|
|
date: string;
|
|
status: "proposed" | "accepted" | "rejected" | "superseded";
|
|
context: string;
|
|
decision: string;
|
|
consequences: string;
|
|
alternatives?: string;
|
|
readonly rawContent: string; // Raw markdown content without frontmatter
|
|
}
|
|
|
|
export interface Document {
|
|
id: string;
|
|
title: string;
|
|
type: "readme" | "guide" | "specification" | "other";
|
|
createdDate: string;
|
|
updatedDate?: string;
|
|
rawContent: string; // Raw markdown content without frontmatter
|
|
tags?: string[];
|
|
// Web UI specific fields
|
|
name?: string;
|
|
path?: string;
|
|
lastModified?: string;
|
|
}
|
|
|
|
export type SearchResultType = "task" | "document" | "decision";
|
|
|
|
export type SearchPriorityFilter = "high" | "medium" | "low";
|
|
|
|
export interface SearchMatch {
|
|
key?: string;
|
|
indices: Array<[number, number]>;
|
|
value?: unknown;
|
|
}
|
|
|
|
export interface SearchFilters {
|
|
status?: string | string[];
|
|
priority?: SearchPriorityFilter | SearchPriorityFilter[];
|
|
assignee?: string | string[];
|
|
labels?: string | string[];
|
|
}
|
|
|
|
export interface SearchOptions {
|
|
query?: string;
|
|
limit?: number;
|
|
types?: SearchResultType[];
|
|
filters?: SearchFilters;
|
|
}
|
|
|
|
export interface TaskSearchResult {
|
|
type: "task";
|
|
score: number | null;
|
|
task: Task;
|
|
matches?: SearchMatch[];
|
|
}
|
|
|
|
export interface DocumentSearchResult {
|
|
type: "document";
|
|
score: number | null;
|
|
document: Document;
|
|
matches?: SearchMatch[];
|
|
}
|
|
|
|
export interface DecisionSearchResult {
|
|
type: "decision";
|
|
score: number | null;
|
|
decision: Decision;
|
|
matches?: SearchMatch[];
|
|
}
|
|
|
|
export type SearchResult = TaskSearchResult | DocumentSearchResult | DecisionSearchResult;
|
|
|
|
export interface Sequence {
|
|
/** 1-based sequence index */
|
|
index: number;
|
|
/** Tasks that can be executed in parallel within this sequence */
|
|
tasks: Task[];
|
|
}
|
|
|
|
export interface BacklogConfig {
|
|
projectName: string;
|
|
defaultAssignee?: string;
|
|
defaultReporter?: string;
|
|
statuses: string[];
|
|
labels: string[];
|
|
milestones: string[];
|
|
defaultStatus?: string;
|
|
dateFormat: string;
|
|
maxColumnWidth?: number;
|
|
taskResolutionStrategy?: "most_recent" | "most_progressed";
|
|
defaultEditor?: string;
|
|
autoOpenBrowser?: boolean;
|
|
defaultPort?: number;
|
|
remoteOperations?: boolean;
|
|
autoCommit?: boolean;
|
|
zeroPaddedIds?: number;
|
|
timezonePreference?: string; // e.g., 'UTC', 'America/New_York', or 'local'
|
|
includeDateTimeInDates?: boolean; // Whether to include time in new dates
|
|
bypassGitHooks?: boolean;
|
|
checkActiveBranches?: boolean; // Check task states across active branches (default: true)
|
|
activeBranchDays?: number; // How many days a branch is considered active (default: 30)
|
|
/** Global callback command to run on any task status change. Supports $TASK_ID, $OLD_STATUS, $NEW_STATUS, $TASK_TITLE variables. */
|
|
onStatusChange?: string;
|
|
mcp?: {
|
|
http?: {
|
|
host?: string;
|
|
port?: number;
|
|
auth?: {
|
|
type?: "bearer" | "basic" | "none";
|
|
token?: string;
|
|
username?: string;
|
|
password?: string;
|
|
};
|
|
cors?: {
|
|
origin?: string | string[];
|
|
credentials?: boolean;
|
|
};
|
|
enableDnsRebindingProtection?: boolean;
|
|
allowedHosts?: string[];
|
|
allowedOrigins?: string[];
|
|
};
|
|
};
|
|
}
|
|
|
|
export interface ParsedMarkdown {
|
|
frontmatter: Record<string, unknown>;
|
|
content: string;
|
|
}
|