/** * Issue Module * * Extracted per DESIGN.md pattern (like milestone.ts, branch.ts). * Handles issue creation, lifecycle (start/pause/resume/close/reopen), * acceptance criteria, and queries. */ import type { VcsOp, IssueType } from './types.js'; import type { EngineContext } from './engine-context.js'; import { type CriterionTemplate } from './test-manifest.js'; export interface IssueInfo { /** * Canonical, collision-resistant identifier. * Legacy unlaned issues use `TRL-N`; lane-scoped use `issue::`. * Always present; safe to use as a map key, link target, and nack ref. */ id: string; /** * Optional human-readable name. * For legacy `TRL-N` ids this mirrors `id`. For lane-scoped ids it is * undefined until a promotion step assigns one. UI may fall back to `id`. */ displayId?: string; title?: string; description?: string; /** * What kind of issue this is (ADR 0026) — `epic` containers hold intent and * leaves roll up to them via `parentId`. Absent on ops minted before the field * existed; treat as `issue`. */ issueType?: string; status?: string; priority?: string; labels: string[]; assignee?: string; createdAt?: string; createdBy?: string; startedAt?: string; pausedAt?: string; pauseNote?: string; closedAt?: string; parentId?: string; branchName?: string; claimedLaneId?: string; claimedSessionId?: string; claimedAt?: string; blockedBy: string[]; blocking: string[]; isBlocked: boolean; criteria: CriterionInfo[]; } export interface CriterionInfo { id: string; description?: string; command?: string; suite?: string; status?: string; lastRunAt?: string; lastOutput?: string; /** Retracted via `vcs:criterionRemove`. Hidden from projections; the entity survives so its id is never reused. */ retracted?: boolean; } export interface CriterionResult { id: string; description?: string; command?: string; status: 'passed' | 'failed' | 'skipped'; output?: string; exitCode?: number; } export interface IssueFilters { status?: string; assignee?: string; label?: string; parentId?: string; blocked?: boolean; /** ADR 0026 — `--type epic` is the query a title prefix could never support. */ issueType?: string; } export interface IssueCreateOptions { /** What kind of issue (ADR 0026). Default `issue`; `epic` holds intent. */ issueType?: IssueType; priority?: 'critical' | 'high' | 'medium' | 'low'; labels?: string[]; assignee?: string; parentId?: string; description?: string; status?: 'backlog' | 'queue'; criteria?: Array<{ description: string; command?: string; suite?: string; }>; /** * Creates a collision-resistant canonical ID scoped to this lane, e.g. * `issue:lane-a:1`. Omit to keep the legacy repo-wide `TRL-N` allocator. */ laneId?: string; /** * Recovery-only: mint a specific legacy `TRL-N` id. Bumps the repo counter so * later allocates continue above N. Refuses if the id already exists. */ forceIssueId?: string; } /** * Create a new issue. */ export declare function createIssue(ctx: EngineContext, rootPath: string, title: string, opts?: IssueCreateOptions): Promise; /** * Update an issue's metadata. */ export declare function updateIssue(ctx: EngineContext, id: string, updates: { title?: string; description?: string; /** Re-kind an issue (ADR 0026) — e.g. promoting a task to an epic. */ issueType?: IssueType; priority?: 'critical' | 'high' | 'medium' | 'low'; labels?: string[]; assignee?: string; status?: 'backlog' | 'queue' | 'in_progress' | 'paused' | 'closed'; /** Set parent issue id, or `null` to remove an existing parent link. */ parentId?: string | null; }): Promise; /** * Start working on an issue: sets in_progress, auto-assigns, creates branch. * Returns the issueStart op. The caller (engine) is responsible for * actually creating the branch and switching to it. */ export declare function startIssue(ctx: EngineContext, id: string, /** Omitted when starting without a branch — the lane is the isolation. */ branchName?: string): Promise; /** * Auto-attach acceptance criteria from `.trellis/tests.json` on issue start. * Skips when the issue already has criteria. */ export declare function applyIssueStartCriteria(ctx: EngineContext, issueId: string, rootPath: string, labels?: string[]): Promise; /** * Pause an in-progress issue. */ export declare function pauseIssue(ctx: EngineContext, id: string, note: string): Promise; /** * Resume a paused issue. */ export declare function resumeIssue(ctx: EngineContext, id: string): Promise; /** * Close an issue. Requires all criteria to have passed and confirm=true. */ export declare function closeIssue(ctx: EngineContext, id: string, opts?: { confirm?: boolean; }): Promise<{ op?: VcsOp; criteriaResults: CriterionResult[]; }>; /** * Triage a backlog issue to queue (ready to start). */ export declare function triageIssue(ctx: EngineContext, id: string): Promise; /** * Reopen a closed issue. */ export declare function reopenIssue(ctx: EngineContext, id: string): Promise; /** * Assign an issue to an agent. */ export declare function assignIssue(ctx: EngineContext, id: string, agentId: string): Promise; /** * Block an issue by another issue. */ export declare function blockIssue(ctx: EngineContext, id: string, blockedById: string): Promise; /** * Remove a blocking relationship. */ export declare function unblockIssue(ctx: EngineContext, id: string, blockedById: string): Promise; /** * Add an acceptance criterion to an issue. */ export declare function addCriterion(ctx: EngineContext, issueId: string, description: string, opts?: { command?: string; suite?: string; }): Promise; /** * Manually set a criterion's status (for non-command criteria). */ export declare function setCriterionStatus(ctx: EngineContext, issueId: string, criterionIndex: number, status: 'passed' | 'failed' | 'pending'): Promise; /** * Retract an acceptance criterion (TRL-1). * * `criterionIndex` is 1-based over the *live* criteria, matching what * `issue show` prints and what `ac-pass` / `ac-fail` accept. * * The criterion entity is not deleted — `vcs:criterionRemove` marks it * retracted, so no existing op is rewritten (TRL-1 AC#1) and the id is * retired rather than freed for reuse. */ export declare function removeCriterion(ctx: EngineContext, issueId: string, criterionIndex: number): Promise; /** * Run all acceptance criteria for an issue. Executes test commands * and emits criterionUpdate + vcs:testRun ops with results. */ export declare function runCriteria(ctx: EngineContext, issueId: string, cwd: string, opts?: { laneId?: string; manifestRoot?: string; }): Promise; /** * List all issues, optionally filtered. */ export declare function listIssues(ctx: EngineContext, filters?: IssueFilters): IssueInfo[]; /** * Get a single issue by ID. */ export declare function getIssue(ctx: EngineContext, id: string): IssueInfo | null; /** * Get all active (in_progress) issues. */ export declare function getActiveIssues(ctx: EngineContext): IssueInfo[]; export interface CompletionReadiness { ready: boolean; queue: IssueInfo[]; paused: IssueInfo[]; inProgress: IssueInfo[]; summary: string; } /** * Check whether all work is complete: no issues in queue, paused, or in_progress. */ export declare function checkCompletionReadiness(ctx: EngineContext): CompletionReadiness; //# sourceMappingURL=issue.d.ts.map