@fermindi/pwn-cli 0.3.0 → 0.3.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.
package/cli/inject.js CHANGED
@@ -65,7 +65,9 @@ export default async function injectCommand(args = []) {
65
65
  console.log(' ├── patterns/ (auto-applied patterns)');
66
66
  console.log(' ├── workflows/ (batch execution)');
67
67
  console.log(' ├── agents/ (AI agent configs)');
68
- console.log(' └── config/ (notifications, etc)\n');
68
+ console.log(' └── config/ (notifications, etc)');
69
+ console.log(' .claude/');
70
+ console.log(' └── commands/ (slash commands: /save)\n');
69
71
 
70
72
  // Show ntfy topic if generated
71
73
  const notifyPath = join(process.cwd(), '.ai', 'config', 'notifications.json');
package/cli/patterns.js CHANGED
@@ -237,7 +237,7 @@ async function addPattern(args) {
237
237
  console.log(`Created pattern: ${patternId}`);
238
238
  console.log(`Directory: .ai/patterns/${category}/${name}/`);
239
239
  console.log('\nNext steps:');
240
- console.log(` 1. Edit .ai/patterns/${category}/${name}/README.md`);
240
+ console.log(` 1. Create .ai/patterns/${category}/${name}/${name}.md with your pattern`);
241
241
  console.log(' 2. Add trigger: pwn patterns triggers add');
242
242
  }
243
243
 
package/cli/update.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync, readFileSync, writeFileSync, cpSync, renameSync } from 'fs';
2
+ import { existsSync, readFileSync, writeFileSync, cpSync, renameSync, mkdirSync, readdirSync } from 'fs';
3
3
  import { join, dirname } from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
 
@@ -13,14 +13,21 @@ const FRAMEWORK_FILES = [
13
13
  'agents/claude.md',
14
14
  'agents/README.md',
15
15
  'patterns/index.md',
16
- 'patterns/frontend/README.md',
17
- 'patterns/backend/README.md',
18
- 'patterns/universal/README.md',
16
+ 'patterns/frontend/frontend.template.md',
17
+ 'patterns/backend/backend.template.md',
18
+ 'patterns/universal/universal.template.md',
19
19
  'workflows/batch-task.md',
20
20
  'config/README.md',
21
21
  'README.md',
22
22
  ];
23
23
 
24
+ /**
25
+ * Claude Code slash commands (in .claude/commands/)
26
+ */
27
+ const CLAUDE_COMMANDS = [
28
+ 'save.md',
29
+ ];
30
+
24
31
  /**
25
32
  * Files that should NOT be updated (user data)
26
33
  * These contain user customizations
@@ -148,6 +155,64 @@ export default async function updateCommand(args = []) {
148
155
  }
149
156
  }
150
157
 
158
+ // Update .claude/commands/ (slash commands)
159
+ const claudeCommandsDir = join(cwd, '.claude', 'commands');
160
+ const templateCommandsDir = join(__dirname, '../templates/workspace/.claude/commands');
161
+
162
+ if (existsSync(templateCommandsDir)) {
163
+ for (const cmdFile of CLAUDE_COMMANDS) {
164
+ const templateFile = join(templateCommandsDir, cmdFile);
165
+ const targetFile = join(claudeCommandsDir, cmdFile);
166
+
167
+ if (!existsSync(templateFile)) {
168
+ continue;
169
+ }
170
+
171
+ const templateContent = readFileSync(templateFile, 'utf8');
172
+ const targetExists = existsSync(targetFile);
173
+ const targetContent = targetExists ? readFileSync(targetFile, 'utf8') : '';
174
+
175
+ if (templateContent !== targetContent) {
176
+ if (dryRun) {
177
+ console.log(` 📝 Would update: .claude/commands/${cmdFile}`);
178
+ } else {
179
+ // Ensure directory exists
180
+ if (!existsSync(claudeCommandsDir)) {
181
+ mkdirSync(claudeCommandsDir, { recursive: true });
182
+ }
183
+ writeFileSync(targetFile, templateContent);
184
+ console.log(` 📝 Updated: .claude/commands/${cmdFile}`);
185
+ }
186
+ updated.push(`.claude/commands/${cmdFile}`);
187
+ }
188
+ }
189
+ }
190
+
191
+ // ============================================
192
+ // MIGRATION: v1.1.0 (can remove after 2025-07-01)
193
+ // Rename README.md → .template.md in patterns/
194
+ // ============================================
195
+ const migrations = [
196
+ { from: 'patterns/frontend/README.md', to: 'patterns/frontend/frontend.template.md' },
197
+ { from: 'patterns/backend/README.md', to: 'patterns/backend/backend.template.md' },
198
+ { from: 'patterns/universal/README.md', to: 'patterns/universal/universal.template.md' },
199
+ ];
200
+
201
+ for (const { from, to } of migrations) {
202
+ const oldPath = join(aiDir, from);
203
+ const newPath = join(aiDir, to);
204
+ if (existsSync(oldPath) && !existsSync(newPath)) {
205
+ if (dryRun) {
206
+ console.log(` 🔄 Would migrate: ${from} → ${to}`);
207
+ } else {
208
+ renameSync(oldPath, newPath);
209
+ console.log(` 🔄 Migrated: ${from} → ${to}`);
210
+ }
211
+ updated.push(`${from} → ${to}`);
212
+ }
213
+ }
214
+ // ============================================
215
+
151
216
  // Update state.json with new version
152
217
  if (!dryRun && existsSync(statePath)) {
153
218
  try {
@@ -185,5 +250,6 @@ export default async function updateCommand(args = []) {
185
250
  console.log('🔒 Preserved (user data):');
186
251
  console.log(' .ai/memory/ (decisions, patterns, deadends)');
187
252
  console.log(' .ai/tasks/ (active, backlog)');
188
- console.log(' .ai/state.json (session state)\n');
253
+ console.log(' .ai/state.json (session state)');
254
+ console.log(' .claude/ (your custom commands preserved)\n');
189
255
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fermindi/pwn-cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Professional AI Workspace - Inject structured memory and automation into any project for AI-powered development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -86,6 +86,14 @@ export function getTemplatePath() {
86
86
  return join(__dirname, '../../templates/workspace/.ai');
87
87
  }
88
88
 
89
+ /**
90
+ * Get the path to the .claude commands template
91
+ * @returns {string} Path to .claude template directory
92
+ */
93
+ export function getClaudeCommandsTemplatePath() {
94
+ return join(__dirname, '../../templates/workspace/.claude');
95
+ }
96
+
89
97
  /**
90
98
  * Inject PWN workspace into a project
91
99
  * @param {object} options - Injection options
@@ -104,7 +112,9 @@ export async function inject(options = {}) {
104
112
  } = options;
105
113
 
106
114
  const templateDir = getTemplatePath();
115
+ const claudeTemplateDir = getClaudeCommandsTemplatePath();
107
116
  const targetDir = join(cwd, '.ai');
117
+ const claudeDir = join(cwd, '.claude');
108
118
 
109
119
  const log = silent ? () => {} : console.log;
110
120
 
@@ -193,6 +203,24 @@ export async function inject(options = {}) {
193
203
  }
194
204
  }
195
205
 
206
+ // Copy .claude/commands/ for slash commands
207
+ if (existsSync(claudeTemplateDir)) {
208
+ // Create .claude/commands/ if it doesn't exist
209
+ const commandsDir = join(claudeDir, 'commands');
210
+ if (!existsSync(commandsDir)) {
211
+ mkdirSync(commandsDir, { recursive: true });
212
+ }
213
+
214
+ // Copy all command files
215
+ const claudeCommandsSource = join(claudeTemplateDir, 'commands');
216
+ if (existsSync(claudeCommandsSource)) {
217
+ cpSync(claudeCommandsSource, commandsDir, { recursive: true });
218
+ if (!silent) {
219
+ console.log('📝 Created .claude/commands/ with PWN slash commands');
220
+ }
221
+ }
222
+ }
223
+
196
224
  // Backup other AI files (not CLAUDE.md) to .ai/
197
225
  const otherFiles = Object.fromEntries(
198
226
  Object.entries(backedUpContent).filter(([k]) => k.toLowerCase() !== 'claude.md')
@@ -85,14 +85,14 @@ export class PatternRegistry {
85
85
  if (!entry.isDirectory()) continue;
86
86
 
87
87
  const patternPath = join(categoryPath, entry.name);
88
- const readmePath = join(patternPath, 'README.md');
88
+ const mainFile = this.findMainPatternFile(patternPath);
89
89
 
90
90
  const pattern = {
91
91
  id: `${category}/${entry.name}`,
92
92
  name: this.formatName(entry.name),
93
93
  category,
94
94
  path: relative(this.aiPath, patternPath),
95
- description: this.extractDescription(readmePath),
95
+ description: this.extractDescription(mainFile),
96
96
  triggers: [],
97
97
  metadata: {
98
98
  usageCount: 0,
@@ -110,10 +110,29 @@ export class PatternRegistry {
110
110
  }
111
111
 
112
112
  /**
113
- * Extract description from README.md first line
113
+ * Find the main pattern file in a directory
114
+ * Looks for .md files (excluding .template.md)
114
115
  */
115
- extractDescription(readmePath) {
116
- if (!existsSync(readmePath)) {
116
+ findMainPatternFile(patternPath) {
117
+ if (!existsSync(patternPath)) return null;
118
+
119
+ try {
120
+ const files = readdirSync(patternPath);
121
+ // Find first .md file that's not a template
122
+ const mdFile = files.find(f =>
123
+ f.endsWith('.md') && !f.endsWith('.template.md')
124
+ );
125
+ return mdFile ? join(patternPath, mdFile) : null;
126
+ } catch {
127
+ return null;
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Extract description from pattern file first line
133
+ */
134
+ extractDescription(filePath) {
135
+ if (!filePath || !existsSync(filePath)) {
117
136
  return 'No description available';
118
137
  }
119
138
 
@@ -213,9 +232,10 @@ export class PatternRegistry {
213
232
  if (!existsSync(patternDir)) {
214
233
  mkdirSync(patternDir, { recursive: true });
215
234
 
216
- // Create README.md with description
217
- const readmePath = join(patternDir, 'README.md');
218
- writeFileSync(readmePath, `# ${pattern.name}\n\n${pattern.description || ''}\n`);
235
+ // Create pattern file with description (use pattern name as filename)
236
+ const patternName = basename(pattern.path || pattern.id);
237
+ const patternFile = join(patternDir, `${patternName}.md`);
238
+ writeFileSync(patternFile, `# ${pattern.name}\n\n${pattern.description || ''}\n`);
219
239
  }
220
240
 
221
241
  // Set metadata
@@ -252,7 +272,7 @@ export class PatternRegistry {
252
272
  }
253
273
 
254
274
  /**
255
- * Get pattern content (README.md)
275
+ * Get pattern content (first .md file, excluding templates)
256
276
  * @param {string} id - Pattern ID
257
277
  * @returns {string|null}
258
278
  */
@@ -261,10 +281,12 @@ export class PatternRegistry {
261
281
  if (!pattern) return null;
262
282
 
263
283
  // pattern.path is relative to aiPath (e.g., "patterns/frontend/react")
264
- const readmePath = join(this.aiPath, pattern.path, 'README.md');
265
- if (!existsSync(readmePath)) return null;
284
+ const patternDir = join(this.aiPath, pattern.path);
285
+ const mainFile = this.findMainPatternFile(patternDir);
286
+
287
+ if (!mainFile) return null;
266
288
 
267
- return readFileSync(readmePath, 'utf8');
289
+ return readFileSync(mainFile, 'utf8');
268
290
  }
269
291
 
270
292
  /**
@@ -0,0 +1,19 @@
1
+ <!--
2
+ AI: This is an example template. DO NOT edit this file.
3
+ Create new .md files as you discover patterns.
4
+ Examples: api-routes.md, prisma-queries.md, auth-flow.md
5
+ -->
6
+
7
+ # [Pattern Name]
8
+
9
+ ## Context
10
+ When to apply this pattern.
11
+
12
+ ## Pattern
13
+ Description or code example.
14
+
15
+ ## Rationale
16
+ Why this approach works better.
17
+
18
+ ## Examples
19
+ - `src/routes/users.ts:28`
@@ -0,0 +1,19 @@
1
+ <!--
2
+ AI: This is an example template. DO NOT edit this file.
3
+ Create new .md files as you discover patterns.
4
+ Examples: react-hooks.md, form-validation.md, state-management.md
5
+ -->
6
+
7
+ # [Pattern Name]
8
+
9
+ ## Context
10
+ When to apply this pattern.
11
+
12
+ ## Pattern
13
+ Description or code example.
14
+
15
+ ## Rationale
16
+ Why this approach works better.
17
+
18
+ ## Examples
19
+ - `src/components/Button.tsx:42`
@@ -208,9 +208,9 @@ patterns/
208
208
  ```
209
209
 
210
210
  Each directory contains:
211
- - `README.md` - Pattern documentation
211
+ - `<category>.template.md` - Template showing pattern format (don't edit)
212
+ - `<pattern-name>.md` - Actual patterns created by AI as it learns
212
213
  - `*.example.ts` - Code examples (optional)
213
- - `checklist.md` - Verification checklist (optional)
214
214
 
215
215
  ---
216
216
 
@@ -220,22 +220,22 @@ Each directory contains:
220
220
 
221
221
  **Condition:** User edits `src/components/Button.tsx`
222
222
  **Triggers:** `*.tsx` matches
223
- **Load:** `patterns/frontend/react/README.md`
224
- **Apply:** React component best practices to Button component
223
+ **Load:** `patterns/frontend/react-components.md` (if exists)
224
+ **Apply:** React component patterns learned in this project
225
225
 
226
226
  ### Example 2: API Endpoint Trigger
227
227
 
228
228
  **Condition:** User imports `from 'express'`
229
229
  **Triggers:** `import.*express` matches
230
- **Load:** `patterns/backend/express/README.md` + `patterns/universal/rest-api/README.md`
231
- **Apply:** Express + REST API patterns to new route
230
+ **Load:** `patterns/backend/api-routes.md` (if exists)
231
+ **Apply:** Express + REST API patterns learned in this project
232
232
 
233
233
  ### Example 3: Test File Trigger
234
234
 
235
235
  **Condition:** User creates `src/__tests__/utils.test.ts`
236
- **Triggers:** `*.test.ts` matches + `import jest` matches
237
- **Load:** `patterns/universal/testing/unit/README.md`
238
- **Apply:** Unit test patterns and Jest best practices
236
+ **Triggers:** `*.test.ts` matches
237
+ **Load:** `patterns/universal/testing.md` (if exists)
238
+ **Apply:** Test patterns learned in this project
239
239
 
240
240
  ---
241
241
 
@@ -0,0 +1,19 @@
1
+ <!--
2
+ AI: This is an example template. DO NOT edit this file.
3
+ Create new .md files as you discover patterns.
4
+ Examples: error-handling.md, testing.md, typescript-utils.md
5
+ -->
6
+
7
+ # [Pattern Name]
8
+
9
+ ## Context
10
+ When to apply this pattern.
11
+
12
+ ## Pattern
13
+ Description or code example.
14
+
15
+ ## Rationale
16
+ Why this approach works better.
17
+
18
+ ## Examples
19
+ - `src/lib/errors.ts:15`
@@ -0,0 +1,142 @@
1
+ # /save - PWN Session Save
2
+
3
+ Save your current work state to PWN framework files (.ai/state.json and .ai/memory/).
4
+
5
+ ## What this command does
6
+
7
+ 1. Updates .ai/state.json with current session state
8
+ 2. Updates .ai/tasks/active.md with task progress
9
+ 3. Logs new dead ends to .ai/memory/deadends.md
10
+ 4. Optionally updates .ai/memory/decisions.md with new decisions
11
+ 5. Creates archive entry in .ai/memory/archive/
12
+
13
+ ---
14
+
15
+ ## Instructions
16
+
17
+ First, identify the current developer by running:
18
+
19
+ ```bash
20
+ git config user.name
21
+ ```
22
+
23
+ Then, analyze the current session and update PWN files accordingly.
24
+
25
+ ## Files to Update
26
+
27
+ ### 1. State File (.ai/state.json)
28
+
29
+ Update the session state:
30
+
31
+ ```json
32
+ {
33
+ "developer": "{username from git config}",
34
+ "session_started": "{ISO timestamp}",
35
+ "session_mode": "interactive",
36
+ "current_task": "{task ID or null}",
37
+ "context_loaded": ["memory", "patterns", "tasks"],
38
+ "last_save": "{current ISO timestamp}"
39
+ }
40
+ ```
41
+
42
+ ### 2. Active Tasks (.ai/tasks/active.md)
43
+
44
+ If there are tasks in progress:
45
+ - Update checkbox status ([ ] or [x])
46
+ - Add notes about blockers
47
+ - Update priority if changed
48
+
49
+ ### 3. Dead Ends (.ai/memory/deadends.md)
50
+
51
+ When a new dead end is discovered:
52
+
53
+ 1. **Get next ID** from existing entries (last DE-XXX + 1)
54
+
55
+ 2. **Add detailed entry**:
56
+ ```markdown
57
+ ## DE-XXX: Title
58
+
59
+ **Date:** YYYY-MM-DD
60
+ **Attempted:** What was tried
61
+ **Problem:** Why it failed
62
+ **Solution:** What worked instead
63
+ **Tags:** relevant, keywords
64
+ ```
65
+
66
+ ### 4. Decisions (.ai/memory/decisions.md)
67
+
68
+ If new architectural decisions were made:
69
+
70
+ 1. **Get next ID** from existing entries (last DEC-XXX + 1)
71
+
72
+ 2. **Add entry**:
73
+ ```markdown
74
+ ## DEC-XXX: Decision Title
75
+
76
+ **Date:** YYYY-MM-DD
77
+ **Status:** Active
78
+ **Context:** Why this decision was needed
79
+ **Decision:** What was decided
80
+ **Rationale:** Why this is the best choice
81
+ ```
82
+
83
+ ### 5. Archive Entry (.ai/memory/archive/{date}-session.md)
84
+
85
+ Create a session summary:
86
+
87
+ ```markdown
88
+ # Session: YYYY-MM-DD
89
+
90
+ ## Summary
91
+ {brief description of what was done this session}
92
+
93
+ ## Tasks
94
+ ### Completed
95
+ - [x] Task descriptions...
96
+
97
+ ### In Progress
98
+ - [ ] Task descriptions...
99
+
100
+ ## Decisions Made
101
+ - DEC-XXX: description (if any)
102
+
103
+ ## Dead Ends
104
+ - DE-XXX: description (if any)
105
+
106
+ ---
107
+ *Saved: {ISO timestamp}*
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Output Format
113
+
114
+ After updating all files, confirm to the user:
115
+
116
+ ```
117
+ PWN Save Complete:
118
+ - State: .ai/state.json updated (developer: {username})
119
+ - Tasks: {X} active, {Y} completed
120
+ - Dead Ends: {new count or "no new"}
121
+ - Decisions: {new count or "no new"}
122
+ - Archive: .ai/memory/archive/{filename}
123
+ - Last updated: {timestamp}
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Rules
129
+
130
+ 1. **state.json**: Only current session state, no history
131
+ 2. **deadends.md**: Detailed entries with proper DE-XXX IDs
132
+ 3. **decisions.md**: Organized entries with proper DEC-XXX IDs
133
+ 4. **active.md**: Only current sprint tasks
134
+ 5. **archive/**: One file per session with summary
135
+
136
+ ---
137
+
138
+ ## Notes
139
+
140
+ - This command replaces the old /checkpoint command
141
+ - Uses PWN framework structure in .ai/ directory
142
+ - Always get the next available ID number before adding entries
@@ -1,126 +0,0 @@
1
- # Backend Patterns
2
-
3
- This directory contains design patterns and best practices for backend development.
4
-
5
- ## Overview
6
-
7
- Backend patterns cover:
8
- - Express.js route structure
9
- - REST API design
10
- - Database queries and migrations
11
- - Error handling and logging
12
- - Authentication and authorization
13
- - Data validation
14
- - Performance optimization
15
- - Middleware patterns
16
- - Integration patterns
17
-
18
- ## Structure
19
-
20
- ```
21
- backend/
22
- ├── README.md # This file
23
- ├── express/ # Express.js patterns
24
- │ └── README.md # Express routing and middleware
25
- ├── database/ # Database patterns
26
- │ └── README.md # Query and ORM patterns
27
- ├── api-design/ # REST API patterns
28
- │ └── README.md # API structure and conventions
29
- ├── security/ # Security patterns
30
- │ └── README.md # Auth, validation, sanitization
31
- └── integration/ # Integration patterns
32
- └── README.md # Working with external services
33
- ```
34
-
35
- ## Auto-Apply Triggers
36
-
37
- These patterns are automatically loaded when:
38
-
39
- - **File:** `*.routes.ts`, `routes/*.ts` (Express routes)
40
- - **Import:** `from.*express`, `import.*Router`
41
- - **Path:** `src/routes/`, `src/api/`
42
- - **Keyword:** `app.get`, `app.post`, `router.use`
43
-
44
- See `patterns/index.md` for trigger configuration.
45
-
46
- ## Common Patterns
47
-
48
- ### Route Structure
49
- ```typescript
50
- // Group related routes together
51
- // Use middleware for common operations (auth, logging)
52
- // Keep route handlers thin, logic in services
53
- // Consistent error handling
54
- ```
55
-
56
- ### Express Middleware
57
- - Authentication middleware early in chain
58
- - Error handling middleware last
59
- - Logging middleware for all requests
60
- - Request validation middleware
61
- - CORS middleware appropriately configured
62
-
63
- ### API Design
64
- - RESTful conventions (GET, POST, PUT, DELETE)
65
- - Consistent response format
66
- - Proper HTTP status codes
67
- - Pagination for list endpoints
68
- - Filtering and sorting support
69
-
70
- ### Database Queries
71
- - Use ORM/query builder (not raw SQL)
72
- - Eager load relationships when needed
73
- - Avoid N+1 query problems
74
- - Index frequently-queried columns
75
- - Use transactions for multi-step operations
76
-
77
- ### Error Handling
78
- - Custom error classes for different error types
79
- - Consistent error response format
80
- - Log errors with full context
81
- - Don't expose internal errors to clients
82
- - Use HTTP status codes correctly
83
-
84
- ### Validation
85
- - Validate all user input
86
- - Use schema validation (Zod, Joi, etc.)
87
- - Sanitize input to prevent injection
88
- - Custom validation rules for domain logic
89
- - Clear error messages for users
90
-
91
- ### Authentication
92
- - Use industry-standard auth (JWT, OAuth, etc.)
93
- - Secure token storage
94
- - Token expiration and refresh strategy
95
- - Role-based access control (RBAC)
96
- - Audit logging of auth events
97
-
98
- ## Usage
99
-
100
- 1. Read the relevant sub-directory README for your task
101
- 2. Check code examples for reference implementations
102
- 3. Follow patterns in new routes and services
103
- 4. Update patterns if you discover improvements
104
-
105
- ## Contributing
106
-
107
- Found a better pattern?
108
-
109
- 1. Document it with examples
110
- 2. Add to appropriate subdirectory
111
- 3. Update this README
112
- 4. Commit with message: `docs: add [pattern name] pattern`
113
- 5. Update triggers in `patterns/index.md` if widely applicable
114
-
115
- ## Links
116
-
117
- - [Express Patterns](express/README.md)
118
- - [Database Patterns](database/README.md)
119
- - [API Design](api-design/README.md)
120
- - [Security Patterns](security/README.md)
121
- - [Integration Patterns](integration/README.md)
122
-
123
- ## Version
124
-
125
- **Last Updated:** (Set on template injection)
126
- **Maintained By:** Development Team
@@ -1,103 +0,0 @@
1
- # Frontend Patterns
2
-
3
- This directory contains design patterns and best practices for frontend development.
4
-
5
- ## Overview
6
-
7
- Frontend patterns cover:
8
- - React component architecture
9
- - TypeScript type definitions
10
- - Styling and CSS strategies
11
- - State management
12
- - Performance optimization
13
- - Accessibility (a11y)
14
- - Component composition
15
- - Hook patterns
16
-
17
- ## Structure
18
-
19
- ```
20
- frontend/
21
- ├── README.md # This file
22
- ├── react/ # React-specific patterns
23
- │ └── README.md # React component patterns
24
- ├── styling/ # CSS and styling patterns
25
- │ └── README.md # Styling strategies
26
- ├── component-libs/ # UI component library patterns
27
- │ └── README.md # Working with component libraries
28
- └── accessibility/ # A11y patterns
29
- └── README.md # Accessibility patterns
30
- ```
31
-
32
- ## Auto-Apply Triggers
33
-
34
- These patterns are automatically loaded when:
35
-
36
- - **File:** `*.tsx`, `*.jsx` (React components)
37
- - **Import:** `import.*React`, `from.*react`
38
- - **Path:** `src/components/`
39
- - **Keyword:** `function Component`, `export default`
40
-
41
- See `patterns/index.md` for trigger configuration.
42
-
43
- ## Common Patterns
44
-
45
- ### Component Architecture
46
- - Functional components with hooks (not class components)
47
- - One component per file
48
- - Props interfaces at top of file
49
- - Hooks (useState, useEffect, useContext)
50
- - Custom hooks for reusable logic
51
-
52
- ### TypeScript
53
- - Define interfaces for component props
54
- - Use `React.FC<Props>` for component type
55
- - Strict null checks enabled
56
- - Export types alongside components
57
-
58
- ### State Management
59
- - Local state with `useState` for component-only state
60
- - Context API for shared state
61
- - Consider Redux/Zustand for complex state
62
- - Avoid prop drilling (use Context instead)
63
-
64
- ### Performance
65
- - Memoize expensive components with `React.memo`
66
- - Use `useCallback` for stable function references
67
- - Use `useMemo` for expensive computations
68
- - Lazy load routes with `React.lazy`
69
-
70
- ### Styling
71
- - TailwindCSS for utility-first styling
72
- - CSS modules for scoped styles
73
- - Avoid inline styles except for dynamic values
74
- - Use design tokens for consistency
75
-
76
- ## Usage
77
-
78
- 1. Read the relevant sub-directory README for your task
79
- 2. Check code examples for reference implementations
80
- 3. Follow patterns in new components
81
- 4. Update patterns if you discover improvements
82
-
83
- ## Contributing
84
-
85
- Found a better pattern?
86
-
87
- 1. Document it with examples
88
- 2. Add to appropriate subdirectory
89
- 3. Update this README
90
- 4. Commit with message: `docs: add [pattern name] pattern`
91
- 5. Update triggers in `patterns/index.md` if widely applicable
92
-
93
- ## Links
94
-
95
- - [React Component Patterns](react/README.md)
96
- - [Styling Strategies](styling/README.md)
97
- - [Component Libraries](component-libs/README.md)
98
- - [Accessibility Patterns](accessibility/README.md)
99
-
100
- ## Version
101
-
102
- **Last Updated:** (Set on template injection)
103
- **Maintained By:** Development Team
@@ -1,141 +0,0 @@
1
- # Universal Patterns
2
-
3
- This directory contains cross-cutting patterns that apply to both frontend and backend development.
4
-
5
- ## Overview
6
-
7
- Universal patterns cover:
8
- - TypeScript best practices
9
- - Testing strategies (unit, integration, e2e)
10
- - Error handling and logging
11
- - Git workflow and commit conventions
12
- - Build tool configuration
13
- - Code organization
14
- - Documentation standards
15
- - Performance profiling
16
- - Security principles
17
-
18
- ## Structure
19
-
20
- ```
21
- universal/
22
- ├── README.md # This file
23
- ├── typescript/ # TypeScript patterns
24
- │ └── README.md # Type definitions, generics, etc.
25
- ├── testing/ # Testing patterns
26
- │ ├── unit/README.md # Unit test patterns
27
- │ ├── integration/README.md # Integration test patterns
28
- │ └── e2e/README.md # End-to-end test patterns
29
- ├── error-handling/ # Error handling patterns
30
- │ └── README.md # Exception handling, logging
31
- ├── git/ # Git workflow patterns
32
- │ └── README.md # Branching, commits, PRs
33
- ├── build-tools/ # Build and package patterns
34
- │ └── README.md # Webpack, Vite, etc.
35
- ├── performance/ # Performance optimization
36
- │ └── README.md # Profiling, optimization
37
- └── security/ # Security patterns
38
- └── README.md # Input validation, secrets, etc.
39
- ```
40
-
41
- ## Auto-Apply Triggers
42
-
43
- These patterns are automatically loaded when:
44
-
45
- - **File:** `*.ts`, `*.tsx` (TypeScript)
46
- - **File:** `*.test.ts`, `*.spec.ts` (Tests)
47
- - **Import:** `from 'jest'`, `from 'vitest'` (Testing)
48
- - **Command:** `git commit`, `npm build` (Git, Build)
49
- - **Path:** `src/__tests__/`, `cypress/`, `playwright/`
50
-
51
- See `patterns/index.md` for trigger configuration.
52
-
53
- ## Common Patterns
54
-
55
- ### TypeScript
56
- - Enable strict mode in `tsconfig.json`
57
- - Use interfaces for object shapes, types for aliases
58
- - Avoid `any` - use `unknown` with type guards instead
59
- - Export types alongside implementations
60
- - Use generics for reusable, type-safe code
61
- - Document complex types with JSDoc comments
62
-
63
- ### Testing Strategy
64
- - Unit tests for utilities and pure functions
65
- - Integration tests for API endpoints and workflows
66
- - E2E tests for critical user journeys
67
- - Test file co-located with source: `feature.ts` + `feature.test.ts`
68
- - Aim for >80% code coverage on critical paths
69
- - Mock external dependencies, test real business logic
70
-
71
- ### Error Handling
72
- - Use custom error classes that extend Error
73
- - Include error context (what, why, how to fix)
74
- - Log errors with full stack traces
75
- - Different handling strategies for different error types
76
- - Never silently catch and ignore errors
77
- - Provide user-friendly error messages
78
-
79
- ### Git Workflow
80
- - Descriptive commit messages (50 char subject, blank line, details)
81
- - Atomic commits (one logical change per commit)
82
- - Branch naming: `feature/name`, `fix/name`, `docs/name`
83
- - Pull request template with context
84
- - Code review before merge
85
- - Squash or rebase to keep history clean
86
-
87
- ### Build Tools
88
- - Consistent build configuration across projects
89
- - Separate dev and production builds
90
- - Fast development build (hot reload, source maps)
91
- - Optimized production build (minification, tree-shaking)
92
- - Automate with npm/pnpm scripts
93
- - Cache dependencies to speed up builds
94
-
95
- ### Code Organization
96
- - Organize by feature, not by type
97
- - Keep related code together
98
- - Use barrel exports (`index.ts`) for clean imports
99
- - Avoid circular dependencies
100
- - Monorepo structure for related packages
101
- - Clear separation of concerns
102
-
103
- ### Documentation
104
- - JSDoc comments for public APIs
105
- - README files in each directory explaining purpose
106
- - Architecture decision records (ADRs)
107
- - Code examples for complex logic
108
- - Keep docs in sync with code
109
- - Link to external references where relevant
110
-
111
- ## Usage
112
-
113
- 1. Read the relevant sub-directory README for your task
114
- 2. Check code examples for reference implementations
115
- 3. Apply patterns to new code
116
- 4. Update patterns if you discover improvements
117
-
118
- ## Contributing
119
-
120
- Found a better pattern?
121
-
122
- 1. Document it with examples
123
- 2. Add to appropriate subdirectory
124
- 3. Update this README
125
- 4. Commit with message: `docs: add [pattern name] pattern`
126
- 5. Update triggers in `patterns/index.md` if widely applicable
127
-
128
- ## Links
129
-
130
- - [TypeScript Patterns](typescript/README.md)
131
- - [Testing Strategies](testing/README.md)
132
- - [Error Handling](error-handling/README.md)
133
- - [Git Workflow](git/README.md)
134
- - [Build Tools](build-tools/README.md)
135
- - [Performance Profiling](performance/README.md)
136
- - [Security Principles](security/README.md)
137
-
138
- ## Version
139
-
140
- **Last Updated:** (Set on template injection)
141
- **Maintained By:** Development Team