/** * Sub-issue cleanup utility (REN-1323) * * Identifies agent-created sub-issues from the deprecated 1-point-gets-3-sub-issues * pattern and recommends disposition: keep-as-independent or close-as-noise. * * Usage: * af-linear cleanup-sub-issues --project --dry-run * af-linear cleanup-sub-issues --project --apply [--tracking ] */ export interface CleanupSubIssuesConfig { /** Linear project name to scan */ project: string; /** When true, print a report but do not modify any issues */ dryRun: boolean; /** When true, apply the recommended dispositions */ apply: boolean; /** Optional tracking issue identifier (e.g. "REN-1323") to post the report on */ trackingIssueId?: string; /** Path to known-agent-authors config (defaults to .rensei/known-agent-authors.json) */ agentAuthorsConfigPath?: string; /** Working directory for config file resolution (defaults to cwd) */ cwd?: string; /** Injected Linear client (for testing) */ linearClient?: LinearClientInterface; } export type Disposition = 'decompose-noise' | 'worth-keeping' | 'already-processed'; export interface SubIssueReport { issueId: string; identifier: string; title: string; parentId: string; parentIdentifier: string; parentTitle: string; parentStatus: string; status: string; authorId: string | undefined; isAgentAuthored: boolean; titlePatternMatch: boolean; descriptionSimilarity: number; disposition: Disposition; reasoning: string[]; } export interface CleanupReport { project: string; scannedParents: number; scannedSubIssues: number; alreadyProcessed: number; toClose: SubIssueReport[]; toDetach: SubIssueReport[]; dryRun: boolean; } export interface LinearIssue { id: string; identifier: string; title: string; description?: string | null; status: string; createdAt: number; parentId?: string; childCount: number; labels: string[]; authorId?: string; /** True if an attachment, PR or commit is linked to this issue */ hasLinkedResources?: boolean; /** True if the issue was edited by a human after creation */ editedByHuman?: boolean; } export interface LinearClientInterface { listProjectIssues(projectName: string): Promise; getIssueFull(issueId: string): Promise<{ id: string; identifier: string; title: string; description?: string | null; authorId?: string; hasLinkedResources?: boolean; editedByHuman?: boolean; labels: string[]; }>; closeIssue(issueId: string, comment: string): Promise; detachFromParent(issueId: string, comment: string): Promise; addLabel(issueId: string, labelName: string): Promise; hasLabel(issueId: string, labelName: string): Promise; createComment(issueId: string, body: string): Promise; } export interface AgentAuthorsConfig { /** Linear user IDs that are known to be agent bots */ agentUserIds: string[]; /** Optional name fragments to recognize agent authors */ agentAuthorPatterns?: string[]; } export declare function isTitleDecomposeNoise(title: string): boolean; /** * Rough word-overlap similarity between two strings. * Returns a value in [0, 1]; 1 = identical word sets. */ export declare function wordOverlapSimilarity(a: string, b: string): number; export declare function renderMarkdownReport(report: CleanupReport): string; export declare function runCleanupSubIssues(config: CleanupSubIssuesConfig): Promise; //# sourceMappingURL=cleanup-sub-issues.d.ts.map