Skip to content

Commit d1bd453

Browse files
committed
evalbuff: add patterns/discover-before-implement.md (carve: cli-init-command)
1 parent 1ca6b47 commit d1bd453

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ Make an efficient learning agent that can do anything.
4343
- [`docs/agents-and-tools.md`](docs/agents-and-tools.md) — Agent system, shell shims, tool definitions
4444
- [`docs/patterns/handle-steps-generators.md`](docs/patterns/handle-steps-generators.md) — handleSteps generator patterns and spawn_agents tool calls
4545
- [docs/evalbuff/interpreting-task-prompts.md](docs/evalbuff/interpreting-task-prompts.md)
46+
- [docs/patterns/discover-before-implement.md](docs/patterns/discover-before-implement.md)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Discover Before Implement: Find Existing Patterns First
2+
3+
Before implementing ANY new feature, search for existing utilities, constants, and templates in the codebase. Duplicating content that already exists is the most common source of architectural drift.
4+
5+
## Key Locations to Check in This Codebase
6+
7+
### Project Root Utilities
8+
- **`cli/src/project-files.ts`** — Use `getProjectRoot()` (NOT `process.cwd()`) to get the user's project directory. `setProjectRoot()` sets it at startup.
9+
- **`cli/src/utils/analytics.ts`** — Use `trackEvent(AnalyticsEvent.X, {...})` to track user actions. Constants are in `common/src/constants/analytics-events.ts`.
10+
11+
### Template Files (DO NOT duplicate as strings)
12+
Template files that users receive when scaffolding live in:
13+
```
14+
common/src/templates/initial-agents-dir/
15+
types/agent-definition.ts ← import with Bun text import
16+
types/tools.ts ← import with Bun text import
17+
types/util-types.ts ← import with Bun text import
18+
my-custom-agent.ts
19+
package.json
20+
```
21+
22+
Import them as text (Bun-specific, requires `@ts-expect-error`):
23+
```typescript
24+
// @ts-expect-error - Bun text import attribute not supported by TypeScript
25+
import agentDefinitionSource from '../../../common/src/templates/initial-agents-dir/types/agent-definition' with { type: 'text' }
26+
```
27+
28+
### Named Constants
29+
- **Knowledge file name**: `PRIMARY_KNOWLEDGE_FILE_NAME` from `@codebuff/common/constants/knowledge` — use this, don't hardcode `'knowledge.md'`
30+
- **Brand name**: `IS_FREEBUFF` from `cli/src/utils/constants` → use `const brandName = IS_FREEBUFF ? 'Freebuff' : 'Codebuff'`
31+
32+
## CLI Command Pattern
33+
34+
When a command produces system messages (not sending to the AI), the handler returns `{ postUserMessage }` and the command-registry calls `params.sendMessage({ content, agentMode, postUserMessage })`:
35+
36+
```typescript
37+
// In command-registry.ts:
38+
defineCommand({
39+
name: 'init',
40+
handler: async (params) => {
41+
const { postUserMessage } = handleInitializationFlowLocally()
42+
// Handle streaming/queue state check...
43+
params.sendMessage({
44+
content: trimmed,
45+
agentMode: params.agentMode,
46+
postUserMessage, // ← injected into message, NOT setMessages directly
47+
})
48+
},
49+
})
50+
```
51+
52+
For commands that only show system messages (no AI response), use `params.setMessages`:
53+
```typescript
54+
params.setMessages((prev) => postUserMessage(prev))
55+
```
56+
57+
## The postUserMessage Contract
58+
59+
Handlers that produce UI messages return this shape (from `cli/src/types/contracts/send-message.ts`):
60+
```typescript
61+
type PostUserMessageFn = (prev: ChatMessage[]) => ChatMessage[]
62+
// Return: { postUserMessage: PostUserMessageFn }
63+
```
64+
65+
Use `getSystemMessage(text)` from `cli/src/utils/message-history.ts` to create each message.
66+
67+
## Checklist Before Writing New Code
68+
69+
1. **Is there a constant for this?** Search `common/src/constants/` first
70+
2. **Is there a utility for this path operation?** Check `cli/src/project-files.ts`
71+
3. **Does a template file already exist?** Check `common/src/templates/`
72+
4. **Should I track analytics?** Most user-facing actions should call `trackEvent()`
73+
5. **What is the naming convention?** Look at 2-3 existing similar handlers (e.g., `handleHelpCommand`, `handleUsageCommand`) before naming your function
74+
75+
## Anti-patterns
76+
77+
**DON'T** hardcode template content as string literals:
78+
```typescript
79+
// BAD - duplicates content that exists in common/src/templates/
80+
const TYPES_AGENT_DEFINITION = `export interface AgentDefinition { ... }`
81+
```
82+
83+
**DO** import from the canonical template location:
84+
```typescript
85+
// GOOD
86+
import agentDefinitionSource from '../../../common/src/templates/initial-agents-dir/types/agent-definition' with { type: 'text' }
87+
```
88+
89+
**DON'T** use `process.cwd()` in CLI commands:
90+
```typescript
91+
// BAD
92+
const projectRoot = process.cwd()
93+
```
94+
95+
**DO** use the project-files utility:
96+
```typescript
97+
// GOOD
98+
import { getProjectRoot } from '../project-files'
99+
const projectRoot = getProjectRoot()
100+
```

0 commit comments

Comments
 (0)