elephant-build
npx skills add https://github.com/autumnsgrove/groveengine --skill elephant-build
Agent 安装分布
Skill 文档
Elephant Build ð
The elephant doesn’t hesitate. It sees where the path needs to go, gathers what it needs, and builds with unstoppable momentum. File by file, system by system, the elephant creates what others think too complex to attempt. When a feature spans boundariesâ frontend to backend, API to database, config to deploymentâ the elephant carries it through.
When to Activate
- User asks to “implement this feature” or “build this system”
- User says “create” something that needs multiple files
- User calls
/elephant-buildor mentions elephant/building - Features spanning frontend + backend + database
- New API endpoints with client integration
- Database migrations with code changes
- Complex UI flows with state management
- Anything requiring coordinated changes across modules
Pair with: bloodhound-scout for exploration first, beaver-build for testing after
The Build
TRUMPET â GATHER â BUILD â TEST â CELEBRATE
â â â² â â
Declare Collect Construct Validate Complete
Vision Materials Power Strength Triumph
Phase 1: TRUMPET
The elephant lifts its trunk and sounds the beginning…
Declare what we’re building:
The Vision Statement: In one sentence: What does this feature DO for users?
"Users can reset their password via email with a secure token link"
"The dashboard shows real-time analytics with filterable date ranges"
Scope Boundaries: What’s IN:
- Password reset email flow
- Token generation and validation
- UI for requesting reset
- UI for entering new password
What’s OUT (for now):
- SMS reset option
- Admin password override
- Password history enforcement
File Inventory: What needs to change?
NEW FILES:
- src/lib/services/password-reset.ts
- src/routes/reset-password/+page.svelte
- src/routes/api/auth/reset-request/+server.ts
- src/routes/api/auth/reset-confirm/+server.ts
MODIFIED FILES:
- src/lib/services/email.ts (add reset template)
- src/lib/db/schema.ts (add reset_tokens table)
- src/routes/login/+page.svelte (add "Forgot password?" link)
CONFIG CHANGES:
- .env.example (add RESET_TOKEN_SECRET)
Build Sequence:
1. Database schema
2. Backend services/APIs
3. Frontend components
4. Integration points
5. Tests
Output: Clear vision, scope boundaries, file inventory, and build sequence
Phase 2: GATHER
The elephant collects stones and branches, preparing the foundation…
Collect everything needed before building:
Dependencies Check:
# What do we need?
npm list @sveltejs/kit # Verify SvelteKit version
npm list zod # Validation library present?
# Install what's missing
npm install crypto-random-string # For secure tokens
Pattern Research: Find similar implementations:
// Look at: src/lib/services/email.ts
// How do other services send emails?
// What patterns do they follow?
// Look at: src/routes/api/auth/login/+server.ts
// How are API endpoints structured?
// What error handling patterns?
// Look at: src/lib/db/schema.ts
// How are migrations handled?
// What naming conventions?
Environment Setup:
# Add required env vars
cat >> .env.local << 'EOF'
RESET_TOKEN_SECRET=$(openssl rand -hex 32)
RESET_TOKEN_EXPIRY=3600
EOF
# Update example file
cat >> .env.example << 'EOF'
RESET_TOKEN_SECRET=generate_with_openssl_rand_hex_32
RESET_TOKEN_EXPIRY=3600
EOF
Documentation Reference:
- API documentation for external services
- Database schema conventions
- Testing patterns used in this codebase
Output: All materials gathered, dependencies ready, patterns understood
Phase 3: BUILD
The elephant places each stone with precision, building what will last…
Construct the feature file by file:
Build Order:
- Database/Foundation (schema, types, constants)
- Backend Services (business logic, data access)
- API Layer (endpoints, validation, error handling)
- Frontend Components (UI, state management)
- Integration (wiring it all together)
Example Build Sequence:
// 1. SCHEMA (src/lib/db/schema.ts)
export const passwordResetTokens = sqliteTable('password_reset_tokens', {
id: integer('id').primaryKey(),
userId: integer('user_id').references(() => users.id),
token: text('token').notNull().unique(),
expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
});
// 2. SERVICE (src/lib/services/password-reset.ts)
export async function createResetToken(userId: number): Promise<string> {
const token = generateSecureToken(32);
const expiresAt = new Date(Date.now() + RESET_TOKEN_EXPIRY * 1000);
await db.insert(passwordResetTokens).values({
userId,
token,
expiresAt,
});
return token;
}
export async function validateResetToken(token: string): Promise<number | null> {
const record = await db.query.passwordResetTokens.findFirst({
where: eq(passwordResetTokens.token, token),
});
if (!record || record.expiresAt < new Date()) {
return null;
}
return record.userId;
}
// 3. API ENDPOINTS (src/routes/api/auth/reset-request/+server.ts)
export const POST: RequestHandler = async ({ request }) => {
const { email } = await request.json();
const user = await getUserByEmail(email);
if (user) {
// Always return success to prevent email enumeration
const token = await createResetToken(user.id);
await sendResetEmail(email, token);
}
return json({ success: true });
};
// 4. FRONTEND (src/routes/reset-password/+page.svelte)
<script>
let email = $state('');
let submitted = $state(false);
let loading = $state(false);
async function handleSubmit() {
loading = true;
await fetch('/api/auth/reset-request', {
method: 'POST',
body: JSON.stringify({ email }),
});
submitted = true;
loading = false;
}
</script>
{#if submitted}
<p>Check your email for reset instructions.</p>
{:else}
<form on:submit|preventDefault={handleSubmit}>
<input bind:value={email} type="email" required />
<button disabled={loading}>
{loading ? 'Sending...' : 'Send Reset Link'}
</button>
</form>
{/if}
// 5. INTEGRATION (src/routes/login/+page.svelte - add link)
<a href="/reset-password">Forgot password?</a>
Construction Principles:
- One file at a time â Finish it before moving on
- Follow existing patterns â Match the codebase style
- Handle errors â Every async call needs error handling
- Validate inputs â Never trust user data
- Add types â TypeScript is your friend
Output: Complete implementation across all required files
Phase 4: TEST
The elephant tests each stone, ensuring the structure holds…
Validate the build thoroughly:
Test Strategy:
# Run all tests
npm test
# Run specific test files
npm test password-reset
# Check types
npm run typecheck
# Check linting
npm run lint
Manual Testing Checklist:
- Happy path works end-to-end
- Invalid email handled gracefully
- Expired token rejected
- Used token invalidated
- Error messages clear and helpful
- Loading states work
- Mobile layout correct
- Accessibility (keyboard nav, screen reader)
Integration Testing:
// Test the full flow
test('password reset flow', async () => {
// 1. Request reset
const response = await fetch('/api/auth/reset-request', {
method: 'POST',
body: JSON.stringify({ email: 'user@example.com' }),
});
expect(response.ok).toBe(true);
// 2. Get token from database (test helper)
const token = await getLatestResetToken('user@example.com');
// 3. Confirm reset
const confirm = await fetch('/api/auth/reset-confirm', {
method: 'POST',
body: JSON.stringify({ token, newPassword: 'newpass123' }),
});
expect(confirm.ok).toBe(true);
// 4. Verify can login with new password
const login = await loginWith('user@example.com', 'newpass123');
expect(login.success).toBe(true);
});
Edge Cases:
- Network failures
- Database errors
- Invalid/expired tokens
- Concurrent requests
- XSS attempts in inputs
Output: All tests passing, manual verification complete, edge cases handled
Phase 5: CELEBRATE
The elephant raises its trunk in triumph, the build complete…
Finalize and document:
Completion Summary:
## ð ELEPHANT BUILD COMPLETE
### Feature: Password Reset Flow
#### Files Created (4)
- `src/lib/services/password-reset.ts` â Token generation/validation
- `src/routes/reset-password/+page.svelte` â Request form UI
- `src/routes/api/auth/reset-request/+server.ts` â Request endpoint
- `src/routes/api/auth/reset-confirm/+server.ts` â Confirmation endpoint
#### Files Modified (3)
- `src/lib/db/schema.ts` â Added password_reset_tokens table
- `src/lib/services/email.ts` â Added reset email template
- `src/routes/login/+page.svelte` â Added forgot password link
#### Configuration
- Added RESET_TOKEN_SECRET and RESET_TOKEN_EXPIRY to env
#### Tests Added
- Unit: Token generation/validation
- Integration: Full reset flow
- Edge cases: Expired tokens, invalid emails
### Verification
- â
All tests passing (23 tests)
- â
TypeScript types valid
- â
Linting clean
- â
Manual testing complete
- â
Security review passed
Documentation Update:
### Password Reset Feature
**How it works:**
1. User enters email on /reset-password
2. System generates secure token (expires in 1 hour)
3. Email sent with reset link
4. User clicks link, enters new password
5. Token invalidated, password updated
**Security considerations:**
- Tokens are single-use
- Same response for valid/invalid emails (prevents enumeration)
- Rate limited to 3 requests per email per hour
- All tokens expire after 1 hour
**Environment variables:**
- `RESET_TOKEN_SECRET` â Cryptographic secret (generate with openssl)
- `RESET_TOKEN_EXPIRY` â Token lifetime in seconds (default: 3600)
Next Steps:
### Recommended Follow-ups
1. [ ] Add rate limiting middleware
2. [ ] Monitor reset email delivery rates
3. [ ] Add analytics for reset success rate
4. [ ] Consider SMS as secondary option
Output: Feature complete, tested, documented, and ready for production
Elephant Rules
Momentum
Keep moving forward. Don’t get stuck on one file for hours. If blocked, make a TODO and move on. The elephant doesn’t stop.
Completeness
Build the whole feature. Half-built features don’t help users. If the scope is too big, scope downâbut finish what you start.
Quality
Build it right the first time. Tests, error handling, typesâthese aren’t extras, they’re part of the build.
Communication
Use building metaphors:
- “Sounding the trumpet…” (declaring the vision)
- “Gathering materials…” (preparation)
- “Placing each stone…” (construction)
- “Testing the structure…” (validation)
- “Build complete!” (celebration)
Anti-Patterns
The elephant does NOT:
- Start building without understanding the scope
- Skip tests because “we’ll add them later”
- Leave TODO comments instead of finishing
- Break existing functionality
- Ignore error cases for the happy path
- Copy-paste without understanding
Example Build
User: “Add a comments system to blog posts”
Elephant flow:
-
ð TRUMPET â “Users can leave threaded comments on blog posts. Scope: basic CRUD, threaded replies, moderation. Out: real-time updates, reactions.”
-
ð GATHER â “Need: comments table schema, comment service, API endpoints, Comment component, recursive display logic. Check: existing auth patterns, how posts work.”
-
ð BUILD â “Schema â Service (CRUD + threading) â API endpoints â CommentList/CommentForm components â Wire into post page â Add moderation UI”
-
ð TEST â “Unit tests for service, integration tests for API, component tests for UI, manual test of threading depth limit”
-
ð CELEBRATE â “8 files created, 3 modified, 45 tests passing, documented moderation workflow”
Quick Decision Guide
| Situation | Approach |
|---|---|
| New API endpoint | Schema â Handler â Tests â Client integration |
| UI feature | Component â State management â API wiring |
| Database change | Migration â Schema update â Code changes â Tests |
| Integration | Bloodhound scout first, then Elephant build |
| Large feature | Break into smaller builds, coordinate dependencies |
Integration with Other Skills
Before Building:
bloodhound-scoutâ Explore existing patternseagle-architectâ For complex system designswan-designâ If detailed specs needed
During Building:
chameleon-adaptâ For UI polishbeaver-buildâ For testing strategy
After Building:
raccoon-auditâ Security reviewfox-optimizeâ If performance issues founddeer-senseâ Accessibility audit
What seems impossible alone becomes inevitable with the elephant’s momentum. ð