prjct-cli 0.15.1 → 0.17.0

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 (57) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/bin/dev.js +0 -1
  3. package/bin/serve.js +19 -20
  4. package/core/agentic/agent-router.ts +79 -14
  5. package/core/agentic/command-executor/command-executor.ts +2 -74
  6. package/core/agentic/services.ts +0 -48
  7. package/core/agentic/template-loader.ts +35 -1
  8. package/core/commands/base.ts +96 -77
  9. package/core/commands/planning.ts +13 -2
  10. package/core/commands/setup.ts +3 -85
  11. package/core/errors.ts +209 -0
  12. package/core/infrastructure/config-manager.ts +22 -5
  13. package/core/infrastructure/setup.ts +5 -50
  14. package/core/storage/storage-manager.ts +42 -6
  15. package/core/utils/logger.ts +19 -12
  16. package/package.json +2 -4
  17. package/templates/agentic/subagent-generation.md +109 -0
  18. package/templates/commands/sync.md +74 -13
  19. package/templates/subagents/domain/backend.md +105 -0
  20. package/templates/subagents/domain/database.md +118 -0
  21. package/templates/subagents/domain/devops.md +148 -0
  22. package/templates/subagents/domain/frontend.md +99 -0
  23. package/templates/subagents/domain/testing.md +169 -0
  24. package/templates/subagents/workflow/prjct-planner.md +158 -0
  25. package/templates/subagents/workflow/prjct-shipper.md +179 -0
  26. package/templates/subagents/workflow/prjct-workflow.md +98 -0
  27. package/bin/generate-views.js +0 -209
  28. package/bin/migrate-to-json.js +0 -742
  29. package/core/agentic/context-filter.ts +0 -365
  30. package/core/agentic/parallel-tools.ts +0 -165
  31. package/core/agentic/response-templates.ts +0 -164
  32. package/core/agentic/semantic-compression.ts +0 -273
  33. package/core/agentic/think-blocks.ts +0 -202
  34. package/core/agentic/validation-rules.ts +0 -313
  35. package/core/domain/agent-matcher.ts +0 -130
  36. package/core/domain/agent-validator.ts +0 -250
  37. package/core/domain/architect-session.ts +0 -315
  38. package/core/domain/product-standards.ts +0 -106
  39. package/core/domain/smart-cache.ts +0 -167
  40. package/core/domain/task-analyzer.ts +0 -296
  41. package/core/infrastructure/legacy-installer-detector/cleanup.ts +0 -216
  42. package/core/infrastructure/legacy-installer-detector/detection.ts +0 -95
  43. package/core/infrastructure/legacy-installer-detector/index.ts +0 -171
  44. package/core/infrastructure/legacy-installer-detector/migration.ts +0 -87
  45. package/core/infrastructure/legacy-installer-detector/types.ts +0 -42
  46. package/core/infrastructure/legacy-installer-detector.ts +0 -7
  47. package/core/infrastructure/migrator/file-operations.ts +0 -125
  48. package/core/infrastructure/migrator/index.ts +0 -288
  49. package/core/infrastructure/migrator/project-scanner.ts +0 -90
  50. package/core/infrastructure/migrator/reports.ts +0 -117
  51. package/core/infrastructure/migrator/types.ts +0 -124
  52. package/core/infrastructure/migrator/validation.ts +0 -94
  53. package/core/infrastructure/migrator/version-migration.ts +0 -117
  54. package/core/infrastructure/migrator.ts +0 -10
  55. package/core/infrastructure/uuid-migration.ts +0 -750
  56. package/templates/commands/migrate-all.md +0 -96
  57. package/templates/commands/migrate.md +0 -140
@@ -2,24 +2,18 @@
2
2
  * Setup Module - Core installation logic
3
3
  *
4
4
  * Executes ALL setup needed for prjct-cli:
5
- * 1. Detect and clean legacy installation (curl-based)
6
- * 2. Install Claude Code CLI if missing
7
- * 3. Sync commands to ~/.claude/commands/p/
8
- * 4. Install global config ~/.claude/CLAUDE.md
9
- * 5. Migrate legacy projects automatically
10
- * 6. Save version in editors-config
5
+ * 1. Install Claude Code CLI if missing
6
+ * 2. Sync commands to ~/.claude/commands/p/
7
+ * 3. Install global config ~/.claude/CLAUDE.md
8
+ * 4. Save version in editors-config
11
9
  *
12
10
  * This module is called from:
13
11
  * - core/index.js (on first CLI use)
14
12
  * - scripts/postinstall.js (if npm scripts are enabled)
15
- *
16
- * @version 0.8.8
17
13
  */
18
14
 
19
15
  import { execSync } from 'child_process'
20
16
  import installer from './command-installer'
21
- import migrator from './migrator'
22
- import legacyDetector from './legacy-installer-detector'
23
17
  import editorsConfig from './editors-config'
24
18
  import { VERSION } from '../utils/version'
25
19
 
@@ -30,13 +24,10 @@ const DIM = '\x1b[2m'
30
24
  const NC = '\x1b[0m'
31
25
 
32
26
  interface SetupResults {
33
- legacyCleaned: boolean
34
- legacyProjectsMigrated: number
35
27
  claudeInstalled: boolean
36
28
  commandsAdded: number
37
29
  commandsUpdated: number
38
30
  configAction: string | null
39
- projectsMigrated: number
40
31
  }
41
32
 
42
33
  /**
@@ -76,21 +67,10 @@ async function installClaudeCode(): Promise<boolean> {
76
67
  */
77
68
  export async function run(): Promise<SetupResults> {
78
69
  const results: SetupResults = {
79
- legacyCleaned: false,
80
- legacyProjectsMigrated: 0,
81
70
  claudeInstalled: false,
82
71
  commandsAdded: 0,
83
72
  commandsUpdated: 0,
84
73
  configAction: null,
85
- projectsMigrated: 0,
86
- }
87
-
88
- // Step 0: Detect and clean legacy curl installation
89
- const needsLegacyCleanup = await legacyDetector.needsCleanup()
90
- if (needsLegacyCleanup) {
91
- const cleanupResult = await legacyDetector.performCleanup({ verbose: true })
92
- results.legacyCleaned = cleanupResult.success
93
- results.legacyProjectsMigrated = cleanupResult.steps.projectsMigrated
94
74
  }
95
75
 
96
76
  // Step 1: Ensure Claude Code CLI is installed
@@ -123,20 +103,9 @@ export async function run(): Promise<SetupResults> {
123
103
  if (configResult.success) {
124
104
  results.configAction = configResult.action
125
105
  }
126
-
127
- // Step 5: Migrate legacy projects automatically
128
- const migrationResult = await migrator.migrateAll({
129
- deepScan: false,
130
- cleanupLegacy: true,
131
- dryRun: false,
132
- })
133
-
134
- if (migrationResult.successfullyMigrated > 0) {
135
- results.projectsMigrated = migrationResult.successfullyMigrated
136
- }
137
106
  }
138
107
 
139
- // Step 6: Save version in editors-config
108
+ // Step 5: Save version in editors-config
140
109
  await editorsConfig.saveConfig(VERSION, installer.getInstallPath())
141
110
 
142
111
  // Show results
@@ -154,16 +123,6 @@ export default { run }
154
123
  function showResults(results: SetupResults): void {
155
124
  console.log('')
156
125
 
157
- // Show what was done
158
- if (results.legacyCleaned) {
159
- console.log(` ${GREEN}✓${NC} Legacy curl installation cleaned up`)
160
- if (results.legacyProjectsMigrated > 0) {
161
- console.log(
162
- ` ${GREEN}✓${NC} ${results.legacyProjectsMigrated} project(s) migrated from legacy`
163
- )
164
- }
165
- }
166
-
167
126
  if (results.claudeInstalled) {
168
127
  console.log(` ${GREEN}✓${NC} Claude Code CLI installed`)
169
128
  } else {
@@ -188,9 +147,5 @@ function showResults(results: SetupResults): void {
188
147
  console.log(` ${GREEN}✓${NC} Global config merged`)
189
148
  }
190
149
 
191
- if (results.projectsMigrated > 0) {
192
- console.log(` ${GREEN}✓${NC} ${results.projectsMigrated} projects migrated to global storage`)
193
- }
194
-
195
150
  console.log('')
196
151
  }
@@ -14,15 +14,44 @@ import path from 'path'
14
14
  import os from 'os'
15
15
  import { eventBus, type SyncEvent } from '../events'
16
16
 
17
+ interface CacheEntry<T> {
18
+ data: T
19
+ timestamp: number
20
+ }
21
+
17
22
  export abstract class StorageManager<T> {
18
23
  protected filename: string
19
- protected cache: Map<string, T> = new Map()
24
+ protected cache: Map<string, CacheEntry<T>> = new Map()
20
25
  protected cacheTimeout = 5000 // 5 seconds
26
+ protected maxCacheSize = 50 // Max projects to cache
21
27
 
22
28
  constructor(filename: string) {
23
29
  this.filename = filename
24
30
  }
25
31
 
32
+ /**
33
+ * Check if cache entry is still valid
34
+ */
35
+ private isCacheValid(entry: CacheEntry<T>): boolean {
36
+ return Date.now() - entry.timestamp < this.cacheTimeout
37
+ }
38
+
39
+ /**
40
+ * Evict oldest entries if cache exceeds max size
41
+ */
42
+ private evictOldEntries(): void {
43
+ if (this.cache.size <= this.maxCacheSize) return
44
+
45
+ // Sort by timestamp and remove oldest
46
+ const entries = Array.from(this.cache.entries())
47
+ .sort((a, b) => a[1].timestamp - b[1].timestamp)
48
+
49
+ const toRemove = entries.slice(0, this.cache.size - this.maxCacheSize)
50
+ for (const [key] of toRemove) {
51
+ this.cache.delete(key)
52
+ }
53
+ }
54
+
26
55
  /**
27
56
  * Get file path for storage JSON
28
57
  */
@@ -73,10 +102,15 @@ export abstract class StorageManager<T> {
73
102
  * Read data from storage
74
103
  */
75
104
  async read(projectId: string): Promise<T> {
76
- // Check cache first
105
+ // Check cache first (with expiration)
77
106
  const cached = this.cache.get(projectId)
107
+ if (cached && this.isCacheValid(cached)) {
108
+ return cached.data
109
+ }
110
+
111
+ // Remove expired entry
78
112
  if (cached) {
79
- return cached
113
+ this.cache.delete(projectId)
80
114
  }
81
115
 
82
116
  const filePath = this.getStoragePath(projectId)
@@ -84,7 +118,8 @@ export abstract class StorageManager<T> {
84
118
  try {
85
119
  const content = await fs.readFile(filePath, 'utf-8')
86
120
  const data = JSON.parse(content) as T
87
- this.cache.set(projectId, data)
121
+ this.cache.set(projectId, { data, timestamp: Date.now() })
122
+ this.evictOldEntries()
88
123
  return data
89
124
  } catch {
90
125
  // Return default if file doesn't exist
@@ -112,8 +147,9 @@ export abstract class StorageManager<T> {
112
147
  const md = this.toMarkdown(data)
113
148
  await fs.writeFile(contextPath, md, 'utf-8')
114
149
 
115
- // 3. Update cache
116
- this.cache.set(projectId, data)
150
+ // 3. Update cache with timestamp
151
+ this.cache.set(projectId, { data, timestamp: Date.now() })
152
+ this.evictOldEntries()
117
153
 
118
154
  // 4. Publish event for backend sync (NOT included in this call - subclass handles)
119
155
  }
@@ -30,21 +30,28 @@ interface Logger {
30
30
 
31
31
  const LEVELS: Record<LogLevel, number> = { error: 0, warn: 1, info: 2, debug: 3 }
32
32
 
33
- const debugEnv = process.env.PRJCT_DEBUG || process.env.DEBUG || ''
34
- const isEnabled = debugEnv === '1' || debugEnv === 'true' || debugEnv.includes('prjct')
35
-
36
- // Determine log level
37
- let currentLevel = -1 // disabled by default
38
- if (isEnabled) {
39
- if (debugEnv === '1' || debugEnv === 'true' || debugEnv === 'prjct') {
40
- currentLevel = LEVELS.debug // all logs
41
- } else if (LEVELS[debugEnv as LogLevel] !== undefined) {
42
- currentLevel = LEVELS[debugEnv as LogLevel]
43
- } else {
44
- currentLevel = LEVELS.debug
33
+ /**
34
+ * Determine log level from environment variables
35
+ * Returns -1 (disabled) or a level from LEVELS
36
+ */
37
+ function getLogLevel(): number {
38
+ const debugEnv = process.env.PRJCT_DEBUG || process.env.DEBUG || ''
39
+
40
+ // Disabled if empty
41
+ if (!debugEnv) return -1
42
+
43
+ // Enable all logs for common truthy values
44
+ if (debugEnv === '1' || debugEnv === 'true' || debugEnv === 'prjct' || debugEnv.includes('prjct')) {
45
+ return LEVELS.debug
45
46
  }
47
+
48
+ // Check for specific level name (error, warn, info, debug)
49
+ const level = LEVELS[debugEnv as LogLevel]
50
+ return level !== undefined ? level : -1
46
51
  }
47
52
 
53
+ const currentLevel = getLogLevel()
54
+
48
55
  // No-op function for disabled logs
49
56
  const noop: LogFunction = () => {}
50
57
 
package/package.json CHANGED
@@ -1,14 +1,12 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "0.15.1",
3
+ "version": "0.17.0",
4
4
  "description": "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
5
5
  "main": "core/index.ts",
6
6
  "bin": {
7
7
  "prjct": "bin/prjct",
8
8
  "prjct-dev": "bin/dev.js",
9
- "prjct-serve": "bin/serve.js",
10
- "prjct-generate-views": "bin/generate-views.js",
11
- "prjct-migrate": "bin/migrate-to-json.js"
9
+ "prjct-serve": "bin/serve.js"
12
10
  },
13
11
  "workspaces": [
14
12
  "packages/*"
@@ -0,0 +1,109 @@
1
+ # Sub-Agent Generation
2
+
3
+ Generate Claude Code sub-agents for this project based on detected stack.
4
+
5
+ ## Input Context
6
+
7
+ You have access to:
8
+ - `{analysis}` - repo-summary.md with detected technologies
9
+ - `{projectPath}` - Path to project root
10
+ - `{projectId}` - Project identifier
11
+
12
+ ## Output Location
13
+
14
+ Write sub-agents to: `{projectPath}/.claude/agents/`
15
+
16
+ ## Sub-Agent Format (Claude Code)
17
+
18
+ ```markdown
19
+ ---
20
+ name: agent-name
21
+ description: When to use this agent. Include "Use PROACTIVELY" for auto-invocation.
22
+ tools: Read, Write, Glob, Grep, Bash
23
+ model: sonnet
24
+ ---
25
+
26
+ Agent system prompt here...
27
+ ```
28
+
29
+ ## Generation Rules
30
+
31
+ ### 1. ALWAYS Generate Workflow Agents
32
+
33
+ These are REQUIRED for every prjct project:
34
+
35
+ #### prjct-workflow.md
36
+ - Commands: /p:now, /p:done, /p:next, /p:pause, /p:resume
37
+ - Tools: Read, Write, Glob
38
+ - Purpose: Task lifecycle management
39
+
40
+ #### prjct-planner.md
41
+ - Commands: /p:feature, /p:idea, /p:spec, /p:bug
42
+ - Tools: Read, Write, Glob, Grep
43
+ - Purpose: Feature planning and breakdown
44
+
45
+ #### prjct-shipper.md
46
+ - Commands: /p:ship
47
+ - Tools: Read, Write, Bash, Glob
48
+ - Purpose: Git operations, testing, deployment
49
+
50
+ ### 2. Generate Domain Agents Based on Stack
51
+
52
+ Analyze `{analysis}` and create ONLY relevant domain agents:
53
+
54
+ | If Detected | Generate | Tools |
55
+ |-------------|----------|-------|
56
+ | React, Vue, Angular, Svelte, CSS, HTML | `frontend.md` | Read, Write, Glob, Grep |
57
+ | Node.js, Express, Go, Python API, REST, GraphQL | `backend.md` | Read, Write, Bash, Glob, Grep |
58
+ | PostgreSQL, MySQL, MongoDB, Redis, Prisma | `database.md` | Read, Write, Bash |
59
+ | Docker, Kubernetes, CI/CD, GitHub Actions | `devops.md` | Read, Bash, Glob |
60
+ | Jest, Pytest, Vitest, Testing Library | `testing.md` | Read, Write, Bash |
61
+
62
+ ### 3. Adapt to Project Context
63
+
64
+ Each generated agent should include:
65
+ - Project-specific paths from analysis
66
+ - Detected frameworks and versions
67
+ - Relevant patterns found in codebase
68
+
69
+ ## Execution Steps
70
+
71
+ 1. **Read Analysis**
72
+ ```
73
+ Read("{projectPath}/.prjct-cli/projects/{projectId}/analysis/repo-summary.md")
74
+ ```
75
+
76
+ 2. **Create Directory**
77
+ ```
78
+ Bash("mkdir -p {projectPath}/.claude/agents")
79
+ ```
80
+
81
+ 3. **Generate Workflow Agents** (always)
82
+ - Read template from `templates/subagents/workflow/prjct-workflow.md`
83
+ - Adapt with project context
84
+ - Write to `{projectPath}/.claude/agents/prjct-workflow.md`
85
+ - Repeat for prjct-planner.md and prjct-shipper.md
86
+
87
+ 4. **Generate Domain Agents** (based on analysis)
88
+ - For each detected technology stack:
89
+ - Read corresponding template from `templates/subagents/domain/`
90
+ - Adapt with project-specific details
91
+ - Write to `{projectPath}/.claude/agents/`
92
+
93
+ 5. **Report Generated Agents**
94
+ ```
95
+ Generated sub-agents in .claude/agents/:
96
+ - prjct-workflow.md (workflow)
97
+ - prjct-planner.md (workflow)
98
+ - prjct-shipper.md (workflow)
99
+ - frontend.md (detected: React)
100
+ - backend.md (detected: Node.js)
101
+ ```
102
+
103
+ ## Critical Rules
104
+
105
+ - NEVER hardcode technology detection in TypeScript
106
+ - ALWAYS read and analyze repo-summary.md
107
+ - ADAPT templates to project context
108
+ - Use Claude Code frontmatter format exactly
109
+ - Include "Use PROACTIVELY" in descriptions for auto-invocation
@@ -336,20 +336,67 @@ WRITE: `{globalPath}/project.json`
336
336
 
337
337
  ---
338
338
 
339
- ## Step 7: Generate Agents (AGENTIC)
340
-
341
- Based on detected stack, generate specialized agents.
342
-
343
- For EACH specialist needed:
344
- ```typescript
345
- const generator = new AgentGenerator('{projectId}')
346
- await generator.generateDynamicAgent('agent-name', {
347
- role: 'specific role',
348
- domain: 'domain',
349
- expertise: 'technologies'
350
- })
339
+ ## Step 7: Generate Claude Code Sub-Agents (AGENTIC)
340
+
341
+ Generate sub-agents for Claude Code in the PROJECT's `.claude/agents/` directory.
342
+
343
+ ### 7.1 Create Directory
344
+
345
+ ```bash
346
+ mkdir -p {cwd}/.claude/agents
351
347
  ```
352
348
 
349
+ ### 7.2 Read Generation Instructions
350
+
351
+ READ: `templates/agentic/subagent-generation.md`
352
+
353
+ This template contains:
354
+ - Which workflow agents to ALWAYS generate
355
+ - Which domain agents to generate based on stack
356
+ - Format and structure requirements
357
+
358
+ ### 7.3 Generate Workflow Agents (ALWAYS)
359
+
360
+ These 3 agents are ALWAYS created for every prjct project:
361
+
362
+ **prjct-workflow.md** - Handles: /p:now, /p:done, /p:next, /p:pause, /p:resume
363
+ READ template: `templates/subagents/workflow/prjct-workflow.md`
364
+ ADAPT with: projectId, projectPath
365
+ WRITE to: `{cwd}/.claude/agents/prjct-workflow.md`
366
+
367
+ **prjct-planner.md** - Handles: /p:feature, /p:idea, /p:spec, /p:bug
368
+ READ template: `templates/subagents/workflow/prjct-planner.md`
369
+ ADAPT with: projectId, projectPath
370
+ WRITE to: `{cwd}/.claude/agents/prjct-planner.md`
371
+
372
+ **prjct-shipper.md** - Handles: /p:ship
373
+ READ template: `templates/subagents/workflow/prjct-shipper.md`
374
+ ADAPT with: projectId, projectPath, detected test/lint commands
375
+ WRITE to: `{cwd}/.claude/agents/prjct-shipper.md`
376
+
377
+ ### 7.4 Generate Domain Agents (Based on Stack)
378
+
379
+ Analyze `{techStack}` from Step 3 and generate ONLY relevant domain agents:
380
+
381
+ | If Detected | Generate | Template |
382
+ |-------------|----------|----------|
383
+ | React, Vue, Angular, Svelte, CSS | `frontend.md` | `templates/subagents/domain/frontend.md` |
384
+ | Node.js, Express, Go, Python API | `backend.md` | `templates/subagents/domain/backend.md` |
385
+ | PostgreSQL, MySQL, MongoDB, Prisma | `database.md` | `templates/subagents/domain/database.md` |
386
+ | Docker, Kubernetes, GitHub Actions | `devops.md` | `templates/subagents/domain/devops.md` |
387
+ | Jest, Pytest, Vitest, testing | `testing.md` | `templates/subagents/domain/testing.md` |
388
+
389
+ For EACH detected stack:
390
+ 1. READ template from `templates/subagents/domain/{name}.md`
391
+ 2. ADAPT description with detected frameworks (e.g., "React specialist" not just "frontend")
392
+ 3. WRITE to `{cwd}/.claude/agents/{name}.md`
393
+
394
+ ### 7.5 Report Generated Agents
395
+
396
+ Track which agents were generated for output:
397
+ - `{workflowAgents}`: Always 3 (prjct-workflow, prjct-planner, prjct-shipper)
398
+ - `{domainAgents}`: List of domain agents generated
399
+
353
400
  ---
354
401
 
355
402
  ## Step 8: Log to Memory
@@ -385,6 +432,10 @@ APPEND to: `{globalPath}/memory/events.jsonl`
385
432
  ├── context/shipped.md
386
433
  └── context/CLAUDE.md
387
434
 
435
+ 🤖 Claude Code Sub-Agents ({workflowAgents.length + domainAgents.length})
436
+ ├── Workflow: prjct-workflow, prjct-planner, prjct-shipper
437
+ └── Domain: {domainAgents.join(', ') || 'none'}
438
+
388
439
  {IF hasUncommittedChanges}
389
440
  ⚠️ You have uncommitted changes
390
441
 
@@ -426,8 +477,18 @@ Next: /p:now to start a new task
426
477
  │ └── shipped.md # Shipped
427
478
  ├── sync/ # Backend Sync
428
479
  │ └── pending.json # Events queue
429
- ├── agents/ # Specialists
480
+ ├── agents/ # Specialists (legacy)
430
481
  ├── memory/ # Audit Trail
431
482
  │ └── events.jsonl
432
483
  └── project.json # Metadata
484
+
485
+ {cwd}/.claude/agents/ # Claude Code Sub-Agents (PER PROJECT)
486
+ ├── prjct-workflow.md # /p:now, /p:done, /p:next
487
+ ├── prjct-planner.md # /p:feature, /p:idea, /p:spec
488
+ ├── prjct-shipper.md # /p:ship
489
+ ├── frontend.md # (if React/Vue/Angular detected)
490
+ ├── backend.md # (if Node/Go/Python API detected)
491
+ ├── database.md # (if DB detected)
492
+ ├── devops.md # (if Docker/K8s detected)
493
+ └── testing.md # (if test framework detected)
433
494
  ```
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: backend
3
+ description: Backend specialist for Node.js, Go, Python, REST APIs, and GraphQL. Use PROACTIVELY when user works on APIs, servers, or backend logic.
4
+ tools: Read, Write, Bash, Glob, Grep
5
+ model: sonnet
6
+ ---
7
+
8
+ You are a backend specialist agent for this project.
9
+
10
+ ## Your Expertise
11
+
12
+ - **Runtimes**: Node.js, Bun, Deno, Go, Python, Rust
13
+ - **Frameworks**: Express, Fastify, Hono, Gin, FastAPI, Axum
14
+ - **APIs**: REST, GraphQL, gRPC, WebSockets
15
+ - **Auth**: JWT, OAuth, Sessions, API Keys
16
+
17
+ ## Project Context
18
+
19
+ When invoked, analyze the project's backend stack:
20
+ 1. Read `package.json`, `go.mod`, `requirements.txt`, or `Cargo.toml`
21
+ 2. Identify framework and patterns
22
+ 3. Check for existing API structure
23
+
24
+ ## Code Patterns
25
+
26
+ ### API Structure
27
+ Follow project's existing patterns. Common patterns:
28
+
29
+ **Express/Fastify:**
30
+ ```typescript
31
+ // Route handler
32
+ export async function getUser(req: Request, res: Response) {
33
+ const { id } = req.params
34
+ const user = await userService.findById(id)
35
+ res.json(user)
36
+ }
37
+ ```
38
+
39
+ **Go (Gin/Chi):**
40
+ ```go
41
+ func GetUser(c *gin.Context) {
42
+ id := c.Param("id")
43
+ user, err := userService.FindByID(id)
44
+ if err != nil {
45
+ c.JSON(500, gin.H{"error": err.Error()})
46
+ return
47
+ }
48
+ c.JSON(200, user)
49
+ }
50
+ ```
51
+
52
+ ### Error Handling
53
+ - Use consistent error format
54
+ - Include error codes
55
+ - Log errors appropriately
56
+ - Never expose internal details to clients
57
+
58
+ ### Validation
59
+ - Validate all inputs
60
+ - Use schema validation (Zod, Joi, etc.)
61
+ - Return meaningful validation errors
62
+
63
+ ## Quality Guidelines
64
+
65
+ 1. **Security**: Validate inputs, sanitize outputs, use parameterized queries
66
+ 2. **Performance**: Use appropriate indexes, cache when needed
67
+ 3. **Reliability**: Handle errors gracefully, implement retries
68
+ 4. **Observability**: Log important events, add metrics
69
+
70
+ ## Common Tasks
71
+
72
+ ### Creating Endpoints
73
+ 1. Check existing route structure
74
+ 2. Follow RESTful conventions
75
+ 3. Add validation middleware
76
+ 4. Include error handling
77
+ 5. Add to route registry/index
78
+
79
+ ### Middleware
80
+ 1. Check existing middleware patterns
81
+ 2. Keep middleware focused (single responsibility)
82
+ 3. Order matters - auth before business logic
83
+
84
+ ### Services
85
+ 1. Keep business logic in services
86
+ 2. Services are testable units
87
+ 3. Inject dependencies
88
+
89
+ ## Output Format
90
+
91
+ When creating/modifying backend code:
92
+ ```
93
+ ✅ {action}: {endpoint/service}
94
+
95
+ Files: {count} | Routes: {affected routes}
96
+ ```
97
+
98
+ ## Critical Rules
99
+
100
+ - NEVER expose sensitive data in responses
101
+ - ALWAYS validate inputs
102
+ - USE parameterized queries (prevent SQL injection)
103
+ - FOLLOW existing error handling patterns
104
+ - LOG errors but don't expose internals
105
+ - CHECK for existing similar endpoints/services
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: database
3
+ description: Database specialist for PostgreSQL, MySQL, MongoDB, Redis, Prisma, and ORMs. Use PROACTIVELY when user works on schemas, migrations, or queries.
4
+ tools: Read, Write, Bash
5
+ model: sonnet
6
+ ---
7
+
8
+ You are a database specialist agent for this project.
9
+
10
+ ## Your Expertise
11
+
12
+ - **SQL**: PostgreSQL, MySQL, SQLite
13
+ - **NoSQL**: MongoDB, Redis, DynamoDB
14
+ - **ORMs**: Prisma, Drizzle, TypeORM, Sequelize, GORM
15
+ - **Migrations**: Schema changes, data migrations
16
+
17
+ ## Project Context
18
+
19
+ When invoked, analyze the project's database setup:
20
+ 1. Check for ORM config (prisma/schema.prisma, drizzle.config.ts)
21
+ 2. Check for migration files
22
+ 3. Identify database type from connection strings/config
23
+
24
+ ## Code Patterns
25
+
26
+ ### Prisma
27
+ ```prisma
28
+ model User {
29
+ id String @id @default(cuid())
30
+ email String @unique
31
+ name String?
32
+ posts Post[]
33
+ createdAt DateTime @default(now())
34
+ updatedAt DateTime @updatedAt
35
+ }
36
+ ```
37
+
38
+ ### Drizzle
39
+ ```typescript
40
+ export const users = pgTable('users', {
41
+ id: serial('id').primaryKey(),
42
+ email: varchar('email', { length: 255 }).notNull().unique(),
43
+ name: varchar('name', { length: 255 }),
44
+ createdAt: timestamp('created_at').defaultNow(),
45
+ })
46
+ ```
47
+
48
+ ### Raw SQL
49
+ ```sql
50
+ CREATE TABLE users (
51
+ id SERIAL PRIMARY KEY,
52
+ email VARCHAR(255) UNIQUE NOT NULL,
53
+ name VARCHAR(255),
54
+ created_at TIMESTAMP DEFAULT NOW()
55
+ );
56
+ ```
57
+
58
+ ## Quality Guidelines
59
+
60
+ 1. **Indexing**: Add indexes for frequently queried columns
61
+ 2. **Normalization**: Avoid data duplication
62
+ 3. **Constraints**: Use foreign keys, unique constraints
63
+ 4. **Naming**: Consistent naming (snake_case for SQL, camelCase for ORM)
64
+
65
+ ## Common Tasks
66
+
67
+ ### Creating Tables/Models
68
+ 1. Check existing schema patterns
69
+ 2. Add appropriate indexes
70
+ 3. Include timestamps (created_at, updated_at)
71
+ 4. Define relationships
72
+
73
+ ### Migrations
74
+ 1. Generate migration with ORM tool
75
+ 2. Review generated SQL
76
+ 3. Test migration on dev first
77
+ 4. Include rollback strategy
78
+
79
+ ### Queries
80
+ 1. Use ORM methods when available
81
+ 2. Parameterize all inputs
82
+ 3. Select only needed columns
83
+ 4. Use pagination for large results
84
+
85
+ ## Migration Commands
86
+
87
+ ```bash
88
+ # Prisma
89
+ npx prisma migrate dev --name {name}
90
+ npx prisma generate
91
+
92
+ # Drizzle
93
+ npx drizzle-kit generate
94
+ npx drizzle-kit migrate
95
+
96
+ # TypeORM
97
+ npx typeorm migration:generate -n {Name}
98
+ npx typeorm migration:run
99
+ ```
100
+
101
+ ## Output Format
102
+
103
+ When creating/modifying database schemas:
104
+ ```
105
+ ✅ {action}: {table/model}
106
+
107
+ Migration: {name} | Indexes: {count}
108
+ Run: {migration command}
109
+ ```
110
+
111
+ ## Critical Rules
112
+
113
+ - NEVER delete columns without data migration plan
114
+ - ALWAYS use parameterized queries
115
+ - ADD indexes for foreign keys
116
+ - BACKUP before destructive migrations
117
+ - TEST migrations on dev first
118
+ - USE transactions for multi-step operations