@mind-fold/open-flow 0.1.17 → 0.2.2

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.
Files changed (40) hide show
  1. package/dist/configurators/templates.d.ts.map +1 -1
  2. package/dist/configurators/templates.js +17 -6
  3. package/dist/configurators/templates.js.map +1 -1
  4. package/dist/configurators/workflow.d.ts.map +1 -1
  5. package/dist/configurators/workflow.js +82 -6
  6. package/dist/configurators/workflow.js.map +1 -1
  7. package/dist/templates/commands/break-loop.txt +107 -0
  8. package/dist/templates/commands/check-cross-layer.txt +153 -0
  9. package/dist/templates/commands/finish-work.txt +129 -0
  10. package/dist/templates/commands/index.d.ts +9 -5
  11. package/dist/templates/commands/index.d.ts.map +1 -1
  12. package/dist/templates/commands/index.js +16 -5
  13. package/dist/templates/commands/index.js.map +1 -1
  14. package/dist/templates/commands/init-agent.txt +100 -9
  15. package/dist/templates/commands/sync-from-runtime.txt +140 -0
  16. package/dist/templates/markdown/flow.md.txt +96 -84
  17. package/dist/templates/markdown/index.d.ts +21 -4
  18. package/dist/templates/markdown/index.d.ts.map +1 -1
  19. package/dist/templates/markdown/index.js +27 -4
  20. package/dist/templates/markdown/index.js.map +1 -1
  21. package/dist/templates/markdown/structure/backend/database-guidelines.md.txt +247 -0
  22. package/dist/templates/markdown/structure/backend/directory-structure.md.txt +153 -0
  23. package/dist/templates/markdown/structure/backend/error-handling.md.txt +257 -0
  24. package/dist/templates/markdown/structure/backend/index.md.txt +88 -0
  25. package/dist/templates/markdown/structure/backend/logging-guidelines.md.txt +212 -0
  26. package/dist/templates/markdown/structure/backend/quality-guidelines.md.txt +219 -0
  27. package/dist/templates/markdown/structure/backend/type-safety.md.txt +192 -0
  28. package/dist/templates/markdown/structure/flows/code-reuse-thinking-guide.md.txt +343 -0
  29. package/dist/templates/markdown/structure/flows/cross-layer-thinking-guide.md.txt +283 -0
  30. package/dist/templates/markdown/structure/flows/index.md.txt +133 -0
  31. package/dist/templates/markdown/structure/flows/pre-implementation-checklist.md.txt +182 -0
  32. package/dist/templates/markdown/structure/flows/spec-flow-template.md.txt +145 -0
  33. package/dist/templates/markdown/structure/frontend/component-guidelines.md.txt +335 -0
  34. package/dist/templates/markdown/structure/frontend/directory-structure.md.txt +172 -0
  35. package/dist/templates/markdown/structure/frontend/hook-guidelines.md.txt +287 -0
  36. package/dist/templates/markdown/structure/frontend/index.md.txt +91 -0
  37. package/dist/templates/markdown/structure/frontend/quality-guidelines.md.txt +274 -0
  38. package/dist/templates/markdown/structure/frontend/state-management.md.txt +293 -0
  39. package/dist/templates/markdown/structure/frontend/type-safety.md.txt +275 -0
  40. package/package.json +2 -2
@@ -0,0 +1,88 @@
1
+ # Backend Development Guidelines
2
+
3
+ > Best practices for backend development
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ This collection of guidelines covers essential patterns and best practices for building robust backend applications.
10
+
11
+ ---
12
+
13
+ ## Guidelines Index
14
+
15
+ ### Core Patterns
16
+
17
+ | Guide | Description |
18
+ |-------|-------------|
19
+ | [Directory Structure](./directory-structure.md) | Module organization and file layout |
20
+ | [Type Safety](./type-safety.md) | Zod validation, non-null handling, type inference |
21
+ | [Quality Guidelines](./quality-guidelines.md) | Forbidden patterns, code standards |
22
+
23
+ ### Database & Data
24
+
25
+ | Guide | Description |
26
+ |-------|-------------|
27
+ | [Database Guidelines](./database-guidelines.md) | ORM patterns, batch operations, migrations |
28
+
29
+ ### Operations
30
+
31
+ | Guide | Description |
32
+ |-------|-------------|
33
+ | [Logging Guidelines](./logging-guidelines.md) | Structured logging, log levels, context |
34
+ | [Error Handling](./error-handling.md) | Error types, handling strategies |
35
+
36
+ ---
37
+
38
+ ## Quick Reference
39
+
40
+ ### Directory Structure
41
+
42
+ ```
43
+ server/
44
+ ├── db/ # Database (client, schema)
45
+ ├── lib/ # Shared utilities
46
+ ├── middleware/ # Middleware
47
+ ├── routes/ # API routes (domain-driven)
48
+ │ └── {domain}/
49
+ │ ├── types.ts # Zod schemas + types
50
+ │ ├── router.ts # Route definitions
51
+ │ ├── procedures/ # One file per endpoint
52
+ │ └── lib/ # Domain-specific logic
53
+ └── types.ts # Shared types
54
+ ```
55
+
56
+ ### Key Rules
57
+
58
+ | Rule | Description |
59
+ |------|-------------|
60
+ | No `!` assertions | Use null checks with local variables |
61
+ | No `console.log` | Use structured logger |
62
+ | No `await` in loops | Use batch queries with `inArray` |
63
+ | Validate all inputs | Use Zod schemas |
64
+
65
+ ---
66
+
67
+ ## Getting Started
68
+
69
+ 1. **New to this codebase?** Start with [Directory Structure](./directory-structure.md)
70
+ 2. **Setting up database?** Read [Database Guidelines](./database-guidelines.md)
71
+ 3. **Before commit?** Check [Quality Guidelines](./quality-guidelines.md)
72
+
73
+ ---
74
+
75
+ ## Common Tasks
76
+
77
+ ### Create a New API Module
78
+
79
+ ```bash
80
+ mkdir -p server/routes/{domain}/procedures
81
+ touch server/routes/{domain}/{types.ts,router.ts}
82
+ ```
83
+
84
+ See: [Directory Structure](./directory-structure.md)
85
+
86
+ ---
87
+
88
+ **Language**: All documentation must be written in **English**.
@@ -0,0 +1,212 @@
1
+ # Logging Guidelines
2
+
3
+ > Structured logging best practices
4
+
5
+ ---
6
+
7
+ ## Core Rules
8
+
9
+ 1. **Never use `console.log`** - Use structured logger
10
+ 2. **Include context** - Add relevant IDs and metadata
11
+ 3. **Use appropriate levels** - Match severity to log level
12
+ 4. **Use snake_case** - For log message names
13
+
14
+ ---
15
+
16
+ ## Log Levels
17
+
18
+ | Level | Use Case | Example |
19
+ |-------|----------|---------|
20
+ | `error` | Errors that need attention | Database connection failed |
21
+ | `warn` | Potential issues, degraded state | Rate limit approaching |
22
+ | `info` | Normal operations, business events | User created, order placed |
23
+ | `debug` | Development details | Query executed, cache hit |
24
+
25
+ ---
26
+
27
+ ## Structured Logging
28
+
29
+ ### Basic Pattern
30
+
31
+ ```typescript
32
+ // ✅ GOOD: Structured with context
33
+ logger.info('user_created', {
34
+ userId: user.id,
35
+ email: user.email
36
+ });
37
+
38
+ logger.error('payment_failed', error, {
39
+ userId: user.id,
40
+ amount: order.total
41
+ });
42
+
43
+ // ❌ BAD: Unstructured string concatenation
44
+ console.log('User created: ' + user.id);
45
+ logger.info('Error: ' + error.message);
46
+ ```
47
+
48
+ ### With Request Context
49
+
50
+ ```typescript
51
+ // In route handler
52
+ app.get('/api/users/:id', async (c) => {
53
+ const logger = c.get('logger');
54
+ const userId = c.req.param('id');
55
+
56
+ logger.info('fetching_user', { userId });
57
+
58
+ const user = await getUser(userId);
59
+ if (!user) {
60
+ logger.warn('user_not_found', { userId });
61
+ return c.json({ error: 'Not found' }, 404);
62
+ }
63
+
64
+ logger.info('user_fetched', { userId, email: user.email });
65
+ return c.json(user);
66
+ });
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Standard Log Messages
72
+
73
+ Use consistent message names across the codebase:
74
+
75
+ | Message | Level | When |
76
+ |---------|-------|------|
77
+ | `request_start` | info | Request begins |
78
+ | `request_end` | info | Request completes |
79
+ | `request_error` | error | Unhandled error |
80
+ | `{entity}_created` | info | Entity created |
81
+ | `{entity}_updated` | info | Entity updated |
82
+ | `{entity}_deleted` | info | Entity deleted |
83
+ | `{entity}_not_found` | warn | Entity lookup failed |
84
+ | `validation_error` | warn | Input validation failed |
85
+ | `auth_failed` | warn | Authentication failed |
86
+ | `permission_denied` | warn | Authorization failed |
87
+
88
+ ---
89
+
90
+ ## Error Logging
91
+
92
+ Always include the error object for stack traces:
93
+
94
+ ```typescript
95
+ try {
96
+ await riskyOperation();
97
+ } catch (error) {
98
+ if (error instanceof Error) {
99
+ logger.error('operation_failed', error, {
100
+ operationId: opId,
101
+ step: currentStep,
102
+ });
103
+ } else {
104
+ logger.error('operation_failed', undefined, {
105
+ error: String(error)
106
+ });
107
+ }
108
+ throw error; // Re-throw or handle appropriately
109
+ }
110
+ ```
111
+
112
+ ---
113
+
114
+ ## Performance Logging
115
+
116
+ Track duration for slow operations:
117
+
118
+ ```typescript
119
+ async function syncData(logger: Logger) {
120
+ const startTime = Date.now();
121
+
122
+ try {
123
+ await performSync();
124
+
125
+ const duration = Date.now() - startTime;
126
+ logger.info('sync_completed', { durationMs: duration });
127
+
128
+ if (duration > 5000) {
129
+ logger.warn('sync_slow', { durationMs: duration });
130
+ }
131
+ } catch (error) {
132
+ logger.error('sync_failed', error, {
133
+ durationMs: Date.now() - startTime
134
+ });
135
+ throw error;
136
+ }
137
+ }
138
+ ```
139
+
140
+ ---
141
+
142
+ ## What NOT to Log
143
+
144
+ | Never Log | Reason |
145
+ |-----------|--------|
146
+ | Passwords | Security |
147
+ | API keys / tokens | Security |
148
+ | Full credit card numbers | PCI compliance |
149
+ | Personal health info | HIPAA compliance |
150
+ | Session cookies | Security |
151
+
152
+ ```typescript
153
+ // ❌ BAD
154
+ logger.info('login_attempt', { email, password });
155
+
156
+ // ✅ GOOD
157
+ logger.info('login_attempt', { email });
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Logger Setup Example
163
+
164
+ ```typescript
165
+ // lib/logger.ts
166
+ export interface Logger {
167
+ info(message: string, meta?: Record<string, unknown>): void;
168
+ warn(message: string, meta?: Record<string, unknown>): void;
169
+ error(message: string, error?: Error, meta?: Record<string, unknown>): void;
170
+ debug(message: string, meta?: Record<string, unknown>): void;
171
+ }
172
+
173
+ export function createLogger(context: Record<string, unknown> = {}): Logger {
174
+ const log = (level: string, message: string, meta: Record<string, unknown> = {}) => {
175
+ const entry = {
176
+ timestamp: new Date().toISOString(),
177
+ level,
178
+ message,
179
+ ...context,
180
+ ...meta,
181
+ };
182
+ console.log(JSON.stringify(entry));
183
+ };
184
+
185
+ return {
186
+ info: (message, meta) => log('info', message, meta),
187
+ warn: (message, meta) => log('warn', message, meta),
188
+ error: (message, error, meta) => log('error', message, {
189
+ ...meta,
190
+ error: error?.message,
191
+ stack: error?.stack,
192
+ }),
193
+ debug: (message, meta) => log('debug', message, meta),
194
+ };
195
+ }
196
+ ```
197
+
198
+ ---
199
+
200
+ ## Summary
201
+
202
+ | Rule | Description |
203
+ |------|-------------|
204
+ | No `console.log` | Use structured logger |
205
+ | snake_case messages | `user_created` not `User Created` |
206
+ | Include IDs | Add entity IDs to context |
207
+ | No sensitive data | Never log passwords/tokens |
208
+ | Track duration | Log `durationMs` for slow ops |
209
+
210
+ ---
211
+
212
+ **Language**: All documentation must be written in **English**.
@@ -0,0 +1,219 @@
1
+ # Quality Guidelines
2
+
3
+ > Code standards and forbidden patterns
4
+
5
+ ---
6
+
7
+ ## Before Every Commit
8
+
9
+ Run these checks before committing:
10
+
11
+ ```bash
12
+ # Must pass with 0 errors
13
+ pnpm lint
14
+
15
+ # Must pass with no type errors
16
+ pnpm type-check
17
+
18
+ # Run tests
19
+ pnpm test
20
+ ```
21
+
22
+ ---
23
+
24
+ ## Forbidden Patterns
25
+
26
+ ### Non-Null Assertions
27
+
28
+ ```typescript
29
+ // ❌ FORBIDDEN
30
+ const name = user!.name;
31
+ const data = response!.data;
32
+
33
+ // ✅ REQUIRED
34
+ const user = await getUser(id);
35
+ if (!user) {
36
+ throw new NotFoundError('User not found');
37
+ }
38
+ const name = user.name;
39
+ ```
40
+
41
+ ### Console.log
42
+
43
+ ```typescript
44
+ // ❌ FORBIDDEN
45
+ console.log('Debug:', data);
46
+ console.error('Error:', error);
47
+
48
+ // ✅ REQUIRED
49
+ logger.debug('processing_data', { data });
50
+ logger.error('operation_failed', error);
51
+ ```
52
+
53
+ ### Await in Loops
54
+
55
+ ```typescript
56
+ // ❌ FORBIDDEN
57
+ for (const id of ids) {
58
+ await db.select().from(users).where(eq(users.id, id));
59
+ }
60
+
61
+ // ✅ REQUIRED
62
+ const results = await db
63
+ .select()
64
+ .from(users)
65
+ .where(inArray(users.id, ids));
66
+ ```
67
+
68
+ ### Type Assertions Without Validation
69
+
70
+ ```typescript
71
+ // ❌ FORBIDDEN
72
+ const data = input as UserData;
73
+ const config = JSON.parse(str) as Config;
74
+
75
+ // ✅ REQUIRED
76
+ const data = userDataSchema.parse(input);
77
+ const config = configSchema.parse(JSON.parse(str));
78
+ ```
79
+
80
+ ### Any Type
81
+
82
+ ```typescript
83
+ // ❌ FORBIDDEN
84
+ function process(data: any) { ... }
85
+ const result: any = await fetch(...);
86
+
87
+ // ✅ REQUIRED
88
+ function process(data: unknown) {
89
+ const validated = schema.parse(data);
90
+ ...
91
+ }
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Required Patterns
97
+
98
+ ### Error Handling
99
+
100
+ ```typescript
101
+ // Always handle errors explicitly
102
+ try {
103
+ await riskyOperation();
104
+ } catch (error) {
105
+ logger.error('operation_failed', error);
106
+ throw new AppError('Operation failed', { cause: error });
107
+ }
108
+ ```
109
+
110
+ ### Input Validation
111
+
112
+ ```typescript
113
+ // All API inputs must be validated
114
+ app.post('/users', async (c) => {
115
+ const input = createUserSchema.parse(await c.req.json());
116
+ // Now input is type-safe
117
+ });
118
+ ```
119
+
120
+ ### Null Checks
121
+
122
+ ```typescript
123
+ // Always check nullable values before use
124
+ const user = await getUser(id);
125
+ if (!user) {
126
+ return c.json({ error: 'User not found' }, 404);
127
+ }
128
+ // TypeScript knows user is not null here
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Code Style
134
+
135
+ ### Naming
136
+
137
+ | Type | Convention | Example |
138
+ |------|------------|---------|
139
+ | Variables | camelCase | `userName`, `isActive` |
140
+ | Functions | camelCase | `createUser`, `validateInput` |
141
+ | Types/Interfaces | PascalCase | `UserData`, `CreateUserInput` |
142
+ | Constants | SCREAMING_SNAKE | `MAX_RETRIES`, `API_TIMEOUT` |
143
+ | Files | kebab-case | `user-service.ts`, `auth-middleware.ts` |
144
+
145
+ ### Function Length
146
+
147
+ - Keep functions under 50 lines
148
+ - Extract helper functions for complex logic
149
+ - One function = one responsibility
150
+
151
+ ### Comments
152
+
153
+ ```typescript
154
+ // ✅ GOOD: Explain WHY, not WHAT
155
+ // Skip validation for internal calls to avoid performance overhead
156
+ const data = trustInternalData(input);
157
+
158
+ // ❌ BAD: Obvious comment
159
+ // Get user by id
160
+ const user = await getUser(id);
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Documentation
166
+
167
+ ### API Endpoints
168
+
169
+ Document every public API endpoint:
170
+
171
+ ```typescript
172
+ /**
173
+ * Create a new user
174
+ *
175
+ * @route POST /api/users
176
+ * @param email - User's email address
177
+ * @param name - User's display name
178
+ * @returns Created user object
179
+ * @throws 400 - Invalid input
180
+ * @throws 409 - Email already exists
181
+ */
182
+ ```
183
+
184
+ ### Complex Logic
185
+
186
+ Document non-obvious business logic:
187
+
188
+ ```typescript
189
+ /**
190
+ * Calculate user's subscription tier based on usage.
191
+ *
192
+ * Tier calculation:
193
+ * - Free: < 100 requests/month
194
+ * - Pro: 100-10000 requests/month
195
+ * - Enterprise: > 10000 requests/month
196
+ *
197
+ * Note: Calculated at month end, not real-time.
198
+ */
199
+ ```
200
+
201
+ ---
202
+
203
+ ## Checklist
204
+
205
+ Before submitting code for review:
206
+
207
+ - [ ] No `console.log` statements
208
+ - [ ] No `!` non-null assertions
209
+ - [ ] No `any` types
210
+ - [ ] No `await` in loops
211
+ - [ ] All inputs validated with Zod
212
+ - [ ] Errors logged with context
213
+ - [ ] `pnpm lint` passes
214
+ - [ ] `pnpm type-check` passes
215
+ - [ ] Tests pass
216
+
217
+ ---
218
+
219
+ **Language**: All documentation must be written in **English**.
@@ -0,0 +1,192 @@
1
+ # Type Safety
2
+
3
+ > Zod validation, non-null handling, and type inference patterns
4
+
5
+ ---
6
+
7
+ ## Core Principles
8
+
9
+ 1. **Validate at boundaries** - All external inputs must be validated
10
+ 2. **Infer from schemas** - Don't duplicate type definitions
11
+ 3. **No assertions** - Never use `!` or `as` without validation
12
+ 4. **Explicit nullability** - Handle null/undefined explicitly
13
+
14
+ ---
15
+
16
+ ## Zod Schema Patterns
17
+
18
+ ### Basic Schema
19
+
20
+ ```typescript
21
+ import { z } from 'zod';
22
+
23
+ export const userSchema = z.object({
24
+ id: z.string(),
25
+ email: z.string().email(),
26
+ name: z.string().min(1).max(100),
27
+ age: z.number().int().positive().optional(),
28
+ role: z.enum(['admin', 'user', 'guest']),
29
+ createdAt: z.date(),
30
+ });
31
+
32
+ // Infer type from schema
33
+ export type User = z.infer<typeof userSchema>;
34
+ ```
35
+
36
+ ### Input vs Output Schemas
37
+
38
+ ```typescript
39
+ // Input: what client sends
40
+ export const createUserInput = z.object({
41
+ email: z.string().email(),
42
+ name: z.string().min(1),
43
+ password: z.string().min(8),
44
+ });
45
+
46
+ // Output: what server returns (no password!)
47
+ export const userOutput = z.object({
48
+ id: z.string(),
49
+ email: z.string(),
50
+ name: z.string(),
51
+ createdAt: z.date(),
52
+ });
53
+
54
+ export type CreateUserInput = z.infer<typeof createUserInput>;
55
+ export type UserOutput = z.infer<typeof userOutput>;
56
+ ```
57
+
58
+ ### Partial and Pick
59
+
60
+ ```typescript
61
+ // For updates - all fields optional
62
+ export const updateUserInput = createUserInput.partial();
63
+
64
+ // Pick specific fields
65
+ export const userSummary = userSchema.pick({
66
+ id: true,
67
+ name: true,
68
+ });
69
+ ```
70
+
71
+ ---
72
+
73
+ ## No Non-Null Assertions
74
+
75
+ **Never use `!` operator.** It bypasses TypeScript's null safety.
76
+
77
+ ### Problem
78
+
79
+ ```typescript
80
+ // ❌ BAD: Crashes if user is null
81
+ const user = await getUser(id);
82
+ const name = user!.name; // TypeScript trusts you, runtime doesn't
83
+ ```
84
+
85
+ ### Solution: Guard with Local Variable
86
+
87
+ ```typescript
88
+ // ✅ GOOD: Explicit null check
89
+ const user = await getUser(id);
90
+ if (!user) {
91
+ throw new NotFoundError('User not found');
92
+ }
93
+ // TypeScript now knows user is not null
94
+ const name = user.name; // Safe access
95
+ ```
96
+
97
+ ### Solution: Early Return
98
+
99
+ ```typescript
100
+ // ✅ GOOD: Early return pattern
101
+ async function getUserName(id: string): Promise<string> {
102
+ const user = await getUser(id);
103
+ if (!user) {
104
+ throw new NotFoundError('User not found');
105
+ }
106
+ return user.name;
107
+ }
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Type Inference from Database
113
+
114
+ ### Drizzle ORM
115
+
116
+ ```typescript
117
+ import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
118
+
119
+ export const users = sqliteTable('users', {
120
+ id: text('id').primaryKey(),
121
+ email: text('email').notNull(),
122
+ name: text('name').notNull(),
123
+ createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),
124
+ });
125
+
126
+ // Infer types from schema
127
+ export type User = typeof users.$inferSelect;
128
+ export type InsertUser = typeof users.$inferInsert;
129
+ ```
130
+
131
+ ### Align Zod with Database
132
+
133
+ ```typescript
134
+ // Database schema is source of truth
135
+ // Zod schema for API validation should match
136
+
137
+ export const createUserInput = z.object({
138
+ email: z.string().email(),
139
+ name: z.string().min(1),
140
+ }) satisfies z.ZodType<Omit<InsertUser, 'id' | 'createdAt'>>;
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Forbidden Patterns
146
+
147
+ | Pattern | Problem | Solution |
148
+ |---------|---------|----------|
149
+ | `user!.name` | Runtime crash if null | Null check + local variable |
150
+ | `data as User` | No runtime validation | Use Zod `.parse()` |
151
+ | `any` type | Disables type checking | Use `unknown` + validation |
152
+ | Duplicate types | Drift between definitions | Infer from single source |
153
+
154
+ ---
155
+
156
+ ## Best Practices
157
+
158
+ ### DO
159
+
160
+ ```typescript
161
+ // Parse external data
162
+ const data = userSchema.parse(externalInput);
163
+
164
+ // Use safeParse for graceful handling
165
+ const result = userSchema.safeParse(input);
166
+ if (!result.success) {
167
+ return { error: result.error.format() };
168
+ }
169
+
170
+ // Explicit null handling
171
+ const user = await db.query.users.findFirst({ where: eq(users.id, id) });
172
+ if (!user) {
173
+ throw new NotFoundError(`User ${id} not found`);
174
+ }
175
+ ```
176
+
177
+ ### DON'T
178
+
179
+ ```typescript
180
+ // Trust external data
181
+ const data = externalInput as User; // ❌
182
+
183
+ // Use non-null assertion
184
+ const name = user!.name; // ❌
185
+
186
+ // Ignore parse errors
187
+ const data = userSchema.parse(input); // ❌ Throws on invalid
188
+ ```
189
+
190
+ ---
191
+
192
+ **Language**: All documentation must be written in **English**.