@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 +3 -1
- package/cli/patterns.js +1 -1
- package/cli/update.js +71 -5
- package/package.json +1 -1
- package/src/core/inject.js +28 -0
- package/src/patterns/registry.js +34 -12
- package/templates/workspace/.ai/patterns/backend/backend.template.md +19 -0
- package/templates/workspace/.ai/patterns/frontend/frontend.template.md +19 -0
- package/templates/workspace/.ai/patterns/index.md +9 -9
- package/templates/workspace/.ai/patterns/universal/universal.template.md +19 -0
- package/templates/workspace/.claude/commands/save.md +142 -0
- package/templates/workspace/.ai/patterns/backend/README.md +0 -126
- package/templates/workspace/.ai/patterns/frontend/README.md +0 -103
- package/templates/workspace/.ai/patterns/universal/README.md +0 -141
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)
|
|
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.
|
|
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/
|
|
17
|
-
'patterns/backend/
|
|
18
|
-
'patterns/universal/
|
|
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)
|
|
253
|
+
console.log(' .ai/state.json (session state)');
|
|
254
|
+
console.log(' .claude/ (your custom commands preserved)\n');
|
|
189
255
|
}
|
package/package.json
CHANGED
package/src/core/inject.js
CHANGED
|
@@ -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')
|
package/src/patterns/registry.js
CHANGED
|
@@ -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
|
|
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(
|
|
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
|
-
*
|
|
113
|
+
* Find the main pattern file in a directory
|
|
114
|
+
* Looks for .md files (excluding .template.md)
|
|
114
115
|
*/
|
|
115
|
-
|
|
116
|
-
if (!existsSync(
|
|
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
|
|
217
|
-
const
|
|
218
|
-
|
|
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 (
|
|
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
|
|
265
|
-
|
|
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(
|
|
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
|
-
-
|
|
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
|
|
224
|
-
**Apply:** React 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/
|
|
231
|
-
**Apply:** Express + REST API patterns
|
|
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
|
|
237
|
-
**Load:** `patterns/universal/testing
|
|
238
|
-
**Apply:**
|
|
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
|