@react-vault/create-app 0.1.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/LICENSE +12 -0
- package/README.md +16 -0
- package/bin/create-app.js +8 -0
- package/claude-toolkit/README.md +131 -0
- package/claude-toolkit/agents/bfsi-accessibility-auditor.md +132 -0
- package/claude-toolkit/agents/bfsi-architect.md +156 -0
- package/claude-toolkit/agents/bfsi-code-reviewer.md +137 -0
- package/claude-toolkit/agents/bfsi-compliance-auditor.md +161 -0
- package/claude-toolkit/agents/bfsi-pii-scanner.md +142 -0
- package/claude-toolkit/agents/bfsi-pr-reviewer.md +114 -0
- package/claude-toolkit/agents/bfsi-security-reviewer.md +136 -0
- package/claude-toolkit/commands/bfsi-audit.md +46 -0
- package/claude-toolkit/commands/bfsi-doctor.md +97 -0
- package/claude-toolkit/commands/bfsi-review.md +46 -0
- package/claude-toolkit/commands/bfsi-scaffold.md +47 -0
- package/claude-toolkit/hooks/hooks.json +181 -0
- package/claude-toolkit/hooks/scripts/a11y-check.sh +63 -0
- package/claude-toolkit/hooks/scripts/audit-prompt.sh +36 -0
- package/claude-toolkit/hooks/scripts/block-destructive.sh +41 -0
- package/claude-toolkit/hooks/scripts/block-force-push.sh +30 -0
- package/claude-toolkit/hooks/scripts/format.sh +42 -0
- package/claude-toolkit/hooks/scripts/inject-context.sh +44 -0
- package/claude-toolkit/hooks/scripts/lint.sh +45 -0
- package/claude-toolkit/hooks/scripts/protect-files.sh +53 -0
- package/claude-toolkit/hooks/scripts/save-compliance-context.sh +35 -0
- package/claude-toolkit/hooks/scripts/scan-pii.sh +87 -0
- package/claude-toolkit/hooks/scripts/scan-secrets.sh +67 -0
- package/claude-toolkit/hooks/scripts/verify-clean.sh +50 -0
- package/claude-toolkit/package.json +22 -0
- package/claude-toolkit/plugin.json +31 -0
- package/claude-toolkit/skills/bfsi-api-endpoint/SKILL.md +105 -0
- package/claude-toolkit/skills/bfsi-commit/SKILL.md +102 -0
- package/claude-toolkit/skills/bfsi-compliance-check/SKILL.md +107 -0
- package/claude-toolkit/skills/bfsi-encrypt-helper/SKILL.md +127 -0
- package/claude-toolkit/skills/bfsi-error-message/SKILL.md +162 -0
- package/claude-toolkit/skills/bfsi-feature/SKILL.md +120 -0
- package/claude-toolkit/skills/bfsi-feature/references/architecture.md +69 -0
- package/claude-toolkit/skills/bfsi-feature/references/audit-events.md +70 -0
- package/claude-toolkit/skills/bfsi-feature/scripts/scaffold.mjs +136 -0
- package/claude-toolkit/skills/bfsi-form/SKILL.md +73 -0
- package/claude-toolkit/skills/bfsi-form/references/validation-regex.md +50 -0
- package/claude-toolkit/skills/bfsi-onboarding/SKILL.md +110 -0
- package/claude-toolkit/skills/bfsi-pii-field/SKILL.md +90 -0
- package/claude-toolkit/skills/bfsi-test-pattern/SKILL.md +179 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +339 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -0
- package/templates/_shared/.claude/settings.json +31 -0
- package/templates/_shared/.env.local.sample +25 -0
- package/templates/_shared/.github/workflows/ci.yml +49 -0
- package/templates/_shared/CLAUDE.md +89 -0
- package/templates/_shared/README.md +50 -0
- package/templates/_shared/index.html +16 -0
- package/templates/_shared/package.json +73 -0
- package/templates/_shared/postcss.config.cjs +6 -0
- package/templates/_shared/src/app/App.tsx +13 -0
- package/templates/_shared/src/app/globals.css +64 -0
- package/templates/_shared/src/env.ts +33 -0
- package/templates/_shared/src/i18n/i18n.ts +18 -0
- package/templates/_shared/src/i18n/translations/en.json +54 -0
- package/templates/_shared/src/i18n/translations/hi.json +30 -0
- package/templates/_shared/src/main.tsx +16 -0
- package/templates/_shared/src/routes/ProtectedRoute.tsx +28 -0
- package/templates/_shared/src/routes/index.tsx +67 -0
- package/templates/_shared/src/shared/ErrorBoundary.tsx +60 -0
- package/templates/_shared/tailwind.config.ts +68 -0
- package/templates/_shared/tests/setup.ts +7 -0
- package/templates/_shared/tsconfig.json +33 -0
- package/templates/_shared/tsconfig.node.json +13 -0
- package/templates/_shared/vite.config.ts +47 -0
- package/templates/rtk-query/.claude/skills/axios-auth/SKILL.md +103 -0
- package/templates/rtk-query/.claude/skills/axios-auth/references/error-shape.md +84 -0
- package/templates/rtk-query/.claude/skills/axios-auth/references/full-code-walkthrough.md +146 -0
- package/templates/rtk-query/.claude/skills/axios-auth/references/notification-wiring.md +141 -0
- package/templates/rtk-query/.claude/skills/constants-organization/SKILL.md +112 -0
- package/templates/rtk-query/.claude/skills/constants-organization/references/example-files.md +134 -0
- package/templates/rtk-query/.claude/skills/constants-organization/references/tag-types-catalog.md +53 -0
- package/templates/rtk-query/.claude/skills/redux-store-integration/SKILL.md +159 -0
- package/templates/rtk-query/.claude/skills/redux-store-integration/references/localStorage-persistence.md +70 -0
- package/templates/rtk-query/.claude/skills/redux-store-integration/references/middleware-patterns.md +82 -0
- package/templates/rtk-query/.claude/skills/rtk-query-api/SKILL.md +148 -0
- package/templates/rtk-query/.claude/skills/rtk-query-api/references/cache-strategies.md +96 -0
- package/templates/rtk-query/.claude/skills/rtk-query-api/references/endpoint-cookbook.md +145 -0
- package/templates/rtk-query/.claude/skills/rtk-query-api/references/optimistic-update.md +53 -0
- package/templates/rtk-query/README.md +84 -0
- package/templates/rtk-query/package.partial.json +7 -0
- package/templates/rtk-query/src/app/App.tsx +23 -0
- package/templates/rtk-query/src/axiosconfig/axiosInstance.ts +26 -0
- package/templates/rtk-query/src/axiosconfig/baseQuery.ts +72 -0
- package/templates/rtk-query/src/axiosconfig/interceptor.ts +42 -0
- package/templates/rtk-query/src/redux/invalidateCacheMiddleware.ts +20 -0
- package/templates/rtk-query/src/redux/reduxHooks.ts +10 -0
- package/templates/rtk-query/src/redux/rootReducer.ts +18 -0
- package/templates/rtk-query/src/redux/store.ts +36 -0
- package/templates/tanstack-query/.claude/skills/axios-auth/SKILL.md +109 -0
- package/templates/tanstack-query/.claude/skills/axios-auth/references/error-shape.md +89 -0
- package/templates/tanstack-query/.claude/skills/axios-auth/references/full-code-walkthrough.md +121 -0
- package/templates/tanstack-query/.claude/skills/axios-auth/references/notification-pattern.md +109 -0
- package/templates/tanstack-query/.claude/skills/constants-organization/SKILL.md +144 -0
- package/templates/tanstack-query/.claude/skills/constants-organization/references/example-files.md +111 -0
- package/templates/tanstack-query/.claude/skills/constants-organization/references/query-key-factories.md +129 -0
- package/templates/tanstack-query/.claude/skills/query-client-setup/SKILL.md +165 -0
- package/templates/tanstack-query/.claude/skills/query-client-setup/references/devtools.md +67 -0
- package/templates/tanstack-query/.claude/skills/query-client-setup/references/global-handlers.md +94 -0
- package/templates/tanstack-query/.claude/skills/tanstack-services/SKILL.md +142 -0
- package/templates/tanstack-query/.claude/skills/tanstack-services/references/audited-mutation.md +144 -0
- package/templates/tanstack-query/.claude/skills/tanstack-services/references/optimistic-update.md +102 -0
- package/templates/tanstack-query/.claude/skills/tanstack-services/references/service-cookbook.md +151 -0
- package/templates/tanstack-query/README.md +63 -0
- package/templates/tanstack-query/package.partial.json +8 -0
- package/templates/tanstack-query/src/api/axiosInstance.ts +20 -0
- package/templates/tanstack-query/src/api/http.ts +62 -0
- package/templates/tanstack-query/src/api/queryClient.ts +28 -0
- package/templates/tanstack-query/src/app/App.tsx +20 -0
- package/templates/tanstack-query/src/services/example.ts +32 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Async post-write ESLint --fix on the changed file. Non-blocking on errors.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
INPUT=$(cat)
|
|
6
|
+
FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // ""')
|
|
7
|
+
|
|
8
|
+
if [[ -z "$FILE_PATH" ]] || [[ ! -f "$FILE_PATH" ]]; then
|
|
9
|
+
exit 0
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
case "$FILE_PATH" in
|
|
13
|
+
*.ts|*.tsx|*.js|*.jsx)
|
|
14
|
+
;;
|
|
15
|
+
*)
|
|
16
|
+
exit 0
|
|
17
|
+
;;
|
|
18
|
+
esac
|
|
19
|
+
|
|
20
|
+
ROOT="$(dirname "$FILE_PATH")"
|
|
21
|
+
while [[ "$ROOT" != "/" ]] && [[ ! -f "$ROOT/package.json" ]]; do
|
|
22
|
+
ROOT="$(dirname "$ROOT")"
|
|
23
|
+
done
|
|
24
|
+
|
|
25
|
+
if [[ ! -f "$ROOT/package.json" ]] || [[ ! -f "$ROOT/.eslintrc.cjs" && ! -f "$ROOT/.eslintrc.js" && ! -f "$ROOT/.eslintrc.json" && ! -f "$ROOT/eslint.config.js" ]]; then
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
if command -v pnpm >/dev/null 2>&1; then
|
|
30
|
+
cd "$ROOT" && OUTPUT=$(pnpm exec eslint --fix "$FILE_PATH" 2>&1 || true)
|
|
31
|
+
elif command -v npx >/dev/null 2>&1; then
|
|
32
|
+
cd "$ROOT" && OUTPUT=$(npx eslint --fix "$FILE_PATH" 2>&1 || true)
|
|
33
|
+
else
|
|
34
|
+
exit 0
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# If ESLint had unfixable errors, surface a summary to Claude on next turn
|
|
38
|
+
if printf '%s' "$OUTPUT" | grep -qE 'error|problem'; then
|
|
39
|
+
SUMMARY=$(printf '%s' "$OUTPUT" | tail -10)
|
|
40
|
+
jq -n --arg msg "$SUMMARY" --arg file "$(basename "$FILE_PATH")" '{
|
|
41
|
+
systemMessage: ("[bfsi] lint issues in " + $file + ":\n" + $msg)
|
|
42
|
+
}'
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
exit 0
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Blocks edits to files that should never be modified by Claude:
|
|
3
|
+
# .env*, *.pem, *.key, credentials.json, secrets.json, .git/*
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
INPUT=$(cat)
|
|
7
|
+
FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // ""')
|
|
8
|
+
|
|
9
|
+
if [[ -z "$FILE_PATH" ]]; then
|
|
10
|
+
exit 0
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
PROTECTED_PATTERNS=(
|
|
14
|
+
'\.env(\..*)?$' # .env, .env.local, .env.production
|
|
15
|
+
'\.pem$'
|
|
16
|
+
'\.key$'
|
|
17
|
+
'credentials\.json$'
|
|
18
|
+
'secrets\.json$'
|
|
19
|
+
'\.git/'
|
|
20
|
+
'/\.husky/'
|
|
21
|
+
'\.npmrc$' # contains registry tokens
|
|
22
|
+
'id_rsa'
|
|
23
|
+
'id_ed25519'
|
|
24
|
+
'\.p12$'
|
|
25
|
+
'\.pfx$'
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# Allow .env.local.sample / .env.example explicitly (placeholders, not secrets)
|
|
29
|
+
if [[ "$FILE_PATH" =~ \.env\.(local\.)?(sample|example)$ ]]; then
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
for pattern in "${PROTECTED_PATTERNS[@]}"; do
|
|
34
|
+
if [[ "$FILE_PATH" =~ $pattern ]]; then
|
|
35
|
+
cat >&2 <<EOF
|
|
36
|
+
[bfsi] Blocked edit to protected file:
|
|
37
|
+
|
|
38
|
+
$FILE_PATH
|
|
39
|
+
|
|
40
|
+
This file matches a protected pattern. bfsi-claude-toolkit prevents
|
|
41
|
+
Claude from editing secrets, keys, and git internals to avoid accidental
|
|
42
|
+
leaks and history corruption.
|
|
43
|
+
|
|
44
|
+
If this edit is intentional:
|
|
45
|
+
- For .env: edit manually outside Claude, then commit only the .sample
|
|
46
|
+
- For .git/*: use git commands instead of file edits
|
|
47
|
+
- For keys: rotate at the source, never edit in-place
|
|
48
|
+
EOF
|
|
49
|
+
exit 2
|
|
50
|
+
fi
|
|
51
|
+
done
|
|
52
|
+
|
|
53
|
+
exit 0
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreCompact hook: snapshot critical context before compaction so compliance
|
|
3
|
+
# state is preserved in the new context window.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
cd "${CLAUDE_PROJECT_DIR:-$(pwd)}" 2>/dev/null || cd "$(pwd)"
|
|
7
|
+
|
|
8
|
+
BRANCH=$(git branch --show-current 2>/dev/null || echo "")
|
|
9
|
+
LAST_COMMIT=$(git log -1 --oneline 2>/dev/null || echo "")
|
|
10
|
+
DIRTY=$(git status --short 2>/dev/null | head -10)
|
|
11
|
+
|
|
12
|
+
# Emit as additionalContext so it survives compaction
|
|
13
|
+
CTX="[bfsi-compact-snapshot] State before compaction:
|
|
14
|
+
|
|
15
|
+
Branch: $BRANCH
|
|
16
|
+
Last commit: $LAST_COMMIT
|
|
17
|
+
Uncommitted changes:
|
|
18
|
+
${DIRTY:-(clean)}
|
|
19
|
+
|
|
20
|
+
BFSI conventions reminder (in effect for this session):
|
|
21
|
+
- useAuditedMutation for all state changes
|
|
22
|
+
- <ProtectedRoute permission=...> for all routes
|
|
23
|
+
- PII via <PIIMaskedDisplay>
|
|
24
|
+
- Zod parse on every API response
|
|
25
|
+
- Conventional Commits with security/compliance/audit types
|
|
26
|
+
"
|
|
27
|
+
|
|
28
|
+
jq -n --arg ctx "$CTX" '{
|
|
29
|
+
hookSpecificOutput: {
|
|
30
|
+
hookEventName: "PreCompact",
|
|
31
|
+
additionalContext: $ctx
|
|
32
|
+
}
|
|
33
|
+
}'
|
|
34
|
+
|
|
35
|
+
exit 0
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Post-write scan for PII patterns in changed content.
|
|
3
|
+
# Non-blocking: this runs after the write has happened. Adds context for Claude.
|
|
4
|
+
# Per Claude Code spec, PostToolUse exit 2 shows stderr to Claude (the file is already written).
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
INPUT=$(cat)
|
|
8
|
+
FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // ""')
|
|
9
|
+
|
|
10
|
+
if [[ -z "$FILE_PATH" ]] || [[ ! -f "$FILE_PATH" ]]; then
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
# Skip non-source files
|
|
15
|
+
case "$FILE_PATH" in
|
|
16
|
+
*.test.*|*__tests__*|*fixtures*|*mocks*)
|
|
17
|
+
# Test files are checked elsewhere; the bfsi-pii-scanner agent handles those.
|
|
18
|
+
exit 0
|
|
19
|
+
;;
|
|
20
|
+
*.md|*.json|*.yaml|*.yml)
|
|
21
|
+
exit 0
|
|
22
|
+
;;
|
|
23
|
+
esac
|
|
24
|
+
|
|
25
|
+
# PII patterns (intentionally narrow to avoid false positives)
|
|
26
|
+
declare -a FINDINGS=()
|
|
27
|
+
|
|
28
|
+
# console.log with PII variables
|
|
29
|
+
if grep -nE 'console\.(log|info|warn|error|debug)\([^)]*\.(pan|aadhaar|account_number|password|cvv|otp|mobile|email)' "$FILE_PATH" >/dev/null 2>&1; then
|
|
30
|
+
while IFS= read -r line; do
|
|
31
|
+
FINDINGS+=("$line — console.* call may include PII")
|
|
32
|
+
done < <(grep -nE 'console\.(log|info|warn|error|debug)\([^)]*\.(pan|aadhaar|account_number|password|cvv|otp|mobile|email)' "$FILE_PATH" | head -5)
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# localStorage with PII
|
|
36
|
+
if grep -nE 'localStorage\.(setItem|set)\([^)]*\.(pan|aadhaar|account_number|password|token)' "$FILE_PATH" >/dev/null 2>&1; then
|
|
37
|
+
while IFS= read -r line; do
|
|
38
|
+
FINDINGS+=("$line — localStorage write may include PII or auth token")
|
|
39
|
+
done < <(grep -nE 'localStorage\.(setItem|set)\([^)]*\.(pan|aadhaar|account_number|password|token)' "$FILE_PATH" | head -5)
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# PAN-shaped literal in source (10 chars: 5 letters, 4 digits, 1 letter)
|
|
43
|
+
if grep -nE '"[A-Z]{5}[0-9]{4}[A-Z]"' "$FILE_PATH" >/dev/null 2>&1; then
|
|
44
|
+
while IFS= read -r line; do
|
|
45
|
+
FINDINGS+=("$line — PAN-shaped string literal (use testPan() generator in tests)")
|
|
46
|
+
done < <(grep -nE '"[A-Z]{5}[0-9]{4}[A-Z]"' "$FILE_PATH" | head -5)
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Aadhaar-shaped literal (12 digits as string)
|
|
50
|
+
if grep -nE '"[0-9]{12}"' "$FILE_PATH" >/dev/null 2>&1; then
|
|
51
|
+
while IFS= read -r line; do
|
|
52
|
+
FINDINGS+=("$line — 12-digit string literal (could be Aadhaar — use testAadhaar() generator)")
|
|
53
|
+
done < <(grep -nE '"[0-9]{12}"' "$FILE_PATH" | head -5)
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Sentry/telemetry with PII
|
|
57
|
+
if grep -nE '(Sentry\.captureMessage|posthog\.capture|analytics\.track)\([^)]*\.(pan|aadhaar|account_number|password)' "$FILE_PATH" >/dev/null 2>&1; then
|
|
58
|
+
while IFS= read -r line; do
|
|
59
|
+
FINDINGS+=("$line — telemetry call may include PII (scrub before send)")
|
|
60
|
+
done < <(grep -nE '(Sentry\.captureMessage|posthog\.capture|analytics\.track)\([^)]*\.(pan|aadhaar|account_number|password)' "$FILE_PATH" | head -5)
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
if [[ ${#FINDINGS[@]} -gt 0 ]]; then
|
|
64
|
+
# Use JSON output for structured context (per Claude Code spec)
|
|
65
|
+
ADDITIONAL_CONTEXT="[bfsi-pii-scanner] possible PII exposure detected in $FILE_PATH:"
|
|
66
|
+
for f in "${FINDINGS[@]}"; do
|
|
67
|
+
ADDITIONAL_CONTEXT="$ADDITIONAL_CONTEXT
|
|
68
|
+
$f"
|
|
69
|
+
done
|
|
70
|
+
ADDITIONAL_CONTEXT="$ADDITIONAL_CONTEXT
|
|
71
|
+
|
|
72
|
+
Consider:
|
|
73
|
+
- Replace console.* with structured log via @rsense/bfsi-core/audit
|
|
74
|
+
- Replace localStorage with secureStorage from @rsense/bfsi-core/storage
|
|
75
|
+
- Replace PAN/Aadhaar literals with testPan() / testAadhaar() generators
|
|
76
|
+
- Run /bfsi-compliance-check before merge"
|
|
77
|
+
|
|
78
|
+
# Emit JSON for additionalContext
|
|
79
|
+
jq -n --arg ctx "$ADDITIONAL_CONTEXT" '{
|
|
80
|
+
hookSpecificOutput: {
|
|
81
|
+
hookEventName: "PostToolUse",
|
|
82
|
+
additionalContext: $ctx
|
|
83
|
+
}
|
|
84
|
+
}'
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
exit 0
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Pre-write scan: rejects content containing obvious secret patterns.
|
|
3
|
+
# Allows the write if no patterns match. Per Claude Code spec, exit 2 blocks.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
INPUT=$(cat)
|
|
7
|
+
FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // ""')
|
|
8
|
+
TOOL=$(printf '%s' "$INPUT" | jq -r '.tool_name // ""')
|
|
9
|
+
|
|
10
|
+
# For Write, scan the full new content. For Edit, scan the new_string.
|
|
11
|
+
if [[ "$TOOL" == "Write" ]]; then
|
|
12
|
+
CONTENT=$(printf '%s' "$INPUT" | jq -r '.tool_input.content // ""')
|
|
13
|
+
elif [[ "$TOOL" == "Edit" ]]; then
|
|
14
|
+
CONTENT=$(printf '%s' "$INPUT" | jq -r '.tool_input.new_string // ""')
|
|
15
|
+
else
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Skip if writing to a .env.sample / placeholder file (those are OK)
|
|
20
|
+
if [[ "$FILE_PATH" =~ \.env\.(local\.)?(sample|example)$ ]] || [[ "$FILE_PATH" =~ /docs/ ]]; then
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Patterns that look like secrets (regex per line is too slow; do substring lookups)
|
|
25
|
+
SECRET_PATTERNS=(
|
|
26
|
+
'AKIA[0-9A-Z]{16}' # AWS access key ID
|
|
27
|
+
'aws_secret_access_key' # AWS in env-style
|
|
28
|
+
'sk-(live|test)_[A-Za-z0-9]{20,}' # Stripe-style
|
|
29
|
+
'sk-ant-[A-Za-z0-9_-]{32,}' # Anthropic
|
|
30
|
+
'xoxb-[0-9]+-[0-9]+-[A-Za-z0-9]+' # Slack bot token
|
|
31
|
+
'ghp_[A-Za-z0-9]{36}' # GitHub personal access token
|
|
32
|
+
'ghs_[A-Za-z0-9]{36}' # GitHub server-to-server
|
|
33
|
+
'github_pat_[A-Za-z0-9_]{82}' # GitHub fine-grained
|
|
34
|
+
'-----BEGIN (RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY' # PEM keys
|
|
35
|
+
'AIza[0-9A-Za-z_-]{35}' # Google API key
|
|
36
|
+
'glpat-[0-9A-Za-z_-]{20}' # GitLab PAT
|
|
37
|
+
'rzp_(live|test)_[A-Za-z0-9]+' # Razorpay
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
for pattern in "${SECRET_PATTERNS[@]}"; do
|
|
41
|
+
if printf '%s' "$CONTENT" | grep -qE "$pattern"; then
|
|
42
|
+
# Show the first 12 chars of the match for context (not the full secret)
|
|
43
|
+
MATCH=$(printf '%s' "$CONTENT" | grep -oE "$pattern" | head -1 | cut -c1-12)
|
|
44
|
+
cat >&2 <<EOF
|
|
45
|
+
[bfsi] Blocked: write contains what looks like a secret.
|
|
46
|
+
|
|
47
|
+
File: $FILE_PATH
|
|
48
|
+
Pattern: $pattern
|
|
49
|
+
Found (truncated): ${MATCH}...
|
|
50
|
+
|
|
51
|
+
bfsi-claude-toolkit blocks writes that contain obvious secret patterns
|
|
52
|
+
to prevent accidental commits of credentials.
|
|
53
|
+
|
|
54
|
+
If this is a false positive:
|
|
55
|
+
- For tests: use clearly-fake values (sk-test-FAKE, AKIAFAKE0000000)
|
|
56
|
+
- For docs: wrap the example in a code block tagged as example
|
|
57
|
+
|
|
58
|
+
If it's a real secret:
|
|
59
|
+
- Rotate immediately at the source
|
|
60
|
+
- Move to an environment variable (.env.local, gitignored)
|
|
61
|
+
- Add only the .sample with a placeholder
|
|
62
|
+
EOF
|
|
63
|
+
exit 2
|
|
64
|
+
fi
|
|
65
|
+
done
|
|
66
|
+
|
|
67
|
+
exit 0
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Post-turn verification: run async after Claude stops. Reports unflushed concerns.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
cd "${CLAUDE_PROJECT_DIR:-$(pwd)}" 2>/dev/null || cd "$(pwd)"
|
|
6
|
+
|
|
7
|
+
# Only run if there are source-file changes
|
|
8
|
+
if ! git diff --quiet 2>/dev/null; then
|
|
9
|
+
HAS_CHANGES=1
|
|
10
|
+
else
|
|
11
|
+
HAS_CHANGES=0
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
# Skip if no changes
|
|
15
|
+
[[ "$HAS_CHANGES" == "1" ]] || exit 0
|
|
16
|
+
|
|
17
|
+
declare -a CONCERNS=()
|
|
18
|
+
|
|
19
|
+
# 1. Typecheck (quick check)
|
|
20
|
+
if [[ -f "package.json" ]] && grep -q '"typecheck"' package.json 2>/dev/null; then
|
|
21
|
+
if ! pnpm exec tsc --noEmit 2>/dev/null; then
|
|
22
|
+
CONCERNS+=("typecheck failing — run \`pnpm typecheck\` to see errors")
|
|
23
|
+
fi
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# 2. Quick secret scan over uncommitted changes
|
|
27
|
+
if git diff 2>/dev/null | grep -qE 'AKIA[0-9A-Z]{16}|sk-(live|test)_[A-Za-z0-9]{20,}|-----BEGIN.*PRIVATE KEY'; then
|
|
28
|
+
CONCERNS+=("uncommitted changes contain what looks like a secret — review with /bfsi-compliance-check")
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# 3. Quick PII shape scan
|
|
32
|
+
if git diff 2>/dev/null | grep -qE '"[A-Z]{5}[0-9]{4}[A-Z]"|"[0-9]{12}"'; then
|
|
33
|
+
CONCERNS+=("uncommitted changes contain PAN/Aadhaar-shaped literals — use test generators")
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
if [[ ${#CONCERNS[@]} -eq 0 ]]; then
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
MSG="[bfsi] post-turn verification surfaced concerns:"
|
|
41
|
+
for c in "${CONCERNS[@]}"; do
|
|
42
|
+
MSG="$MSG
|
|
43
|
+
- $c"
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
jq -n --arg msg "$MSG" '{
|
|
47
|
+
systemMessage: $msg
|
|
48
|
+
}'
|
|
49
|
+
|
|
50
|
+
exit 0
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@react-vault/toolkit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Claude Code plugin: BFSI-aware skills, agents, hooks, and commands.",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"files": [
|
|
8
|
+
"plugin.json",
|
|
9
|
+
"skills",
|
|
10
|
+
"agents",
|
|
11
|
+
"hooks",
|
|
12
|
+
"commands",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"lint": "echo 'no source code to lint'",
|
|
17
|
+
"test": "echo 'plugin validation via /bfsi-doctor'",
|
|
18
|
+
"typecheck": "echo 'no TS sources'",
|
|
19
|
+
"build": "echo 'plugin is distribution-ready'",
|
|
20
|
+
"validate": "node ./scripts/validate-plugin.mjs"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "toolkit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "BFSI-aware skills, agents, hooks, and commands for Claude Code. Bakes in security review, PII scanning, audit logging, compliance checks, and BFSI scaffolding for every Your Real Company BFSI React project.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Your Real Company",
|
|
7
|
+
"url": "https://your-org.example"
|
|
8
|
+
},
|
|
9
|
+
"license": "UNLICENSED",
|
|
10
|
+
"homepage": "https://github.com/your-real-org/react-starter",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"bfsi",
|
|
13
|
+
"banking",
|
|
14
|
+
"fintech",
|
|
15
|
+
"claude-code",
|
|
16
|
+
"security",
|
|
17
|
+
"rbi",
|
|
18
|
+
"pci-dss",
|
|
19
|
+
"irdai",
|
|
20
|
+
"soc2"
|
|
21
|
+
],
|
|
22
|
+
"components": {
|
|
23
|
+
"skills": "./skills",
|
|
24
|
+
"agents": "./agents",
|
|
25
|
+
"hooks": "./hooks/hooks.json",
|
|
26
|
+
"commands": "./commands"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"claude-code": ">=2.1.0"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bfsi-api-endpoint
|
|
3
|
+
description: Adds a typed API endpoint with Zod validation, audit hooks, and idempotency-key support. Variant-aware (RTK Query OR TanStack Query). Use when the user types /bfsi-api-endpoint, asks to "add an API endpoint", "wire up GET /something", "create a mutation", or "add a new RTK query".
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
argument-hint: <Method> <Path> [--feature FeatureName] [--mutation]
|
|
6
|
+
allowed-tools: Read Write Edit Glob Grep
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# BFSI API Endpoint
|
|
10
|
+
|
|
11
|
+
Adds a new endpoint to an existing feature module's `api.ts`.
|
|
12
|
+
|
|
13
|
+
## What it generates
|
|
14
|
+
|
|
15
|
+
For RTK Query (variant):
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// In src/features/<Feature>/api.ts
|
|
19
|
+
export const <featureApi>.injectEndpoints({
|
|
20
|
+
endpoints: (builder) => ({
|
|
21
|
+
<endpointName>: builder.<query|mutation><Response, RequestArg>({
|
|
22
|
+
query: (arg) => ({
|
|
23
|
+
url: <URL_CONSTANT>,
|
|
24
|
+
method: '<METHOD>',
|
|
25
|
+
body: arg,
|
|
26
|
+
headers: needsIdempotency ? { 'Idempotency-Key': uuid() } : undefined,
|
|
27
|
+
}),
|
|
28
|
+
transformResponse: (raw: unknown) => <ResponseSchema>.parse(raw),
|
|
29
|
+
providesTags: [...],
|
|
30
|
+
invalidatesTags: [...],
|
|
31
|
+
onQueryStarted: auditOnQueryStarted('<auditEventName>'),
|
|
32
|
+
}),
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For TanStack Query (variant):
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// In src/features/<Feature>/api.ts
|
|
41
|
+
export const use<EndpointName> = createQuery({
|
|
42
|
+
queryKey: [<TAG>],
|
|
43
|
+
queryFn: async (arg) => {
|
|
44
|
+
const raw = await http.<method>(<URL>, arg);
|
|
45
|
+
return <ResponseSchema>.parse(raw);
|
|
46
|
+
},
|
|
47
|
+
meta: { audit: '<auditEventName>' },
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Workflow
|
|
52
|
+
|
|
53
|
+
### Step 1: Detect variant
|
|
54
|
+
|
|
55
|
+
Check the project's `package.json` for `@reduxjs/toolkit` vs `@tanstack/react-query`. If both, ask the user.
|
|
56
|
+
|
|
57
|
+
### Step 2: Locate the api.ts
|
|
58
|
+
|
|
59
|
+
Find the feature's `api.ts` (either via `--feature` flag or by inferring from the current file's path). If the user is editing `src/features/Foo/components/X.tsx`, target `src/features/Foo/api.ts`.
|
|
60
|
+
|
|
61
|
+
### Step 3: Generate Zod schemas
|
|
62
|
+
|
|
63
|
+
If schemas for the request/response don't exist in `schema.ts`, add them. Default shape:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
export const <endpointName>RequestSchema = z.object({ /* infer from path params and method */ });
|
|
67
|
+
export const <endpointName>ResponseSchema = z.object({ /* placeholder — user fills in */ });
|
|
68
|
+
export type <EndpointName>Request = z.infer<typeof <endpointName>RequestSchema>;
|
|
69
|
+
export type <EndpointName>Response = z.infer<typeof <endpointName>ResponseSchema>;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Step 4: Add the endpoint
|
|
73
|
+
|
|
74
|
+
Use the variant-specific template.
|
|
75
|
+
|
|
76
|
+
### Step 5: Add the URL constant
|
|
77
|
+
|
|
78
|
+
In `constants.ts`:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
export const <FEATURE>_URLS = {
|
|
82
|
+
// ...existing
|
|
83
|
+
<ENDPOINT_NAME>: '<path>',
|
|
84
|
+
} as const;
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Step 6: Mutations: idempotency-key
|
|
88
|
+
|
|
89
|
+
If method is `POST | PUT | PATCH | DELETE`, automatically include the Idempotency-Key header. Tell the user this is automatic.
|
|
90
|
+
|
|
91
|
+
### Step 7: Audit event
|
|
92
|
+
|
|
93
|
+
Pick a name following the convention: `<feature>.<entity>.<action>`. For GET endpoints, skip audit (reads are not audited by default; opt in via `--audit-reads`).
|
|
94
|
+
|
|
95
|
+
### Step 8: Verify
|
|
96
|
+
|
|
97
|
+
Run `pnpm typecheck`. If the Zod schemas have placeholder shapes, flag it: "I've added the endpoint but the response schema is a placeholder. Open `schema.ts` and define the response shape."
|
|
98
|
+
|
|
99
|
+
## Conventions
|
|
100
|
+
|
|
101
|
+
- **No `any`** — every endpoint must have typed request + response.
|
|
102
|
+
- **All responses go through Zod** — runtime safety against XSS via malformed API.
|
|
103
|
+
- **All mutations get Idempotency-Key** — backend de-dupes accidental double-submit.
|
|
104
|
+
- **All errors throw typed `ApiError`** — handled by the global error boundary.
|
|
105
|
+
- **All caching uses tags**, never hard times. Invalidation is explicit.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bfsi-commit
|
|
3
|
+
description: Generates an audit-friendly Conventional Commits message from the current staged diff. Uses BFSI-extended types (feat, fix, security, compliance, audit, docs, perf, refactor, test, ci, chore). Use when the user types /bfsi-commit, asks to "write a commit message", "commit my changes", or "generate a commit".
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
allowed-tools: Read Grep Bash(git status:*) Bash(git diff:*) Bash(git log:*)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# BFSI Commit Message
|
|
9
|
+
|
|
10
|
+
Generates a Conventional Commits message tuned for BFSI audit logs.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
### Step 1: Inspect staged changes
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
git status --short
|
|
18
|
+
git diff --cached
|
|
19
|
+
git log --oneline -5
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
If there are no staged changes, ask the user to stage first.
|
|
23
|
+
|
|
24
|
+
### Step 2: Pick a type
|
|
25
|
+
|
|
26
|
+
Use the most-specific applicable type. BFSI-extended set:
|
|
27
|
+
|
|
28
|
+
| Type | When |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `feat` | new feature/capability |
|
|
31
|
+
| `fix` | bug fix |
|
|
32
|
+
| `security` | security-related change (CSP, headers, auth tightening) |
|
|
33
|
+
| `compliance` | regulatory/compliance change (RBI/PCI/IRDAI/SOC2 item) |
|
|
34
|
+
| `audit` | audit log additions, observability changes |
|
|
35
|
+
| `perf` | performance improvement |
|
|
36
|
+
| `refactor` | code restructure, no behaviour change |
|
|
37
|
+
| `docs` | docs only |
|
|
38
|
+
| `style` | formatting only |
|
|
39
|
+
| `test` | tests only |
|
|
40
|
+
| `build` | build system, deps |
|
|
41
|
+
| `ci` | CI configuration |
|
|
42
|
+
| `chore` | maintenance |
|
|
43
|
+
| `revert` | reverting prior commit |
|
|
44
|
+
|
|
45
|
+
`security` and `compliance` are BFSI-extensions. Use them whenever applicable so audit reviewers can grep `git log --grep="^security:"` or `git log --grep="^compliance:"` to find every relevant commit quickly.
|
|
46
|
+
|
|
47
|
+
### Step 3: Pick a scope (optional)
|
|
48
|
+
|
|
49
|
+
The feature or area: `kyc`, `transactions`, `auth`, `audit`, `ui`, `core`, etc.
|
|
50
|
+
|
|
51
|
+
### Step 4: Write subject
|
|
52
|
+
|
|
53
|
+
- Imperative mood ("add", not "added" or "adds")
|
|
54
|
+
- ≤ 50 chars
|
|
55
|
+
- Lowercase first word (after type/scope)
|
|
56
|
+
- No trailing period
|
|
57
|
+
|
|
58
|
+
### Step 5: Write body (if WHY is non-obvious)
|
|
59
|
+
|
|
60
|
+
- Wrap at ~72 chars
|
|
61
|
+
- Focus on WHY not WHAT (diff already shows WHAT)
|
|
62
|
+
- For `security` or `compliance` types, the body should reference the regulation/control (e.g. "addresses RBI Annexure I §6.2 — session timeout enforcement")
|
|
63
|
+
- Reference issue / Jira ticket if applicable
|
|
64
|
+
|
|
65
|
+
### Step 6: Output
|
|
66
|
+
|
|
67
|
+
Print the message in a code block. Do NOT run `git commit` automatically — let the user copy or invoke it manually.
|
|
68
|
+
|
|
69
|
+
## Examples
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
feat(kyc): add PAN+Aadhaar e-KYC submission flow
|
|
73
|
+
|
|
74
|
+
Implements the customer-facing e-KYC submission per
|
|
75
|
+
section 5 of the KYC redesign spec. Adds PIIMaskedDisplay
|
|
76
|
+
on Aadhaar in confirmation step. All submission events
|
|
77
|
+
are audited as kyc.verification.submitted.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
security(auth): tighten session idle timeout to 5min on transaction routes
|
|
82
|
+
|
|
83
|
+
Addresses RBI Annexure I §6.2 — sensitive transaction
|
|
84
|
+
flows must auto-logout after ≤ 5min idle. Adds
|
|
85
|
+
idleTimeout prop to <ProtectedRoute scope="transaction">.
|
|
86
|
+
Non-transaction routes remain at 15min.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
compliance(audit): emit data.pan.revealed events with reveal_duration
|
|
91
|
+
|
|
92
|
+
PCI-DSS req 10.2.1 — log every access to cardholder
|
|
93
|
+
data. Extends auditClient to record reveal_duration_ms
|
|
94
|
+
so reveal events can be queried for anomaly detection.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Conventions reinforced
|
|
98
|
+
|
|
99
|
+
- Subject ≤ 50 chars. Body lines ≤ 72.
|
|
100
|
+
- Body present only when WHY isn't obvious from subject + diff.
|
|
101
|
+
- For `security` / `compliance` types, body MUST include the regulation reference.
|
|
102
|
+
- Never include the actual content of secrets, PII, or sensitive data in the message.
|