opencode-agile-agent 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -0
- package/bin/cli.js +434 -0
- package/bin/validate-templates.js +58 -0
- package/package.json +52 -0
- package/templates/.opencode/ARCHITECTURE.md +368 -0
- package/templates/.opencode/README.md +391 -0
- package/templates/.opencode/agents/api-designer.md +312 -0
- package/templates/.opencode/agents/backend-specialist.md +214 -0
- package/templates/.opencode/agents/code-archaeologist.md +260 -0
- package/templates/.opencode/agents/database-architect.md +212 -0
- package/templates/.opencode/agents/debugger.md +302 -0
- package/templates/.opencode/agents/developer.md +523 -0
- package/templates/.opencode/agents/devops-engineer.md +253 -0
- package/templates/.opencode/agents/documentation-writer.md +247 -0
- package/templates/.opencode/agents/explorer-agent.md +239 -0
- package/templates/.opencode/agents/feature-lead.md +302 -0
- package/templates/.opencode/agents/frontend-specialist.md +186 -0
- package/templates/.opencode/agents/game-developer.md +391 -0
- package/templates/.opencode/agents/mobile-developer.md +264 -0
- package/templates/.opencode/agents/orchestrator.md +463 -0
- package/templates/.opencode/agents/penetration-tester.md +256 -0
- package/templates/.opencode/agents/performance-optimizer.md +292 -0
- package/templates/.opencode/agents/pr-reviewer.md +468 -0
- package/templates/.opencode/agents/product-manager.md +225 -0
- package/templates/.opencode/agents/product-owner.md +264 -0
- package/templates/.opencode/agents/project-planner.md +248 -0
- package/templates/.opencode/agents/qa-automation-engineer.md +276 -0
- package/templates/.opencode/agents/security-auditor.md +260 -0
- package/templates/.opencode/agents/seo-specialist.md +266 -0
- package/templates/.opencode/agents/system-analyst.md +428 -0
- package/templates/.opencode/agents/test-engineer.md +229 -0
- package/templates/.opencode/config.template.json +129 -0
- package/templates/.opencode/rules/coding-standards.md +250 -0
- package/templates/.opencode/rules/git-conventions.md +149 -0
- package/templates/.opencode/skills/api-patterns/SKILL.md +162 -0
- package/templates/.opencode/skills/brainstorming/SKILL.md +255 -0
- package/templates/.opencode/skills/clean-code/SKILL.md +351 -0
- package/templates/.opencode/skills/code-philosophy/SKILL.md +512 -0
- package/templates/.opencode/skills/frontend-design/SKILL.md +237 -0
- package/templates/.opencode/skills/intelligent-routing/SKILL.md +195 -0
- package/templates/.opencode/skills/parallel-agents/SKILL.md +274 -0
- package/templates/.opencode/skills/plan-writing/SKILL.md +251 -0
- package/templates/.opencode/skills/systematic-debugging/SKILL.md +210 -0
- package/templates/.opencode/skills/testing-patterns/SKILL.md +252 -0
- package/templates/.opencode/workflows/brainstorm.md +110 -0
- package/templates/.opencode/workflows/create.md +108 -0
- package/templates/.opencode/workflows/debug.md +128 -0
- package/templates/.opencode/workflows/deploy.md +160 -0
- package/templates/.opencode/workflows/enhance.md +253 -0
- package/templates/.opencode/workflows/orchestrate.md +130 -0
- package/templates/.opencode/workflows/plan.md +163 -0
- package/templates/.opencode/workflows/review.md +135 -0
- package/templates/.opencode/workflows/status.md +102 -0
- package/templates/.opencode/workflows/test.md +146 -0
- package/templates/AGENTS.template.md +426 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clean-code
|
|
3
|
+
description: Global coding standards and best practices. All agents should follow these principles.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Clean Code - Global Standards
|
|
8
|
+
|
|
9
|
+
Universal coding principles that apply across all domains and languages.
|
|
10
|
+
|
|
11
|
+
## The 5 Laws of Elegant Code
|
|
12
|
+
|
|
13
|
+
### 1. Guard Clauses First
|
|
14
|
+
|
|
15
|
+
Handle unhappy paths at the beginning of functions. Return early.
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// ❌ Nested conditionals
|
|
19
|
+
function process(user) {
|
|
20
|
+
if (user) {
|
|
21
|
+
if (user.isActive) {
|
|
22
|
+
if (user.hasPermission) {
|
|
23
|
+
return doSomething(user);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ✅ Guard clauses
|
|
31
|
+
function process(user) {
|
|
32
|
+
if (!user) return null;
|
|
33
|
+
if (!user.isActive) return null;
|
|
34
|
+
if (!user.hasPermission) return null;
|
|
35
|
+
|
|
36
|
+
return doSomething(user);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Parsed State at Boundaries
|
|
41
|
+
|
|
42
|
+
Validate and transform input at the edge. Trust inside.
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// ❌ Checking everywhere
|
|
46
|
+
function updateEmail(email) {
|
|
47
|
+
if (!isValidEmail(email)) throw new Error('Invalid');
|
|
48
|
+
// ... logic
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function saveUser(user) {
|
|
52
|
+
if (!isValidEmail(user.email)) throw new Error('Invalid');
|
|
53
|
+
// ... logic
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ✅ Parse once, trust everywhere
|
|
57
|
+
type Email = string & { readonly __brand: unique symbol };
|
|
58
|
+
|
|
59
|
+
function parseEmail(input: string): Email | Error {
|
|
60
|
+
if (!emailRegex.test(input)) {
|
|
61
|
+
return new Error('Invalid email');
|
|
62
|
+
}
|
|
63
|
+
return input as Email;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Now Email is guaranteed valid
|
|
67
|
+
function updateEmail(email: Email) {
|
|
68
|
+
// No validation needed - Email type guarantees validity
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 3. Pure Functions
|
|
73
|
+
|
|
74
|
+
Functions should be predictable. Same input → same output. No side effects.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// ❌ Impure - depends on external state
|
|
78
|
+
let total = 0;
|
|
79
|
+
function addToTotal(amount) {
|
|
80
|
+
total += amount;
|
|
81
|
+
return total;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ✅ Pure - predictable
|
|
85
|
+
function addToTotal(currentTotal: number, amount: number): number {
|
|
86
|
+
return currentTotal + amount;
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 4. Fail Loud
|
|
91
|
+
|
|
92
|
+
Invalid states should throw errors, not silently continue.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// ❌ Silent failure
|
|
96
|
+
function getConfig(key) {
|
|
97
|
+
return config[key] || null; // Hides the problem
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ✅ Fail loud
|
|
101
|
+
function getConfig(key: keyof Config): ConfigValue {
|
|
102
|
+
const value = config[key];
|
|
103
|
+
if (value === undefined) {
|
|
104
|
+
throw new Error(`Missing required config: ${key}`);
|
|
105
|
+
}
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 5. Readability First
|
|
111
|
+
|
|
112
|
+
Code reads like a sentence. Names are documentation.
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// ❌ Unclear
|
|
116
|
+
const d = new Date();
|
|
117
|
+
const x = users.filter(u => u.a).map(u => u.n);
|
|
118
|
+
|
|
119
|
+
// ✅ Readable
|
|
120
|
+
const now = new Date();
|
|
121
|
+
const activeUserNames = users
|
|
122
|
+
.filter(user => user.isActive)
|
|
123
|
+
.map(user => user.name);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Naming Conventions
|
|
127
|
+
|
|
128
|
+
### Variables
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// Use descriptive names
|
|
132
|
+
const users = [...]; // Good
|
|
133
|
+
const userList = [...]; // Redundant
|
|
134
|
+
const data = [...]; // Too vague
|
|
135
|
+
|
|
136
|
+
// Boolean names should read naturally
|
|
137
|
+
const isActive = true;
|
|
138
|
+
const hasPermission = false;
|
|
139
|
+
const canEdit = true;
|
|
140
|
+
|
|
141
|
+
// Avoid negatives in names
|
|
142
|
+
const isNotActive = false; // Confusing: !isNotActive
|
|
143
|
+
const isDisabled = false; // Better: !isDisabled
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Functions
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// Functions should describe actions
|
|
150
|
+
function getUser() { } // Good
|
|
151
|
+
function userData() { } // Is it a getter or setter?
|
|
152
|
+
|
|
153
|
+
// Boolean functions should be questions
|
|
154
|
+
function isValid() { } // Good
|
|
155
|
+
function validate() { } // Sounds like it throws
|
|
156
|
+
|
|
157
|
+
// Event handlers should describe what happens
|
|
158
|
+
function handleSubmit() { } // Good
|
|
159
|
+
function onClick() { } // Too generic
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Classes
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Classes should be nouns
|
|
166
|
+
class User { } // Good
|
|
167
|
+
class UserManager { } // Good
|
|
168
|
+
class CreateUser { } // Sounds like a function
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Function Guidelines
|
|
172
|
+
|
|
173
|
+
### Single Responsibility
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// ❌ Does too many things
|
|
177
|
+
function processOrder(order) {
|
|
178
|
+
validateOrder(order);
|
|
179
|
+
calculateTotal(order);
|
|
180
|
+
chargePayment(order);
|
|
181
|
+
sendConfirmation(order);
|
|
182
|
+
updateInventory(order);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ✅ One thing, well
|
|
186
|
+
function processOrder(order: Order): ProcessResult {
|
|
187
|
+
return pipe(
|
|
188
|
+
validateOrder,
|
|
189
|
+
calculateTotal,
|
|
190
|
+
chargePayment,
|
|
191
|
+
sendConfirmation,
|
|
192
|
+
updateInventory
|
|
193
|
+
)(order);
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Small Functions
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
// ❌ 100+ line function
|
|
201
|
+
function doEverything() {
|
|
202
|
+
// 100 lines of code
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// ✅ Small, focused functions
|
|
206
|
+
function validateInput(input: Input): ValidationResult {
|
|
207
|
+
// 5-10 lines
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function processData(data: Data): ProcessedData {
|
|
211
|
+
// 5-10 lines
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Avoid Side Effects
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
// ❌ Modifies input
|
|
219
|
+
function addItem(cart, item) {
|
|
220
|
+
cart.items.push(item);
|
|
221
|
+
return cart;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ✅ Returns new value
|
|
225
|
+
function addItem(cart: Cart, item: Item): Cart {
|
|
226
|
+
return {
|
|
227
|
+
...cart,
|
|
228
|
+
items: [...cart.items, item]
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Code Organization
|
|
234
|
+
|
|
235
|
+
### File Structure
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
src/
|
|
239
|
+
├── components/ # UI components
|
|
240
|
+
├── hooks/ # Custom hooks
|
|
241
|
+
├── services/ # Business logic
|
|
242
|
+
├── utils/ # Pure utilities
|
|
243
|
+
├── types/ # TypeScript types
|
|
244
|
+
└── constants/ # Constants
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Import Order
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
// 1. External dependencies
|
|
251
|
+
import { useState, useEffect } from 'react';
|
|
252
|
+
import { z } from 'zod';
|
|
253
|
+
|
|
254
|
+
// 2. Internal modules
|
|
255
|
+
import { UserService } from '@/services/user';
|
|
256
|
+
import { Button } from '@/components/ui';
|
|
257
|
+
|
|
258
|
+
// 3. Types
|
|
259
|
+
import type { User } from '@/types';
|
|
260
|
+
|
|
261
|
+
// 4. Constants
|
|
262
|
+
import { MAX_RETRIES } from './constants';
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Comments
|
|
266
|
+
|
|
267
|
+
### When to Comment
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
// ✅ Explain WHY, not WHAT
|
|
271
|
+
// Using exponential backoff to avoid overwhelming the server
|
|
272
|
+
const delay = Math.pow(2, retryCount) * 1000;
|
|
273
|
+
|
|
274
|
+
// ✅ Document complex algorithms
|
|
275
|
+
// Using Fisher-Yates shuffle for unbiased randomization
|
|
276
|
+
function shuffle(array) { ... }
|
|
277
|
+
|
|
278
|
+
// ✅ Add TODOs with context
|
|
279
|
+
// TODO(#123): Remove after migrating to new API
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### When NOT to Comment
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
// ❌ Explains the obvious
|
|
286
|
+
// Loop through users
|
|
287
|
+
for (const user of users) { }
|
|
288
|
+
|
|
289
|
+
// ❌ Outdated comment
|
|
290
|
+
// This function does X (but it actually does Y now)
|
|
291
|
+
|
|
292
|
+
// ❌ Commented-out code
|
|
293
|
+
// function oldFunction() { ... }
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Error Handling
|
|
297
|
+
|
|
298
|
+
### Use Specific Errors
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
// ❌ Generic error
|
|
302
|
+
throw new Error('Something went wrong');
|
|
303
|
+
|
|
304
|
+
// ✅ Specific error
|
|
305
|
+
throw new ValidationError('Email is invalid', { field: 'email' });
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Handle Errors at Boundaries
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
// ❌ Silent catch
|
|
312
|
+
try {
|
|
313
|
+
doSomething();
|
|
314
|
+
} catch (e) {
|
|
315
|
+
// Do nothing
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// ✅ Log and handle
|
|
319
|
+
try {
|
|
320
|
+
doSomething();
|
|
321
|
+
} catch (error) {
|
|
322
|
+
logger.error('Failed to do something', { error });
|
|
323
|
+
throw new ServiceError('Operation failed', { cause: error });
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Testing Principles
|
|
328
|
+
|
|
329
|
+
### Test Behavior, Not Implementation
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
// ❌ Tests implementation
|
|
333
|
+
expect(component.state.count).toBe(1);
|
|
334
|
+
|
|
335
|
+
// ✅ Tests behavior
|
|
336
|
+
expect(screen.getByText('Count: 1')).toBeInTheDocument();
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Use Descriptive Test Names
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
// ❌ Vague
|
|
343
|
+
test('user', () => { ... });
|
|
344
|
+
|
|
345
|
+
// ✅ Descriptive
|
|
346
|
+
test('should create user with valid email', () => { ... });
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
**These principles apply to all code, regardless of language or domain.**
|