class-ai-agent 1.2.3 → 1.3.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.
- package/.agent/README.md +33 -0
- package/.agent/SESSION.md +54 -0
- package/.agent/SESSION.template.md +46 -0
- package/.claude/CLAUDE.md +21 -6
- package/.claude/commands/build.md +5 -4
- package/.claude/commands/debug.md +2 -1
- package/.claude/commands/handoff.md +94 -0
- package/.claude/commands/plan.md +1 -0
- package/.claude/commands/publish-npm.md +119 -0
- package/.claude/commands/resume.md +107 -0
- package/.claude/commands/spec.md +2 -1
- package/.claude/references/agent-continuity.md +42 -0
- package/.claude/references/codegraph.md +50 -0
- package/.claude/rules/agent-continuity.md +39 -0
- package/.claude/skills/agent-continuity/SKILL.md +70 -0
- package/.cursor/CURSOR.md +37 -5
- package/.cursor/commands/build.md +5 -4
- package/.cursor/commands/debug.md +2 -1
- package/.cursor/commands/handoff.md +94 -0
- package/.cursor/commands/plan.md +1 -0
- package/.cursor/commands/publish-npm.md +119 -0
- package/.cursor/commands/resume.md +107 -0
- package/.cursor/commands/spec.md +2 -1
- package/.cursor/mcp.json +15 -0
- package/.cursor/references/agent-continuity.md +42 -0
- package/.cursor/references/codegraph.md +87 -0
- package/.cursor/rules/agent-continuity.mdc +44 -0
- package/.cursor/rules/codegraph.mdc +47 -0
- package/.cursor/rules/cursor-overview.mdc +10 -3
- package/.cursor/skills/agent-continuity/SKILL.md +70 -0
- package/.kiro/KIRO.md +146 -0
- package/.kiro/agents/backend.md +395 -0
- package/.kiro/agents/code-reviewer.md +110 -0
- package/.kiro/agents/copywriter-seo.md +236 -0
- package/.kiro/agents/frontend.md +384 -0
- package/.kiro/agents/project-manager.md +201 -0
- package/.kiro/agents/qa.md +221 -0
- package/.kiro/agents/security-auditor.md +143 -0
- package/.kiro/agents/systems-architect.md +211 -0
- package/.kiro/agents/test-engineer.md +123 -0
- package/.kiro/agents/ui-ux-designer.md +210 -0
- package/.kiro/commands/build.md +133 -0
- package/.kiro/commands/debug.md +243 -0
- package/.kiro/commands/deploy.md +40 -0
- package/.kiro/commands/fix-issue.md +42 -0
- package/.kiro/commands/handoff.md +94 -0
- package/.kiro/commands/plan.md +126 -0
- package/.kiro/commands/publish-npm.md +119 -0
- package/.kiro/commands/resume.md +107 -0
- package/.kiro/commands/review.md +50 -0
- package/.kiro/commands/simplify.md +222 -0
- package/.kiro/commands/spec.md +96 -0
- package/.kiro/commands/test.md +214 -0
- package/.kiro/references/accessibility-checklist.md +174 -0
- package/.kiro/references/agent-continuity.md +42 -0
- package/.kiro/references/codegraph.md +86 -0
- package/.kiro/references/performance-checklist.md +150 -0
- package/.kiro/references/security-checklist.md +94 -0
- package/.kiro/references/testing-patterns.md +183 -0
- package/.kiro/settings/mcp.json +15 -0
- package/.kiro/settings.json +8 -0
- package/.kiro/skills/agent-continuity/SKILL.md +70 -0
- package/.kiro/skills/code-review/SKILL.md +208 -0
- package/.kiro/skills/deploy/SKILL.md +68 -0
- package/.kiro/skills/deploy/deploy.md +735 -0
- package/.kiro/skills/incremental-implementation/SKILL.md +210 -0
- package/.kiro/skills/security-review/SKILL.md +71 -0
- package/.kiro/skills/tdd/SKILL.md +217 -0
- package/.kiro/skills/ui-ux-pro-max/SKILL.md +288 -0
- package/.kiro/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.kiro/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.kiro/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/.kiro/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.kiro/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.kiro/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.kiro/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/.kiro/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.kiro/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.kiro/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.kiro/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/search.py +114 -0
- package/.kiro/steering/agent-continuity.md +44 -0
- package/.kiro/steering/api-conventions.md +85 -0
- package/.kiro/steering/clean-code.md +211 -0
- package/.kiro/steering/code-style.md +92 -0
- package/.kiro/steering/codegraph.md +47 -0
- package/.kiro/steering/database.md +66 -0
- package/.kiro/steering/error-handling.md +98 -0
- package/.kiro/steering/git-workflow.md +83 -0
- package/.kiro/steering/kiro-overview.md +38 -0
- package/.kiro/steering/monitoring.md +317 -0
- package/.kiro/steering/naming-conventions.md +266 -0
- package/.kiro/steering/project-structure.md +71 -0
- package/.kiro/steering/security.md +95 -0
- package/.kiro/steering/system-design.md +168 -0
- package/.kiro/steering/tech-stack.md +462 -0
- package/.kiro/steering/testing.md +110 -0
- package/AGENTS.md +13 -7
- package/README.md +122 -18
- package/bin/class-ai-agent.cjs +165 -11
- package/package.json +10 -4
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
UI/UX Pro Max Search - BM25 search engine for UI/UX style guides
|
|
5
|
+
Usage: python search.py "<query>" [--domain <domain>] [--stack <stack>] [--max-results 3]
|
|
6
|
+
python search.py "<query>" --design-system [-p "Project Name"]
|
|
7
|
+
python search.py "<query>" --design-system --persist [-p "Project Name"] [--page "dashboard"]
|
|
8
|
+
|
|
9
|
+
Domains: style, prompt, color, chart, landing, product, ux, typography
|
|
10
|
+
Stacks: html-tailwind, react, nextjs
|
|
11
|
+
|
|
12
|
+
Persistence (Master + Overrides pattern):
|
|
13
|
+
--persist Save design system to design-system/MASTER.md
|
|
14
|
+
--page Also create a page-specific override file in design-system/pages/
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import sys
|
|
19
|
+
import io
|
|
20
|
+
from core import CSV_CONFIG, AVAILABLE_STACKS, MAX_RESULTS, search, search_stack
|
|
21
|
+
from design_system import generate_design_system, persist_design_system
|
|
22
|
+
|
|
23
|
+
# Force UTF-8 for stdout/stderr to handle emojis on Windows (cp1252 default)
|
|
24
|
+
if sys.stdout.encoding and sys.stdout.encoding.lower() != 'utf-8':
|
|
25
|
+
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
|
26
|
+
if sys.stderr.encoding and sys.stderr.encoding.lower() != 'utf-8':
|
|
27
|
+
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def format_output(result):
|
|
31
|
+
"""Format results for Claude consumption (token-optimized)"""
|
|
32
|
+
if "error" in result:
|
|
33
|
+
return f"Error: {result['error']}"
|
|
34
|
+
|
|
35
|
+
output = []
|
|
36
|
+
if result.get("stack"):
|
|
37
|
+
output.append(f"## UI Pro Max Stack Guidelines")
|
|
38
|
+
output.append(f"**Stack:** {result['stack']} | **Query:** {result['query']}")
|
|
39
|
+
else:
|
|
40
|
+
output.append(f"## UI Pro Max Search Results")
|
|
41
|
+
output.append(f"**Domain:** {result['domain']} | **Query:** {result['query']}")
|
|
42
|
+
output.append(f"**Source:** {result['file']} | **Found:** {result['count']} results\n")
|
|
43
|
+
|
|
44
|
+
for i, row in enumerate(result['results'], 1):
|
|
45
|
+
output.append(f"### Result {i}")
|
|
46
|
+
for key, value in row.items():
|
|
47
|
+
value_str = str(value)
|
|
48
|
+
if len(value_str) > 300:
|
|
49
|
+
value_str = value_str[:300] + "..."
|
|
50
|
+
output.append(f"- **{key}:** {value_str}")
|
|
51
|
+
output.append("")
|
|
52
|
+
|
|
53
|
+
return "\n".join(output)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
if __name__ == "__main__":
|
|
57
|
+
parser = argparse.ArgumentParser(description="UI Pro Max Search")
|
|
58
|
+
parser.add_argument("query", help="Search query")
|
|
59
|
+
parser.add_argument("--domain", "-d", choices=list(CSV_CONFIG.keys()), help="Search domain")
|
|
60
|
+
parser.add_argument("--stack", "-s", choices=AVAILABLE_STACKS, help="Stack-specific search (html-tailwind, react, nextjs)")
|
|
61
|
+
parser.add_argument("--max-results", "-n", type=int, default=MAX_RESULTS, help="Max results (default: 3)")
|
|
62
|
+
parser.add_argument("--json", action="store_true", help="Output as JSON")
|
|
63
|
+
# Design system generation
|
|
64
|
+
parser.add_argument("--design-system", "-ds", action="store_true", help="Generate complete design system recommendation")
|
|
65
|
+
parser.add_argument("--project-name", "-p", type=str, default=None, help="Project name for design system output")
|
|
66
|
+
parser.add_argument("--format", "-f", choices=["ascii", "markdown"], default="ascii", help="Output format for design system")
|
|
67
|
+
# Persistence (Master + Overrides pattern)
|
|
68
|
+
parser.add_argument("--persist", action="store_true", help="Save design system to design-system/MASTER.md (creates hierarchical structure)")
|
|
69
|
+
parser.add_argument("--page", type=str, default=None, help="Create page-specific override file in design-system/pages/")
|
|
70
|
+
parser.add_argument("--output-dir", "-o", type=str, default=None, help="Output directory for persisted files (default: current directory)")
|
|
71
|
+
|
|
72
|
+
args = parser.parse_args()
|
|
73
|
+
|
|
74
|
+
# Design system takes priority
|
|
75
|
+
if args.design_system:
|
|
76
|
+
result = generate_design_system(
|
|
77
|
+
args.query,
|
|
78
|
+
args.project_name,
|
|
79
|
+
args.format,
|
|
80
|
+
persist=args.persist,
|
|
81
|
+
page=args.page,
|
|
82
|
+
output_dir=args.output_dir
|
|
83
|
+
)
|
|
84
|
+
print(result)
|
|
85
|
+
|
|
86
|
+
# Print persistence confirmation
|
|
87
|
+
if args.persist:
|
|
88
|
+
project_slug = args.project_name.lower().replace(' ', '-') if args.project_name else "default"
|
|
89
|
+
print("\n" + "=" * 60)
|
|
90
|
+
print(f"✅ Design system persisted to design-system/{project_slug}/")
|
|
91
|
+
print(f" 📄 design-system/{project_slug}/MASTER.md (Global Source of Truth)")
|
|
92
|
+
if args.page:
|
|
93
|
+
page_filename = args.page.lower().replace(' ', '-')
|
|
94
|
+
print(f" 📄 design-system/{project_slug}/pages/{page_filename}.md (Page Overrides)")
|
|
95
|
+
print("")
|
|
96
|
+
print(f"📖 Usage: When building a page, check design-system/{project_slug}/pages/[page].md first.")
|
|
97
|
+
print(f" If exists, its rules override MASTER.md. Otherwise, use MASTER.md.")
|
|
98
|
+
print("=" * 60)
|
|
99
|
+
# Stack search
|
|
100
|
+
elif args.stack:
|
|
101
|
+
result = search_stack(args.query, args.stack, args.max_results)
|
|
102
|
+
if args.json:
|
|
103
|
+
import json
|
|
104
|
+
print(json.dumps(result, indent=2, ensure_ascii=False))
|
|
105
|
+
else:
|
|
106
|
+
print(format_output(result))
|
|
107
|
+
# Domain search
|
|
108
|
+
else:
|
|
109
|
+
result = search(args.query, args.domain, args.max_results)
|
|
110
|
+
if args.json:
|
|
111
|
+
import json
|
|
112
|
+
print(json.dumps(result, indent=2, ensure_ascii=False))
|
|
113
|
+
else:
|
|
114
|
+
print(format_output(result))
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
inclusion: always
|
|
3
|
+
description: "Agent session continuity — cross-tool handoff via .agent/SESSION.md"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent continuity
|
|
7
|
+
|
|
8
|
+
Cross-tool handoff lives in **`.agent/SESSION.md`** (committed). Cursor, Claude Code, and Kiro agents share this file.
|
|
9
|
+
|
|
10
|
+
## Session start
|
|
11
|
+
|
|
12
|
+
1. If **`.agent/SESSION.md`** exists, read it **before** planning or editing code.
|
|
13
|
+
2. When the user says **continue**, **resume**, or **pick up**, use **`.kiro/commands/resume.md`** (or equivalent in `.claude/` / `.kiro/`).
|
|
14
|
+
3. Then read **`tasks/todo.md`** and linked **SPEC** paths from SESSION **Pointers**.
|
|
15
|
+
|
|
16
|
+
**Do not** call `codegraph_context` with `query` / `limit` for session resume — that tool requires **`task`** and is for code symbols, not handoff state. For continuity, **Read** `.agent/SESSION.md` (and `tasks/todo.md`); use `codegraph_context` only when you need structural code context for the work described in SESSION.
|
|
17
|
+
|
|
18
|
+
## Session end and phase changes
|
|
19
|
+
|
|
20
|
+
1. Update **`.agent/SESSION.md`** before ending a session or switching tools — use **`.kiro/commands/handoff.md`** when possible.
|
|
21
|
+
2. Keep **Done**, **In progress**, and **Next** accurate; do not leave stale **In progress** items.
|
|
22
|
+
3. Sync **`tasks/todo.md`** checkboxes when tasks change.
|
|
23
|
+
|
|
24
|
+
## Security (SESSION.md)
|
|
25
|
+
|
|
26
|
+
**Never** store in `.agent/SESSION.md`:
|
|
27
|
+
|
|
28
|
+
- API keys, passwords, tokens, credentials
|
|
29
|
+
- PII or customer data
|
|
30
|
+
|
|
31
|
+
Use issue links, commit SHAs, and file paths instead.
|
|
32
|
+
|
|
33
|
+
## Workflow integration
|
|
34
|
+
|
|
35
|
+
| Phase | SESSION `phase` value |
|
|
36
|
+
|-------|------------------------|
|
|
37
|
+
| Spec | `spec` |
|
|
38
|
+
| Plan | `plan` |
|
|
39
|
+
| Build | `build` |
|
|
40
|
+
| Test | `test` |
|
|
41
|
+
| Review | `review` |
|
|
42
|
+
| Debug | `debug` |
|
|
43
|
+
|
|
44
|
+
Set **Meta → Tool** to `cursor`, `claude`, or `kiro` as appropriate.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
inclusion: fileMatch
|
|
3
|
+
fileMatchPattern: "**/*.{ts,tsx,js,jsx,mjs,cjs,json,md,prisma,yml,yaml}"
|
|
4
|
+
description: "API Conventions"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# API Conventions
|
|
8
|
+
|
|
9
|
+
## REST API Design Standards
|
|
10
|
+
|
|
11
|
+
### URL Structure
|
|
12
|
+
- Use **kebab-case** for URL paths: `/api/user-profiles`
|
|
13
|
+
- Use **plural nouns** for resource collections: `/api/users`, `/api/products`
|
|
14
|
+
- Nest related resources: `/api/users/:id/orders`
|
|
15
|
+
- API version prefix: `/api/v1/...`
|
|
16
|
+
|
|
17
|
+
### HTTP Methods
|
|
18
|
+
| Method | Usage |
|
|
19
|
+
|--------|-------|
|
|
20
|
+
| GET | Read resources (idempotent) |
|
|
21
|
+
| POST | Create new resource |
|
|
22
|
+
| PUT | Replace entire resource |
|
|
23
|
+
| PATCH | Partial update |
|
|
24
|
+
| DELETE | Remove resource |
|
|
25
|
+
|
|
26
|
+
### HTTP Status Codes
|
|
27
|
+
| Code | Meaning |
|
|
28
|
+
|------|---------|
|
|
29
|
+
| 200 | OK — Successful GET/PUT/PATCH |
|
|
30
|
+
| 201 | Created — Successful POST |
|
|
31
|
+
| 204 | No Content — Successful DELETE |
|
|
32
|
+
| 400 | Bad Request — Invalid input |
|
|
33
|
+
| 401 | Unauthorized — Not authenticated |
|
|
34
|
+
| 403 | Forbidden — No permission |
|
|
35
|
+
| 404 | Not Found |
|
|
36
|
+
| 409 | Conflict |
|
|
37
|
+
| 422 | Unprocessable Entity — Validation failed |
|
|
38
|
+
| 500 | Internal Server Error |
|
|
39
|
+
|
|
40
|
+
### Request/Response Format
|
|
41
|
+
```json
|
|
42
|
+
// Success response
|
|
43
|
+
{
|
|
44
|
+
"success": true,
|
|
45
|
+
"data": { ... },
|
|
46
|
+
"message": "Optional message"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Error response
|
|
50
|
+
{
|
|
51
|
+
"success": false,
|
|
52
|
+
"error": {
|
|
53
|
+
"code": "VALIDATION_ERROR",
|
|
54
|
+
"message": "Human readable message",
|
|
55
|
+
"details": [ ... ]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Paginated list response
|
|
60
|
+
{
|
|
61
|
+
"success": true,
|
|
62
|
+
"data": [ ... ],
|
|
63
|
+
"pagination": {
|
|
64
|
+
"page": 1,
|
|
65
|
+
"limit": 20,
|
|
66
|
+
"total": 100,
|
|
67
|
+
"totalPages": 5
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Naming Conventions
|
|
73
|
+
- Request/response body fields: **camelCase**
|
|
74
|
+
- Query parameters: **camelCase**
|
|
75
|
+
- Always return consistent field names
|
|
76
|
+
|
|
77
|
+
### Filtering & Pagination
|
|
78
|
+
```
|
|
79
|
+
GET /api/users?page=1&limit=20&sortBy=createdAt&order=desc
|
|
80
|
+
GET /api/products?category=electronics&minPrice=100
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Documentation
|
|
84
|
+
- Every endpoint MUST have JSDoc/Swagger annotations
|
|
85
|
+
- Include request body schema, response schema, and error codes
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
inclusion: fileMatch
|
|
3
|
+
fileMatchPattern: "**/*.{ts,tsx,js,jsx,mjs,cjs,json,md,prisma,yml,yaml}"
|
|
4
|
+
description: "Clean Code — JavaScript Rules"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Clean Code — JavaScript Rules
|
|
8
|
+
> Source: [clean-code-javascript](https://github.com/ryanmcdermott/clean-code-javascript) by Ryan McDermott
|
|
9
|
+
|
|
10
|
+
## 📦 Variables
|
|
11
|
+
|
|
12
|
+
### ✅ Use meaningful, pronounceable names
|
|
13
|
+
```js
|
|
14
|
+
// ❌ Bad
|
|
15
|
+
const yyyymmdstr = moment().format('YYYY/MM/DD');
|
|
16
|
+
|
|
17
|
+
// ✅ Good
|
|
18
|
+
const currentDate = moment().format('YYYY/MM/DD');
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### ✅ Same vocabulary for same type
|
|
22
|
+
```js
|
|
23
|
+
// ❌ getUserInfo(), getClientData(), getCustomerRecord()
|
|
24
|
+
// ✅ getUser()
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### ✅ Use searchable names (no magic numbers)
|
|
28
|
+
```js
|
|
29
|
+
// ❌ setTimeout(blastOff, 86400000);
|
|
30
|
+
const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000;
|
|
31
|
+
setTimeout(blastOff, MILLISECONDS_PER_DAY); // ✅
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### ✅ Use explanatory variables
|
|
35
|
+
```js
|
|
36
|
+
// ❌ Bad
|
|
37
|
+
saveCityZipCode(address.match(regex)[1], address.match(regex)[2]);
|
|
38
|
+
|
|
39
|
+
// ✅ Good
|
|
40
|
+
const [_, city, zipCode] = address.match(cityZipCodeRegex) || [];
|
|
41
|
+
saveCityZipCode(city, zipCode);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### ✅ Avoid mental mapping — be explicit
|
|
45
|
+
```js
|
|
46
|
+
// ❌ locations.forEach(l => { dispatch(l); });
|
|
47
|
+
// ✅ locations.forEach(location => { dispatch(location); });
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### ✅ Don't add redundant context
|
|
51
|
+
```js
|
|
52
|
+
// ❌ const Car = { carMake, carModel, carColor }
|
|
53
|
+
// ✅ const Car = { make, model, color }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### ✅ Use default parameters
|
|
57
|
+
```js
|
|
58
|
+
// ❌ const name = name || 'Default';
|
|
59
|
+
// ✅ function create(name = 'Default') {}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 🔧 Functions
|
|
65
|
+
|
|
66
|
+
### ✅ 2 arguments or fewer — use object destructuring for more
|
|
67
|
+
```js
|
|
68
|
+
// ❌ function createMenu(title, body, buttonText, cancellable) {}
|
|
69
|
+
// ✅ function createMenu({ title, body, buttonText, cancellable }) {}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### ✅ Functions should do ONE thing
|
|
73
|
+
```js
|
|
74
|
+
// ❌ emailClients() — fetches DB + checks active + sends email
|
|
75
|
+
// ✅ emailActiveClients() calls isActiveClient() separately
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### ✅ Function names should say what they do
|
|
79
|
+
```js
|
|
80
|
+
// ❌ addToDate(date, 1) → unclear what is added
|
|
81
|
+
// ✅ addMonthToDate(1, date) → crystal clear
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### ✅ One level of abstraction per function
|
|
85
|
+
```js
|
|
86
|
+
// ❌ parseBetterJSAlternative() — tokenizes + parses + AST walks in one function
|
|
87
|
+
// ✅ parseBetterJSAlternative() → calls tokenize() → calls parse()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### ✅ Remove duplicate code — extract shared logic
|
|
91
|
+
### ✅ No flag parameters — split into separate functions
|
|
92
|
+
```js
|
|
93
|
+
// ❌ function createFile(name, isTemp) { if (isTemp) ... }
|
|
94
|
+
// ✅ function createFile(name) {}
|
|
95
|
+
// function createTempFile(name) {}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### ✅ Avoid Side Effects
|
|
99
|
+
- Don't mutate global state
|
|
100
|
+
- Don't mutate function arguments (use copies)
|
|
101
|
+
```js
|
|
102
|
+
// ✅ Return new array instead of mutating
|
|
103
|
+
function addItemToCart(cart, item) {
|
|
104
|
+
return [...cart, { item, date: Date.now() }];
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### ✅ Favor functional programming
|
|
109
|
+
```js
|
|
110
|
+
// ❌ for loop with mutations
|
|
111
|
+
// ✅ filter(), map(), reduce()
|
|
112
|
+
const totalOutput = programmerOutput
|
|
113
|
+
.filter(p => p.linesOfCode > 0)
|
|
114
|
+
.reduce((acc, p) => acc + p.linesOfCode, 0);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### ✅ Encapsulate conditionals
|
|
118
|
+
```js
|
|
119
|
+
// ❌ if (fsm.state === 'fetching' && isEmpty(listNode)) {}
|
|
120
|
+
// ✅ if (shouldShowSpinner(fsmInstance, listNodeInstance)) {}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### ✅ Avoid negative conditionals
|
|
124
|
+
```js
|
|
125
|
+
// ❌ if (!isNotDOMNodePresent(node)) {}
|
|
126
|
+
// ✅ if (isDOMNodePresent(node)) {}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### ✅ Remove dead code immediately
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 🏛️ Classes
|
|
134
|
+
|
|
135
|
+
### ✅ Prefer ES6 classes
|
|
136
|
+
### ✅ Use method chaining (builder pattern)
|
|
137
|
+
```js
|
|
138
|
+
class QueryBuilder {
|
|
139
|
+
select(fields) { this.fields = fields; return this; }
|
|
140
|
+
from(table) { this.table = table; return this; }
|
|
141
|
+
build() { return `SELECT ${this.fields} FROM ${this.table}`; }
|
|
142
|
+
}
|
|
143
|
+
new QueryBuilder().select('*').from('users').build();
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### ✅ Prefer composition over inheritance
|
|
147
|
+
> "Favor has-a over is-a"
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 🧱 SOLID Principles
|
|
152
|
+
|
|
153
|
+
| Principle | Rule |
|
|
154
|
+
|-----------|------|
|
|
155
|
+
| **S** — Single Responsibility | One class = one job. Never combine unrelated concerns |
|
|
156
|
+
| **O** — Open/Closed | Open for extension, closed for modification |
|
|
157
|
+
| **L** — Liskov Substitution | Subclasses must be substitutable for their base class |
|
|
158
|
+
| **I** — Interface Segregation | Clients shouldn't depend on interfaces they don't use |
|
|
159
|
+
| **D** — Dependency Inversion | Depend on abstractions, not concretions |
|
|
160
|
+
|
|
161
|
+
```js
|
|
162
|
+
// ✅ D — Dependency Inversion
|
|
163
|
+
class InventoryService {
|
|
164
|
+
constructor(inventoryRequester) { // inject the dependency
|
|
165
|
+
this.inventoryRequester = inventoryRequester;
|
|
166
|
+
}
|
|
167
|
+
requestItems(customer) {
|
|
168
|
+
return this.inventoryRequester.requestItem(customer.purchaseHistory);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## ⚡ Concurrency
|
|
176
|
+
|
|
177
|
+
### ✅ Use Promises over callbacks
|
|
178
|
+
### ✅ Use async/await over Promises
|
|
179
|
+
```js
|
|
180
|
+
// ✅ Clearest form
|
|
181
|
+
async function getCleanCodeArticle() {
|
|
182
|
+
try {
|
|
183
|
+
const response = await request.get(cleanCodeUrl);
|
|
184
|
+
await fs.writeFile('article.html', response);
|
|
185
|
+
} catch (err) {
|
|
186
|
+
console.error(err);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 🗒️ Comments
|
|
194
|
+
|
|
195
|
+
### ✅ Only comment business logic complexity
|
|
196
|
+
### ❌ Never leave commented-out code
|
|
197
|
+
### ❌ No journal comments (use git log instead)
|
|
198
|
+
### ❌ No positional markers (`/////`)
|
|
199
|
+
```js
|
|
200
|
+
// ✅ Good comment — explains WHY
|
|
201
|
+
// We retry 3x because OAuth2 tokens can have clock skew
|
|
202
|
+
const MAX_RETRIES = 3;
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 📐 Formatting
|
|
208
|
+
|
|
209
|
+
- Use consistent capitalization (camelCase for vars/fns, PascalCase for classes, UPPER_SNAKE for constants)
|
|
210
|
+
- Keep callers and callees close in the file
|
|
211
|
+
- Related code should appear together
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
inclusion: fileMatch
|
|
3
|
+
fileMatchPattern: "**/*.{ts,tsx,js,jsx,mjs,cjs,json,md,prisma,yml,yaml}"
|
|
4
|
+
description: "Code Style Guide"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Code Style Guide
|
|
8
|
+
|
|
9
|
+
## General Principles
|
|
10
|
+
- **Clarity over cleverness** — Write code that is easy to read and understand
|
|
11
|
+
- **Consistency** — Follow existing patterns in the codebase
|
|
12
|
+
- **DRY** — Don't Repeat Yourself, but don't over-abstract
|
|
13
|
+
|
|
14
|
+
## JavaScript / TypeScript
|
|
15
|
+
|
|
16
|
+
### Formatting
|
|
17
|
+
- Indentation: **2 spaces** (no tabs)
|
|
18
|
+
- Max line length: **100 characters**
|
|
19
|
+
- Use **single quotes** for strings
|
|
20
|
+
- Always use **semicolons**
|
|
21
|
+
- Trailing commas in multi-line structures
|
|
22
|
+
|
|
23
|
+
### Naming
|
|
24
|
+
```js
|
|
25
|
+
// Variables and functions: camelCase
|
|
26
|
+
const userProfile = {};
|
|
27
|
+
function getUserById(id) {}
|
|
28
|
+
|
|
29
|
+
// Classes and interfaces: PascalCase
|
|
30
|
+
class UserService {}
|
|
31
|
+
interface UserRepository {}
|
|
32
|
+
|
|
33
|
+
// Constants: UPPER_SNAKE_CASE
|
|
34
|
+
const MAX_RETRY_COUNT = 3;
|
|
35
|
+
const API_BASE_URL = 'https://api.example.com';
|
|
36
|
+
|
|
37
|
+
// Files: kebab-case
|
|
38
|
+
// user-service.js, auth-middleware.js
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Functions
|
|
42
|
+
```js
|
|
43
|
+
// ✅ Good — Arrow functions for simple operations
|
|
44
|
+
const double = (x) => x * 2;
|
|
45
|
+
|
|
46
|
+
// ✅ Good — Named functions for complex logic
|
|
47
|
+
function processUserData(user) {
|
|
48
|
+
// ...
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ❌ Avoid — Functions longer than 30 lines (extract helpers)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Async/Await
|
|
55
|
+
```js
|
|
56
|
+
// ✅ Always use async/await over raw promises
|
|
57
|
+
async function fetchUser(id) {
|
|
58
|
+
try {
|
|
59
|
+
const user = await userRepository.findById(id);
|
|
60
|
+
return user;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
throw new AppError('User not found', 404);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ❌ Avoid promise chains
|
|
67
|
+
fetchUser(id).then(...).catch(...);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Imports
|
|
71
|
+
```js
|
|
72
|
+
// Order: 1. Node built-ins, 2. External deps, 3. Internal modules
|
|
73
|
+
import path from 'path';
|
|
74
|
+
import express from 'express';
|
|
75
|
+
import { UserService } from './user-service.js';
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Comments
|
|
79
|
+
```js
|
|
80
|
+
// ✅ Explain WHY, not WHAT
|
|
81
|
+
// We retry 3 times because the external API has transient failures
|
|
82
|
+
const MAX_RETRIES = 3;
|
|
83
|
+
|
|
84
|
+
// ❌ Avoid obvious comments
|
|
85
|
+
// Set x to 5
|
|
86
|
+
const x = 5;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## File Organization
|
|
90
|
+
- One class/service per file
|
|
91
|
+
- Group related files in feature folders
|
|
92
|
+
- Index files for clean imports
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
inclusion: always
|
|
3
|
+
description: "CodeGraph MCP usage guide — when to use which tool"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## CodeGraph
|
|
7
|
+
|
|
8
|
+
This project has a CodeGraph MCP server (`codegraph_*` tools) configured. CodeGraph is a tree-sitter-parsed knowledge graph of every symbol, edge, and file. Reads are sub-millisecond and return structural information grep cannot.
|
|
9
|
+
|
|
10
|
+
### When to prefer codegraph over native search
|
|
11
|
+
|
|
12
|
+
Use codegraph for **structural** questions — what calls what, what would break, where is X defined, what is X's signature. Use native grep/read only for **literal text** queries (string contents, comments, log messages) or after you already have a specific file open.
|
|
13
|
+
|
|
14
|
+
| Question | Tool |
|
|
15
|
+
|---|---|
|
|
16
|
+
| "Where is X defined?" / "Find symbol named X" | `codegraph_search` |
|
|
17
|
+
| "What calls function Y?" | `codegraph_callers` |
|
|
18
|
+
| "What does Y call?" | `codegraph_callees` |
|
|
19
|
+
| "How does X reach/become Y? / trace the flow from X to Y" | `codegraph_trace` (one call = the whole path, incl. callback/React/JSX dynamic hops) |
|
|
20
|
+
| "What would break if I changed Z?" | `codegraph_impact` |
|
|
21
|
+
| "Show me Y's signature / source / docstring" | `codegraph_node` |
|
|
22
|
+
| "Give me focused context for a task/area" | `codegraph_context` |
|
|
23
|
+
| "See several related symbols' source at once" | `codegraph_explore` |
|
|
24
|
+
| "What files exist under path/" | `codegraph_files` |
|
|
25
|
+
| "Is the index healthy?" | `codegraph_status` |
|
|
26
|
+
|
|
27
|
+
### Tool parameters (do not mix)
|
|
28
|
+
|
|
29
|
+
| Tool | Required arg | Optional cap | Wrong args → error |
|
|
30
|
+
|------|--------------|--------------|-------------------|
|
|
31
|
+
| `codegraph_search` | **`query`** (symbol name) | `limit` (default 10) | — |
|
|
32
|
+
| `codegraph_context` | **`task`** (feature/bug description) | `maxNodes` (default 20) | `query` / `limit` → **`task must be a non-empty string`** |
|
|
33
|
+
|
|
34
|
+
`codegraph_context` is for **code structure** around a task — not for loading **`.agent/SESSION.md`** or `/resume` handoff (use **Read** + `.kiro/commands/resume.md`).
|
|
35
|
+
|
|
36
|
+
### Rules of thumb
|
|
37
|
+
|
|
38
|
+
- **Answer directly — don't delegate exploration.** For "how does X work" / architecture questions, answer with 2-3 codegraph calls: `codegraph_context` first, then ONE `codegraph_explore` for the source of the symbols it surfaces. For a specific **flow** ("how does X reach Y") start with `codegraph_trace` from→to — one call returns the whole path with dynamic hops bridged — then ONE `codegraph_explore` for the bodies; don't rebuild the path with `codegraph_search` + `codegraph_callers`. Codegraph IS the pre-built index, so spawning a separate file-reading sub-task/agent — or running a grep + read loop — repeats work codegraph already did and costs more for the same answer.
|
|
39
|
+
- **Trust codegraph results.** They come from a full AST parse. Do NOT re-verify them with grep — that's slower, less accurate, and wastes context.
|
|
40
|
+
- **Don't grep first** when looking up a symbol by name. `codegraph_search` is faster and returns kind + location + signature in one call.
|
|
41
|
+
- **Don't chain `codegraph_search` + `codegraph_node`** when you just want context — `codegraph_context` is one call.
|
|
42
|
+
- **Don't loop `codegraph_node` over many symbols** — one `codegraph_explore` call returns several symbols' source grouped in a single capped call, while each separate node/Read call re-reads the whole context and costs far more.
|
|
43
|
+
- **Index lag — check the staleness banner, don't guess a wait.** When a codegraph response starts with "⚠️ Some files referenced below were edited since the last index sync…", the listed files are pending re-index — Read those specific files for accurate content. Files NOT in that banner are fresh and codegraph is authoritative for them. `codegraph_status` also lists pending files under "Pending sync".
|
|
44
|
+
|
|
45
|
+
### If `.codegraph/` doesn't exist
|
|
46
|
+
|
|
47
|
+
The MCP server returns "not initialized." Ask the user: *"I notice this project doesn't have CodeGraph initialized. Want me to run `codegraph init -i` to build the index?"*
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
inclusion: fileMatch
|
|
3
|
+
fileMatchPattern: "**/*.{ts,tsx,js,jsx,mjs,cjs,json,md,prisma,yml,yaml}"
|
|
4
|
+
description: "doc# Database Rules"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
doc# Database Rules
|
|
8
|
+
|
|
9
|
+
## General Rules
|
|
10
|
+
- **Never** write raw SQL strings directly in business logic
|
|
11
|
+
- Always use an ORM (Prisma/Sequelize/TypeORM) or query builder
|
|
12
|
+
- All database calls must be inside try/catch blocks
|
|
13
|
+
- Use **transactions** for multi-step operations
|
|
14
|
+
|
|
15
|
+
## Connection Management
|
|
16
|
+
```js
|
|
17
|
+
// ✅ Use connection pooling
|
|
18
|
+
const pool = new Pool({ max: 10, idleTimeoutMillis: 30000 });
|
|
19
|
+
|
|
20
|
+
// ❌ Never create a new connection per request
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Query Best Practices
|
|
24
|
+
```js
|
|
25
|
+
// ✅ Select only needed fields
|
|
26
|
+
const user = await db.user.findUnique({
|
|
27
|
+
where: { id },
|
|
28
|
+
select: { id: true, email: true, name: true }
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// ❌ Avoid SELECT *
|
|
32
|
+
const user = await db.user.findUnique({ where: { id } });
|
|
33
|
+
|
|
34
|
+
// ✅ Use pagination for lists
|
|
35
|
+
const users = await db.user.findMany({
|
|
36
|
+
take: limit,
|
|
37
|
+
skip: (page - 1) * limit,
|
|
38
|
+
orderBy: { createdAt: 'desc' }
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Transactions
|
|
43
|
+
```js
|
|
44
|
+
// ✅ Use transactions for atomic operations
|
|
45
|
+
await db.$transaction(async (tx) => {
|
|
46
|
+
const order = await tx.order.create({ data: orderData });
|
|
47
|
+
await tx.inventory.update({ where: { id: productId }, data: { stock: { decrement: 1 } } });
|
|
48
|
+
return order;
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Migrations
|
|
53
|
+
- Always use migration files, never modify the database schema directly
|
|
54
|
+
- Migration files are version-controlled and immutable
|
|
55
|
+
- Run migrations in CI/CD before deploying
|
|
56
|
+
|
|
57
|
+
## Naming Conventions
|
|
58
|
+
- Tables: **snake_case** plural (`user_profiles`, `order_items`)
|
|
59
|
+
- Columns: **snake_case** (`created_at`, `user_id`)
|
|
60
|
+
- Indexes: `idx_[table]_[column]`
|
|
61
|
+
- Foreign keys: `fk_[table]_[referenced_table]`
|
|
62
|
+
|
|
63
|
+
## Security
|
|
64
|
+
- Never log query results containing sensitive data (passwords, tokens)
|
|
65
|
+
- Use parameterized queries — never string concatenation
|
|
66
|
+
- Apply row-level security where applicable
|