Completed
on 2 Jan 2026, 12:10 pm

Output

Todo Progress Tracking for Crash Recovery

The Problem

When konsole restarts or client disconnects, the todo state (what Claude was working on, what's completed) is lost. The current recovery relies on:

  • workingHistory - tool calls streamed to client
  • requestId matching - finding the kontask by request
  • kontexts - stored after completion only

Gap: Mid-flight todo state isn't persisted anywhere recoverable.

Current Architecture

Dashboard ──SSE──► Konui ──HTTP──► Konsole ──spawn──► Claude
    │                                      │
    └── localStorage                       └── workingHistory (in-memory)
         • pending prompt                      • tool_use events
         • requestId                           • kontexts (saved after done)
         • deleted IDs

Proposed Solution: Live Kontask Updates

Store todo state inside the kontask context as Claude works, not just at completion.

Option A: Incremental Kontask Updates

// Konsole watches for TodoWrite tool calls
// Updates kontask.context.todos in real-time

kontask.context = {
  output: "<div>...</div>",
  requestId: "abc123",
  todos: [
    { content: "Fix X", status: "completed" },
    { content: "Update Y", status: "in_progress" },
    { content: "Test Z", status: "pending" }
  ],
  lastTodoUpdate: "2026-01-02T08:45:00Z"
}

Option B: Separate Progress Kontask

// Create a "progress" kontask type that's auto-updated
// Client polls/subscribes for progress updates

{
  type: "progress",
  title: "Working: Fix authentication bug",
  context: {
    parentRequestId: "abc123",
    todos: [...],
    workingHistory: [...],
    startedAt: "...",
    lastActivity: "..."
  }
}

Implementation Points

Component Change
konsole/stream.ts Detect TodoWrite calls, update kontask via MCP
konui/kontask-db.ts Add updateKontaskTodos() method
dashboard-console.ts Render todos from recovered kontask
konui/router.ts API endpoint to get progress by requestId

Recovery Flow (After Change)

1. Client reconnects
2. Loads pendingRequestId from localStorage
3. Fetches kontask by requestId
4. If kontask has context.todos:
   → Render todo list showing progress
   → Show "Claude was working on: {activeForm}"
5. If kontask has output:
   → Display completed output card

Key Insight: The kontask already has requestId for matching. Adding context.todos and updating it during streaming gives us persistent todo state without new storage.

Quick Actions

Original Request

No layout configured

Details

Type General
Status Completed
Scope vibetools
Tags kontaskstodosrecoverykonsole
Created 2 Jan 2026, 12:10 pm
Updated 2 Jan 2026, 12:10 pm
Created By claude

📋 Claude's Context

Working On Analyzing todo persistence options for kontask crash recovery
Session dashboard...

Raw Data

{
  "id": "797af873-c2e6-4a61-9e56-3c8b442af44f",
  "type": "general",
  "status": "completed",
  "title": "Todo Progress Tracking in Kontasks",
  "description": "Analysis of how to persist Claude's todo state in kontasks for crash recovery",
  "context": {
    "output": "<div style=\"background:#1e1e1e;color:#e0e0e0;padding:20px;border-radius:8px;font-family:sans-serif;\">\n<h2 style=\"color:#fff;margin:0 0 16px 0;\">Todo Progress Tracking for Crash Recovery</h2>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#f44336;margin:0 0 12px 0;\">The Problem</h3>\n<p style=\"margin:0;line-height:1.6;\">When konsole restarts or client disconnects, the todo state (what Claude was working on, what's completed) is lost. The current recovery relies on:</p>\n<ul style=\"margin:12px 0 0 0;padding-left:20px;line-height:1.8;\">\n<li><code style=\"background:#3d3d3d;padding:2px 6px;border-radius:3px;\">workingHistory</code> - tool calls streamed to client</li>\n<li><code style=\"background:#3d3d3d;padding:2px 6px;border-radius:3px;\">requestId</code> matching - finding the kontask by request</li>\n<li><code style=\"background:#3d3d3d;padding:2px 6px;border-radius:3px;\">kontexts</code> - stored after completion only</li>\n</ul>\n<p style=\"margin:12px 0 0 0;color:#ff9800;\">Gap: Mid-flight todo state isn't persisted anywhere recoverable.</p>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#4caf50;margin:0 0 12px 0;\">Current Architecture</h3>\n<pre style=\"background:#1e1e1e;padding:12px;border-radius:4px;font-family:monospace;font-size:0.85rem;overflow-x:auto;line-height:1.6;\">\n<span style=\"color:#61afef;\">Dashboard</span> ──SSE──► <span style=\"color:#98c379;\">Konui</span> ──HTTP──► <span style=\"color:#e5c07b;\">Konsole</span> ──spawn──► <span style=\"color:#c678dd;\">Claude</span>\n    │                                      │\n    └── localStorage                       └── <span style=\"color:#7f848e;\">workingHistory (in-memory)</span>\n         • pending prompt                      • tool_use events\n         • requestId                           • kontexts (saved after done)\n         • deleted IDs\n</pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#2196f3;margin:0 0 12px 0;\">Proposed Solution: Live Kontask Updates</h3>\n<p style=\"margin:0 0 12px 0;line-height:1.6;\">Store todo state <strong>inside the kontask context</strong> as Claude works, not just at completion.</p>\n\n<div style=\"background:#1e1e1e;padding:12px;border-radius:4px;margin:12px 0;\">\n<p style=\"margin:0 0 8px 0;color:#98c379;font-weight:bold;\">Option A: Incremental Kontask Updates</p>\n<pre style=\"font-family:monospace;font-size:0.85rem;margin:0;line-height:1.5;\">\n// Konsole watches for TodoWrite tool calls\n// Updates kontask.context.todos in real-time\n\nkontask.context = {\n  output: \"&lt;div&gt;...&lt;/div&gt;\",\n  requestId: \"abc123\",\n  <span style=\"color:#98c379;\">todos: [</span>\n    <span style=\"color:#98c379;\">{ content: \"Fix X\", status: \"completed\" },</span>\n    <span style=\"color:#98c379;\">{ content: \"Update Y\", status: \"in_progress\" },</span>\n    <span style=\"color:#98c379;\">{ content: \"Test Z\", status: \"pending\" }</span>\n  <span style=\"color:#98c379;\">],</span>\n  <span style=\"color:#98c379;\">lastTodoUpdate: \"2026-01-02T08:45:00Z\"</span>\n}\n</pre>\n</div>\n\n<div style=\"background:#1e1e1e;padding:12px;border-radius:4px;margin:12px 0;\">\n<p style=\"margin:0 0 8px 0;color:#61afef;font-weight:bold;\">Option B: Separate Progress Kontask</p>\n<pre style=\"font-family:monospace;font-size:0.85rem;margin:0;line-height:1.5;\">\n// Create a \"progress\" kontask type that's auto-updated\n// Client polls/subscribes for progress updates\n\n{\n  type: \"progress\",\n  title: \"Working: Fix authentication bug\",\n  context: {\n    parentRequestId: \"abc123\",\n    todos: [...],\n    workingHistory: [...],\n    startedAt: \"...\",\n    lastActivity: \"...\"\n  }\n}\n</pre>\n</div>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#ff9800;margin:0 0 12px 0;\">Implementation Points</h3>\n\n<table style=\"width:100%;border-collapse:collapse;font-size:0.9rem;\">\n<tr style=\"border-bottom:1px solid #444;\">\n<th style=\"text-align:left;padding:8px;color:#e0e0e0;\">Component</th>\n<th style=\"text-align:left;padding:8px;color:#e0e0e0;\">Change</th>\n</tr>\n<tr style=\"border-bottom:1px solid #3d3d3d;\">\n<td style=\"padding:8px;\"><code>konsole/stream.ts</code></td>\n<td style=\"padding:8px;\">Detect TodoWrite calls, update kontask via MCP</td>\n</tr>\n<tr style=\"border-bottom:1px solid #3d3d3d;\">\n<td style=\"padding:8px;\"><code>konui/kontask-db.ts</code></td>\n<td style=\"padding:8px;\">Add <code>updateKontaskTodos()</code> method</td>\n</tr>\n<tr style=\"border-bottom:1px solid #3d3d3d;\">\n<td style=\"padding:8px;\"><code>dashboard-console.ts</code></td>\n<td style=\"padding:8px;\">Render todos from recovered kontask</td>\n</tr>\n<tr>\n<td style=\"padding:8px;\"><code>konui/router.ts</code></td>\n<td style=\"padding:8px;\">API endpoint to get progress by requestId</td>\n</tr>\n</table>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#9c27b0;margin:0 0 12px 0;\">Recovery Flow (After Change)</h3>\n<pre style=\"background:#1e1e1e;padding:12px;border-radius:4px;font-family:monospace;font-size:0.85rem;line-height:1.6;\">\n<span style=\"color:#7f848e;\">1. Client reconnects</span>\n<span style=\"color:#7f848e;\">2. Loads pendingRequestId from localStorage</span>\n<span style=\"color:#7f848e;\">3. Fetches kontask by requestId</span>\n<span style=\"color:#7f848e;\">4. If kontask has context.todos:</span>\n   <span style=\"color:#98c379;\">→ Render todo list showing progress</span>\n   <span style=\"color:#98c379;\">→ Show \"Claude was working on: {activeForm}\"</span>\n<span style=\"color:#7f848e;\">5. If kontask has output:</span>\n   <span style=\"color:#98c379;\">→ Display completed output card</span>\n</pre>\n</div>\n\n<div style=\"background:#3d3d3d;padding:12px;border-radius:6px;border-left:4px solid #2196f3;\">\n<p style=\"margin:0;color:#e0e0e0;\"><strong>Key Insight:</strong> The kontask already has <code>requestId</code> for matching. Adding <code>context.todos</code> and updating it during streaming gives us persistent todo state without new storage.</p>\n</div>\n</div>",
    "requestedAt": "2026-01-02T08:45:00Z",
    "requestId": "b4240372-4ace-4b8e-a12e-5aaf4ab5b351",
    "choices": [
      {
        "label": "Option A: Incremental updates",
        "value": "Implement Option A - update the existing kontask context with todo state during streaming",
        "primary": true
      },
      {
        "label": "Option B: Progress kontasks",
        "value": "Implement Option B - create a separate progress kontask type for in-flight work"
      },
      {
        "label": "Explore alternatives",
        "value": "Research other approaches to crash recovery for long-running Claude tasks"
      }
    ]
  },
  "createdBy": "claude",
  "createdAt": "2026-01-02T02:10:56.965Z",
  "updatedAt": "2026-01-02T02:10:57.117Z",
  "requestId": "b4240372-4ace-4b8e-a12e-5aaf4ab5b351",
  "scope": "vibetools",
  "tags": [
    "kontasks",
    "todos",
    "recovery",
    "konsole"
  ],
  "sessionId": "dashboard",
  "planSummary": "Analyzing todo persistence options for kontask crash recovery",
  "targetUser": "claude"
}
DashboardReportsKontasksSessionsTelemetryLogs + Go