refactor(issue): remove 'merged' queue status, use 'archived' instead

- Remove 'merged' from VALID_QUEUE_STATUSES constant
- Update mergeQueues() to set status to 'archived' instead of 'merged'
- Preserve merged_into/merged_at metadata for traceability
- Update frontend to use 'archived' for button visibility checks
- Fix queue --json returning fake queue ID when no active queue exists
This commit is contained in:
catlog22
2026-01-25 10:56:46 +08:00
parent fe2536d4cd
commit 9cff6f5f43
2 changed files with 16 additions and 16 deletions

View File

@@ -172,7 +172,7 @@ interface ExecutionGroup {
interface Queue {
id: string; // Queue unique ID: QUE-YYYYMMDD-HHMMSS (derived from filename)
name?: string; // Optional queue name
status: 'active' | 'completed' | 'archived' | 'failed' | 'merged';
status: 'active' | 'completed' | 'archived' | 'failed';
issue_ids: string[]; // Issues in this queue
tasks: QueueItem[]; // Task items (task-level queue)
solutions?: QueueItem[]; // Solution items (solution-level queue)
@@ -235,7 +235,7 @@ const ISSUES_DIR = '.workflow/issues';
// ============ Status Constants ============
const VALID_QUEUE_STATUSES = ['active', 'completed', 'archived', 'failed', 'merged'] as const;
const VALID_QUEUE_STATUSES = ['active', 'completed', 'archived', 'failed'] as const;
const VALID_ITEM_STATUSES = ['pending', 'ready', 'executing', 'completed', 'failed', 'blocked'] as const;
const VALID_ISSUE_STATUSES = ['registered', 'planning', 'planned', 'queued', 'executing', 'completed', 'failed', 'paused'] as const;
@@ -777,7 +777,7 @@ interface MergeResult {
* Merge items from source queue into target queue
* - Skips duplicate items (same issue_id + solution_id)
* - Re-generates item IDs for merged items
* - Marks source queue as 'merged' with metadata (or deletes if deleteSource=true)
* - Marks source queue as 'archived' with metadata (or deletes if deleteSource=true)
* - Updates queue index
*/
function mergeQueues(target: Queue, source: Queue, options?: { deleteSource?: boolean }): MergeResult {
@@ -832,7 +832,7 @@ function mergeQueues(target: Queue, source: Queue, options?: { deleteSource?: bo
// Write updated target queue
writeQueue(target);
// Handle source queue: delete or mark as merged
// Handle source queue: delete or mark as archived
const index = readQueueIndex();
if (options?.deleteSource) {
@@ -843,8 +843,8 @@ function mergeQueues(target: Queue, source: Queue, options?: { deleteSource?: bo
}
index.queues = index.queues.filter(q => q.id !== source.id);
} else {
// Mark source queue as merged
source.status = 'merged';
// Mark source queue as archived (was merged)
source.status = 'archived';
if (!source._metadata) {
source._metadata = {
version: '2.1',
@@ -862,7 +862,7 @@ function mergeQueues(target: Queue, source: Queue, options?: { deleteSource?: bo
const sourceEntry = index.queues.find(q => q.id === source.id);
if (sourceEntry) {
sourceEntry.status = 'merged';
sourceEntry.status = 'archived';
}
}
@@ -2265,7 +2265,7 @@ async function queueAction(subAction: string | undefined, issueId: string | unde
process.exit(1);
}
// mergeQueues marks source as 'merged' and updates index
// mergeQueues marks source as 'archived' and updates index
const result = mergeQueues(targetQueue, sourceQueue);
if (options.json) {
@@ -2285,7 +2285,7 @@ async function queueAction(subAction: string | undefined, issueId: string | unde
console.log(chalk.gray(` Skipped ${result.skippedDuplicates} duplicate items`));
}
console.log(chalk.gray(` Total items in target: ${result.totalItems}`));
console.log(chalk.gray(` Source queue ${sourceQueueId} marked as 'merged'`));
console.log(chalk.gray(` Source queue ${sourceQueueId} archived`));
} else {
console.log(chalk.yellow(`⚠ Merge skipped: ${result.reason}`));
}

View File

@@ -702,7 +702,7 @@ function renderQueueCard(queue, isActive) {
const completedCount = queue.completed_solutions || queue.completed_tasks || 0;
const progressPercent = itemCount > 0 ? Math.round((completedCount / itemCount) * 100) : 0;
const issueCount = queue.issue_ids?.length || 0;
const statusClass = queue.status === 'merged' ? 'merged' : queue.status || '';
const statusClass = queue.status || '';
const safeQueueId = escapeHtml(queue.id || '');
return `
@@ -740,17 +740,17 @@ function renderQueueCard(queue, isActive) {
<button class="btn-sm" onclick="toggleQueueExpand('${safeQueueId}')" title="View details">
<i data-lucide="eye" class="w-3 h-3"></i>
</button>
${!isActive && queue.status !== 'merged' ? `
${!isActive && queue.status !== 'archived' ? `
<button class="btn-sm btn-primary" onclick="activateQueue('${safeQueueId}')" title="Set as active">
<i data-lucide="check-circle" class="w-3 h-3"></i>
</button>
` : ''}
${queue.status !== 'merged' ? `
${queue.status !== 'archived' ? `
<button class="btn-sm" onclick="showMergeQueueModal('${safeQueueId}')" title="Merge into another queue">
<i data-lucide="git-merge" class="w-3 h-3"></i>
</button>
` : ''}
${queue.status !== 'merged' && issueCount > 1 ? `
${queue.status !== 'archived' && issueCount > 1 ? `
<button class="btn-sm" onclick="showSplitQueueModal('${safeQueueId}')" title="Split queue into multiple queues">
<i data-lucide="git-branch" class="w-3 h-3"></i>
</button>
@@ -896,7 +896,7 @@ async function renderExpandedQueueView(queueId) {
</div>
</div>
<div class="queue-detail-actions">
${!isActive && queue.status !== 'merged' ? `
${!isActive && queue.status !== 'archived' ? `
<button class="btn-primary" onclick="activateQueue('${safeQueueId}')">
<i data-lucide="check-circle" class="w-4 h-4"></i>
<span>${t('issues.activate') || 'Activate'}</span>
@@ -1141,7 +1141,7 @@ function showMergeQueueModal(sourceQueueId) {
}
const otherQueues = queueData.queues.filter(q =>
q.id !== sourceQueueId && q.status !== 'merged'
q.id !== sourceQueueId && q.status !== 'archived'
);
const safeSourceId = escapeHtml(sourceQueueId || '');
@@ -1170,7 +1170,7 @@ function showMergeQueueModal(sourceQueueId) {
</div>
<p class="text-sm text-muted-foreground mt-2">
<i data-lucide="info" class="w-4 h-4 inline mr-1"></i>
Items from source queue will be appended to target queue. Source queue will be marked as "merged".
Items from source queue will be appended to target queue. Source queue will be archived.
</p>
`}
</div>