Tofie Script Reference #
Complete reference for all Tofie automation scripts.
Overview #
All Tofie scripts are located in: tools/local/scripts/tofie/
Script Variants:
- Standard scripts: Direct Claude CLI invocation (faster)
- Subagent scripts: Launch isolated Claude subagents (thorough)
Common Script Patterns #
All Tofie scripts follow this structure:
Input/Output Format #
Input: JSON via stdin Output: JSON via stdout Logs: stderr (for debugging)
Exit Codes #
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Dependency missing (jq, claude CLI) |
| 2 | Invalid input (missing required fields) |
| 3 | Worktree creation failed |
| 4 | Metadata creation failed |
| 5 | Claude CLI execution failed |
Common Functions #
All scripts include:
log_info() # Log informational messages (stderr)
log_error() # Log error messages (stderr)
output_json() # Output structured JSON result (stdout)
planning.sh #
Purpose: Create implementation plan using Context Engineering framework
When to use: Standard planning for well-defined issues
Execution time: 2-5 minutes
Input Schema #
{
"branchName": "string (required)",
"issueIdentifier": "string (required)",
"agentSessionId": "string (optional)",
"project": {
"id": "string",
"name": "string",
"key": "string"
},
"issue": {
"id": "string",
"identifier": "string",
"title": "string (required)",
"description": "string",
"comments": []
}
}
Output Schema #
{
"success": boolean,
"message": "string",
"worktreePath": "string",
"planPath": "string",
"linearMetadataPath": "string",
"n8nMetadataPath": "string",
"claudeOutput": "string",
"timestamp": "ISO 8601 timestamp"
}
Workflow #
- Validate JSON input
- Create/reuse git worktree from
main - Create
.plans/directory - Write
linear-metadata.jsonandn8n-metadata.json - Execute Claude CLI with
/tofie-planslash command - Validate
PLAN.mdwas created - Return JSON result
Claude CLI Invocation #
claude \
--print \
--output-format text \
--model sonnet \
--permission-mode acceptEdits \
"$CLAUDE_PROMPT"
Example Usage #
echo '{
"branchName": "john/eng-1144-feat-filtering",
"issueIdentifier": "ENG-1144",
"issue": {
"title": "Add date range filtering",
"description": "Users need filtering..."
}
}' | ./planning.sh
planning-subagent.sh #
Purpose: Create comprehensive plan using isolated Claude subagent
When to use: Complex issues requiring deep research
Execution time: 5-15 minutes
Input Schema #
Same as planning.sh plus:
{
"thoroughness": "quick|medium|very thorough (optional, default: medium)"
}
Key Differences from planning.sh #
- Prompt: Asks Claude to use “tofie-planner SUBAGENT”
- Permission mode:
--dangerously-skip-permissions - Collapsible sections: Instructions embedded in prompt (not slash command)
- Research depth: Subagent does more thorough codebase analysis
Claude CLI Invocation #
claude \
--print \
--output-format text \
--model sonnet \
--dangerously-skip-permissions \
"$CLAUDE_PROMPT"
When to Use #
- ✅ Multiple approach exploration needed
- ✅ Long-running research without blocking
- ✅ Isolated planning context required
- ❌ Quick, straightforward planning (use planning.sh)
implement.sh #
Purpose: Execute implementation plan with code changes
When to use: Standard implementation following a plan
Execution time: 5-15 minutes
Input Schema #
{
"branchName": "string (required)",
"issueIdentifier": "string (required)",
"skipTests": boolean (optional, default: false),
"skipCodegen": boolean (optional, default: false),
"enableReview": boolean (optional, default: false),
"createPR": boolean (optional, default: false)
}
Output Schema #
{
"success": boolean,
"message": "string",
"worktreePath": "string",
"planPath": "string",
"prUrl": "string (if createPR: true)",
"prNumber": number (if createPR: true),
"reviewStatus": "not_requested|in_progress|completed",
"claudeOutput": "string",
"timestamp": "ISO 8601 timestamp"
}
Workflow #
- Find existing worktree from planning stage
- Read
.plans/PLAN.mdand.plans/linear-metadata.json - Execute Claude CLI with
/tofie-implementslash command - Claude implements changes phase by phase
- Run quality checks (
mise fix && mise ci) - Create conventional commits
- Optionally create PR via
submit-pr.sh - Return JSON result
Quality Checks #
Always runs:
mise fix: Format codemise ci: Lint, type-check, tests, build
Conditional:
mise codegen: IfskipCodegen: falseand API changes detected- E2E tests: If
skipTests: falseand E2E tests exist
Example Usage #
echo '{
"branchName": "john/eng-1144-feat-filtering",
"issueIdentifier": "ENG-1144",
"createPR": true
}' | ./implement.sh
implement-subagent.sh #
Purpose: Execute implementation using isolated Claude subagent
When to use: Parallel orchestration, experimental implementation, background execution
Execution time: 10-30 minutes
Input Schema #
Same as implement.sh
Key Differences from implement.sh #
- Prompt: Asks Claude to use “tofie-coder SUBAGENT”
- Permission mode:
--dangerously-skip-permissions - Parallel review: Can spawn
tofie-reviewersubagent simultaneously - Checkpointing: Better for long-running implementations
When to Use #
- ✅ Implement + review in parallel
- ✅ Experimental approach exploration
- ✅ Background execution with checkpoints
- ❌ Quick, straightforward implementation (use implement.sh)
adjust.sh #
Purpose: Make targeted adjustments based on review feedback
When to use: Fix issues after code review or QA
Execution time: 2-10 minutes
Input Schema #
{
"branchName": "string (required)",
"issueIdentifier": "string (required)",
"scope": "string (optional, e.g., 'fix tests', 'update types')",
"files": "string (optional, glob pattern like 'src/**/*.ts')",
"dryRun": boolean (optional, default: false)
}
Output Schema #
Same as implement.sh
Workflow #
- Find existing worktree
- Read review feedback from Linear or
.plans/review-notes.md - Execute Claude CLI with
/tofie-adjustslash command - Claude makes targeted fixes
- Run quality checks
- Create commit if
dryRun: false - Return JSON result
Example Usage #
echo '{
"branchName": "john/eng-1144-feat-filtering",
"issueIdentifier": "ENG-1144",
"scope": "fix timezone handling in tests"
}' | ./adjust.sh
adjust-subagent.sh #
Purpose: Make adjustments using isolated Claude subagent
When to use: Complex refactoring or large-scale adjustments
Execution time: 5-20 minutes
Key Differences from adjust.sh #
- Permission mode:
--dangerously-skip-permissions - Scope: Can handle broader refactoring
- Isolation: Changes don’t affect main conversation context
submit-pr.sh #
Purpose: Create GitHub pull request with proper formatting
When to use: Standalone PR creation or after implementation
Execution time: 1-2 minutes
Input Schema #
{
"branchName": "string (required)"
}
Output Schema #
{
"success": boolean,
"alreadyExists": boolean,
"prNumber": number,
"prUrl": "string",
"prTitle": "string",
"prState": "string (if alreadyExists: true)"
}
Workflow #
- Check if PR already exists for branch (
gh pr list) - If exists: Return existing PR info (no duplicate)
- If not exists:
- Find branch location (worktree or main repo)
- Read
.plans/PLAN.mdfor context - Read
.plans/linear-metadata.jsonfor issue info - Execute Claude CLI with
submit-github-prskill - Claude generates PR title and description
- Create draft PR (
gh pr create --draft) - Store PR info in
.plans/pr-info.json
- Return JSON result
PR Format #
Title: Conventional commit format
feat(webapp): add date range filtering to invoice list
Description: Structured markdown
## Summary
[Brief description]
Closes: https://linear.app/bonsai/issue/ENG-1144
## Changes
- [Bullet points]
## Testing
- [x] Test checklist
## Risks
- [Risk assessment]
---
🤖 Generated with Claude Code - Tofie
IMPORTANT: Always Creates Drafts #
All PRs are created as drafts (--draft flag) to ensure human review before marking ready.
Example Usage #
echo '{
"branchName": "john/eng-1144-feat-filtering"
}' | ./submit-pr.sh
cleanup.sh #
Purpose: Clean up worktree and branch after PR is merged
When to use: After PR is merged to remove worktree and local branch
Execution time: < 10 seconds
Input Schema #
{
"branchName": "string (required)"
}
Output Schema #
{
"success": boolean,
"message": "string",
"worktreeRemoved": boolean,
"worktreePath": "string",
"branchDeleted": boolean,
"branchName": "string",
"timestamp": "ISO 8601 timestamp"
}
Workflow #
- Validate JSON input
- Find worktree for the branch (
git worktree list) - If worktree exists:
- Remove worktree (
git worktree remove) - Force remove if needed (
--force) - Manual cleanup if git command fails
- Remove worktree (
- Delete local branch (
git branch -D) - Optionally delete remote branch (if
DELETE_REMOTE=true) - Prune worktree metadata
- Return JSON result
Cleanup Strategies #
Standard removal:
git worktree remove /path/to/worktree
Force removal (if files modified):
git worktree remove --force /path/to/worktree
Manual cleanup (last resort):
rm -rf /path/to/worktree
git worktree prune
Environment Variables #
DELETE_REMOTE: Set to true to also delete remote branch
DELETE_REMOTE=true echo '{"branchName": "..."}' | ./cleanup.sh
Example Usage #
Basic cleanup:
echo '{
"branchName": "john/eng-1144-feat-filtering"
}' | ./cleanup.sh
Output:
{
"success": true,
"message": "Cleanup completed successfully",
"worktreeRemoved": true,
"worktreePath": "/home/coder/trees/john-eng-1144",
"branchDeleted": true,
"branchName": "john/eng-1144-feat-filtering",
"timestamp": "2025-11-03T12:00:00Z"
}
With remote branch deletion:
DELETE_REMOTE=true echo '{
"branchName": "john/eng-1144-feat-filtering"
}' | ./cleanup.sh
Common Scenarios #
Worktree not found (already removed):
{
"success": true,
"message": "Branch deleted (worktree not found)",
"worktreeRemoved": false,
"worktreePath": "",
"branchDeleted": true,
"branchName": "john/eng-1144-feat-filtering"
}
Branch already deleted:
{
"success": true,
"message": "Worktree removed (branch not found)",
"worktreeRemoved": true,
"worktreePath": "/home/coder/trees/john-eng-1144",
"branchDeleted": true,
"branchName": "john/eng-1144-feat-filtering"
}
Integration with n8n #
Can be triggered automatically after PR merge:
- GitHub webhook: PR merged event
- n8n workflow: Extract branch name from PR
- Execute cleanup.sh: Remove worktree and branch
- Update Linear: Comment “Cleanup complete”
Manual Usage #
# List all worktrees
git worktree list
# Clean up specific branch
echo '{"branchName": "john/eng-1144"}' | ./cleanup.sh
# Check result
echo $? # Should be 0 for success
Script Comparison Matrix #
| Feature | planning.sh | planning-subagent.sh | implement.sh | implement-subagent.sh | adjust.sh | adjust-subagent.sh | submit-pr.sh | cleanup.sh |
|---|---|---|---|---|---|---|---|---|
| Speed | Fast (2-5min) | Slow (5-15min) | Medium (5-15min) | Slow (10-30min) | Fast (2-10min) | Medium (5-20min) | Fast (1-2min) | Very Fast (<10s) |
| Permission Mode | acceptEdits | skip-permissions | acceptEdits | skip-permissions | acceptEdits | skip-permissions | skip-permissions | N/A |
| Uses Slash Command | Yes (/tofie-plan) | No (custom prompt) | Yes (/tofie-implement) | No (custom prompt) | Yes (/tofie-adjust) | No (custom prompt) | No (uses skill) | No |
| Parallel Execution | No | No | No | Yes (with reviewer) | No | No | No | No |
| Requires Worktree | No (creates it) | No (creates it) | Yes | Yes | Yes | Yes | Yes (or finds branch) | Yes (removes it) |
| Creates PR | No | No | Optional | Optional | No | No | Always (if not exists) | No |
| Quality Checks | No | No | Yes | Yes | Yes | Yes | No | No |
Debugging Scripts #
Enable Debug Mode #
DEBUG=1 ./planning.sh < input.json
Debug output includes:
- Parsed input values
- File path checks
- Claude CLI prompts
- Command outputs
Test Script Locally #
# Create test input
cat > /tmp/test-input.json <<EOF
{
"branchName": "test/debug-plan",
"issueIdentifier": "ENG-TEST",
"issue": {
"title": "Test planning script"
}
}
EOF
# Run script
cat /tmp/test-input.json | ./planning.sh
# Check output
echo $? # Exit code
Common Issues #
“claude CLI not found”
# Check Claude CLI installation
which claude
ls -la /home/$USER/.local/bin/claude
# Verify it's executable
chmod +x /home/$USER/.local/bin/claude
“Invalid JSON input”
# Validate JSON before piping
cat input.json | jq empty
# If this fails, fix JSON syntax
“Failed to create worktree”
# Check if branch already exists
git branch -a | grep "john/eng-1144"
# Remove existing branch if needed
git branch -D john/eng-1144
# Remove existing worktree
git worktree remove /home/coder/trees/john-eng-1144
Script Maintenance #
Adding New Scripts #
- Copy template from existing script
- Update input/output schemas
- Implement main logic
- Add to this documentation
- Update n8n workflow router
Testing Changes #
# Test with real Linear data
echo "$LINEAR_WEBHOOK_PAYLOAD" | \
jq '{branchName, issueIdentifier, project, issue}' | \
./planning.sh
# Verify output
echo $? # Should be 0
Version Control #
All scripts are version controlled in the main repository:
git log --follow tools/local/scripts/tofie/planning.sh
Related Documentation #
- Architecture - System design and data flow
- Workflows - Detailed workflow documentation
- Troubleshooting - Common issues and solutions