npm package: @comfanion/usethis_todo
Description: OpenCode plugin: enhanced TODO tools (dual storage + dependency graph)
Latest version: 0.1.17

# 📋 @comfanion/usethis_todo

**Smart TODO management with dependency graphs and priority tracking**

Stop juggling tasks in your head — let the graph show you what to do next!

---

## ✨ What is this?

An OpenCode plugin that transforms TODO lists into **intelligent task graphs**:

- 🎯 **Dependency tracking** — tasks know what blocks them
- 📊 **Visual graph analysis** — see available, blocked, and parallel tasks
- 🔥 **Priority system** — CRIT | HIGH | MED | LOW with auto-sorting
- 🏗️ **Hierarchical IDs** — E01-S01-T01 (Epic → Story → Task)
- 💾 **Dual storage** — enhanced features + native TUI integration
- 🚀 **Smart transitions** — auto-promote tasks when conditions are met

---

## 🧹 Context Leak Problem & Auto-Pruning

### The Problem

This is **not** a problem introduced by this plugin — it is an existing problem in the **default `TodoRead` / `TodoWrite` MCP tools** that ship with AI coding agents (Claude Code, OpenCode, etc.).

The default TODO tools work through MCP (Model Context Protocol). When the agent calls a TODO tool, two things happen:

1. The **MCP tool response** is added to conversation history (the agent sees the result)
2. A **separate chat message** is injected into the conversation as a workaround for UI display

The agent sees **both** — the tool result AND the duplicate chat message. Every single TODO call produces **double output** in the context window:

```
Agent calls: TodoWrite(...)
  → tool response:   +800 tokens  (MCP result — agent sees this)
  → chat message:    +800 tokens  (UI workaround — agent sees this too)
  ─────────────────────────────────
  Total per call:    ~1,600 tokens (2x duplication)
```

In a typical session, an agent calls TODO tools **dozens of times** — creating tasks, updating statuses, reading the list, checking what's next. Without cleanup:

```
Call 1:  TodoWrite   →  +1,600 tokens (tool result + chat duplicate)
Call 2:  TodoUpdate  →  +1,600 tokens (tool result + chat duplicate)
Call 3:  TodoRead    →  +1,600 tokens (tool result + chat duplicate)
Call 4:  TodoUpdate  →  +1,600 tokens (tool result + chat duplicate)
...
Call 20: TodoUpdate  →  +1,600 tokens (tool result + chat duplicate)
─────────────────────────────────────────────────────
Total TODO overhead: ~32,000 tokens — stale duplicated snapshots
```

Only the **last** call result matters. The other 19 are stale data sitting in the context window, pushing out useful code, conversation, and reasoning. This is the **context leak** — silent, cumulative, and it degrades agent performance as the session progresses.

The problem compounds with larger task lists. A 30-task graph with dependencies can produce 2,000+ tokens per call. With 2x duplication, after 15 updates that's **60,000 tokens** of dead weight — roughly 20-30% of a typical context window, gone.

### The Solution: Auto-Pruning

This plugin solves both problems — stale accumulation **and** duplication — by hooking into `experimental.chat.messages.transform` to automatically clean up old TODO results **before each LLM call**:

```
Call 1: usethis_todo_write  →  [TODO pruned] + snapshot removed     ← cleaned
Call 2: usethis_todo_update →  [TODO pruned] + snapshot removed     ← cleaned
Call 3: usethis_todo_read   →  [TODO pruned] + snapshot removed     ← cleaned
Call 4: usethis_todo_update →  (full graph output) + latest snapshot ← only latest kept
─────────────────────────────────────────────────────
Total TODO overhead: ~800 tokens — constant, not cumulative
```

**How it works:**

1. **Track last call** — after each TODO tool execution, the plugin records the `callID` in a per-session state
2. **Transform messages** — before each LLM inference, the plugin scans all messages and replaces old TODO tool outputs with `[TODO pruned]`, clearing both `output` and `input` fields
3. **Keep latest** — only the most recent TODO call result is preserved in full, giving the agent current state
4. **Prune chat snapshots** — the plugin publishes TODO state as `## TODO` user messages for UI display; old snapshot messages are **removed entirely** from the message list, keeping only the latest one. This eliminates the duplication problem where the agent would otherwise see both the tool result and the chat message
5. **Complete cleanup** — when all tasks are marked `done`, even the last result and the last snapshot are pruned — the TODO list served its purpose and no longer needs context space

**Result:** TODO tool overhead is **O(1)** instead of **O(n)** — constant ~800 tokens regardless of how many times the agent interacts with the task list. The 2x duplication from the chat workaround is also eliminated.

### What Gets Pruned

| Content | Pruned? | Why |
|---------|---------|-----|
| Old tool outputs (`todo_write`, `todo_update`, etc.) | Yes | Stale state, agent doesn't need old snapshots |
| Old tool inputs | Yes | Arguments to stale calls are not useful |
| Old `## TODO` chat snapshot messages | Yes | Duplicate of tool output injected for UI display |
| Latest tool call output | **No** | Agent needs current state to make decisions |
| Latest `## TODO` chat snapshot | **No** | Kept for UI consistency |
| All outputs when all tasks are done | **Yes** | Work is finished, free the entire context budget |

### Default tools vs. this plugin

| | Default `TodoRead`/`TodoWrite` | `@comfanion/usethis_todo` |
|---|---|---|
| Tool result in context | Accumulates forever | Auto-pruned, only latest kept |
| Chat message duplicate | Accumulates forever | Auto-pruned, only latest kept |
| Tokens per call (visible to agent) | ~1,600 (tool + chat duplicate) | ~800 (only latest) |
| After 20 calls | ~32,000 tokens wasted | ~800 tokens constant |
| When all tasks done | Still in context | Fully cleaned up |
| Context overhead | **O(n)** — grows with every call | **O(1)** — constant |

---

## 🚀 Quick Start

### Installation

```bash
npm install @comfanion/usethis_todo
```

### Configuration

Add to `opencode.json`:

```json
{
  "plugin": ["@comfanion/usethis_todo"]
}
```

### First TODO

```javascript
usethis_todo_write({
  todos: [
    {
      id: "E01-S01-T01",
      content: "Setup database schema",
      status: "todo",
      priority: "HIGH"
    },
    {
      id: "E01-S01-T02",
      content: "Create API endpoints",
      status: "todo",
      priority: "HIGH",
      blockedBy: ["E01-S01-T01"]  // Waits for T01
    }
  ]
})
```

**Output:**
```
TODO Graph [0/2 done, 0 in progress]

All Tasks:
- E01
  - E01-S01
    - ○ 🟠 E01-S01-T01: Setup database schema
    - ⊗ 🟠 E01-S01-T02: Create API endpoints ← E01-S01-T01

Available Now:
- E01
  - E01-S01
    - ○ 🟠 E01-S01-T01: Setup database schema

Blocked:
- E01
  - E01-S01
    - ⊗ 🟠 E01-S01-T02: Create API endpoints ← E01-S01-T01
```

---

## 🎯 Core Features

### 1. Dependency Graph

Tasks can depend on other tasks. The plugin automatically:
- ✅ Shows which tasks are **available** (no blockers)
- ⊗ Shows which tasks are **blocked** (waiting on others)
- 🔗 Resolves **transitive dependencies** (A → B → C)
- ⚡ Identifies **parallel tasks** (can work on simultaneously)

**Example:**
```javascript
usethis_todo_write({
  todos: [
    { id: "T01", content: "Design API", status: "done", priority: "HIGH" },
    { id: "T02", content: "Implement API", status: "todo", priority: "HIGH", blockedBy: ["T01"] },
    { id: "T03", content: "Write tests", status: "todo", priority: "MED", blockedBy: ["T02"] },
    { id: "T04", content: "Setup CI/CD", status: "todo", priority: "MED" }  // Parallel!
  ]
})
```

**Graph shows:**
- **Available:** T02 (T01 done), T04 (no blockers)
- **Blocked:** T03 (waits for T02)
- **Parallel:** T02 and T04 can be done simultaneously

### 2. Priority System

Four priority levels with visual indicators:

| Priority | Icon | Use Case |
|----------|------|----------|
| `CRIT` | 🔴 | Production down, security issue |
| `HIGH` | 🟠 | Sprint goal, blocking others |
| `MED` | 🟡 | Normal work (default) |
| `LOW` | 🟢 | Nice to have, refactoring |

Tasks are **auto-sorted** by priority in all views.

### 3. Hierarchical IDs

Organize tasks in 3 levels:

```
E01-S01-T01
│   │   └── Task 01
│   └────── Story 01
└────────── Epic 01
```

**Benefits:**
- 📁 Nested display (epics → stories → tasks)
- 🔍 Easy filtering (all tasks in E01-S01)
- 📊 Progress tracking per epic/story

### 4. Status Lifecycle

```
todo → in_progress → ready → done
  ↓         ↓          ↓       ↓
  ○         ⚙          ⏳      ✓
```

**Auto-transitions:**
- `ready` → `done` when `releases` field is set
- Blocked tasks show `⊗` icon (even if status is `todo`)

### 5. Release Tracking

Mark tasks as part of releases:

```javascript
usethis_todo_update({
  todos: [{
    id: "E01-S01-T01",
    status: "ready",
    releases: ["E01-S01-T01-ST02"]  // Auto-promotes to "done"
  }]
})
```

---

## 🛠️ Tools Reference

### `usethis_todo_write`

Create or replace entire TODO list.

```javascript
usethis_todo_write({
  todos: [
    {
      id: "E01-S01-T01",                     // Required: Hierarchical ID
      content: "Task summary",               // Required: Short description
      description: "Full details...",        // Optional: Long description
      status: "todo",                        // Required: todo | in_progress | ready | done
      priority: "HIGH",                      // Required: CRIT | HIGH | MED | LOW
      blockedBy: ["E01-S01-T02"],            // Optional: Dependency IDs
      releases: ["E01-S01", "E01-S01-T02"]   // Optional: Release tags
    }
  ]
})
```

**Returns:** Full graph analysis

### `usethis_todo_read`

Read all tasks with graph analysis.

```javascript
usethis_todo_read()
```

**Returns:**
- All tasks (nested by epic/story)
- Available tasks (ready to work on)
- Blocked tasks (waiting on dependencies)
- Progress stats (X/Y done, Z in progress)

### `usethis_todo_read_five`

Get next 5 available tasks (smart view).

```javascript
usethis_todo_read_five()
```

**Returns:**
- Top 5 tasks by priority
- Resolved blockers (what they depend on)
- Missing dependencies (if any)

**Perfect for:** "What should I work on next?"

### `usethis_todo_read_by_id`

Get details for specific task.

```javascript
usethis_todo_read_by_id({ id: "E01-S01-T01" })
```

**Returns:**
- Task details
- Full dependency chain
- Missing dependencies

### `usethis_todo_update`

Update one or more tasks (merge mode).

```javascript
usethis_todo_update({
  todos: [
    {
      id: "E01-S01-T01",
      status: "done"  // Only update status, keep other fields
    },
    {
      id: "E01-S01-T02",
      status: "in_progress",
      priority: "CRIT"  // Update multiple fields
    }
  ]
})
```

**Returns:** Updated graph

---

## 🎨 Usage Examples

### Example 1: Sprint Planning

```javascript
// Create sprint tasks
usethis_todo_write({
  todos: [
    // Epic 01: User Authentication
    { id: "E01-S01-T01", content: "Design auth API", status: "done", priority: "HIGH" },
    { id: "E01-S01-T02", content: "Implement JWT", status: "in_progress", priority: "HIGH", blockedBy: ["E01-S01-T01"] },
    { id: "E01-S01-T03", content: "Add refresh tokens", status: "todo", priority: "MED", blockedBy: ["E01-S01-T02"] },
    
    // Epic 02: User Profile (parallel work)
    { id: "E02-S01-T01", content: "Design profile schema", status: "todo", priority: "MED" },
    { id: "E02-S01-T02", content: "Create profile API", status: "todo", priority: "MED", blockedBy: ["E02-S01-T01"] }
  ]
})
```

**Graph shows:**
- **Available:** E01-S01-T02 (in progress), E02-S01-T01 (can start)
- **Blocked:** E01-S01-T03, E02-S01-T02
- **Parallel:** E01 and E02 can progress simultaneously

### Example 2: Daily Workflow

```javascript
// Morning: What's next?
usethis_todo_read_five()
// → Shows top 5 tasks by priority

// Start working
usethis_todo_update({
  todos: [{ id: "E01-S01-T02", status: "in_progress" }]
})

// Finish task
usethis_todo_update({
  todos: [{ id: "E01-S01-T02", status: "done" }]
})

// Check what unblocked
usethis_todo_read_five()
// → E01-S01-T03 now available!
```

### Example 3: Bug Triage

```javascript
// Critical bug found!
usethis_todo_update({
  todos: [{
    id: "BUG-001",
    content: "Fix login crash",
    status: "todo",
    priority: "CRIT"  // Jumps to top of queue
  }]
})

usethis_todo_read_five()
// → BUG-001 is first (CRIT priority)
```

### Example 4: Task Completion Tracking

```javascript
// Mark tasks as completed with linked subtask IDs
usethis_todo_update({
  todos: [
    { id: "E01-S01-T01", status: "ready", releases: ["E01-S01-T01-ST01", "E01-S01-T01-ST02"] },
    { id: "E01-S01-T02", status: "ready", releases: ["E01-S01-T02-ST01"] }
  ]
})
// → Auto-promotes to "done" when releases set

// Check progress
usethis_todo_read()
// → Both tasks promoted to "done"
```

### Example 5: Complex Dependencies

```javascript
usethis_todo_write({
  todos: [
    { id: "T01", content: "Database schema", status: "done", priority: "HIGH" },
    { id: "T02", content: "API layer", status: "done", priority: "HIGH", blockedBy: ["T01"] },
    { id: "T03", content: "Business logic", status: "todo", priority: "HIGH", blockedBy: ["T02"] },
    { id: "T04", content: "UI components", status: "todo", priority: "MED", blockedBy: ["T03"] },
    { id: "T05", content: "Integration tests", status: "todo", priority: "MED", blockedBy: ["T04"] }
  ]
})

// Check specific task
usethis_todo_read_by_id({ id: "T05" })
// → Shows full chain: T05 ← T04 ← T03 ← T02 ← T01
```

---

## 📦 Storage

### Dual Storage System

The plugin writes to **two locations**:

#### 1. Enhanced Storage (Project-local)
```
.opencode/
  session-todo/
    {session-id}.json    # Full data with dependencies
  todo.log               # Action log
```

**Contains:**
- Full task data (description, blockedBy, releases)
- Timestamps (createdAt, updatedAt)
- All custom fields

#### 2. Native Storage (TUI Integration)
```
~/.local/share/opencode/storage/todo/{session-id}.json
# or
~/Library/Application Support/opencode/storage/todo/{session-id}.json
```

**Contains:**
- Simplified format for OpenCode TUI
- Status/priority mapped to native values
- Dependencies shown in content field

**Why dual storage?**
- ✅ Enhanced features (graph, dependencies)
- ✅ Native TUI display (sidebar integration)
- ✅ Best of both worlds!

---

## 🎨 Visual Indicators

### Status Icons

| Icon | Status | Meaning |
|------|--------|---------|
| ○ | `todo` | Not started |
| ⚙ | `in_progress` | Working on it |
| ⏳ | `ready` | Done, awaiting release |
| ✓ | `done` | Completed |
| ✗ | `cancelled` | Abandoned |
| ⊗ | (blocked) | Has active blockers |

### Priority Icons

| Icon | Priority | Color |
|------|----------|-------|
| 🔴 | CRIT | Red |
| 🟠 | HIGH | Orange |
| 🟡 | MED | Yellow |
| 🟢 | LOW | Green |

---

## 🧠 Smart Features

### 1. Auto-Promotion

Tasks automatically transition when conditions are met:

```javascript
// Task in "ready" status
{ id: "T01", status: "ready", releases: [] }

// Add completed subtask IDs
usethis_todo_update({
  todos: [{ id: "T01", releases: ["T01-ST01", "T01-ST02"] }]
})

// → Auto-promotes to "done"!
```

### 2. Transitive Dependencies

The plugin resolves entire dependency chains:

```javascript
// T03 depends on T02, T02 depends on T01
usethis_todo_read_by_id({ id: "T03" })

// Shows full chain:
// Blocked By (resolved):
// - T02 (in_progress)
// - T01 (done)
```

### 3. Parallel Detection

Identifies tasks that can be worked on simultaneously:

```javascript
// Graph analysis shows:
// Parallel groups:
// - [T02, T04, T05]  ← Can all start now
// - [T03, T06]       ← Can start after T02 done
```

### 4. Missing Dependency Detection

Warns about broken references:

```javascript
{ id: "T01", blockedBy: ["T99"] }  // T99 doesn't exist

usethis_todo_read_by_id({ id: "T01" })
// → Blocked By missing: T99
```

---

## 🔧 Advanced Usage

### Custom ID Schemes

While hierarchical IDs are recommended, you can use any format:

```javascript
// Hierarchical (recommended)
{ id: "E01-S01-T01" }  // Epic-Story-Task

// Flat
{ id: "TASK-001" }

// Custom
{ id: "AUTH-LOGIN-JWT" }
```

**Note:** Hierarchical IDs get nested display, others show flat.

### Filtering by Status

```javascript
// Get all in-progress tasks
const todos = await usethis_todo_read()
const wip = todos.filter(t => t.status === "in_progress")
```

### Progress Tracking

```javascript
// Track epic progress
const todos = await usethis_todo_read()
const epic01 = todos.filter(t => t.id.startsWith("E01-"))
const done = epic01.filter(t => t.status === "done").length
const total = epic01.length
console.log(`Epic 01: ${done}/${total} done`)
```

---

## 🐛 Debugging

### Enable Logging

All operations are logged to `.opencode/todo.log`:

```
[2024-01-15T10:30:00.000Z] WRITE: Created/Updated 5 tasks in session abc123
[2024-01-15T10:31:00.000Z] UPDATE: Updated 1 task(s) in session abc123
[2024-01-15T10:32:00.000Z] READ_FIVE: Read next 5 tasks (total ready: 12)
```

### Check Storage

```bash
# Enhanced storage
cat .opencode/session-todo/{session-id}.json

# Native storage (macOS)
cat ~/Library/Application\ Support/opencode/storage/todo/{session-id}.json

# Native storage (Linux)
cat ~/.local/share/opencode/storage/todo/{session-id}.json
```

### Validate Dependencies

```javascript
// Check for circular dependencies
usethis_todo_read()
// → Graph analysis will show if tasks are mutually blocked
```

---

## 🌟 Advantages

### Compared to Simple TODO Lists

| Feature | Simple TODO | usethis_todo |
|---------|-------------|--------------|
| Task list | ✅ | ✅ |
| Dependencies | ❌ | ✅ |
| Priority sorting | ❌ | ✅ |
| Graph analysis | ❌ | ✅ |
| Parallel detection | ❌ | ✅ |
| Hierarchical IDs | ❌ | ✅ |
| Auto-transitions | ❌ | ✅ |
| Release tracking | ❌ | ✅ |

### Compared to Project Management Tools

| Feature | Jira/Asana | usethis_todo |
|---------|------------|--------------|
| In your editor | ❌ | ✅ |
| Offline | ❌ | ✅ |
| Free | ❌ | ✅ |
| Fast | 🐌 | ⚡ |
| No context switch | ❌ | ✅ |
| Version controlled | ❌ | ✅ (project-local) |

---

## 📊 Technical Details

- **Storage format:** JSON
- **Session isolation:** Tasks are per-session (multi-session support)
- **Dependency resolution:** Recursive graph traversal
- **Priority sorting:** Stable sort (CRIT → HIGH → MED → LOW → ID)
- **Status normalization:** Backward-compatible with old formats
- **TUI integration:** Automatic sync to native storage

---

## 🤝 Contributing

Found a bug? Have an idea? Open an issue or PR!

---

## 📄 License

MIT

---

## 🎉 Authors

Made with ❤️ by the **Comfanion** team

---

**Work smart, not hard — let the graph guide you!** 🚀