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:
- 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:
- Assign Tofie or [Dev] Tofie to the issue
What Happens: n8n webhook triggers planning workflow
What Happens Behind the Scenes #
n8n Workflow (< 1 second):
- Linear webhook received
- Validates: status = “Planning” AND assignee = “Tofie”
- Prepares input JSON with issue data
- SSH to development server
- 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:
- Create ExportButton component
- Integrate into invoice list toolbar
- Implement download logic
- 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:
- Add unit tests for CSV generation
- Add E2E test for export flow
- Test with various filters
- Verify filename format
Files to create:
apps/bonsapi/tests/services/csv_export_test.rstests/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:
- Invoice Number
- Date (YYYY-MM-DD)
- Customer Name
- Amount (with currency symbol)
- 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 cipasses
+++
📁 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
Related Documentation #
- Planning Workflow - Detailed planning workflow docs
- Tofie Scripts - Script documentation
- n8n Integration - Webhook setup
- Linear Setup - Linear configuration