401 lines
12 KiB
Markdown
401 lines
12 KiB
Markdown
# 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 TODO.md first** — treat it as the authoritative queue
|
|
2. **Pick the first unchecked task** in the current active phase section
|
|
3. **If all phase tasks are done,** report completion and request milestone transition
|
|
4. **Do not jump to backlog phases** unless TODO explicitly marks the new phase active
|
|
|
|
### 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
```markdown
|
|
⚠️ **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
|
|
```markdown
|
|
❌ **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
|
|
```markdown
|
|
🎉 **ALL_TASKS_COMPLETE**
|
|
|
|
[summary of what was built]
|
|
[deployment instructions]
|
|
```
|
|
|
|
---
|
|
|
|
## Communication Protocol
|
|
|
|
### Progress Updates (After Each Commit)
|
|
|
|
```markdown
|
|
✅ **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
|
|
|
|
```markdown
|
|
🎉 **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)
|
|
|
|
```markdown
|
|
⚠️ **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
|
|
```bash
|
|
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
|
|
```bash
|
|
npm test # All tests
|
|
npm test -- RecipeService # Specific file
|
|
npm run test:coverage # Coverage report
|
|
```
|
|
|
|
### Building & deploying
|
|
```bash
|
|
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._
|