refactor: extract shared isBacklogLikeStatus helper and improve comments

Address PR #825 review feedback:
- Extract duplicated backlog-like status check into shared helper in constants.ts
- Improve spec-parser regex comment to clarify subsection preservation
- Add file path reference in row-actions.tsx comment for traceability

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-03-02 20:45:23 -08:00
committed by gsxdsm
parent 4a128efbf4
commit 341a6534e6
4 changed files with 57 additions and 43 deletions

View File

@@ -214,7 +214,8 @@ export function extractSummary(text: string): string | null {
} }
// Check for ## Summary section (use last match) // Check for ## Summary section (use last match)
// Use \n## [^#] to stop at same-level headers (## Foo) but NOT subsections (### Root Cause) // Stop at \n## [^#] (same-level headers like "## Changes") but preserve ### subsections
// (like "### Root Cause", "### Fix Applied") that belong to the summary content.
const sectionMatches = text.matchAll(/##\s*Summary\s*\n+([\s\S]*?)(?=\n## [^#]|\n\*\*|$)/gi); const sectionMatches = text.matchAll(/##\s*Summary\s*\n+([\s\S]*?)(?=\n## [^#]|\n\*\*|$)/gi);
const sectionMatch = getLastMatch(sectionMatches); const sectionMatch = getLastMatch(sectionMatches);
if (sectionMatch) { if (sectionMatch) {

View File

@@ -83,7 +83,7 @@ import type {
StashApplyConflictInfo, StashApplyConflictInfo,
} from './board-view/worktree-panel/types'; } from './board-view/worktree-panel/types';
import { BoardErrorBoundary } from './board-view/board-error-boundary'; import { BoardErrorBoundary } from './board-view/board-error-boundary';
import { COLUMNS, getColumnsWithPipeline } from './board-view/constants'; import { COLUMNS, getColumnsWithPipeline, isBacklogLikeStatus } from './board-view/constants';
import { import {
useBoardFeatures, useBoardFeatures,
useBoardDragDrop, useBoardDragDrop,
@@ -1908,12 +1908,7 @@ export function BoardView({ initialFeatureId }: BoardViewProps) {
// Running features should always show logs, even if status is // Running features should always show logs, even if status is
// stale (still 'backlog'/'ready'/'interrupted' during race window) // stale (still 'backlog'/'ready'/'interrupted' during race window)
const isRunning = runningAutoTasksAllWorktrees.includes(feature.id); const isRunning = runningAutoTasksAllWorktrees.includes(feature.id);
const isBacklogLike = if (isBacklogLikeStatus(feature.status) && !isRunning) {
feature.status === 'backlog' ||
feature.status === 'merge_conflict' ||
feature.status === 'ready' ||
feature.status === 'interrupted';
if (isBacklogLike && !isRunning) {
setEditingFeature(feature); setEditingFeature(feature);
} else { } else {
handleViewOutput(feature); handleViewOutput(feature);

View File

@@ -30,6 +30,7 @@ import {
DropdownMenuTrigger, DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'; } from '@/components/ui/dropdown-menu';
import type { Feature } from '@/store/app-store'; import type { Feature } from '@/store/app-store';
import { isBacklogLikeStatus } from '../../constants';
/** /**
* Action handler types for row actions * Action handler types for row actions
@@ -431,15 +432,12 @@ export const RowActions = memo(function RowActions({
</> </>
)} )}
{/* Running task with stale status (backlog/ready/interrupted but tracked as running). {/* Running task with stale status - the feature is tracked as running but its
persisted status hasn't caught up yet during WebSocket/cache sync delays.
These features are placed in the in_progress column by useBoardColumnFeatures These features are placed in the in_progress column by useBoardColumnFeatures
but their actual status hasn't updated yet, so no other menu block matches. */} (hooks/use-board-column-features.ts) but no other menu block matches their
{!isCurrentAutoTask && stale status, so we provide running-appropriate actions here. */}
isRunningTask && {!isCurrentAutoTask && isRunningTask && isBacklogLikeStatus(feature.status) && (
(feature.status === 'backlog' ||
feature.status === 'ready' ||
feature.status === 'interrupted' ||
feature.status === 'merge_conflict') && (
<> <>
{handlers.onViewOutput && ( {handlers.onViewOutput && (
<MenuItem <MenuItem

View File

@@ -136,6 +136,26 @@ export function getPipelineInsertIndex(): number {
return BASE_COLUMNS.length; return BASE_COLUMNS.length;
} }
/**
* Statuses that display in the backlog column because they don't have dedicated columns:
* - 'backlog': Default state for new features
* - 'ready': Feature has an approved plan, waiting for execution
* - 'interrupted': Feature execution was aborted (user stopped it, server restart)
* - 'merge_conflict': Automatic merge failed, user must resolve conflicts
*
* Used to determine row click behavior and menu actions when a feature is running
* but its status hasn't updated yet (race condition during WebSocket/cache sync).
* See use-board-column-features.ts for the column assignment logic.
*/
export function isBacklogLikeStatus(status: string): boolean {
return (
status === 'backlog' ||
status === 'ready' ||
status === 'interrupted' ||
status === 'merge_conflict'
);
}
/** /**
* Check if a status is a pipeline status * Check if a status is a pipeline status
*/ */