diff --git a/.claude/agents/issue-plan-agent.md b/.claude/agents/issue-plan-agent.md index cb975f4b..2437094c 100644 --- a/.claude/agents/issue-plan-agent.md +++ b/.claude/agents/issue-plan-agent.md @@ -100,10 +100,49 @@ mcp__ace-tool__search_context({ - [ ] Discover dependencies - [ ] Locate test patterns -**Fallback**: ACE → ripgrep → Glob +**Fallback Chain**: ACE → smart_search → Grep → rg → Glob + +| Tool | When to Use | +|------|-------------| +| `mcp__ace-tool__search_context` | Semantic search (primary) | +| `mcp__ccw-tools__smart_search` | Symbol/pattern search | +| `Grep` | Exact regex matching | +| `rg` / `grep` | CLI fallback | +| `Glob` | File path discovery | #### Phase 3: Solution Planning +**Multi-Solution Generation**: + +Generate multiple candidate solutions when: +- Issue complexity is HIGH +- Multiple valid implementation approaches exist +- Trade-offs between approaches (performance vs simplicity, etc.) + +| Condition | Solutions | +|-----------|-----------| +| Low complexity, single approach | 1 solution, auto-bind | +| Medium complexity, clear path | 1-2 solutions | +| High complexity, multiple approaches | 2-3 solutions, user selection | + +**Solution Evaluation** (for each candidate): +```javascript +{ + analysis: { + risk: "low|medium|high", // Implementation risk + impact: "low|medium|high", // Scope of changes + complexity: "low|medium|high" // Technical complexity + }, + score: 0.0-1.0 // Overall quality score (higher = recommended) +} +``` + +**Selection Flow**: +1. Generate all candidate solutions +2. Evaluate and score each +3. Single solution → auto-bind +4. Multiple solutions → return `pending_selection` for user choice + **Task Decomposition** following schema: ```javascript function decomposeTasks(issue, exploration) { @@ -139,56 +178,33 @@ ccw issue bind --solution /tmp/sol.json --- -## 2. Output Specifications +## 2. Output Requirements -### 2.1 Return Format - -```json -{ - "bound": [{ "issue_id": "...", "solution_id": "...", "task_count": N }], - "pending_selection": [{ "issue_id": "...", "solutions": [{ "id": "...", "description": "...", "task_count": N }] }], - "conflicts": [{ "file": "...", "issues": [...] }] -} -``` - -### 2.2 Binding Rules - -| Scenario | Action | -|----------|--------| -| Single solution | Register AND auto-bind | -| Multiple solutions | Register only, return for user selection | - -### 2.3 Task Schema - -**Schema-Driven Output**: Read schema before generating tasks: -```bash -cat .claude/workflows/cli-templates/schemas/issue-task-jsonl-schema.json -``` - -**Required Fields**: -- `id`: Task ID (pattern: `TASK-NNN`) -- `title`: Short summary (max 100 chars) -- `type`: feature | bug | refactor | test | chore | docs -- `description`: Detailed instructions -- `depends_on`: Array of prerequisite task IDs -- `delivery_criteria`: Checklist items defining completion -- `status`: pending | ready | in_progress | completed | failed | paused | skipped -- `current_phase`: analyze | implement | test | optimize | commit | done -- `executor`: agent | codex | gemini | auto - -**Optional Fields**: -- `file_context`: Relevant files/globs -- `pause_criteria`: Conditions to halt execution -- `priority`: 1-5 (1=highest) -- `phase_results`: Results from each execution phase - -### 2.4 Solution File Structure +### 2.1 Generate Files (Primary) +**Solution file per issue**: ``` .workflow/issues/solutions/{issue-id}.jsonl ``` -Each line is a complete solution JSON. +Each line is a solution JSON containing tasks. Schema: `cat .claude/workflows/cli-templates/schemas/solution-schema.json` + +### 2.2 Binding + +| Scenario | Action | +|----------|--------| +| Single solution | `ccw issue bind --solution ` (auto) | +| Multiple solutions | Register only, return for selection | + +### 2.3 Return Summary + +```json +{ + "bound": [{ "issue_id": "...", "solution_id": "...", "task_count": N }], + "pending_selection": [{ "issue_id": "...", "solutions": [{ "id": "SOL-001", "description": "...", "task_count": N }] }], + "conflicts": [{ "file": "...", "issues": [...] }] +} +``` --- @@ -215,12 +231,14 @@ Each line is a complete solution JSON. ### 3.3 Guidelines **ALWAYS**: -1. Read schema first: `cat .claude/workflows/cli-templates/schemas/issue-task-jsonl-schema.json` +1. Read schema first: `cat .claude/workflows/cli-templates/schemas/solution-schema.json` 2. Use ACE semantic search as PRIMARY exploration tool 3. Fetch issue details via `ccw issue status --json` -4. Quantify delivery_criteria with testable conditions +4. Quantify acceptance.criteria with testable conditions 5. Validate DAG before output -6. Single solution → auto-bind; Multiple → return for selection +6. Evaluate each solution with `analysis` and `score` +7. Single solution → auto-bind; Multiple → return `pending_selection` +8. For HIGH complexity: generate 2-3 candidate solutions **NEVER**: 1. Execute implementation (return plan only) diff --git a/.claude/agents/issue-queue-agent.md b/.claude/agents/issue-queue-agent.md index 20e5b85f..294f3beb 100644 --- a/.claude/agents/issue-queue-agent.md +++ b/.claude/agents/issue-queue-agent.md @@ -36,21 +36,21 @@ color: orange ```javascript { tasks: [{ + key: string, // e.g., "GH-123:TASK-001" issue_id: string, // e.g., "GH-123" solution_id: string, // e.g., "SOL-001" - task: { - id: string, // e.g., "TASK-001" - title: string, - type: string, - file_context: string[], - depends_on: string[] - } + task_id: string, // e.g., "TASK-001" + type: string, // feature | bug | refactor | test | chore | docs + file_context: string[], + depends_on: string[] // composite keys, e.g., ["GH-123:TASK-001"] }], project_root?: string, rebuild?: boolean } ``` +**Note**: Agent generates unique `item_id` (pattern: `T-{N}`) for queue output. + ### 1.2 Execution Flow ``` @@ -76,19 +76,17 @@ function buildDependencyGraph(tasks) { const fileModifications = new Map() for (const item of tasks) { - const key = `${item.issue_id}:${item.task.id}` - graph.set(key, { ...item, key, inDegree: 0, outEdges: [] }) + graph.set(item.key, { ...item, inDegree: 0, outEdges: [] }) - for (const file of item.task.file_context || []) { + for (const file of item.file_context || []) { if (!fileModifications.has(file)) fileModifications.set(file, []) - fileModifications.get(file).push(key) + fileModifications.get(file).push(item.key) } } // Add dependency edges for (const [key, node] of graph) { - for (const dep of node.task.depends_on || []) { - const depKey = `${node.issue_id}:${dep}` + for (const depKey of node.depends_on || []) { if (graph.has(depKey)) { graph.get(depKey).outEdges.push(key) node.inDegree++ @@ -147,48 +145,29 @@ function detectConflicts(fileModifications, graph) { --- -## 3. Output Specifications +## 3. Output Requirements -### 3.1 Queue Schema +### 3.1 Generate Files (Primary) -Read schema before output: -```bash -cat .claude/workflows/cli-templates/schemas/queue-schema.json +**Queue files**: +``` +.workflow/issues/queues/{queue-id}.json # Full queue with tasks, conflicts, groups +.workflow/issues/queues/index.json # Update with new queue entry ``` -### 3.2 Output Format +Queue ID format: `QUE-YYYYMMDD-HHMMSS` (UTC timestamp) + +Schema: `cat .claude/workflows/cli-templates/schemas/queue-schema.json` + +### 3.2 Return Summary ```json { - "tasks": [{ - "item_id": "T-1", - "issue_id": "GH-123", - "solution_id": "SOL-001", - "task_id": "TASK-001", - "status": "pending", - "execution_order": 1, - "execution_group": "P1", - "depends_on": [], - "semantic_priority": 0.7 - }], - "conflicts": [{ - "file": "src/auth.ts", - "tasks": ["GH-123:TASK-001", "GH-124:TASK-002"], - "resolution": "sequential", - "resolution_order": ["GH-123:TASK-001", "GH-124:TASK-002"], - "rationale": "TASK-001 creates file before TASK-002 updates", - "resolved": true - }], - "execution_groups": [ - { "id": "P1", "type": "parallel", "task_count": 3, "tasks": ["T-1", "T-2", "T-3"] }, - { "id": "S2", "type": "sequential", "task_count": 2, "tasks": ["T-4", "T-5"] } - ], - "_metadata": { - "total_tasks": 5, - "total_conflicts": 1, - "resolved_conflicts": 1, - "timestamp": "2025-12-27T10:00:00Z" - } + "queue_id": "QUE-20251227-143000", + "total_tasks": N, + "execution_groups": [{ "id": "P1", "type": "parallel", "count": N }], + "conflicts_resolved": N, + "issues_queued": ["GH-123", "GH-124"] } ``` @@ -231,5 +210,6 @@ cat .claude/workflows/cli-templates/schemas/queue-schema.json 5. Merge conflicting tasks in parallel group **OUTPUT**: -1. Write queue via `ccw issue queue` CLI -2. Return JSON with `tasks`, `conflicts`, `execution_groups`, `_metadata` +1. Write `.workflow/issues/queues/{queue-id}.json` +2. Update `.workflow/issues/queues/index.json` +3. Return summary with `queue_id`, `total_tasks`, `execution_groups`, `conflicts_resolved`, `issues_queued` diff --git a/.claude/commands/issue/plan.md b/.claude/commands/issue/plan.md index ea8ed10f..13c93c82 100644 --- a/.claude/commands/issue/plan.md +++ b/.claude/commands/issue/plan.md @@ -1,7 +1,7 @@ --- name: plan description: Batch plan issue resolution using issue-plan-agent (explore + plan closed-loop) -argument-hint: "[,,...] [--batch-size 3] --all-pending" +argument-hint: "--all-pending [,,...] [--batch-size 3] " allowed-tools: TodoWrite(*), Task(*), SlashCommand(*), AskUserQuestion(*), Bash(*), Read(*), Write(*) --- @@ -29,7 +29,7 @@ Unified planning command using **issue-plan-agent** that combines exploration an - [ ] Solution file generated for each issue - [ ] Single solution → auto-bound via `ccw issue bind` - [ ] Multiple solutions → returned for user selection -- [ ] Tasks conform to schema: `cat .claude/workflows/cli-templates/schemas/issue-task-jsonl-schema.json` +- [ ] Tasks conform to schema: `cat .claude/workflows/cli-templates/schemas/solution-schema.json` - [ ] Each task has quantified `delivery_criteria` ## Core Capabilities @@ -164,7 +164,7 @@ for (const [batchIndex, batch] of batches.entries()) { 3. Register & bind: \`ccw issue bind --solution \` ### Generate Files -\`.workflow/issues/solutions/{issue-id}.jsonl\` - Solution with tasks (schema: cat .claude/workflows/cli-templates/schemas/issue-task-jsonl-schema.json) +\`.workflow/issues/solutions/{issue-id}.jsonl\` - Solution with tasks (schema: cat .claude/workflows/cli-templates/schemas/solution-schema.json) ### Binding Rules - **Single solution**: Auto-bind via \`ccw issue bind --solution \` diff --git a/.claude/workflows/cli-templates/schemas/issue-task-jsonl-schema.json b/.claude/workflows/cli-templates/schemas/issue-task-jsonl-schema.json deleted file mode 100644 index 9f6e80ed..00000000 --- a/.claude/workflows/cli-templates/schemas/issue-task-jsonl-schema.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Issue Task JSONL Schema", - "description": "Schema for individual task entries in tasks.jsonl file", - "type": "object", - "required": ["id", "title", "type", "description", "depends_on", "delivery_criteria", "status", "current_phase", "executor"], - "properties": { - "id": { - "type": "string", - "description": "Unique task identifier (e.g., TASK-001)", - "pattern": "^TASK-[0-9]+$" - }, - "title": { - "type": "string", - "description": "Short summary of the task", - "maxLength": 100 - }, - "type": { - "type": "string", - "enum": ["feature", "bug", "refactor", "test", "chore", "docs"], - "description": "Task category" - }, - "description": { - "type": "string", - "description": "Detailed instructions for the task" - }, - "file_context": { - "type": "array", - "items": { "type": "string" }, - "description": "List of relevant files/globs", - "default": [] - }, - "depends_on": { - "type": "array", - "items": { "type": "string" }, - "description": "Array of Task IDs that must complete first", - "default": [] - }, - "delivery_criteria": { - "type": "array", - "items": { "type": "string" }, - "description": "Checklist items that define task completion", - "minItems": 1 - }, - "pause_criteria": { - "type": "array", - "items": { "type": "string" }, - "description": "Conditions that should halt execution (e.g., 'API spec unclear')", - "default": [] - }, - "status": { - "type": "string", - "enum": ["pending", "ready", "in_progress", "completed", "failed", "paused", "skipped"], - "description": "Current task status", - "default": "pending" - }, - "current_phase": { - "type": "string", - "enum": ["analyze", "implement", "test", "optimize", "commit", "done"], - "description": "Current execution phase within the task lifecycle", - "default": "analyze" - }, - "executor": { - "type": "string", - "enum": ["agent", "codex", "gemini", "auto"], - "description": "Preferred executor for this task", - "default": "auto" - }, - "priority": { - "type": "integer", - "minimum": 1, - "maximum": 5, - "description": "Task priority (1=highest, 5=lowest)", - "default": 3 - }, - "phase_results": { - "type": "object", - "description": "Results from each execution phase", - "properties": { - "analyze": { - "type": "object", - "properties": { - "status": { "type": "string" }, - "findings": { "type": "array", "items": { "type": "string" } }, - "timestamp": { "type": "string", "format": "date-time" } - } - }, - "implement": { - "type": "object", - "properties": { - "status": { "type": "string" }, - "files_modified": { "type": "array", "items": { "type": "string" } }, - "timestamp": { "type": "string", "format": "date-time" } - } - }, - "test": { - "type": "object", - "properties": { - "status": { "type": "string" }, - "test_results": { "type": "string" }, - "retry_count": { "type": "integer" }, - "timestamp": { "type": "string", "format": "date-time" } - } - }, - "optimize": { - "type": "object", - "properties": { - "status": { "type": "string" }, - "improvements": { "type": "array", "items": { "type": "string" } }, - "timestamp": { "type": "string", "format": "date-time" } - } - }, - "commit": { - "type": "object", - "properties": { - "status": { "type": "string" }, - "commit_hash": { "type": "string" }, - "message": { "type": "string" }, - "timestamp": { "type": "string", "format": "date-time" } - } - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "Task creation timestamp" - }, - "updated_at": { - "type": "string", - "format": "date-time", - "description": "Last update timestamp" - } - }, - "additionalProperties": false -} diff --git a/.claude/workflows/cli-templates/schemas/queue-schema.json b/.claude/workflows/cli-templates/schemas/queue-schema.json index a67c5353..8903a860 100644 --- a/.claude/workflows/cli-templates/schemas/queue-schema.json +++ b/.claude/workflows/cli-templates/schemas/queue-schema.json @@ -9,11 +9,11 @@ "description": "Ordered list of tasks to execute", "items": { "type": "object", - "required": ["queue_id", "issue_id", "solution_id", "task_id", "status"], + "required": ["item_id", "issue_id", "solution_id", "task_id", "status"], "properties": { - "queue_id": { + "item_id": { "type": "string", - "pattern": "^Q-[0-9]+$", + "pattern": "^T-[0-9]+$", "description": "Unique queue item identifier" }, "issue_id": { diff --git a/.claude/workflows/cli-templates/schemas/solution-schema.json b/.claude/workflows/cli-templates/schemas/solution-schema.json index 977d1de8..6c92d205 100644 --- a/.claude/workflows/cli-templates/schemas/solution-schema.json +++ b/.claude/workflows/cli-templates/schemas/solution-schema.json @@ -23,7 +23,7 @@ "description": "Task breakdown for this solution", "items": { "type": "object", - "required": ["id", "title", "scope", "action", "acceptance"], + "required": ["id", "title", "scope", "action", "implementation", "acceptance"], "properties": { "id": { "type": "string", @@ -61,10 +61,40 @@ "items": { "type": "string" }, "description": "Step-by-step implementation guide" }, - "acceptance": { + "test": { + "type": "object", + "description": "Test requirements", + "properties": { + "unit": { "type": "array", "items": { "type": "string" } }, + "integration": { "type": "array", "items": { "type": "string" } }, + "commands": { "type": "array", "items": { "type": "string" } }, + "coverage_target": { "type": "number" } + } + }, + "regression": { "type": "array", "items": { "type": "string" }, - "description": "Quantified completion criteria" + "description": "Regression check points" + }, + "acceptance": { + "type": "object", + "description": "Acceptance criteria & verification", + "required": ["criteria", "verification"], + "properties": { + "criteria": { "type": "array", "items": { "type": "string" } }, + "verification": { "type": "array", "items": { "type": "string" } }, + "manual_checks": { "type": "array", "items": { "type": "string" } } + } + }, + "commit": { + "type": "object", + "description": "Commit specification", + "properties": { + "type": { "type": "string", "enum": ["feat", "fix", "refactor", "test", "docs", "chore"] }, + "scope": { "type": "string" }, + "message_template": { "type": "string" }, + "breaking": { "type": "boolean" } + } }, "depends_on": { "type": "array", @@ -80,6 +110,28 @@ "type": "string", "enum": ["codex", "gemini", "agent", "auto"], "default": "auto" + }, + "lifecycle_status": { + "type": "object", + "description": "Lifecycle phase tracking", + "properties": { + "implemented": { "type": "boolean" }, + "tested": { "type": "boolean" }, + "regression_passed": { "type": "boolean" }, + "accepted": { "type": "boolean" }, + "committed": { "type": "boolean" } + } + }, + "status": { + "type": "string", + "enum": ["pending", "ready", "executing", "completed", "failed", "blocked"], + "default": "pending" + }, + "priority": { + "type": "integer", + "minimum": 1, + "maximum": 5, + "default": 3 } } } @@ -97,6 +149,21 @@ "integration_points": { "type": "string" } } }, + "analysis": { + "type": "object", + "description": "Solution risk assessment", + "properties": { + "risk": { "type": "string", "enum": ["low", "medium", "high"] }, + "impact": { "type": "string", "enum": ["low", "medium", "high"] }, + "complexity": { "type": "string", "enum": ["low", "medium", "high"] } + } + }, + "score": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Solution quality score (0.0-1.0)" + }, "status": { "type": "string", "enum": ["draft", "candidate", "bound", "queued", "executing", "completed", "failed"], diff --git a/.claude/workflows/cli-templates/schemas/solutions-jsonl-schema.json b/.claude/workflows/cli-templates/schemas/solutions-jsonl-schema.json deleted file mode 100644 index d7617068..00000000 --- a/.claude/workflows/cli-templates/schemas/solutions-jsonl-schema.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Solutions JSONL Schema", - "description": "Schema for each line in solutions/{issue-id}.jsonl", - "type": "object", - "required": ["id", "tasks", "created_at"], - "properties": { - "id": { - "type": "string", - "description": "Unique solution identifier", - "pattern": "^SOL-[0-9]+$" - }, - "description": { - "type": "string", - "description": "Solution approach description" - }, - "tasks": { - "type": "array", - "description": "Task breakdown for this solution", - "items": { - "type": "object", - "required": ["id", "title", "scope", "action", "acceptance"], - "properties": { - "id": { - "type": "string", - "pattern": "^T[0-9]+$" - }, - "title": { - "type": "string", - "description": "Action verb + target" - }, - "scope": { - "type": "string", - "description": "Module path or feature area" - }, - "action": { - "type": "string", - "enum": ["Create", "Update", "Implement", "Refactor", "Add", "Delete", "Configure", "Test", "Fix"] - }, - "description": { - "type": "string", - "description": "1-2 sentences describing what to implement" - }, - "modification_points": { - "type": "array", - "items": { - "type": "object", - "properties": { - "file": { "type": "string" }, - "target": { "type": "string" }, - "change": { "type": "string" } - } - } - }, - "implementation": { - "type": "array", - "items": { "type": "string" }, - "description": "Step-by-step implementation guide" - }, - "acceptance": { - "type": "array", - "items": { "type": "string" }, - "description": "Quantified completion criteria" - }, - "depends_on": { - "type": "array", - "items": { "type": "string" }, - "default": [], - "description": "Task IDs this task depends on" - }, - "estimated_minutes": { - "type": "integer", - "description": "Estimated time to complete" - }, - "executor": { - "type": "string", - "enum": ["codex", "gemini", "agent", "auto"], - "default": "auto" - } - } - } - }, - "exploration_context": { - "type": "object", - "description": "ACE exploration results", - "properties": { - "project_structure": { "type": "string" }, - "relevant_files": { - "type": "array", - "items": { "type": "string" } - }, - "patterns": { "type": "string" }, - "integration_points": { "type": "string" } - } - }, - "analysis": { - "type": "object", - "properties": { - "risk": { "type": "string", "enum": ["low", "medium", "high"] }, - "impact": { "type": "string", "enum": ["low", "medium", "high"] }, - "complexity": { "type": "string", "enum": ["low", "medium", "high"] } - } - }, - "score": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Solution quality score (0.0-1.0)" - }, - "is_bound": { - "type": "boolean", - "default": false, - "description": "Whether this solution is bound to the issue" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "bound_at": { - "type": "string", - "format": "date-time", - "description": "When this solution was bound to the issue" - } - } -} diff --git a/ccw/src/commands/issue.ts b/ccw/src/commands/issue.ts index 6e969588..4a93e3b7 100644 --- a/ccw/src/commands/issue.ts +++ b/ccw/src/commands/issue.ts @@ -129,14 +129,31 @@ interface QueueItem { failure_reason?: string; } +interface QueueConflict { + type: 'file_conflict' | 'dependency_conflict' | 'resource_conflict'; + tasks: string[]; // Item IDs involved in conflict + file?: string; // Conflicting file path + resolution: 'sequential' | 'merge' | 'manual'; + resolution_order?: string[]; + rationale?: string; + resolved: boolean; +} + +interface ExecutionGroup { + id: string; // Group ID: P1, S1, etc. + type: 'parallel' | 'sequential'; + task_count: number; + tasks: string[]; // Item IDs in this group +} + interface Queue { id: string; // Queue unique ID: QUE-YYYYMMDD-HHMMSS (derived from filename) name?: string; // Optional queue name status: 'active' | 'completed' | 'archived' | 'failed'; issue_ids: string[]; // Issues in this queue tasks: QueueItem[]; // Task items (formerly 'queue') - conflicts: any[]; - execution_groups?: any[]; + conflicts: QueueConflict[]; + execution_groups?: ExecutionGroup[]; _metadata: { version: string; total_tasks: number; diff --git a/ccw/src/templates/dashboard-css/32-issue-manager.css b/ccw/src/templates/dashboard-css/32-issue-manager.css index f994b14a..026f1fc6 100644 --- a/ccw/src/templates/dashboard-css/32-issue-manager.css +++ b/ccw/src/templates/dashboard-css/32-issue-manager.css @@ -2723,28 +2723,66 @@ .queue-detail-item { display: flex; - align-items: center; - gap: 1rem; + flex-direction: column; + gap: 0.25rem; padding: 0.5rem 0.75rem; border-radius: 0.25rem; + border-left: 3px solid transparent; } .queue-detail-item:hover { background: hsl(var(--muted) / 0.3); } +.queue-detail-item.completed { + border-left-color: hsl(142 76% 36%); +} + +.queue-detail-item.pending { + border-left-color: hsl(48 96% 53%); +} + +.queue-detail-item.executing { + border-left-color: hsl(217 91% 60%); +} + +.queue-detail-item.failed { + border-left-color: hsl(0 84% 60%); +} + +.queue-detail-item .item-main { + display: flex; + align-items: center; + gap: 0.75rem; +} + .queue-detail-item .item-id { - min-width: 120px; + min-width: 50px; color: hsl(var(--muted-foreground)); + font-family: var(--font-mono); +} + +.queue-detail-item .item-title { + flex: 1; + color: hsl(var(--foreground)); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.queue-detail-item .item-meta { + display: flex; + align-items: center; + gap: 0.75rem; + padding-left: calc(50px + 0.75rem); } .queue-detail-item .item-issue { - min-width: 80px; color: hsl(var(--primary)); + font-family: var(--font-mono); } .queue-detail-item .item-status { - margin-left: auto; padding: 0.125rem 0.5rem; font-size: 0.75rem; border-radius: 0.25rem; diff --git a/ccw/src/templates/dashboard-js/views/issue-manager.js b/ccw/src/templates/dashboard-js/views/issue-manager.js index ba4f8c7e..4a9b1309 100644 --- a/ccw/src/templates/dashboard-js/views/issue-manager.js +++ b/ccw/src/templates/dashboard-js/views/issue-manager.js @@ -1555,7 +1555,7 @@ async function showQueueHistoryModal() {
-

${t('issues.queueHistory') || 'Queue History'}

+

Queue History

@@ -1563,7 +1563,7 @@ async function showQueueHistoryModal() {
- ${t('common.loading') || 'Loading...'} + Loading...
@@ -1583,7 +1583,7 @@ async function showQueueHistoryModal() { const queueListHtml = queues.length === 0 ? `
-

${t('issues.noQueueHistory') || 'No queue history found'}

+

No queue history found

` : `
${queues.map(q => ` @@ -1611,12 +1611,12 @@ async function showQueueHistoryModal() { ${q.id !== activeQueueId ? ` ` : ''}
@@ -1631,7 +1631,7 @@ async function showQueueHistoryModal() { modal.querySelector('.issue-modal-body').innerHTML = `
-

${t('errors.loadFailed') || 'Failed to load queue history'}

+

Failed to load queue history

`; lucide.createIcons(); @@ -1689,7 +1689,7 @@ async function viewQueueDetail(queueId) { throw new Error(queue.error); } - const tasks = queue.tasks || []; + const tasks = queue.queue || []; const metadata = queue._metadata || {}; // Group by execution_group @@ -1705,27 +1705,30 @@ async function viewQueueDetail(queueId) {
-

${queue.id || queueId}

+
+

${queue.name || queue.id || queueId}

+ ${queue.name ? `${queue.id}` : ''} +
${tasks.length} - ${t('issues.totalTasks') || 'Total'} + Total
${tasks.filter(t => t.status === 'completed').length} - ${t('issues.completed') || 'Completed'} + Completed
${tasks.filter(t => t.status === 'pending').length} - ${t('issues.pending') || 'Pending'} + Pending
${tasks.filter(t => t.status === 'failed').length} - ${t('issues.failed') || 'Failed'} + Failed
@@ -1740,9 +1743,14 @@ async function viewQueueDetail(queueId) {
${items.map(item => `
- ${item.item_id || item.task_id} - ${item.issue_id} - ${item.status || 'unknown'} +
+ ${item.queue_id || item.task_id || 'N/A'} + ${item.title || item.action || 'Untitled'} +
+
+ ${item.issue_id || ''} + ${item.status || 'unknown'} +
`).join('')}
@@ -1761,11 +1769,11 @@ async function viewQueueDetail(queueId) {
-

${t('errors.loadFailed') || 'Failed to load queue detail'}

+

Failed to load queue detail

`;