recipe-manager/AGENT_INSTRUCTIONS.md

12 KiB

Recipe Manager — Agent Instructions

Purpose: How agents should approach development on this project
Last Updated: 2026-03-23


Core Principles

1. Orientation First

Every time you wake up (new session):

  1. Read PROJECT.md — What are we building?
  2. Read ARCHITECTURE.md — How are we building it?
  3. Read ROADMAP.md — What's next?
  4. Read git log --oneline -10 — What happened recently?
  5. Check TODO.md (if exists) — Any pending tasks?

Never start coding without context.


Development Loop

The Agent Workflow (Single Iteration)

┌─────────────────────────────────────────────────┐
│ 1. ORIENT    Read context files, git log        │
└────────────┬────────────────────────────────────┘
             │
┌────────────┴────────────────────────────────────┐
│ 2. PLAN      Pick ONE task from roadmap         │
│              Break into <1hr subtasks if needed  │
└────────────┬────────────────────────────────────┘
             │
┌────────────┴────────────────────────────────────┐
│ 3. IMPLEMENT Write code + tests                 │
│              Follow architecture patterns        │
└────────────┬────────────────────────────────────┘
             │
┌────────────┴────────────────────────────────────┐
│ 4. VERIFY    Run tests, lint, manual check      │
│              Does it meet acceptance criteria?   │
└────────────┬────────────────────────────────────┘
             │
┌────────────┴────────────────────────────────────┐
│ 5. COMMIT    Conventional commit message        │
│              Update docs (README, ADR, etc.)     │
└────────────┬────────────────────────────────────┘
             │
┌────────────┴────────────────────────────────────┐
│ 6. REPORT    Summarize what you did + what's    │
│              next (or escalate if blocked)       │
└─────────────────────────────────────────────────┘

One loop = one commit. Don't try to do everything at once.


Task Selection Rules

What to Work On

  1. Check ROADMAP.md for the current milestone
  2. Pick the next uncompleted feature in that milestone
  3. If all features done, move to testing/documentation
  4. If milestone complete, report to Paul for approval before moving to next

How to Break Down Tasks

Good task (1-4 hours):

  • "Implement recipe list API endpoint with pagination"
  • "Add tag filtering to search UI"
  • "Write E2E test for cook mode"

Bad task (too big):

  • "Build entire recipe import system"
  • "Finish frontend"

If task feels big (>4 hours), break it into subtasks and commit each one.


Code Quality Standards

TypeScript

  • Strict mode enabled
  • No any types (use unknown if needed)
  • All public APIs have JSDoc comments
  • Interfaces for all data models

Testing

  • Unit test new business logic (services, utilities)
  • Integration test API endpoints
  • E2E test critical user flows (cook mode, search)
  • Aim for >80% coverage on core logic

Commits

  • Conventional Commits format: type(scope): description
    • feat: new feature
    • fix: bug fix
    • docs: documentation only
    • test: test additions/changes
    • refactor: code restructure (no behavior change)
    • chore: tooling, dependencies
  • Descriptive messages (not "fix stuff" or "wip")
  • Commit working code only (tests pass)

Documentation

  • Update README when setup changes
  • Add ADR (Architecture Decision Record) in docs/ for significant choices
    • Format: ADR-001-why-sqlite.md, ADR-002-recipe-scraping-strategy.md
  • Update API docs when endpoints change
  • Keep TODO.md current (add new tasks, remove completed)

Common Patterns

API Endpoint Template

// src/routes/recipes.ts
import { Router } from 'express';
import { z } from 'zod';
import { RecipeService } from '../services/RecipeService';

const router = Router();
const recipeService = new RecipeService();

// Validation schema
const createRecipeSchema = z.object({
  title: z.string().min(1),
  ingredients: z.array(z.string()),
  instructions: z.array(z.string()),
  // ...
});

router.post('/recipes', async (req, res) => {
  try {
    const data = createRecipeSchema.parse(req.body);
    const recipe = await recipeService.create(data);
    res.json({ success: true, data: recipe });
  } catch (error) {
    if (error instanceof z.ZodError) {
      res.status(400).json({ success: false, error: error.errors });
    } else {
      res.status(500).json({ success: false, error: 'Internal error' });
    }
  }
});

export default router;

React Component Template

// src/components/RecipeCard.tsx
import { Recipe } from '../types/recipe';

interface RecipeCardProps {
  recipe: Recipe;
  onEdit: (id: number) => void;
  onDelete: (id: number) => void;
}

export function RecipeCard({ recipe, onEdit, onDelete }: RecipeCardProps) {
  return (
    <div className="border rounded-lg p-4 shadow-sm">
      <h3 className="text-lg font-bold">{recipe.title}</h3>
      <p className="text-gray-600">{recipe.description}</p>
      {/* ... */}
    </div>
  );
}

Database Query Template

// src/repositories/RecipeRepository.ts
import Database from 'better-sqlite3';
import { Recipe } from '../types/recipe';

export class RecipeRepository {
  constructor(private db: Database.Database) {}

  findAll(): Recipe[] {
    const stmt = this.db.prepare('SELECT * FROM recipes ORDER BY created_at DESC');
    return stmt.all() as Recipe[];
  }

  findById(id: number): Recipe | undefined {
    const stmt = this.db.prepare('SELECT * FROM recipes WHERE id = ?');
    return stmt.get(id) as Recipe | undefined;
  }

  // ...
}

Error Handling

When Things Go Wrong

  1. Build errors: Fix immediately, don't commit broken code
  2. Test failures: Investigate, fix, re-run
  3. Stuck on implementation (>30 min):
    • Document what you tried
    • Explain the blocker
    • Ask Paul for guidance
  4. Unclear requirements: Propose 2-3 options, ask Paul to choose

Never Guess

If PROJECT.md or ARCHITECTURE.md doesn't specify:

  • Good: "Should recipe images be stored in SQLite or filesystem? I recommend filesystem for simpler backups."
  • Bad: Just implementing without asking

Error Signals (CRITICAL)

If you encounter a blocker or error, DO NOT fail silently. Include one of these signals in your response:

STUCK Signal

⚠️ **STUCK:** Cannot complete task "[task name]"

**Attempted:**
- [what you tried]
- [what you tried]

**Error/Blocker:**
[exact error message or description of the problem]

**Need from Paul:**
[specific question or decision needed]

ERROR Signal

**ERROR:** Build/test failure

**Command:** `[exact command that failed]`

**Error output:**

[paste last 20 lines of error]


**Context:** [what you were trying to do]

ALL_TASKS_COMPLETE Signal

🎉 **ALL_TASKS_COMPLETE**

[summary of what was built]
[deployment instructions]

Communication Protocol

Progress Updates (After Each Commit)

**Completed:** Added recipe list API endpoint with pagination
- Implemented GET /api/recipes with offset/limit
- Added integration tests (100% coverage)
- Updated API docs

**Next up:** Recipe detail view UI component
**ETA:** 1-2 hours

Milestone Completion

🎉 **MVP Complete!**

All MVP features implemented:
- ✅ Manual recipe entry
- ✅ Recipe CRUD operations
- ✅ Tagging & search
- ✅ Cook mode with wake lock
- ✅ Docker deployment

**Test results:** 47/47 passing  
**Documentation:** README, API docs, user guide updated  
**Deployment:** Tested locally, ready for paje.ca

**Awaiting approval** to start v1.0 milestone (recipe scraping).

Escalation (Blocked)

⚠️ **Blocked:** Recipe scraping strategy unclear

**Context:** Working on browser extension for recipe import. Need decision on:

1. **Puppeteer vs Cheerio?**
   - Puppeteer: Handles JS-rendered sites, heavier
   - Cheerio: Fast, static HTML only
   
2. **Where to run scraping?**
   - Client-side (extension scrapes, sends JSON to API)
   - Server-side (extension sends URL, server scrapes)

**Recommendation:** Cheerio for v1 (80% of sites), Puppeteer later if needed. Server-side scraping for easier updates.

**Action needed:** Paul, which approach do you prefer?

Anti-Patterns (Don't Do This)

Committing without testing
Changing architecture without documenting (ADR)
Working on multiple unrelated tasks in one commit
Ignoring linting errors "to fix later"
Hardcoding values that should be env vars
Skipping documentation updates
Assuming requirements without asking


Quick Reference

Starting a new feature

git pull origin main
git checkout -b feat/recipe-scaling
# ... code ...
npm test
git add .
git commit -m "feat: add recipe serving size scaling"
git push origin feat/recipe-scaling

Running tests

npm test                 # All tests
npm test -- RecipeService  # Specific file
npm run test:coverage     # Coverage report

Building & deploying

docker-compose build      # Build containers
docker-compose up -d      # Start services
docker-compose logs -f    # Watch logs

Success Metrics

You're doing it right if:

  • Every commit is small, focused, tested
  • Paul wakes up to completed features, not questions
  • Tests pass consistently
  • Documentation stays current
  • Code is readable (you're writing for future-you)

OpenClaw Environment Notes

File Access

  • Working directory: /home/paulh/.openclaw/workspace/projects/recipe-manager
  • CRITICAL: Use absolute paths in all exec commands
  • The ~ shorthand does NOT work in exec — use /home/paulh/ instead

Build Commands

  • Use cd /absolute/path && command pattern
  • Example: cd /home/paulh/.openclaw/workspace/projects/recipe-manager && npm test
  • Never rely on implicit working directory

Git

  • Commit after each completed task
  • Use conventional commit format: feat(scope): description
  • Don't push — Paul will review and push

Exit Signals

  • Include ALL_TASKS_COMPLETE when all TODO.md tasks are checked
  • Include STUCK: or ERROR: if blocked (see Error Signals above)
  • Always exit after ONE commit (don't chain multiple tasks)

Remember: You're not just writing code—you're building a product Paul's family will use. Quality matters.