Full Workflow Example

Tofie Planning Workflow Example #

A complete example showing Tofie automated planning from Linear issue status change.

Current Status: Only the planning workflow is currently implemented. Implementation, QA, and PR submission workflows are coming soon.

Scenario #

User: Sarah (Product Manager) Task: Add export functionality to invoice list Linear Issue: ENG-2310

Step 1: Create Linear Issue #

Sarah creates a new issue in Linear:

Title: Add CSV export for invoice list

Description:

Users need to export invoice lists to CSV for accounting purposes.

Requirements:
- Export button in invoice list view
- Include all visible columns
- Apply current filters to export
- Download as CSV file

Acceptance Criteria:
- [ ] Export button visible in invoice list
- [ ] CSV includes invoice number, date, amount, status
- [ ] Filtered invoices export correctly
- [ ] File downloads with proper filename (invoices-YYYY-MM-DD.csv)

Status: Backlog Labels: feature, webapp Project: BonsAI Core

Step 2: Trigger Planning #

Sarah triggers Tofie planning using one of two methods:

Method 1: Change Status to “Planning” (Tofie Already Assigned) #

Prerequisites: Tofie (or [Dev] Tofie) is already assigned to the issue

Action:

  1. Change issue status from any state → Planning

What Happens: n8n webhook triggers planning workflow

Method 2: Assign Tofie (Status Already “Planning”) #

Prerequisites: Issue status is already “Planning”

Action:

  1. Assign Tofie or [Dev] Tofie to the issue

What Happens: n8n webhook triggers planning workflow


What Happens Behind the Scenes #

n8n Workflow (< 1 second):

  1. Linear webhook received
  2. Validates: status = “Planning” AND assignee = “Tofie”
  3. Prepares input JSON with issue data
  4. SSH to development server
  5. Executes planning-subagent.sh

Development Server (~2-5 minutes):

Phase 1: Worktree Setup (5-10 seconds)

[INFO] Reading JSON input from stdin...
[INFO] Parsed input:
[INFO]   Branch: sarah/eng-2310-feat-csv-export
[INFO]   Base Branch: main
[INFO]   Issue: ENG-2310 - Add CSV export for invoice list
[INFO]   Project: BonsAI Core
[INFO]   Thoroughness: very thorough
[INFO]   Comments: 0
[INFO] Project root: /home/coder/bonsai
[INFO] Worktree path: /home/coder/trees/sarah-eng-2310-feat-csv-export
[INFO] Creating worktree from main branch...
[INFO] Worktree created
[INFO] Metadata files created

Phase 2: Claude Code Planning (2-5 minutes)

[SUBAGENT] Building prompt to request tofie-planner subagent...
[SUBAGENT] Executing Claude Code CLI with subagent request...

Claude Code Output:
- Analyzing codebase structure
- Reading existing export patterns
- Reviewing invoice list implementation
- Understanding API architecture
- Creating comprehensive plan
- Writing PLAN.md with Linear formatting

Phase 3: Completion (< 1 second)

[INFO] Plan created: .plans/PLAN.md (15234 bytes)
[INFO] Planning completed successfully with subagent!

Total Time: ~3-5 minutes

Planning Result - Events Sent to n8n #

During planning, real-time events are sent to n8n (if hooks are enabled):

// PreToolUse events
{"hook_event_type": "PreToolUse", "tool_name": "Read", "file": "src/app.tsx"}
{"hook_event_type": "PreToolUse", "tool_name": "Grep", "pattern": "export"}

// PostToolUse events
{"hook_event_type": "PostToolUse", "tool_name": "Read", "status": "success"}

// SubagentStop event
{"hook_event_type": "SubagentStop", "subagent_type": "tofie-planner"}

// Stop event (completion)
{"hook_event_type": "Stop", "completion_reason": "finished"}

n8n processes these events and updates Linear with progress comments:

📖 Reading src/app/(authenticated)/invoices/page.tsx
🔍 Searching for export patterns
📖 Reading apps/bonsapi/src/controllers/invoice.rs
🤖 Subagent (Tofie Planner) finished its work
🎉 Planning completed successfully

Plan Posted to Linear #

Tofie (via n8n or manual posting) updates Linear:

✅ Planning Complete

I've created a comprehensive implementation plan for this issue.

## Summary
- **Estimated time**: 4-6 hours
- **Phases**: 3 (Backend, Frontend, Testing)
- **Files to modify**: 5
- **New files**: 2

## Plan Details

📄 Full plan available in worktree: `.plans/PLAN.md`

# CSV Export Implementation Plan

## Executive Summary

- Add CSV export functionality to invoice list view
- Impacts: webapp frontend, API endpoint
- Expected completion: 4-6 hours
- Linear issue: https://linear.app/bonsai/issue/ENG-2310

## Comments Analysis

**Key takeaways from issue comments:**
- Export should respect current filters
- Filename format specified: invoices-YYYY-MM-DD.csv

+++ Detailed Comments Analysis

[Full comment analysis collapsed]

+++

+++ Background Research

### Existing Code Analysis

- Invoice list: `apps/webapp/src/app/(authenticated)/invoices/page.tsx`
- API endpoint: `apps/bonsapi/src/controllers/invoice.rs`
- Existing export pattern: `apps/webapp/src/lib/utils/export.ts` (for PDF)

### Architecture Patterns

- Uses TanStack Query for data fetching
- API follows REST conventions
- CSV export similar to existing PDF export flow

+++

## Implementation Phases

**High-level overview:**
- Phase 1: Backend API (1.5 hours)
- Phase 2: Frontend Component (2 hours)
- Phase 3: Testing (1.5 hours)

**Total estimated effort:** 4-6 hours

+++ Phase 1: Backend API

**Tasks:**
1. Add CSV export endpoint `GET /api/invoices/export`
2. Implement CSV generation logic
3. Apply filters from query params
4. Update OpenAPI spec

**Files to modify:**
- `apps/bonsapi/src/controllers/invoice.rs`
- `apps/bonsapi/docs/openapi/invoices.yaml`

**Files to create:**
- `apps/bonsapi/src/services/csv_export.rs`

**Implementation Details:**
```rust
// New endpoint in invoice controller
pub async fn export_csv(
    query: web::Query<InvoiceFilters>,
) -> Result<HttpResponse> {
    let csv_data = csv_export::generate_invoice_csv(query).await?;
    Ok(HttpResponse::Ok()
        .content_type("text/csv")
        .body(csv_data))
}

+++

+++ Phase 2: Frontend Component

Tasks:

  1. Create ExportButton component
  2. Integrate into invoice list toolbar
  3. Implement download logic
  4. Add loading states

Files to modify:

  • apps/webapp/src/app/(authenticated)/invoices/page.tsx

Files to create:

  • apps/webapp/src/components/invoices/ExportButton.tsx

Implementation Details:

export function ExportButton() {
  const { filters } = useInvoices();
  const [isLoading, setIsLoading] = useState(false);

  const handleExport = async () => {
    setIsLoading(true);
    const response = await fetch('/api/invoices/export?' +
      new URLSearchParams(filters));
    const blob = await response.blob();
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `invoices-${format(new Date(), 'yyyy-MM-dd')}.csv`;
    a.click();
    setIsLoading(false);
  };

  return (
    <Button onClick={handleExport} disabled={isLoading}>
      {isLoading ? 'Exporting...' : 'Export CSV'}
    </Button>
  );
}

+++

+++ Phase 3: Testing

Tasks:

  1. Add unit tests for CSV generation
  2. Add E2E test for export flow
  3. Test with various filters
  4. Verify filename format

Files to create:

  • apps/bonsapi/tests/services/csv_export_test.rs
  • tests/e2e/invoices/export.spec.ts

+++

+++ Technical Specifications

API Endpoint #

Endpoint: GET /api/invoices/export

Query Parameters:

  • All existing invoice filter params (date, status, customer, etc.)

Response:

Content-Type: text/csv
Content-Disposition: attachment; filename="invoices-2025-01-15.csv"

Invoice Number,Date,Customer,Amount,Status
INV-001,2025-01-15,Acme Corp,$1234.56,Paid
INV-002,2025-01-14,Beta Inc,$5678.90,Pending

CSV Format #

Columns:

  1. Invoice Number
  2. Date (YYYY-MM-DD)
  3. Customer Name
  4. Amount (with currency symbol)
  5. Status

Encoding: UTF-8 with BOM (for Excel compatibility)

+++

+++ Risk Assessment

Low Risk:

  • New feature, no breaking changes
  • Similar to existing PDF export
  • Standard CSV format
  • Uses existing filter logic

Potential Issues:

  • Large invoice lists may take time to export
  • Memory usage for very large datasets

Mitigation:

  • Add export limit (e.g., max 10,000 invoices)
  • Show loading indicator
  • Consider streaming for very large exports (future enhancement)

+++

+++ Success Criteria

Acceptance Criteria from Issue:

  • Export button visible in invoice list
  • CSV includes invoice number, date, amount, status
  • Filtered invoices export correctly
  • File downloads with proper filename (invoices-YYYY-MM-DD.csv)

Additional Success Criteria:

  • Export respects user permissions
  • Loading state shows during export
  • Error handling for failed exports
  • Unit tests pass
  • E2E tests pass
  • mise ci passes

+++


📁 Worktree: /home/coder/trees/sarah-eng-2310-feat-csv-export 📄 Plan: .plans/PLAN.md


**Linear Status**: Planning → **Planned**

## Step 3: Review Plan

Sarah reviews the plan in Linear and provides feedback:

Looks good! Please also include the customer name column in the export.

Also, can we add a limit to prevent exporting too many invoices at once?


**Next Steps** (Currently Manual):
- Developer manually implements following the plan
- Or wait for implementation workflow (coming soon)

## What's NOT Automated Yet

The following steps are **not yet automated** and require manual work:

### ❌ Not Automated - Implementation

@Tofie implement # ← Coming soon!


Manual process:
1. Pull the worktree branch
2. Read `.plans/PLAN.md`
3. Implement following the plan
4. Run tests locally
5. Create commits

### ❌ Not Automated - Code Review

@Tofie review # ← Coming soon!


Manual process:
1. Create PR manually
2. Request human review
3. Address feedback

### ❌ Not Automated - Adjustments

@Tofie adjust: Add success toast notification # ← Coming soon!


Manual process:
1. Make changes manually
2. Commit and push

### ❌ Not Automated - QA

@Tofie qa # ← Coming soon!


Manual process:
1. Test functionality manually
2. Verify acceptance criteria

### ❌ Not Automated - PR Creation

@Tofie pr # ← Coming soon!


Manual process:
1. Create PR via GitHub UI or `gh` CLI
2. Write PR description manually

## Timeline Summary

| Stage | Duration | Status | Automation |
|-------|----------|--------|------------|
| Create issue | 5 minutes | Backlog | Manual |
| Trigger planning | 10 seconds | Planning | **Automated** |
| Planning | 3-5 minutes | Planning | **Automated** |
| Status update | Instant | Planned | **Automated** |
| Review plan | 10 minutes | Planned | Manual |
| Implementation | 4-6 hours | - | ❌ Not automated yet |
| Code review | 1-2 hours | - | ❌ Not automated yet |
| Merge | 2 minutes | - | Manual |

**Total automated time**: ~3-5 minutes (planning only)
**Total manual time**: Still 5-8 hours for implementation and review

## Trigger Conditions Reference

### ✅ Triggers Planning Workflow

**Case 1**: Status changed to "Planning" + Tofie assigned

Before: Status = “Backlog”, Assignee = “Tofie” Action: Change status to “Planning” Result: ✅ Planning triggered


**Case 2**: Tofie assigned + Status is "Planning"

Before: Status = “Planning”, Assignee = None Action: Assign “Tofie” or “[Dev] Tofie” Result: ✅ Planning triggered


### ❌ Does NOT Trigger Planning

**Wrong status**:

Status = “In Progress”, Assignee = “Tofie” Result: ❌ Not triggered (must be “Planning”)


**Wrong assignee**:

Status = “Planning”, Assignee = “John” Result: ❌ Not triggered (must be “Tofie” or “[Dev] Tofie”)


**Both conditions must be true**:

Status = “Planning” AND (Assignee = “Tofie” OR Assignee = “[Dev] Tofie”)


## Configuration Reference

### Linear Webhook (n8n)

**Trigger Events**:
- Issue updated
- Issue assignee changed

**Filter Logic**:
```javascript
const status = $json.data.state.name;
const assignee = $json.data.assignee?.name;

// Only proceed if both conditions are true
if (status === 'Planning' &&
    (assignee === 'Tofie' || assignee === '[Dev] Tofie')) {
  return [$json];  // Continue workflow
}

return [];  // Stop workflow

Input JSON Format #

n8n sends this JSON to planning-subagent.sh:

{
  "branchName": "sarah/eng-2310-feat-csv-export",
  "issueIdentifier": "ENG-2310",
  "agentSessionId": "n8n-workflow-12345",
  "thoroughness": "very thorough",
  "baseBranch": "main",
  "project": {
    "id": "proj-abc123",
    "name": "BonsAI Core",
    "key": "ENG"
  },
  "issue": {
    "id": "issue-xyz789",
    "identifier": "ENG-2310",
    "title": "Add CSV export for invoice list",
    "description": "Users need to export invoice lists...",
    "labels": ["feature", "webapp"],
    "comments": [
      {
        "id": "comment-001",
        "body": "Please also include customer name",
        "createdAt": "2025-01-15T10:00:00Z",
        "user": {"name": "Sarah"}
      }
    ]
  }
}

Environment Variables #

On the development server:

# Required for n8n event webhooks
export TOFIE_N8N_EVENT_URL="https://bonsai.app.n8n.cloud/webhook/tofie-event"
export TOFIE_N8N_SIGNING_KEY="your-signing-key"

Troubleshooting #

Planning Not Triggered #

Check 1: Status is “Planning”?

Linear → Issue → Status must be exactly "Planning"

Check 2: Tofie is assigned?

Linear → Issue → Assignee must be "Tofie" or "[Dev] Tofie"

Check 3: n8n workflow is active?

n8n → Workflows → "Tofie Planning Workflow" → Active

Check 4: Linear webhook is configured?

Linear → Settings → Webhooks → n8n webhook exists

Planning Failed #

Check worktree error:

# Script now shows actual git error
[ERROR] Failed to create worktree
[ERROR] Git error: fatal: a branch named 'sarah/eng-2310' already exists

# Solution: Delete existing branch
git branch -D sarah/eng-2310-feat-csv-export

Check environment variables:

# On dev server
echo $TOFIE_N8N_EVENT_URL
echo $TOFIE_N8N_SIGNING_KEY

Check Claude Code logs:

# On dev server
tail -f ~/.cache/claude-code/logs/*.log

Key Takeaways #

✅ What’s Automated (Planning Only) #

Fully Automated:

  • Trigger on Linear status change or assignee change
  • Worktree creation from base branch
  • Comprehensive codebase analysis
  • Implementation plan generation with Linear collapsible sections
  • Real-time progress events to n8n
  • Linear status update to “Planned”
  • Linear comments with plan summary

Benefits:

  • ⚡ 3-5 minutes vs 30-60 minutes manual planning
  • 📋 Structured, comprehensive plans
  • 🎯 Follows Context Engineering framework
  • 🔄 Consistent format and quality
  • 📊 Real-time progress tracking

❌ What’s Not Automated (Coming Soon) #

Still Manual:

  • Implementation
  • Code review
  • Testing
  • PR creation
  • Adjustments based on feedback
  • Merging

Why Not Yet:

  • Implementation workflow in development
  • QA workflow in development
  • Review workflow in development
  • PR workflow in development