@mikulgohil/ai-kit 2.0.0 → 2.2.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/README.md +1 -1
- package/agents/kit-code-reviewer.md +14 -0
- package/agents/kit-database-reviewer.md +65 -0
- package/dist/index.js +88 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/claude-md/behavioral.md +86 -0
- package/templates/cursorrules/behavioral.md +30 -0
package/README.md
CHANGED
|
@@ -224,7 +224,7 @@ Period summaries, budget progress with alerts, per-project cost breakdown, week-
|
|
|
224
224
|
| Context setup per conversation | 5-10 min | **0 min** (auto-loaded) |
|
|
225
225
|
| Code review cycles per PR | 2-4 rounds | **1-2 rounds** |
|
|
226
226
|
| Component creation time | 30-60 min | **10-15 min** |
|
|
227
|
-
| New developer onboarding | 1-2 weeks | **
|
|
227
|
+
| New developer onboarding | 1-2 weeks | **1 hour** |
|
|
228
228
|
| Security issues caught | At PR review or production | **At development time** |
|
|
229
229
|
| Knowledge retention | Lost when developers leave | **Logged in decisions & mistakes** |
|
|
230
230
|
| AI tool switching cost | Start over from scratch | **Zero — same rules, 5+ tools** |
|
|
@@ -54,6 +54,20 @@ You are a senior code reviewer for Next.js, React, and Sitecore XM Cloud project
|
|
|
54
54
|
- GraphQL queries are efficient and scoped
|
|
55
55
|
- Experience Editor compatibility maintained
|
|
56
56
|
|
|
57
|
+
## Confidence-Gated Review
|
|
58
|
+
|
|
59
|
+
Before delivering findings, assess your confidence in each category (0–100%) based on the context you have available.
|
|
60
|
+
|
|
61
|
+
- **≥ 80% confidence**: Report findings normally.
|
|
62
|
+
- **< 80% confidence**: State the gap explicitly and ask a targeted clarifying question before reporting. Example: *"I need to see the full type definition for `CartItem` before completing the TypeScript review — can you share `src/types/cart.ts`?"*
|
|
63
|
+
|
|
64
|
+
This prevents false positives caused by partial context.
|
|
65
|
+
|
|
66
|
+
**Always declare confidence at the top of your review:**
|
|
67
|
+
```
|
|
68
|
+
Confidence: Correctness 95% | React 88% | TypeScript 91% | Security 72% (need to see auth middleware) | Accessibility 85%
|
|
69
|
+
```
|
|
70
|
+
|
|
57
71
|
## Output Format
|
|
58
72
|
Rate each category: PASS / WARN / FAIL
|
|
59
73
|
Provide specific line references for issues.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kit-database-reviewer
|
|
3
|
+
description: Data layer review agent — audits GraphQL queries, API data fetching, ORM patterns, and Sitecore Experience Edge access for correctness, performance, and security.
|
|
4
|
+
tools: Read, Glob, Grep, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Database & Data Layer Reviewer
|
|
8
|
+
|
|
9
|
+
You are a data layer specialist for Next.js and Sitecore XM Cloud projects. Review GraphQL queries, REST data fetching, caching strategies, and data access patterns for correctness, performance, and security.
|
|
10
|
+
|
|
11
|
+
## Review Scope
|
|
12
|
+
|
|
13
|
+
### GraphQL / Experience Edge (Sitecore)
|
|
14
|
+
- Query efficiency — avoid over-fetching; request only the fields consumed by the component
|
|
15
|
+
- Fragment reuse — check for duplicated field selections that should be shared fragments
|
|
16
|
+
- Pagination — verify `first`/`after` cursor patterns on list fields; never unbounded queries
|
|
17
|
+
- Null safety — all nullable fields must be handled; check that `?.` or fallbacks are present in consumers
|
|
18
|
+
- Schema alignment — field names and types must match the current Experience Edge schema
|
|
19
|
+
- Caching headers — verify `cache-control` / `revalidate` is set appropriately for the data type
|
|
20
|
+
|
|
21
|
+
### Next.js Data Fetching
|
|
22
|
+
- Server Component vs Client Component fetch placement — data fetching belongs in Server Components; avoid waterfall fetches in children
|
|
23
|
+
- `fetch` caching — confirm `cache: 'no-store'` vs `revalidate` is intentional and documented
|
|
24
|
+
- Parallel fetching — use `Promise.all` / `Promise.allSettled` for independent fetches; flag sequential `await` chains
|
|
25
|
+
- Error handling — every fetch must have an error boundary or explicit error handling; no bare `await fetch()` without `.ok` check
|
|
26
|
+
- Sensitive data leakage — confirm no server-only data (credentials, internal IDs) reaches client components via props
|
|
27
|
+
|
|
28
|
+
### ORM / Database Patterns (if applicable)
|
|
29
|
+
- N+1 detection — flag loops that call the database per iteration; suggest batch queries
|
|
30
|
+
- Index usage — for raw SQL or Prisma, flag `WHERE` clauses on non-indexed columns in large tables
|
|
31
|
+
- Transaction scope — writes that should be atomic must be wrapped in a transaction
|
|
32
|
+
- Connection pooling — no new database connections created inside request handlers
|
|
33
|
+
|
|
34
|
+
### Security
|
|
35
|
+
- Injection — parameterized queries only; no string interpolation in query bodies
|
|
36
|
+
- Authorization — verify that data access checks (role, ownership) happen before the query, not after
|
|
37
|
+
- Exposed internals — IDs, internal references, or admin-only fields must not appear in public GraphQL queries
|
|
38
|
+
- Rate limiting — flag data endpoints with no rate limiting that could be abused
|
|
39
|
+
|
|
40
|
+
## Review Process
|
|
41
|
+
|
|
42
|
+
1. **Identify all data access points** — search for `fetch(`, `useQuery`, `gql`, `graphql`, `prisma.`, SQL queries
|
|
43
|
+
2. **Map fetch-to-render** — trace where the data lands and whether it could be fetched higher in the tree
|
|
44
|
+
3. **Check field selection** — compare fields requested vs fields used in the rendering component
|
|
45
|
+
4. **Verify error paths** — confirm every fetch has handled loading, error, and empty states
|
|
46
|
+
5. **Flag security concerns** — auth checks, injection risk, data exposure
|
|
47
|
+
|
|
48
|
+
## Confidence-Gated Review
|
|
49
|
+
|
|
50
|
+
Before delivering findings, assess your confidence in each area (0–100%).
|
|
51
|
+
|
|
52
|
+
- **≥ 80%**: Report findings normally.
|
|
53
|
+
- **< 80%**: State the gap and ask a targeted clarifying question. Example: *"I need to see the Experience Edge schema for the `Article` type before auditing field selection — can you run `ai-kit export` or share the schema file?"*
|
|
54
|
+
|
|
55
|
+
Declare confidence at the top of your review:
|
|
56
|
+
```
|
|
57
|
+
Confidence: GraphQL efficiency 90% | Caching 85% | Security 70% (need to see auth middleware) | N+1 detection 92%
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Output Format
|
|
61
|
+
|
|
62
|
+
Rate each area: PASS / WARN / FAIL
|
|
63
|
+
Provide specific file and line references for issues.
|
|
64
|
+
For WARN/FAIL items, include a concrete fix recommendation.
|
|
65
|
+
End with a **Data Layer Score** (0–100) with a one-line rationale.
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ var GUIDES_DIR = path.join(PACKAGE_ROOT, "guides");
|
|
|
15
15
|
var DOCS_SCAFFOLDS_DIR = path.join(PACKAGE_ROOT, "docs-scaffolds");
|
|
16
16
|
var AGENTS_DIR = path.join(PACKAGE_ROOT, "agents");
|
|
17
17
|
var CONTEXTS_DIR = path.join(PACKAGE_ROOT, "contexts");
|
|
18
|
-
var VERSION = "2.
|
|
18
|
+
var VERSION = "2.2.0";
|
|
19
19
|
var SKILL_PREFIX = "kit-";
|
|
20
20
|
var AI_KIT_CONFIG_FILE = "ai-kit.config.json";
|
|
21
21
|
var BACKUP_DIR = ".ai-kit/backups";
|
|
@@ -33,6 +33,7 @@ var GENERATED_FILES = {
|
|
|
33
33
|
};
|
|
34
34
|
var TEMPLATE_FRAGMENTS = [
|
|
35
35
|
"base",
|
|
36
|
+
"behavioral",
|
|
36
37
|
"nextjs-app-router",
|
|
37
38
|
"nextjs-pages-router",
|
|
38
39
|
"sitecore-xmc",
|
|
@@ -951,7 +952,7 @@ function replacePlaceholders(content, variables) {
|
|
|
951
952
|
|
|
952
953
|
// src/generator/claude-md.ts
|
|
953
954
|
function selectFragments(scan) {
|
|
954
|
-
const fragments = ["base"];
|
|
955
|
+
const fragments = ["base", "behavioral"];
|
|
955
956
|
if (scan.framework === "nextjs") {
|
|
956
957
|
if (scan.routerType === "app" || scan.routerType === "hybrid") {
|
|
957
958
|
fragments.push("nextjs-app-router");
|
|
@@ -1338,6 +1339,25 @@ function generateHooks(scan, profile = "standard") {
|
|
|
1338
1339
|
]
|
|
1339
1340
|
});
|
|
1340
1341
|
}
|
|
1342
|
+
if (profile !== "minimal") {
|
|
1343
|
+
preToolUse.push({
|
|
1344
|
+
matcher: "Edit|Write",
|
|
1345
|
+
hooks: [
|
|
1346
|
+
{
|
|
1347
|
+
type: "command",
|
|
1348
|
+
command: [
|
|
1349
|
+
'if [ -f "$CLAUDE_FILE_PATH" ]; then',
|
|
1350
|
+
' LINES=$(wc -l < "$CLAUDE_FILE_PATH" 2>/dev/null || echo 0)',
|
|
1351
|
+
' if [ "$LINES" -gt 150 ]; then',
|
|
1352
|
+
' echo "\u{1F4D6} Large file ($LINES lines): $CLAUDE_FILE_PATH"',
|
|
1353
|
+
' echo " Ensure you have read the full file before editing to avoid missing imports or breaking invariants."',
|
|
1354
|
+
" fi",
|
|
1355
|
+
"fi"
|
|
1356
|
+
].join("\n")
|
|
1357
|
+
}
|
|
1358
|
+
]
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1341
1361
|
if (profile === "strict") {
|
|
1342
1362
|
preToolUse.push({
|
|
1343
1363
|
matcher: "Bash(git commit*)",
|
|
@@ -1423,6 +1443,65 @@ function generateHooks(scan, profile = "standard") {
|
|
|
1423
1443
|
]
|
|
1424
1444
|
});
|
|
1425
1445
|
}
|
|
1446
|
+
if (profile === "strict") {
|
|
1447
|
+
postToolUse.push({
|
|
1448
|
+
matcher: "Edit|Write",
|
|
1449
|
+
hooks: [
|
|
1450
|
+
{
|
|
1451
|
+
type: "command",
|
|
1452
|
+
command: [
|
|
1453
|
+
'if [ -f "$CLAUDE_FILE_PATH" ]; then',
|
|
1454
|
+
' GUARDS=""',
|
|
1455
|
+
' case "$CLAUDE_FILE_PATH" in',
|
|
1456
|
+
" *.ts|*.tsx|*.js|*.jsx|*.mjs)",
|
|
1457
|
+
' DISABLE=$(grep -c "eslint-disable" "$CLAUDE_FILE_PATH" 2>/dev/null || echo 0)',
|
|
1458
|
+
' if [ "$DISABLE" -gt 0 ]; then',
|
|
1459
|
+
' GUARDS="${GUARDS}\\n \u26A0\uFE0F eslint-disable: $DISABLE directive(s) found \u2014 weakens linting"',
|
|
1460
|
+
" fi",
|
|
1461
|
+
' SUPPRESS=$(grep -cE "@ts-ignore|@ts-nocheck" "$CLAUDE_FILE_PATH" 2>/dev/null || echo 0)',
|
|
1462
|
+
' if [ "$SUPPRESS" -gt 0 ]; then',
|
|
1463
|
+
' GUARDS="${GUARDS}\\n \u26A0\uFE0F TypeScript suppression: $SUPPRESS @ts-ignore/@ts-nocheck found"',
|
|
1464
|
+
" fi",
|
|
1465
|
+
" ;;",
|
|
1466
|
+
" *tsconfig*.json)",
|
|
1467
|
+
` if grep -qE '"strict"[[:space:]]*:[[:space:]]*false|"noImplicitAny"[[:space:]]*:[[:space:]]*false' "$CLAUDE_FILE_PATH" 2>/dev/null; then`,
|
|
1468
|
+
' GUARDS="${GUARDS}\\n \u26A0\uFE0F TypeScript strict mode disabled \u2014 this weakens type safety"',
|
|
1469
|
+
" fi",
|
|
1470
|
+
" ;;",
|
|
1471
|
+
" esac",
|
|
1472
|
+
' if [ -n "$GUARDS" ]; then',
|
|
1473
|
+
' echo "\u{1F6E1}\uFE0F Config guard triggered in $CLAUDE_FILE_PATH:"',
|
|
1474
|
+
' printf "$GUARDS\\n"',
|
|
1475
|
+
' echo " Confirm these are intentional before committing."',
|
|
1476
|
+
" fi",
|
|
1477
|
+
"fi"
|
|
1478
|
+
].join("\n")
|
|
1479
|
+
}
|
|
1480
|
+
]
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1483
|
+
if (profile === "strict") {
|
|
1484
|
+
postToolUse.push({
|
|
1485
|
+
matcher: "Edit|Write",
|
|
1486
|
+
hooks: [
|
|
1487
|
+
{
|
|
1488
|
+
type: "command",
|
|
1489
|
+
command: [
|
|
1490
|
+
'case "$CLAUDE_FILE_PATH" in',
|
|
1491
|
+
" *.ts|*.tsx|*.js|*.jsx|*.json|*.yaml|*.yml)",
|
|
1492
|
+
' CREDS=$(grep -inE "(apikey|api_key|secret_key|access_token|private_key|password|auth_token)[[:space:]]*[:=][[:space:]]*[^$][^[:space:]]{8,}" "$CLAUDE_FILE_PATH" 2>/dev/null | grep -v "process\\.env" | head -3)',
|
|
1493
|
+
' if [ -n "$CREDS" ]; then',
|
|
1494
|
+
' echo "\u{1F510} Credential scan \u2014 potential secret detected in $CLAUDE_FILE_PATH:"',
|
|
1495
|
+
' echo "$CREDS"',
|
|
1496
|
+
' echo " Move real secrets to .env and reference via process.env \u2014 never commit credentials."',
|
|
1497
|
+
" fi",
|
|
1498
|
+
" ;;",
|
|
1499
|
+
"esac"
|
|
1500
|
+
].join("\n")
|
|
1501
|
+
}
|
|
1502
|
+
]
|
|
1503
|
+
});
|
|
1504
|
+
}
|
|
1426
1505
|
if (profile !== "minimal") {
|
|
1427
1506
|
postCompact.push({
|
|
1428
1507
|
matcher: "",
|
|
@@ -1463,6 +1542,9 @@ function generateHooks(scan, profile = "standard") {
|
|
|
1463
1542
|
function generateSettingsLocal(scan, profile = "standard") {
|
|
1464
1543
|
const hooks = generateHooks(scan, profile);
|
|
1465
1544
|
return {
|
|
1545
|
+
env: {
|
|
1546
|
+
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "65"
|
|
1547
|
+
},
|
|
1466
1548
|
hooks
|
|
1467
1549
|
};
|
|
1468
1550
|
}
|
|
@@ -1682,6 +1764,10 @@ var CONDITIONAL_AGENTS = [
|
|
|
1682
1764
|
{
|
|
1683
1765
|
name: `${SKILL_PREFIX}tdd-guide`,
|
|
1684
1766
|
condition: (scan) => scan.tools.playwright || !!scan.scripts["test"]
|
|
1767
|
+
},
|
|
1768
|
+
{
|
|
1769
|
+
name: `${SKILL_PREFIX}database-reviewer`,
|
|
1770
|
+
condition: (scan) => scan.cms !== "none" || scan.framework === "nextjs"
|
|
1685
1771
|
}
|
|
1686
1772
|
];
|
|
1687
1773
|
async function copyAgents(targetDir, scan) {
|