ai-devcontext 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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +55 -0
  3. package/package.json +42 -0
  4. package/src/index.js +90 -0
  5. package/templates/.claude/agents/security-scanner/security-scanner.md +27 -0
  6. package/templates/.claude/commands/clean.sh +6 -0
  7. package/templates/.claude/commands/db-migrate.sh +6 -0
  8. package/templates/.claude/commands/docker-down.sh +5 -0
  9. package/templates/.claude/commands/docker-up.sh +11 -0
  10. package/templates/.claude/commands/format.sh +9 -0
  11. package/templates/.claude/commands/lint-fix.sh +5 -0
  12. package/templates/.claude/commands/new-resource.sh +76 -0
  13. package/templates/.claude/commands/outdated-deps.sh +7 -0
  14. package/templates/.claude/commands/seed-db.sh +5 -0
  15. package/templates/.claude/commands/test-watch.sh +5 -0
  16. package/templates/.claude/commands/typecheck.sh +9 -0
  17. package/templates/.claude/hooks/after-edit.sh +12 -0
  18. package/templates/.claude/rules/architectural-docs.md +7 -0
  19. package/templates/.claude/rules/security-checklist.md +25 -0
  20. package/templates/.claude/settings.json +15 -0
  21. package/templates/.claude/settings.local.json +5 -0
  22. package/templates/.claude/skills/testing-patterns/SKILL.md +22 -0
  23. package/templates/.claude/workflows/deployment-guide.md +13 -0
  24. package/templates/.cursor/.cursorignore +12 -0
  25. package/templates/.cursor/.cursorrules +24 -0
  26. package/templates/.cursor/commands/build-and-test.sh +8 -0
  27. package/templates/.cursor/commands/clean.sh +6 -0
  28. package/templates/.cursor/commands/docker-down.sh +5 -0
  29. package/templates/.cursor/commands/docker-up.sh +11 -0
  30. package/templates/.cursor/commands/format.sh +9 -0
  31. package/templates/.cursor/commands/lint-fix.sh +5 -0
  32. package/templates/.cursor/commands/new-resource.sh +76 -0
  33. package/templates/.cursor/commands/outdated-deps.sh +7 -0
  34. package/templates/.cursor/commands/seed-db.sh +5 -0
  35. package/templates/.cursor/commands/test-watch.sh +5 -0
  36. package/templates/.cursor/commands/typecheck.sh +9 -0
  37. package/templates/.cursor/cursor.json +9 -0
  38. package/templates/.cursor/hooks/after-edit.sh +13 -0
  39. package/templates/.cursor/rules/backend-rules.mdc +19 -0
  40. package/templates/.cursor/rules/ui-conventions.md +8 -0
  41. package/templates/.cursor/skills/code-reviewer/SKILL.md +16 -0
  42. package/templates/CLAUDE.md +46 -0
  43. package/templates/claude.local.md +11 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Abu Hurayra
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # ai-devcontext
2
+
3
+ Instantly bootstrap AI coding assistant configuration into any project — `CLAUDE.md`, `claude.local.md`, `.claude/` (rules, skills, commands, agents, hooks, workflows), and `.cursor/` (rules, commands, skills, hooks).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g ai-devcontext
9
+ ```
10
+
11
+ Or run it once without installing:
12
+
13
+ ```bash
14
+ npx ai-devcontext init
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ From the root of any project:
20
+
21
+ ```bash
22
+ devcontext init
23
+ ```
24
+
25
+ This copies the full template tree into your project, skipping any file that already exists, marks shell command scripts executable, and adds `claude.local.md` / `.claude/settings.local.json` to your `.gitignore`.
26
+
27
+ ## What gets created
28
+
29
+ ```
30
+ CLAUDE.md Root project guide (stack, build/test/lint, conventions)
31
+ claude.local.md Personal, git-ignored local notes
32
+
33
+ .cursor/
34
+ ├── .cursorignore
35
+ ├── cursor.json
36
+ ├── .cursorrules Legacy fallback rules
37
+ ├── rules/ Scoped rules (backend, UI conventions)
38
+ ├── commands/ Dev task scripts (lint, format, test, docker, db, etc.)
39
+ ├── skills/code-reviewer/
40
+ └── hooks/after-edit.sh
41
+
42
+ .claude/
43
+ ├── settings.json
44
+ ├── settings.local.json Machine-specific, git-ignored
45
+ ├── rules/ Architecture + security checklist
46
+ ├── skills/testing-patterns/
47
+ ├── commands/ Same dev task scripts as .cursor/commands/
48
+ ├── agents/security-scanner/
49
+ ├── hooks/after-edit.sh
50
+ └── workflows/deployment-guide.md
51
+ ```
52
+
53
+ ## License
54
+
55
+ MIT
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "ai-devcontext",
3
+ "version": "1.0.0",
4
+ "description": "Instantly bootstrap AI configuration templates (CLAUDE.md, .claude/, .cursor/) into any project.",
5
+ "type": "module",
6
+ "bin": {
7
+ "devcontext": "./src/index.js"
8
+ },
9
+ "files": [
10
+ "src",
11
+ "templates"
12
+ ],
13
+ "scripts": {
14
+ "start": "node src/index.js"
15
+ },
16
+ "dependencies": {
17
+ "chalk": "^5.3.0",
18
+ "commander": "^12.0.0",
19
+ "fs-extra": "^11.2.0"
20
+ },
21
+ "engines": {
22
+ "node": ">=18.0.0"
23
+ },
24
+ "keywords": [
25
+ "ai",
26
+ "cursor",
27
+ "claude",
28
+ "devtools",
29
+ "cli",
30
+ "templates"
31
+ ],
32
+ "author": "Abu Hurayra <abu.hurayra@sjinnovation.com>",
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/abuhurayra0889/ai-devcontext-cli.git"
37
+ },
38
+ "bugs": {
39
+ "url": "https://github.com/abuhurayra0889/ai-devcontext-cli/issues"
40
+ },
41
+ "homepage": "https://github.com/abuhurayra0889/ai-devcontext-cli#readme"
42
+ }
package/src/index.js ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import chalk from 'chalk';
5
+ import fs from 'fs-extra';
6
+ import path from 'path';
7
+ import { fileURLToPath } from 'url';
8
+
9
+ // ESM __dirname fix
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
12
+
13
+ // Files that should never be committed by the consuming project.
14
+ const GITIGNORE_ENTRIES = ['claude.local.md', '.claude/settings.local.json'];
15
+
16
+ const program = new Command();
17
+
18
+ program
19
+ .name('devcontext')
20
+ .description('Bootstrap AI configuration templates into your project.')
21
+ .version('1.0.0');
22
+
23
+ async function copyTemplateTree(srcDir, destDir, targetDir) {
24
+ const entries = await fs.readdir(srcDir, { withFileTypes: true });
25
+
26
+ for (const entry of entries) {
27
+ const srcPath = path.join(srcDir, entry.name);
28
+ const destPath = path.join(destDir, entry.name);
29
+ const relPath = path.relative(targetDir, destPath);
30
+
31
+ if (entry.isDirectory()) {
32
+ await copyTemplateTree(srcPath, destPath, targetDir);
33
+ continue;
34
+ }
35
+
36
+ const exists = await fs.pathExists(destPath);
37
+ if (exists) {
38
+ console.log(chalk.yellow(` ⚠ Skipped → ${relPath} (already exists)`));
39
+ continue;
40
+ }
41
+
42
+ await fs.ensureDir(path.dirname(destPath));
43
+ await fs.copy(srcPath, destPath);
44
+
45
+ if (entry.name.endsWith('.sh')) {
46
+ await fs.chmod(destPath, 0o755);
47
+ }
48
+
49
+ console.log(chalk.green(` ✔ Created → ${relPath}`));
50
+ }
51
+ }
52
+
53
+ async function updateGitignore(targetDir) {
54
+ const gitignorePath = path.join(targetDir, '.gitignore');
55
+ const existing = (await fs.pathExists(gitignorePath))
56
+ ? await fs.readFile(gitignorePath, 'utf8')
57
+ : '';
58
+
59
+ const missing = GITIGNORE_ENTRIES.filter(
60
+ (entry) => !existing.split('\n').some((line) => line.trim() === entry)
61
+ );
62
+
63
+ if (missing.length === 0) return;
64
+
65
+ const header = existing.trim().length > 0 ? '\n\n# devcontext: local/personal AI context\n' : '# devcontext: local/personal AI context\n';
66
+ await fs.appendFile(gitignorePath, header + missing.join('\n') + '\n');
67
+ console.log(chalk.green(` ✔ Updated → .gitignore`));
68
+ }
69
+
70
+ program
71
+ .command('init')
72
+ .description('Copy AI context templates into the current working directory.')
73
+ .action(async () => {
74
+ const templatesDir = path.resolve(__dirname, '../templates');
75
+ const targetDir = process.cwd();
76
+
77
+ console.log(chalk.cyan('\n⚙ Initializing AI context templates...\n'));
78
+
79
+ try {
80
+ await copyTemplateTree(templatesDir, targetDir, targetDir);
81
+ await updateGitignore(targetDir);
82
+
83
+ console.log(chalk.bold.greenBright('\n✅ Done! AI context templates are ready.\n'));
84
+ } catch (err) {
85
+ console.error(chalk.red('\n❌ Failed to copy templates:'), err.message);
86
+ process.exit(1);
87
+ }
88
+ });
89
+
90
+ program.parse(process.argv);
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: security-scanner
3
+ description: Use proactively after changes touching auth, input handling, or data access to scan for OWASP-class vulnerabilities. Runs in an isolated sandbox with read access to the diff.
4
+ tools: Read, Grep, Glob, Bash
5
+ ---
6
+
7
+ # Security Scanner Agent
8
+
9
+ ## Identity
10
+ You audit code changes for security vulnerabilities. You do not fix issues yourself —
11
+ you report findings for the calling agent or user to act on.
12
+
13
+ ## Scope
14
+ - Injection risks: SQL/NoSQL, command, path traversal
15
+ - Auth/authz: missing checks, ownership bypass, token handling
16
+ - Secrets: hardcoded credentials, secrets in logs or error responses
17
+ - Dependency risks: known-vulnerable packages introduced by the change
18
+
19
+ ## Process
20
+ 1. Read the diff or changed files provided.
21
+ 2. Cross-reference against `.claude/rules/security-checklist.md`.
22
+ 3. For each finding, report: file, line, the concrete exploit scenario, and severity.
23
+ 4. Do not report style or correctness issues outside of security — that's a different agent's job.
24
+
25
+ ## Boundaries
26
+ - Read-only: never modify files
27
+ - Never execute code from the diff being audited
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ # Removes build artifacts and caches so the next install/build starts from a clean slate.
3
+ set -euo pipefail
4
+
5
+ rm -rf dist build coverage .turbo .next .cache node_modules/.cache
6
+ echo "Cleaned build artifacts and caches. Run 'npm install' if node_modules was affected."
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ # Task runner invoked by name or agent intent: applies pending database migrations.
3
+ set -euo pipefail
4
+
5
+ echo "Running database migrations..."
6
+ npm run migrate
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Stops and removes the local Docker Compose stack.
3
+ set -euo pipefail
4
+
5
+ docker compose down
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env bash
2
+ # Builds and starts the local Docker Compose stack in the background.
3
+ set -euo pipefail
4
+
5
+ if [ ! -f "docker-compose.yml" ] && [ ! -f "compose.yml" ]; then
6
+ echo "No docker-compose.yml/compose.yml found in this project."
7
+ exit 1
8
+ fi
9
+
10
+ docker compose up -d --build
11
+ docker compose ps
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ # Formats the codebase with Prettier (or the project's configured formatter).
3
+ set -euo pipefail
4
+
5
+ if npm run format --if-present; then
6
+ exit 0
7
+ fi
8
+
9
+ npx --no-install prettier --write . 2>/dev/null || echo "No formatter configured — add a 'format' script or Prettier config."
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Runs the linter in autofix mode.
3
+ set -euo pipefail
4
+
5
+ npm run lint --if-present -- --fix
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env bash
2
+ # Scaffolds a new REST resource: model + controller + route stub.
3
+ # Usage: new-resource.sh <ResourceName> e.g. new-resource.sh Invoice
4
+ set -euo pipefail
5
+
6
+ NAME="${1:-}"
7
+ if [ -z "$NAME" ]; then
8
+ echo "Usage: new-resource.sh <ResourceName>"
9
+ exit 1
10
+ fi
11
+
12
+ LOWER="$(echo "${NAME:0:1}" | tr '[:upper:]' '[:lower:]')${NAME:1}"
13
+
14
+ mkdir -p models controllers routes
15
+
16
+ cat > "models/${NAME}.js" <<EOF
17
+ import mongoose from 'mongoose';
18
+
19
+ const ${LOWER}Schema = new mongoose.Schema(
20
+ {
21
+ // TODO: define fields
22
+ },
23
+ { timestamps: true }
24
+ );
25
+
26
+ export default mongoose.model('${NAME}', ${LOWER}Schema);
27
+ EOF
28
+
29
+ cat > "controllers/${LOWER}Controller.js" <<EOF
30
+ import ${NAME} from '../models/${NAME}.js';
31
+
32
+ export async function list(req, res) {
33
+ const items = await ${NAME}.find();
34
+ res.json(items);
35
+ }
36
+
37
+ export async function getById(req, res) {
38
+ const item = await ${NAME}.findById(req.params.id);
39
+ if (!item) return res.status(404).json({ error: { code: 'NOT_FOUND', message: '${NAME} not found' } });
40
+ res.json(item);
41
+ }
42
+
43
+ export async function create(req, res) {
44
+ const item = await ${NAME}.create(req.body);
45
+ res.status(201).json(item);
46
+ }
47
+
48
+ export async function update(req, res) {
49
+ const item = await ${NAME}.findByIdAndUpdate(req.params.id, req.body, { new: true });
50
+ if (!item) return res.status(404).json({ error: { code: 'NOT_FOUND', message: '${NAME} not found' } });
51
+ res.json(item);
52
+ }
53
+
54
+ export async function remove(req, res) {
55
+ await ${NAME}.findByIdAndDelete(req.params.id);
56
+ res.status(204).end();
57
+ }
58
+ EOF
59
+
60
+ cat > "routes/${LOWER}Routes.js" <<EOF
61
+ import { Router } from 'express';
62
+ import * as ${LOWER}Controller from '../controllers/${LOWER}Controller.js';
63
+
64
+ const router = Router();
65
+
66
+ router.get('/', ${LOWER}Controller.list);
67
+ router.get('/:id', ${LOWER}Controller.getById);
68
+ router.post('/', ${LOWER}Controller.create);
69
+ router.patch('/:id', ${LOWER}Controller.update);
70
+ router.delete('/:id', ${LOWER}Controller.remove);
71
+
72
+ export default router;
73
+ EOF
74
+
75
+ echo "Created models/${NAME}.js, controllers/${LOWER}Controller.js, routes/${LOWER}Routes.js"
76
+ echo "Remember to mount the router in your app entrypoint and fill in the schema fields."
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ # Reports outdated dependencies. Read-only — does not upgrade anything automatically.
3
+ set -euo pipefail
4
+
5
+ npm outdated || true
6
+ echo ""
7
+ echo "Review before upgrading — check changelogs for breaking changes, especially major bumps."
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Seeds the local database with fixture/development data.
3
+ set -euo pipefail
4
+
5
+ npm run seed --if-present || echo "No 'seed' script defined in package.json."
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Runs the test suite in watch mode for tight feedback loops during development.
3
+ set -euo pipefail
4
+
5
+ npm test -- --watch
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ # Runs the TypeScript compiler in check-only mode, if the project uses TS.
3
+ set -euo pipefail
4
+
5
+ if [ -f "tsconfig.json" ]; then
6
+ npx --no-install tsc --noEmit
7
+ else
8
+ echo "No tsconfig.json found — nothing to typecheck."
9
+ fi
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bash
2
+ # Automated cleanup/formatting script, fired after Claude modifies a file.
3
+ set -euo pipefail
4
+
5
+ FILE="${1:-}"
6
+ [ -z "$FILE" ] && exit 0
7
+
8
+ case "$FILE" in
9
+ *.js|*.jsx|*.ts|*.tsx|*.json|*.css)
10
+ npx --no-install prettier --write "$FILE" 2>/dev/null || true
11
+ ;;
12
+ esac
@@ -0,0 +1,7 @@
1
+ # Architectural Documentation Principles
2
+
3
+ - Document decisions, not implementation — code already shows *what*; docs should explain *why*
4
+ - Keep architecture docs close to the code they describe; prefer a short README per module over one giant doc
5
+ - When a doc and the code disagree, the code wins — flag the doc as stale rather than trusting it blindly
6
+ - Record trade-offs considered and rejected, not just the chosen path — future readers need to know what was ruled out and why
7
+ - Avoid documenting anything derivable by reading the code (file layout, obvious naming) — it will rot
@@ -0,0 +1,25 @@
1
+ # Security Checklist
2
+
3
+ Run through this before finalizing any change that touches input handling, auth, or data access.
4
+
5
+ ## Input & Injection
6
+ - All user input is validated/sanitized before use (never trust client data)
7
+ - Database queries use parameterization/ODM query builders — no string-concatenated queries
8
+ - File paths derived from user input are validated against traversal (`../`)
9
+ - Shell commands never interpolate unsanitized user input
10
+
11
+ ## Auth & Access Control
12
+ - Every endpoint checks authentication before authorization
13
+ - Authorization checks resource ownership, not just role — a valid token isn't enough
14
+ - Tokens/secrets are never logged, echoed in error messages, or committed to source
15
+
16
+ ## Data Handling
17
+ - Secrets and credentials come from environment variables, never hardcoded
18
+ - Sensitive fields (passwords, tokens) are hashed/encrypted at rest, never stored plaintext
19
+ - Responses don't leak internal details (stack traces, DB errors) to the client
20
+
21
+ ## Dependencies
22
+ - New dependencies are checked for maintenance status and known CVEs before adding
23
+ - Prefer built-in APIs over adding a dependency for something trivial
24
+
25
+ Flag any violation explicitly with a `⚠️ Security:` prefix rather than silently fixing or ignoring it.
@@ -0,0 +1,15 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npm run *)",
5
+ "Bash(npm test)",
6
+ "Bash(git status)",
7
+ "Bash(git diff*)",
8
+ "Bash(git log*)"
9
+ ],
10
+ "deny": [
11
+ "Bash(git push --force*)",
12
+ "Bash(rm -rf *)"
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "permissions": {
3
+ "allow": []
4
+ }
5
+ }
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: testing-patterns
3
+ description: Conventions for writing and running tests in this project — use when adding or modifying tests.
4
+ ---
5
+
6
+ # Testing Patterns
7
+
8
+ ## When to use
9
+ When writing new tests, fixing failing tests, or asked to add test coverage.
10
+
11
+ ## Conventions
12
+ - Test files live next to the code they test, or under a mirrored `__tests__`/`test` directory — match whatever the repo already does
13
+ - One behavior per test; test names describe the behavior, not the implementation
14
+ - Use real dependencies where feasible; mock only true external boundaries (network, third-party APIs, time)
15
+ - Cover the golden path plus the edge cases that actually matter for this code — not exhaustive permutations
16
+ - A failing test must fail for the reason it claims to — verify by temporarily breaking the code under test
17
+
18
+ ## Running tests
19
+ ```bash
20
+ npm test # full suite
21
+ npm test -- <pattern> # filtered run
22
+ ```
@@ -0,0 +1,13 @@
1
+ # Deployment Guide
2
+
3
+ Strict, chronological steps for shipping a release. Do not reorder or skip steps.
4
+
5
+ 1. Confirm `main` is green in CI (build, lint, test all passing)
6
+ 2. Bump the version (`npm version <patch|minor|major>`)
7
+ 3. Update the changelog with user-facing changes since the last release
8
+ 4. Push the version commit and tag: `git push && git push --tags`
9
+ 5. Confirm the release workflow in GitHub Actions builds and pushes the Docker image
10
+ 6. Deploy to staging first; run smoke tests against staging
11
+ 7. Promote staging to production
12
+ 8. Watch error/latency dashboards for 15 minutes post-deploy before considering the deploy complete
13
+ 9. If anything regresses, roll back immediately rather than attempting a forward fix under pressure
@@ -0,0 +1,12 @@
1
+ node_modules/
2
+ dist/
3
+ build/
4
+ coverage/
5
+ .next/
6
+ .turbo/
7
+ *.log
8
+ .env
9
+ .env.*
10
+ *.lock
11
+ *.min.js
12
+ *.map
@@ -0,0 +1,24 @@
1
+ # Cursor AI Rules (legacy fallback — prefer .cursor/rules/*.mdc)
2
+
3
+ ## Project Philosophy
4
+ - Write clean, readable, and maintainable code above all else.
5
+ - Prefer explicit over implicit; avoid magic unless well-documented.
6
+ - Follow SOLID principles and separation of concerns.
7
+
8
+ ## Code Style
9
+ - Use `async/await` — never raw `.then()/.catch()` chains
10
+ - Always destructure imports: `import { foo } from 'bar'`
11
+ - Prefer `const` > `let`; never use `var`
12
+ - File names: `kebab-case.js`, component names: `PascalCase.jsx`
13
+ - Max function length: ~40 lines. Extract if longer.
14
+
15
+ ## Error Handling
16
+ - All async functions must have a `try/catch` block
17
+ - Never silently swallow errors — always log or rethrow
18
+ - Use structured error objects: `{ code, message, details }`
19
+
20
+ ## AI Behavior
21
+ - Do not generate commented-out code
22
+ - Do not add unnecessary boilerplate or placeholder TODO blocks
23
+ - When refactoring, touch only the requested scope
24
+ - Always suggest the simplest solution first
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ # AI-invokable task: install, lint, test, and build in one pass.
3
+ set -euo pipefail
4
+
5
+ npm install
6
+ npm run lint
7
+ npm test
8
+ npm run build
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ # Removes build artifacts and caches so the next install/build starts from a clean slate.
3
+ set -euo pipefail
4
+
5
+ rm -rf dist build coverage .turbo .next .cache node_modules/.cache
6
+ echo "Cleaned build artifacts and caches. Run 'npm install' if node_modules was affected."
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Stops and removes the local Docker Compose stack.
3
+ set -euo pipefail
4
+
5
+ docker compose down
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env bash
2
+ # Builds and starts the local Docker Compose stack in the background.
3
+ set -euo pipefail
4
+
5
+ if [ ! -f "docker-compose.yml" ] && [ ! -f "compose.yml" ]; then
6
+ echo "No docker-compose.yml/compose.yml found in this project."
7
+ exit 1
8
+ fi
9
+
10
+ docker compose up -d --build
11
+ docker compose ps
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ # Formats the codebase with Prettier (or the project's configured formatter).
3
+ set -euo pipefail
4
+
5
+ if npm run format --if-present; then
6
+ exit 0
7
+ fi
8
+
9
+ npx --no-install prettier --write . 2>/dev/null || echo "No formatter configured — add a 'format' script or Prettier config."
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Runs the linter in autofix mode.
3
+ set -euo pipefail
4
+
5
+ npm run lint --if-present -- --fix
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env bash
2
+ # Scaffolds a new REST resource: model + controller + route stub.
3
+ # Usage: new-resource.sh <ResourceName> e.g. new-resource.sh Invoice
4
+ set -euo pipefail
5
+
6
+ NAME="${1:-}"
7
+ if [ -z "$NAME" ]; then
8
+ echo "Usage: new-resource.sh <ResourceName>"
9
+ exit 1
10
+ fi
11
+
12
+ LOWER="$(echo "${NAME:0:1}" | tr '[:upper:]' '[:lower:]')${NAME:1}"
13
+
14
+ mkdir -p models controllers routes
15
+
16
+ cat > "models/${NAME}.js" <<EOF
17
+ import mongoose from 'mongoose';
18
+
19
+ const ${LOWER}Schema = new mongoose.Schema(
20
+ {
21
+ // TODO: define fields
22
+ },
23
+ { timestamps: true }
24
+ );
25
+
26
+ export default mongoose.model('${NAME}', ${LOWER}Schema);
27
+ EOF
28
+
29
+ cat > "controllers/${LOWER}Controller.js" <<EOF
30
+ import ${NAME} from '../models/${NAME}.js';
31
+
32
+ export async function list(req, res) {
33
+ const items = await ${NAME}.find();
34
+ res.json(items);
35
+ }
36
+
37
+ export async function getById(req, res) {
38
+ const item = await ${NAME}.findById(req.params.id);
39
+ if (!item) return res.status(404).json({ error: { code: 'NOT_FOUND', message: '${NAME} not found' } });
40
+ res.json(item);
41
+ }
42
+
43
+ export async function create(req, res) {
44
+ const item = await ${NAME}.create(req.body);
45
+ res.status(201).json(item);
46
+ }
47
+
48
+ export async function update(req, res) {
49
+ const item = await ${NAME}.findByIdAndUpdate(req.params.id, req.body, { new: true });
50
+ if (!item) return res.status(404).json({ error: { code: 'NOT_FOUND', message: '${NAME} not found' } });
51
+ res.json(item);
52
+ }
53
+
54
+ export async function remove(req, res) {
55
+ await ${NAME}.findByIdAndDelete(req.params.id);
56
+ res.status(204).end();
57
+ }
58
+ EOF
59
+
60
+ cat > "routes/${LOWER}Routes.js" <<EOF
61
+ import { Router } from 'express';
62
+ import * as ${LOWER}Controller from '../controllers/${LOWER}Controller.js';
63
+
64
+ const router = Router();
65
+
66
+ router.get('/', ${LOWER}Controller.list);
67
+ router.get('/:id', ${LOWER}Controller.getById);
68
+ router.post('/', ${LOWER}Controller.create);
69
+ router.patch('/:id', ${LOWER}Controller.update);
70
+ router.delete('/:id', ${LOWER}Controller.remove);
71
+
72
+ export default router;
73
+ EOF
74
+
75
+ echo "Created models/${NAME}.js, controllers/${LOWER}Controller.js, routes/${LOWER}Routes.js"
76
+ echo "Remember to mount the router in your app entrypoint and fill in the schema fields."
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ # Reports outdated dependencies. Read-only — does not upgrade anything automatically.
3
+ set -euo pipefail
4
+
5
+ npm outdated || true
6
+ echo ""
7
+ echo "Review before upgrading — check changelogs for breaking changes, especially major bumps."
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Seeds the local database with fixture/development data.
3
+ set -euo pipefail
4
+
5
+ npm run seed --if-present || echo "No 'seed' script defined in package.json."
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Runs the test suite in watch mode for tight feedback loops during development.
3
+ set -euo pipefail
4
+
5
+ npm test -- --watch
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ # Runs the TypeScript compiler in check-only mode, if the project uses TS.
3
+ set -euo pipefail
4
+
5
+ if [ -f "tsconfig.json" ]; then
6
+ npx --no-install tsc --noEmit
7
+ else
8
+ echo "No tsconfig.json found — nothing to typecheck."
9
+ fi
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "https://cursor.sh/schema/cursor.json",
3
+ "rules": {
4
+ "directory": ".cursor/rules"
5
+ },
6
+ "editor": {
7
+ "formatOnSave": true
8
+ }
9
+ }
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env bash
2
+ # Fires automatically after the AI modifies a file.
3
+ # Keep this fast — it runs synchronously in the edit loop.
4
+ set -euo pipefail
5
+
6
+ FILE="${1:-}"
7
+ [ -z "$FILE" ] && exit 0
8
+
9
+ case "$FILE" in
10
+ *.js|*.jsx|*.ts|*.tsx)
11
+ npx --no-install prettier --write "$FILE" 2>/dev/null || true
12
+ ;;
13
+ esac
@@ -0,0 +1,19 @@
1
+ ---
2
+ description: Backend/API conventions
3
+ globs:
4
+ - "server/**/*"
5
+ - "backend/**/*"
6
+ - "**/controllers/**/*"
7
+ - "**/routes/**/*"
8
+ - "**/models/**/*"
9
+ alwaysApply: false
10
+ ---
11
+
12
+ # Backend Rules
13
+
14
+ - API routes follow REST conventions: `GET /api/resource`, `POST /api/resource`, `PATCH /api/resource/:id`
15
+ - Controllers stay thin — business logic lives in services, not route handlers
16
+ - Every route handler validates input before touching the database
17
+ - Never trust client-supplied IDs for authorization — always check ownership server-side
18
+ - Return consistent error shapes: `{ error: { code, message } }`
19
+ - Log errors with enough context to reproduce (request id, user id, input shape) — never log secrets
@@ -0,0 +1,8 @@
1
+ # UI Conventions (applies globally to frontend assets)
2
+
3
+ - Components are function components using hooks — no class components
4
+ - Co-locate component styles: `Button.jsx` + `Button.module.css`
5
+ - Keep components under ~150 lines; extract subcomponents or hooks when larger
6
+ - Derive state where possible instead of syncing it with `useEffect`
7
+ - Accessibility is not optional: interactive elements need proper roles, labels, and keyboard support
8
+ - Avoid inline styles except for values computed at runtime
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: code-reviewer
3
+ description: Reviews a diff for correctness bugs, security issues, and unnecessary complexity before it's committed.
4
+ ---
5
+
6
+ # Code Reviewer
7
+
8
+ ## When to use
9
+ Invoke before committing or opening a PR, or when explicitly asked to review changes.
10
+
11
+ ## Steps
12
+ 1. Get the diff (`git diff` for unstaged, `git diff --staged` for staged).
13
+ 2. Check correctness: does the change do what it claims, including edge cases?
14
+ 3. Check security: input validation, auth checks, injection risks (see `.claude/rules/security-checklist.md` if present).
15
+ 4. Check scope: does the diff touch only what's needed, or drag in unrelated changes?
16
+ 5. Report findings ranked by severity. Don't restate the diff — only flag actionable issues.
@@ -0,0 +1,46 @@
1
+ # Project Context
2
+
3
+ ## Role
4
+ You are a senior full-stack engineer working within this codebase.
5
+ Your primary goals are correctness, simplicity, and developer ergonomics.
6
+
7
+ ## Stack
8
+ <!-- Replace with your actual stack. Example (MERN): -->
9
+ - **Frontend:** React 18 SPA, Vite bundler, TailwindCSS
10
+ - **Backend:** Node.js + Express REST API, ES Modules
11
+ - **Database:** MongoDB Atlas, Mongoose schemas
12
+ - **Auth:** JWT access tokens (15min) + HTTP-only refresh tokens (7d)
13
+ - **Deployment:** Docker + GitHub Actions CI/CD
14
+
15
+ ## Build, Test, Lint
16
+ ```bash
17
+ npm install # install dependencies
18
+ npm run dev # start local dev server
19
+ npm test # run test suite
20
+ npm run lint # run linter
21
+ npm run build # production build
22
+ ```
23
+
24
+ ## Coding Conventions
25
+ - Match the existing code style in the file you're editing over any generic default
26
+ - Prefer small, focused functions and modules over large ones
27
+ - Keep naming consistent with surrounding code (case style, verb/noun patterns)
28
+ - Validate configuration and environment variables at startup, not at point of use
29
+ - Don't introduce new dependencies when the standard library or an existing dependency covers the need
30
+
31
+ ## Response Guidelines
32
+ - Respond with working code, not pseudocode
33
+ - When modifying existing files, show only the changed diff, not the entire file
34
+ - If a request is ambiguous, ask one clarifying question before proceeding
35
+ - Flag security risks explicitly with a `⚠️ Security:` prefix
36
+ - Prefer built-in APIs over adding new dependencies
37
+
38
+ ## Out of Scope
39
+ - Do not suggest switching the core stack unless a critical flaw is identified
40
+ - Do not refactor unrelated code in the same response
41
+ - Do not generate files containing real secrets or credentials
42
+
43
+ ## See Also
44
+ - [.claude/rules/](.claude/rules/) — additional context-injected rules (architecture, security)
45
+ - [.claude/workflows/deployment-guide.md](.claude/workflows/deployment-guide.md) — deployment procedure
46
+ - `claude.local.md` — your personal, git-ignored local notes (not committed)
@@ -0,0 +1,11 @@
1
+ # Local Notes (git-ignored)
2
+
3
+ Personal, machine-specific context for working with Claude Code on this project.
4
+ This file is not committed — use it for scratch notes, WIP context, or preferences
5
+ you don't want to impose on the rest of the team.
6
+
7
+ ## Examples of what to put here
8
+ - Local environment quirks (ports, service URLs, test accounts)
9
+ - In-progress investigation notes
10
+ - Personal shortcuts or aliases you want Claude to know about
11
+ - Anything from CLAUDE.md you want to temporarily override for yourself