@claude-code-mastery/starter-kit 1.0.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/.claude/.starter-kit/profiles/clean.md +113 -0
- package/.claude/.starter-kit/profiles/go.md +458 -0
- package/.claude/.starter-kit/profiles/node.md +429 -0
- package/.claude/.starter-kit/profiles/python.md +475 -0
- package/.claude/.starter-kit/shared/analytics-rybbit.md +55 -0
- package/.claude/.starter-kit/shared/claude-md-base.md +93 -0
- package/.claude/.starter-kit/shared/deployment-dokploy.md +158 -0
- package/.claude/.starter-kit/shared/feature-manifest.md +43 -0
- package/.claude/.starter-kit/shared/mcp-and-pooler.md +38 -0
- package/.claude/.starter-kit/shared/mongo-setup.md +20 -0
- package/.claude/.starter-kit/shared/profile-config.md +65 -0
- package/.claude/.starter-kit/shared/seo.md +113 -0
- package/.claude/.starter-kit/shared/sql-setup.md +37 -0
- package/.claude/commands/add-feature.md +349 -0
- package/.claude/commands/add-project-setup.md +156 -0
- package/.claude/commands/architecture.md +27 -0
- package/.claude/commands/commit.md +61 -0
- package/.claude/commands/convert-project-to-starter-kit.md +508 -0
- package/.claude/commands/create-api.md +385 -0
- package/.claude/commands/create-e2e.md +230 -0
- package/.claude/commands/diagram.md +301 -0
- package/.claude/commands/help.md +120 -0
- package/.claude/commands/install-global.md +145 -0
- package/.claude/commands/new-project.md +244 -0
- package/.claude/commands/optimize-docker.md +352 -0
- package/.claude/commands/progress.md +61 -0
- package/.claude/commands/projects-created.md +79 -0
- package/.claude/commands/quickstart.md +105 -0
- package/.claude/commands/refactor.md +267 -0
- package/.claude/commands/remove-project.md +95 -0
- package/.claude/commands/review.md +59 -0
- package/.claude/commands/security-check.md +77 -0
- package/.claude/commands/set-project-profile-default.md +79 -0
- package/.claude/commands/setup.md +337 -0
- package/.claude/commands/show-user-guide.md +58 -0
- package/.claude/commands/starter-kit.md +90 -0
- package/.claude/commands/test-plan.md +118 -0
- package/.claude/commands/update-project.md +413 -0
- package/.claude/commands/what-is-my-ai-doing.md +42 -0
- package/.claude/commands/worktree.md +124 -0
- package/.claude/hooks/block-dangerous-bash.py +55 -0
- package/.claude/hooks/check-branch.sh +116 -0
- package/.claude/hooks/check-e2e.sh +71 -0
- package/.claude/hooks/check-env-sync.sh +41 -0
- package/.claude/hooks/check-file-length.py +47 -0
- package/.claude/hooks/check-ports.sh +59 -0
- package/.claude/hooks/check-rulecatch.sh +33 -0
- package/.claude/hooks/check-rybbit.sh +63 -0
- package/.claude/hooks/lint-on-save.sh +59 -0
- package/.claude/hooks/verify-no-secrets.sh +80 -0
- package/.claude/settings.json +34 -0
- package/.claude/skills/api-conventions/SKILL.md +34 -0
- package/.claude/skills/code-review/SKILL.md +87 -0
- package/.claude/skills/code-review/references/mongodb-checks.md +25 -0
- package/.claude/skills/code-review/references/project-checks.md +38 -0
- package/.claude/skills/create-service/SKILL.md +222 -0
- package/.claude/skills/debugger/SKILL.md +39 -0
- package/.claude/skills/dependency-vetting/SKILL.md +46 -0
- package/.claude/skills/design-review/SKILL.md +50 -0
- package/.claude/skills/mcp-builder/SKILL.md +57 -0
- package/.claude/skills/mongodb-rules/SKILL.md +62 -0
- package/.claude/skills/terminal-tui/SKILL.md +106 -0
- package/.claude/skills/test-writer/SKILL.md +78 -0
- package/LICENSE +21 -0
- package/README.md +2152 -0
- package/bin/cli.js +205 -0
- package/claude-mastery-project.conf +220 -0
- package/global-claude-md/CLAUDE.md +212 -0
- package/global-claude-md/settings.json +3 -0
- package/package.json +81 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import https from 'https';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
const PKG_ROOT = path.resolve(__dirname, '..');
|
|
11
|
+
|
|
12
|
+
// ── low-level helpers (declared first — no hoisting dependency) ───────────────
|
|
13
|
+
|
|
14
|
+
function paths(homeDir) {
|
|
15
|
+
const claudeDir = path.join(homeDir, '.claude');
|
|
16
|
+
return { claudeDir, starterKitDir: path.join(claudeDir, 'starter-kit') };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function ensureDir(dir) {
|
|
20
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function symlinkEntry(src, dest, label) {
|
|
24
|
+
if (fs.existsSync(dest)) {
|
|
25
|
+
if (fs.lstatSync(dest).isSymbolicLink()) return; // already linked
|
|
26
|
+
console.log(` ⚠ Skipped ${label} — existing user file at ${dest}`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
fs.symlinkSync(src, dest);
|
|
30
|
+
console.log(` Linked ${label}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function symlinkFiles(srcDir, destDir) {
|
|
34
|
+
if (!fs.existsSync(srcDir)) return;
|
|
35
|
+
ensureDir(destDir);
|
|
36
|
+
for (const name of fs.readdirSync(srcDir)) {
|
|
37
|
+
symlinkEntry(path.join(srcDir, name), path.join(destDir, name), name);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function symlinkDirs(srcDir, destDir) {
|
|
42
|
+
if (!fs.existsSync(srcDir)) return;
|
|
43
|
+
ensureDir(destDir);
|
|
44
|
+
for (const name of fs.readdirSync(srcDir)) {
|
|
45
|
+
const src = path.join(srcDir, name);
|
|
46
|
+
if (fs.statSync(src).isDirectory()) {
|
|
47
|
+
symlinkEntry(src, path.join(destDir, name), name);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function readInstalledVersion(homeDir) {
|
|
53
|
+
const { starterKitDir } = paths(homeDir);
|
|
54
|
+
const versionFile = path.join(starterKitDir, 'version');
|
|
55
|
+
return fs.existsSync(versionFile) ? fs.readFileSync(versionFile, 'utf8').trim() : null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function fetchLatestVersion() {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
https.get(
|
|
61
|
+
'https://registry.npmjs.org/@claude-code-mastery/starter-kit/latest',
|
|
62
|
+
{ headers: { Accept: 'application/json' } },
|
|
63
|
+
res => {
|
|
64
|
+
let body = '';
|
|
65
|
+
res.on('data', chunk => { body += chunk; });
|
|
66
|
+
res.on('end', () => {
|
|
67
|
+
try { resolve(JSON.parse(body).version); } catch { reject(new Error('parse')); }
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
).on('error', reject);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ── exported helpers ──────────────────────────────────────────────────────────
|
|
75
|
+
|
|
76
|
+
export function rewriteHookPath(command, starterKitDir) {
|
|
77
|
+
return command.replace(/(?<=^|\s)\.claude\/hooks\//g, `${starterKitDir}/hooks/`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function copyPackageFiles(homeDir = os.homedir()) {
|
|
81
|
+
const { starterKitDir } = paths(homeDir);
|
|
82
|
+
ensureDir(starterKitDir);
|
|
83
|
+
fs.cpSync(path.join(PKG_ROOT, '.claude'), starterKitDir, { recursive: true, force: true });
|
|
84
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(PKG_ROOT, 'package.json'), 'utf8'));
|
|
85
|
+
fs.writeFileSync(path.join(starterKitDir, 'version'), pkg.version, 'utf8');
|
|
86
|
+
console.log(` Copied package files → ${starterKitDir}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function symlinkAll(homeDir = os.homedir()) {
|
|
90
|
+
const { claudeDir, starterKitDir } = paths(homeDir);
|
|
91
|
+
symlinkFiles(path.join(starterKitDir, 'commands'), path.join(claudeDir, 'commands'));
|
|
92
|
+
symlinkDirs(path.join(starterKitDir, 'skills'), path.join(claudeDir, 'skills'));
|
|
93
|
+
symlinkFiles(path.join(starterKitDir, 'agents'), path.join(claudeDir, 'agents'));
|
|
94
|
+
// Expose scaffolding templates at ~/.claude/.starter-kit/ so command files can
|
|
95
|
+
// reference .claude/.starter-kit/ from any project without a local kit install.
|
|
96
|
+
symlinkEntry(
|
|
97
|
+
path.join(starterKitDir, '.starter-kit'),
|
|
98
|
+
path.join(claudeDir, '.starter-kit'),
|
|
99
|
+
'.starter-kit',
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function mergeSettings(homeDir = os.homedir()) {
|
|
104
|
+
const { claudeDir, starterKitDir } = paths(homeDir);
|
|
105
|
+
const kitPath = path.join(starterKitDir, 'settings.json');
|
|
106
|
+
if (!fs.existsSync(kitPath)) return;
|
|
107
|
+
|
|
108
|
+
const kit = JSON.parse(fs.readFileSync(kitPath, 'utf8'));
|
|
109
|
+
const glPath = path.join(claudeDir, 'settings.json');
|
|
110
|
+
const gl = fs.existsSync(glPath) ? JSON.parse(fs.readFileSync(glPath, 'utf8')) : {};
|
|
111
|
+
if (!gl.hooks) gl.hooks = {};
|
|
112
|
+
|
|
113
|
+
for (const [event, groups] of Object.entries(kit.hooks ?? {})) {
|
|
114
|
+
if (!gl.hooks[event]) gl.hooks[event] = [];
|
|
115
|
+
|
|
116
|
+
for (const group of groups) {
|
|
117
|
+
const rewritten = (group.hooks ?? []).map(h => ({
|
|
118
|
+
...h,
|
|
119
|
+
command: rewriteHookPath(h.command ?? '', starterKitDir),
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
const registered = new Set(
|
|
123
|
+
gl.hooks[event].flatMap(g => (g.hooks ?? []).map(h => h.command)),
|
|
124
|
+
);
|
|
125
|
+
const fresh = rewritten.filter(h => !registered.has(h.command));
|
|
126
|
+
if (fresh.length === 0) continue;
|
|
127
|
+
|
|
128
|
+
const existing = gl.hooks[event].find(g => g.matcher === group.matcher);
|
|
129
|
+
if (existing) {
|
|
130
|
+
existing.hooks.push(...fresh);
|
|
131
|
+
} else {
|
|
132
|
+
gl.hooks[event].push({ ...group, hooks: fresh });
|
|
133
|
+
}
|
|
134
|
+
for (const h of fresh) console.log(` Registered hook: ${h.command}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
fs.writeFileSync(glPath, JSON.stringify(gl, null, 2), 'utf8');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ── main commands ─────────────────────────────────────────────────────────────
|
|
142
|
+
|
|
143
|
+
export async function init(homeDir = os.homedir()) {
|
|
144
|
+
const { claudeDir, starterKitDir } = paths(homeDir);
|
|
145
|
+
console.log('Installing @claude-code-mastery/starter-kit...\n');
|
|
146
|
+
copyPackageFiles(homeDir);
|
|
147
|
+
symlinkAll(homeDir);
|
|
148
|
+
mergeSettings(homeDir);
|
|
149
|
+
// Copy conf to ~/.claude/ and record source path
|
|
150
|
+
const confSrc = path.join(PKG_ROOT, 'claude-mastery-project.conf');
|
|
151
|
+
if (fs.existsSync(confSrc)) {
|
|
152
|
+
ensureDir(claudeDir);
|
|
153
|
+
fs.copyFileSync(confSrc, path.join(claudeDir, 'claude-mastery-project.conf'));
|
|
154
|
+
console.log(` Copied claude-mastery-project.conf → ${claudeDir}`);
|
|
155
|
+
}
|
|
156
|
+
fs.writeFileSync(path.join(claudeDir, 'starter-kit-source-path'), starterKitDir, 'utf8');
|
|
157
|
+
const version = readInstalledVersion(homeDir);
|
|
158
|
+
console.log(`\n✅ Installed v${version} to ${starterKitDir}`);
|
|
159
|
+
console.log(' Run /starter-kit update inside Claude Code to update in future.\n');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export async function update(homeDir = os.homedir()) {
|
|
163
|
+
const { starterKitDir } = paths(homeDir);
|
|
164
|
+
if (!fs.existsSync(starterKitDir)) {
|
|
165
|
+
console.error('Not installed. Run: npx @claude-code-mastery/starter-kit init');
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
console.log(`Updating from v${readInstalledVersion(homeDir)}...\n`);
|
|
169
|
+
copyPackageFiles(homeDir);
|
|
170
|
+
symlinkAll(homeDir);
|
|
171
|
+
mergeSettings(homeDir);
|
|
172
|
+
console.log(`\n✅ Updated to v${readInstalledVersion(homeDir)}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export async function status(homeDir = os.homedir()) {
|
|
176
|
+
const installed = readInstalledVersion(homeDir);
|
|
177
|
+
if (!installed) {
|
|
178
|
+
console.log('Not installed. Run: npx @claude-code-mastery/starter-kit init');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
console.log(`Installed: v${installed}`);
|
|
182
|
+
try {
|
|
183
|
+
const latest = await fetchLatestVersion();
|
|
184
|
+
console.log(latest === installed
|
|
185
|
+
? `Latest: v${latest} (up to date ✅)`
|
|
186
|
+
: `Latest: v${latest} (run /starter-kit update to upgrade)`);
|
|
187
|
+
} catch {
|
|
188
|
+
console.log('Latest: (could not reach npm registry)');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// ── entry point ───────────────────────────────────────────────────────────────
|
|
193
|
+
|
|
194
|
+
const isMain = process.argv[1] && __filename === fs.realpathSync(process.argv[1]);
|
|
195
|
+
if (isMain) {
|
|
196
|
+
const subcommand = process.argv[2];
|
|
197
|
+
switch (subcommand) {
|
|
198
|
+
case 'init': await init(); break;
|
|
199
|
+
case 'update': await update(); break;
|
|
200
|
+
case 'status': await status(); break;
|
|
201
|
+
default:
|
|
202
|
+
console.log('Usage: npx @claude-code-mastery/starter-kit <init|update|status>');
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Claude Mastery Project Configuration
|
|
2
|
+
# =====================================
|
|
3
|
+
# Define reusable profiles for /new-project
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# /new-project my-app clean → Claude infrastructure only, zero coding opinions
|
|
7
|
+
# /new-project my-app default → creates at ~/projects/my-app with full opinionated stack
|
|
8
|
+
# /new-project my-app api → creates at ~/projects/my-app with API profile
|
|
9
|
+
# /new-project ./custom/path my-app → explicit path overrides root_dir
|
|
10
|
+
# /new-project my-app default vercel → profile + override
|
|
11
|
+
#
|
|
12
|
+
# Global settings:
|
|
13
|
+
# root_dir: Default parent directory for new projects
|
|
14
|
+
# If just a project name is given (no path), it creates at root_dir/<name>
|
|
15
|
+
# Override by passing an explicit path (./foo, ~/bar, /abs/path)
|
|
16
|
+
# default_profile: Profile to use when no profile is specified in /new-project arguments
|
|
17
|
+
# e.g. default_profile = clean → /new-project my-app uses [clean] automatically
|
|
18
|
+
# If not set, /new-project asks the user for all choices
|
|
19
|
+
# auto_branch: Auto-create feature branches when commands detect you're on main (default: true)
|
|
20
|
+
# Set to false if you prefer manual branch management
|
|
21
|
+
# sanitize: Auto-sanitize all database query inputs (default: true, handled by StrictDB)
|
|
22
|
+
# Set to false if you handle sanitization yourself
|
|
23
|
+
# docker_test_before_push:
|
|
24
|
+
# When true, BLOCK any docker push until the image is built, run locally,
|
|
25
|
+
# and verified to start without error (exit code 0, health check passes).
|
|
26
|
+
# Default: false. Enable for production projects to prevent broken deploys.
|
|
27
|
+
#
|
|
28
|
+
# Profile values:
|
|
29
|
+
# type: webapp | api | fullstack | cli
|
|
30
|
+
# language: node | go | python (default: node)
|
|
31
|
+
# framework:
|
|
32
|
+
# Node.js frontend: vite | react | vue | svelte | sveltekit | angular | nuxt | next | astro
|
|
33
|
+
# Node.js backend: fastify | express | hono
|
|
34
|
+
# Go: gin | chi | echo | fiber | stdlib
|
|
35
|
+
# Python: fastapi | django | flask
|
|
36
|
+
# hosting: dokploy | vercel | static
|
|
37
|
+
# package_manager: pnpm | npm | bun | gomod | pip | uv | poetry
|
|
38
|
+
# database: mongo | postgres | mysql | mssql | sqlite | none
|
|
39
|
+
# analytics: rybbit | none
|
|
40
|
+
# options: seo, ssr, tailwind, prisma, docker, ci, multiregion
|
|
41
|
+
# mcp: playwright, context7, rulecatch, classmcp, strictdb
|
|
42
|
+
# npm: additional npm packages (e.g., @rulecatch/ai-pooler, classpresso)
|
|
43
|
+
#
|
|
44
|
+
# Customize these profiles to match YOUR preferred stack.
|
|
45
|
+
# Global fallback: ~/.claude/claude-mastery-project.conf
|
|
46
|
+
|
|
47
|
+
[global]
|
|
48
|
+
root_dir = ~/projects
|
|
49
|
+
auto_branch = true # Auto-create feature branches when on main (set false to disable)
|
|
50
|
+
sanitize = true # Auto-sanitize all database query inputs (handled by StrictDB, set false to disable)
|
|
51
|
+
docker_test_before_push = false # When true, must build + run + health-check locally before pushing to Docker Hub
|
|
52
|
+
ask_task_on_build = false # When true, /mdd Build Mode asks "feature or task?" before Phase 1 questions
|
|
53
|
+
|
|
54
|
+
[clean]
|
|
55
|
+
# All Claude Code infrastructure, zero coding opinions.
|
|
56
|
+
# You get: .claude/ (commands, skills, agents, hooks), project-docs templates,
|
|
57
|
+
# CLAUDE.md (security rules only), .env pattern, .gitignore, tests/ templates.
|
|
58
|
+
# You DON'T get: TypeScript enforcement, port assignments, database wrapper,
|
|
59
|
+
# testing frameworks, quality gates, API versioning, SEO rules.
|
|
60
|
+
# Your project, your rules. Claude just works.
|
|
61
|
+
opinionated = false
|
|
62
|
+
|
|
63
|
+
[default]
|
|
64
|
+
type = fullstack
|
|
65
|
+
framework = next
|
|
66
|
+
hosting = dokploy
|
|
67
|
+
package_manager = pnpm
|
|
68
|
+
database = mongo
|
|
69
|
+
analytics = rybbit
|
|
70
|
+
options = seo, tailwind, docker, ci
|
|
71
|
+
mcp = playwright, context7, rulecatch, classmcp, strictdb
|
|
72
|
+
npm = @rulecatch/ai-pooler, classpresso
|
|
73
|
+
|
|
74
|
+
[api]
|
|
75
|
+
type = api
|
|
76
|
+
framework = fastify
|
|
77
|
+
hosting = dokploy
|
|
78
|
+
package_manager = pnpm
|
|
79
|
+
database = mongo
|
|
80
|
+
analytics = none
|
|
81
|
+
options = docker, ci
|
|
82
|
+
mcp = context7, rulecatch, strictdb
|
|
83
|
+
npm = @rulecatch/ai-pooler
|
|
84
|
+
|
|
85
|
+
[static-site]
|
|
86
|
+
type = webapp
|
|
87
|
+
framework = astro
|
|
88
|
+
hosting = static
|
|
89
|
+
package_manager = pnpm
|
|
90
|
+
database = none
|
|
91
|
+
analytics = rybbit
|
|
92
|
+
options = seo, tailwind
|
|
93
|
+
mcp = context7, classmcp
|
|
94
|
+
npm = classpresso
|
|
95
|
+
|
|
96
|
+
[quick]
|
|
97
|
+
type = webapp
|
|
98
|
+
framework = vite
|
|
99
|
+
hosting = vercel
|
|
100
|
+
package_manager = pnpm
|
|
101
|
+
database = none
|
|
102
|
+
analytics = none
|
|
103
|
+
options = tailwind
|
|
104
|
+
mcp = context7, classmcp
|
|
105
|
+
npm = classpresso
|
|
106
|
+
|
|
107
|
+
[enterprise]
|
|
108
|
+
type = fullstack
|
|
109
|
+
framework = next
|
|
110
|
+
hosting = dokploy
|
|
111
|
+
package_manager = pnpm
|
|
112
|
+
database = mongo
|
|
113
|
+
analytics = rybbit
|
|
114
|
+
options = seo, ssr, tailwind, prisma, docker, ci, multiregion
|
|
115
|
+
mcp = playwright, context7, rulecatch, classmcp, strictdb
|
|
116
|
+
npm = @rulecatch/ai-pooler, classpresso
|
|
117
|
+
|
|
118
|
+
[go]
|
|
119
|
+
language = go
|
|
120
|
+
type = api
|
|
121
|
+
framework = gin
|
|
122
|
+
hosting = dokploy
|
|
123
|
+
package_manager = gomod
|
|
124
|
+
database = mongo
|
|
125
|
+
analytics = none
|
|
126
|
+
options = docker, ci
|
|
127
|
+
mcp = context7, rulecatch, strictdb
|
|
128
|
+
|
|
129
|
+
[vue]
|
|
130
|
+
language = node
|
|
131
|
+
type = webapp
|
|
132
|
+
framework = vue
|
|
133
|
+
hosting = vercel
|
|
134
|
+
package_manager = pnpm
|
|
135
|
+
database = none
|
|
136
|
+
analytics = rybbit
|
|
137
|
+
options = tailwind
|
|
138
|
+
mcp = playwright, context7, classmcp
|
|
139
|
+
npm = classpresso
|
|
140
|
+
|
|
141
|
+
[nuxt]
|
|
142
|
+
language = node
|
|
143
|
+
type = fullstack
|
|
144
|
+
framework = nuxt
|
|
145
|
+
hosting = dokploy
|
|
146
|
+
package_manager = pnpm
|
|
147
|
+
database = mongo
|
|
148
|
+
analytics = rybbit
|
|
149
|
+
options = seo, tailwind, docker, ci
|
|
150
|
+
mcp = playwright, context7, rulecatch, classmcp, strictdb
|
|
151
|
+
npm = classpresso
|
|
152
|
+
|
|
153
|
+
[svelte]
|
|
154
|
+
language = node
|
|
155
|
+
type = webapp
|
|
156
|
+
framework = svelte
|
|
157
|
+
hosting = vercel
|
|
158
|
+
package_manager = pnpm
|
|
159
|
+
database = none
|
|
160
|
+
analytics = rybbit
|
|
161
|
+
options = tailwind
|
|
162
|
+
mcp = playwright, context7, classmcp
|
|
163
|
+
npm = classpresso
|
|
164
|
+
|
|
165
|
+
[sveltekit]
|
|
166
|
+
language = node
|
|
167
|
+
type = fullstack
|
|
168
|
+
framework = sveltekit
|
|
169
|
+
hosting = dokploy
|
|
170
|
+
package_manager = pnpm
|
|
171
|
+
database = mongo
|
|
172
|
+
analytics = rybbit
|
|
173
|
+
options = seo, tailwind, docker, ci
|
|
174
|
+
mcp = playwright, context7, rulecatch, classmcp, strictdb
|
|
175
|
+
npm = classpresso
|
|
176
|
+
|
|
177
|
+
[angular]
|
|
178
|
+
language = node
|
|
179
|
+
type = webapp
|
|
180
|
+
framework = angular
|
|
181
|
+
hosting = vercel
|
|
182
|
+
package_manager = npm
|
|
183
|
+
database = none
|
|
184
|
+
analytics = rybbit
|
|
185
|
+
options = tailwind
|
|
186
|
+
mcp = playwright, context7, classmcp
|
|
187
|
+
npm = classpresso
|
|
188
|
+
|
|
189
|
+
[python-api]
|
|
190
|
+
language = python
|
|
191
|
+
type = api
|
|
192
|
+
framework = fastapi
|
|
193
|
+
hosting = dokploy
|
|
194
|
+
package_manager = pip
|
|
195
|
+
database = postgres
|
|
196
|
+
analytics = none
|
|
197
|
+
options = docker, ci
|
|
198
|
+
mcp = context7, rulecatch, strictdb
|
|
199
|
+
|
|
200
|
+
[django]
|
|
201
|
+
language = python
|
|
202
|
+
type = fullstack
|
|
203
|
+
framework = django
|
|
204
|
+
hosting = dokploy
|
|
205
|
+
package_manager = pip
|
|
206
|
+
database = postgres
|
|
207
|
+
analytics = rybbit
|
|
208
|
+
options = docker, ci
|
|
209
|
+
mcp = context7, rulecatch, classmcp, strictdb
|
|
210
|
+
|
|
211
|
+
[flask]
|
|
212
|
+
language = python
|
|
213
|
+
type = api
|
|
214
|
+
framework = flask
|
|
215
|
+
hosting = dokploy
|
|
216
|
+
package_manager = pip
|
|
217
|
+
database = postgres
|
|
218
|
+
analytics = none
|
|
219
|
+
options = docker, ci
|
|
220
|
+
mcp = context7, strictdb
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Global CLAUDE.md — Security Gatekeeper & Standards
|
|
2
|
+
|
|
3
|
+
> Place this at ~/.claude/CLAUDE.md
|
|
4
|
+
> It applies to EVERY project you work on.
|
|
5
|
+
> Based on Claude Code Mastery Guides V1-V5 by TheDecipherist
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Identity
|
|
10
|
+
|
|
11
|
+
- GitHub: **YourUsername**
|
|
12
|
+
- SSH: `git@github.com:YourUsername/<repo>.git`
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## NEVER EVER DO
|
|
17
|
+
|
|
18
|
+
These rules are ABSOLUTE and apply to every project:
|
|
19
|
+
|
|
20
|
+
### NEVER Publish Sensitive Data
|
|
21
|
+
- NEVER publish passwords, API keys, tokens to git/npm/docker
|
|
22
|
+
- Before ANY commit: verify no secrets included
|
|
23
|
+
- NEVER output secrets in responses, logs, or suggestions
|
|
24
|
+
|
|
25
|
+
### NEVER Commit .env Files
|
|
26
|
+
- NEVER commit `.env` to git
|
|
27
|
+
- ALWAYS verify `.env` is in `.gitignore`
|
|
28
|
+
|
|
29
|
+
### NEVER Auto-Deploy
|
|
30
|
+
- ALWAYS ask before deploying to production
|
|
31
|
+
- NEVER assume approval — wait for explicit "yes, deploy"
|
|
32
|
+
|
|
33
|
+
### NEVER Hardcode Credentials
|
|
34
|
+
- ALWAYS use environment variables for secrets
|
|
35
|
+
- NEVER put API keys, passwords, or tokens directly in source code
|
|
36
|
+
|
|
37
|
+
### NEVER Publish Dynamic Data in Markdown Files
|
|
38
|
+
- NEVER hardcode repo names, project names, or URLs in `.md` files
|
|
39
|
+
- ALWAYS reference environment variables instead
|
|
40
|
+
- BAD: `docker push myusername/myproject:latest`
|
|
41
|
+
- GOOD: `docker push $DOCKER_HUB_REPO:latest`
|
|
42
|
+
- This applies to: CLAUDE.md, README.md, CONTRIBUTING.md, and all documentation
|
|
43
|
+
|
|
44
|
+
### NEVER Put Personal Instructions in Public Files
|
|
45
|
+
- NEVER add personal workflows or non-project instructions to a project's main `CLAUDE.md`
|
|
46
|
+
- ALWAYS store personal procedures in `.claude/LOCAL-INSTRUCTIONS.md` (gitignored)
|
|
47
|
+
- Examples of what belongs there: social media workflows, personal tracking, marketing procedures
|
|
48
|
+
|
|
49
|
+
### NEVER Rename Without a Plan
|
|
50
|
+
- NEVER do project-wide search-and-replace renames without a checklist
|
|
51
|
+
- Renaming causes cascading failures in .md, .env, comments, strings, and paths
|
|
52
|
+
|
|
53
|
+
### NEVER Push Docker Images Without Local Testing
|
|
54
|
+
- NEVER push a Docker image without testing it locally first
|
|
55
|
+
- ALWAYS run the container and verify it starts correctly before pushing
|
|
56
|
+
- Check for: no crash on startup, no 502 errors, basic pages load
|
|
57
|
+
|
|
58
|
+
#### Docker Pre-Push Checklist
|
|
59
|
+
1. Build: `docker build -t $IMAGE_NAME .`
|
|
60
|
+
2. Run: `docker run -d -p 3000:3000 --name test-container $IMAGE_NAME`
|
|
61
|
+
3. Wait for startup, then verify: `curl -s -o /dev/null -w "%{http_code}" http://localhost:3000` (expect 200)
|
|
62
|
+
4. Check logs: `docker logs test-container`
|
|
63
|
+
5. Clean up: `docker stop test-container && docker rm test-container`
|
|
64
|
+
6. Only then push
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## If Credentials Are Ever Exposed
|
|
69
|
+
|
|
70
|
+
1. IMMEDIATELY rotate/change the exposed credentials
|
|
71
|
+
2. Clean git history: `git filter-repo --replace-text <(echo 'OLD_SECRET==>REDACTED')`
|
|
72
|
+
3. Force push: `git push --force origin main`
|
|
73
|
+
4. Verify credentials are removed from ALL commits
|
|
74
|
+
5. Alert anyone who may have cloned the repo
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## New Project Setup
|
|
79
|
+
|
|
80
|
+
When creating ANY new project:
|
|
81
|
+
|
|
82
|
+
### Required Files
|
|
83
|
+
- `.env` - Environment variables (NEVER commit)
|
|
84
|
+
- `.env.example` - Template with placeholders (committed)
|
|
85
|
+
- `.gitignore` - Must include: .env, .env.*, node_modules/, dist/, CLAUDE.local.md
|
|
86
|
+
- `.dockerignore` - Must include: .env, .git/, node_modules/
|
|
87
|
+
- `CLAUDE.md` - Project instructions
|
|
88
|
+
- `tsconfig.json` - TypeScript configuration (strict mode)
|
|
89
|
+
|
|
90
|
+
### Required Structure
|
|
91
|
+
```
|
|
92
|
+
project/
|
|
93
|
+
├── src/
|
|
94
|
+
├── tests/
|
|
95
|
+
├── project-docs/
|
|
96
|
+
├── .claude/
|
|
97
|
+
│ ├── commands/
|
|
98
|
+
│ ├── skills/
|
|
99
|
+
│ └── agents/
|
|
100
|
+
└── scripts/
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### TypeScript - Always
|
|
104
|
+
- All new files MUST be TypeScript
|
|
105
|
+
- Use strict mode
|
|
106
|
+
- Never use `any` unless absolutely necessary
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Local Instructions Storage
|
|
111
|
+
|
|
112
|
+
When you have personal procedures that are NOT project code:
|
|
113
|
+
|
|
114
|
+
- **Project `CLAUDE.md`** - code architecture, build/test/deploy commands, technical standards
|
|
115
|
+
- **`.claude/LOCAL-INSTRUCTIONS.md`** - personal workflows, social media posting, marketing procedures, anything that shouldn't be in the public repo
|
|
116
|
+
|
|
117
|
+
Setup:
|
|
118
|
+
1. Create `.claude/` in the project root if it doesn't exist
|
|
119
|
+
2. Add `.claude/` to `.gitignore`
|
|
120
|
+
3. Create `.claude/LOCAL-INSTRUCTIONS.md` for personal procedures
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Markdown Writing Rules
|
|
125
|
+
|
|
126
|
+
These apply to any `.md` file:
|
|
127
|
+
|
|
128
|
+
### No Em Dashes
|
|
129
|
+
- NEVER use em dashes (--)
|
|
130
|
+
- ALWAYS use a regular hyphen (-) instead
|
|
131
|
+
|
|
132
|
+
### Write Like a Human
|
|
133
|
+
- Avoid AI writing patterns: no "delve into", "leverage", "seamlessly", "robust", "comprehensive", "streamline"
|
|
134
|
+
- Be direct and specific - say what something does, not how impressive it is
|
|
135
|
+
- No filler sentences that add length without adding meaning
|
|
136
|
+
|
|
137
|
+
### No Repetition
|
|
138
|
+
- NEVER repeat a point already made earlier in the same document
|
|
139
|
+
- If the opening makes an argument, the body must go deeper - not restate it
|
|
140
|
+
- Introductions and conclusions are the worst offenders
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Default File Locations
|
|
145
|
+
|
|
146
|
+
### Documents and Reports
|
|
147
|
+
When asked to create documents (PDF, MD, reports, notes) with no specified location:
|
|
148
|
+
- ALWAYS default to the `/docs` directory in the project root
|
|
149
|
+
- Create `/docs` if it doesn't exist
|
|
150
|
+
- Add `/docs` to `.gitignore` - generated docs don't belong in git
|
|
151
|
+
|
|
152
|
+
### Tracking Files (CSVs, Logs, Metrics)
|
|
153
|
+
When tracking data in files:
|
|
154
|
+
- ALWAYS create tracking files in `/docs`
|
|
155
|
+
- NEVER commit tracking files to git
|
|
156
|
+
- Before creating any tracking file: verify `/docs` is in `.gitignore`
|
|
157
|
+
|
|
158
|
+
### Temporary AI Research Files
|
|
159
|
+
When creating research notes, API doc summaries, or analysis during a session:
|
|
160
|
+
- ALWAYS store in `_ai_temp/` directory
|
|
161
|
+
- Add `_ai_temp/` to `.gitignore` if not already there
|
|
162
|
+
- What goes here: research compilations, code analysis notes, temporary drafts, brainstorming
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Coding Standards (All Projects)
|
|
167
|
+
|
|
168
|
+
### Error Handling
|
|
169
|
+
- NEVER swallow errors silently
|
|
170
|
+
- ALWAYS log errors with context before re-throwing
|
|
171
|
+
- Add `process.on('unhandledRejection')` handler to entry points
|
|
172
|
+
|
|
173
|
+
### Testing
|
|
174
|
+
- ALWAYS define explicit success criteria
|
|
175
|
+
- "Page loads" is NOT a success criterion
|
|
176
|
+
- Every test must assert something meaningful
|
|
177
|
+
|
|
178
|
+
### Quality Gates
|
|
179
|
+
- No file > 300 lines (split if larger)
|
|
180
|
+
- No function > 50 lines (extract helpers)
|
|
181
|
+
- All tests must pass before committing
|
|
182
|
+
- TypeScript compiles with no errors
|
|
183
|
+
- No linter warnings
|
|
184
|
+
|
|
185
|
+
### Database
|
|
186
|
+
- ALWAYS use StrictDB for all database access (shared instance pattern)
|
|
187
|
+
- NEVER create database connections in individual files
|
|
188
|
+
|
|
189
|
+
### Async Performance
|
|
190
|
+
- When multiple `await` calls are independent, ALWAYS use `Promise.all`
|
|
191
|
+
- NEVER await independent operations sequentially - evaluate dependencies first
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Image Conversion
|
|
196
|
+
|
|
197
|
+
When converting images to WebP:
|
|
198
|
+
- Try `ffmpeg` first (most commonly available)
|
|
199
|
+
- Fallback: `cwebp` then `convert` (ImageMagick)
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
ffmpeg -i input.png -quality 85 output.webp
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Workflow
|
|
208
|
+
|
|
209
|
+
- One task, one chat
|
|
210
|
+
- Use `/clear` between unrelated tasks
|
|
211
|
+
- Quality over speed - ask if unsure
|
|
212
|
+
- Use Plan Mode for anything bigger than a simple fix
|