thrivekit 2.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/commands/explain.md +114 -0
- package/.claude/commands/idea.md +370 -0
- package/.claude/commands/my-dna.md +122 -0
- package/.claude/commands/prd.md +286 -0
- package/.claude/commands/review.md +167 -0
- package/.claude/commands/sign.md +32 -0
- package/.claude/commands/styleguide.md +450 -0
- package/.claude/commands/tour.md +301 -0
- package/.claude/commands/vibe-check.md +116 -0
- package/.claude/commands/vibe-help.md +47 -0
- package/.claude/commands/vibe-list.md +203 -0
- package/.claude/settings.json +75 -0
- package/.claude/settings.local.json +12 -0
- package/.pre-commit-hooks.yaml +102 -0
- package/LICENSE +21 -0
- package/README.md +214 -0
- package/bin/postinstall.sh +29 -0
- package/bin/ralph.sh +171 -0
- package/bin/thrivekit.sh +24 -0
- package/bin/vibe-check.js +19 -0
- package/dist/checks/check-any-types.d.ts +6 -0
- package/dist/checks/check-any-types.d.ts.map +1 -0
- package/dist/checks/check-any-types.js +73 -0
- package/dist/checks/check-any-types.js.map +1 -0
- package/dist/checks/check-commented-code.d.ts +6 -0
- package/dist/checks/check-commented-code.d.ts.map +1 -0
- package/dist/checks/check-commented-code.js +81 -0
- package/dist/checks/check-commented-code.js.map +1 -0
- package/dist/checks/check-console-error.d.ts +6 -0
- package/dist/checks/check-console-error.d.ts.map +1 -0
- package/dist/checks/check-console-error.js +41 -0
- package/dist/checks/check-console-error.js.map +1 -0
- package/dist/checks/check-debug-statements.d.ts +6 -0
- package/dist/checks/check-debug-statements.d.ts.map +1 -0
- package/dist/checks/check-debug-statements.js +120 -0
- package/dist/checks/check-debug-statements.js.map +1 -0
- package/dist/checks/check-deep-nesting.d.ts +6 -0
- package/dist/checks/check-deep-nesting.d.ts.map +1 -0
- package/dist/checks/check-deep-nesting.js +116 -0
- package/dist/checks/check-deep-nesting.js.map +1 -0
- package/dist/checks/check-docker-platform.d.ts +6 -0
- package/dist/checks/check-docker-platform.d.ts.map +1 -0
- package/dist/checks/check-docker-platform.js +42 -0
- package/dist/checks/check-docker-platform.js.map +1 -0
- package/dist/checks/check-dry-violations.d.ts +6 -0
- package/dist/checks/check-dry-violations.d.ts.map +1 -0
- package/dist/checks/check-dry-violations.js +124 -0
- package/dist/checks/check-dry-violations.js.map +1 -0
- package/dist/checks/check-empty-catch.d.ts +6 -0
- package/dist/checks/check-empty-catch.d.ts.map +1 -0
- package/dist/checks/check-empty-catch.js +111 -0
- package/dist/checks/check-empty-catch.js.map +1 -0
- package/dist/checks/check-function-length.d.ts +6 -0
- package/dist/checks/check-function-length.d.ts.map +1 -0
- package/dist/checks/check-function-length.js +152 -0
- package/dist/checks/check-function-length.js.map +1 -0
- package/dist/checks/check-hardcoded-ai-models.d.ts +10 -0
- package/dist/checks/check-hardcoded-ai-models.d.ts.map +1 -0
- package/dist/checks/check-hardcoded-ai-models.js +102 -0
- package/dist/checks/check-hardcoded-ai-models.js.map +1 -0
- package/dist/checks/check-hardcoded-urls.d.ts +6 -0
- package/dist/checks/check-hardcoded-urls.d.ts.map +1 -0
- package/dist/checks/check-hardcoded-urls.js +124 -0
- package/dist/checks/check-hardcoded-urls.js.map +1 -0
- package/dist/checks/check-magic-numbers.d.ts +6 -0
- package/dist/checks/check-magic-numbers.d.ts.map +1 -0
- package/dist/checks/check-magic-numbers.js +116 -0
- package/dist/checks/check-magic-numbers.js.map +1 -0
- package/dist/checks/check-secrets.d.ts +6 -0
- package/dist/checks/check-secrets.d.ts.map +1 -0
- package/dist/checks/check-secrets.js +138 -0
- package/dist/checks/check-secrets.js.map +1 -0
- package/dist/checks/check-snake-case-ts.d.ts +6 -0
- package/dist/checks/check-snake-case-ts.d.ts.map +1 -0
- package/dist/checks/check-snake-case-ts.js +78 -0
- package/dist/checks/check-snake-case-ts.js.map +1 -0
- package/dist/checks/check-todo-fixme.d.ts +6 -0
- package/dist/checks/check-todo-fixme.d.ts.map +1 -0
- package/dist/checks/check-todo-fixme.js +41 -0
- package/dist/checks/check-todo-fixme.js.map +1 -0
- package/dist/checks/check-unsafe-html.d.ts +6 -0
- package/dist/checks/check-unsafe-html.d.ts.map +1 -0
- package/dist/checks/check-unsafe-html.js +101 -0
- package/dist/checks/check-unsafe-html.js.map +1 -0
- package/dist/checks/index.d.ts +30 -0
- package/dist/checks/index.d.ts.map +1 -0
- package/dist/checks/index.js +57 -0
- package/dist/checks/index.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +206 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/file-reader.d.ts +24 -0
- package/dist/utils/file-reader.d.ts.map +1 -0
- package/dist/utils/file-reader.js +140 -0
- package/dist/utils/file-reader.js.map +1 -0
- package/dist/utils/patterns.d.ts +27 -0
- package/dist/utils/patterns.d.ts.map +1 -0
- package/dist/utils/patterns.js +84 -0
- package/dist/utils/patterns.js.map +1 -0
- package/dist/utils/reporters.d.ts +21 -0
- package/dist/utils/reporters.d.ts.map +1 -0
- package/dist/utils/reporters.js +115 -0
- package/dist/utils/reporters.js.map +1 -0
- package/dist/utils/types.d.ts +71 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +5 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +82 -0
- package/ralph/api.sh +210 -0
- package/ralph/backup.sh +838 -0
- package/ralph/browser-verify/README.md +135 -0
- package/ralph/browser-verify/verify.ts +450 -0
- package/ralph/checks/check-fastapi-responses.py +155 -0
- package/ralph/hooks/hooks-config.json +72 -0
- package/ralph/hooks/inject-context.sh +44 -0
- package/ralph/hooks/install.sh +207 -0
- package/ralph/hooks/log-tools.sh +45 -0
- package/ralph/hooks/protect-prd.sh +27 -0
- package/ralph/hooks/save-learnings.sh +36 -0
- package/ralph/hooks/warn-debug.sh +54 -0
- package/ralph/hooks/warn-empty-catch.sh +63 -0
- package/ralph/hooks/warn-secrets.sh +89 -0
- package/ralph/hooks/warn-urls.sh +77 -0
- package/ralph/init.sh +388 -0
- package/ralph/loop.sh +570 -0
- package/ralph/playwright.sh +238 -0
- package/ralph/prd.sh +295 -0
- package/ralph/setup/feature-tour.sh +155 -0
- package/ralph/setup/quick-setup.sh +239 -0
- package/ralph/setup/tutorial.sh +159 -0
- package/ralph/setup/ui.sh +136 -0
- package/ralph/setup.sh +353 -0
- package/ralph/signs.sh +150 -0
- package/ralph/utils.sh +682 -0
- package/ralph/verify/browser.sh +324 -0
- package/ralph/verify/lint.sh +363 -0
- package/ralph/verify/review.sh +164 -0
- package/ralph/verify/tests.sh +81 -0
- package/ralph/verify.sh +224 -0
- package/templates/PROMPT.md +235 -0
- package/templates/config/fullstack.json +86 -0
- package/templates/config/go.json +81 -0
- package/templates/config/minimal.json +76 -0
- package/templates/config/node.json +81 -0
- package/templates/config/python.json +81 -0
- package/templates/config/rust.json +81 -0
- package/templates/examples/CLAUDE-django.md +174 -0
- package/templates/examples/CLAUDE-fastapi.md +270 -0
- package/templates/examples/CLAUDE-fastmcp.md +352 -0
- package/templates/examples/CLAUDE-fullstack.md +256 -0
- package/templates/examples/CLAUDE-node.md +246 -0
- package/templates/examples/CLAUDE-react.md +138 -0
- package/templates/optional/cursorrules.template +147 -0
- package/templates/optional/eslint.config.js +34 -0
- package/templates/optional/lint-staged.config.js +34 -0
- package/templates/optional/ruff.toml +125 -0
- package/templates/optional/vibe-check.yml +116 -0
- package/templates/optional/vscode-settings.json +127 -0
- package/templates/signs.json +46 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"auth": {
|
|
3
|
+
"testUser": "",
|
|
4
|
+
"testPassword": "",
|
|
5
|
+
"loginEndpoint": "/api/auth/login",
|
|
6
|
+
"loginMethod": "POST",
|
|
7
|
+
"tokenType": "session",
|
|
8
|
+
"tokenHeader": "Authorization",
|
|
9
|
+
"tokenPrefix": "Bearer"
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
"docker": {
|
|
13
|
+
"enabled": false,
|
|
14
|
+
"composeFile": "docker-compose.yml",
|
|
15
|
+
"serviceName": "web",
|
|
16
|
+
"execPrefix": "docker compose exec -T"
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
"paths": {
|
|
20
|
+
"frontend": "frontend",
|
|
21
|
+
"backend": ".",
|
|
22
|
+
"tests": "tests",
|
|
23
|
+
"e2e": "frontend/tests/e2e"
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
"commands": {
|
|
27
|
+
"devFrontend": "cd frontend && npm run dev",
|
|
28
|
+
"devBackend": "python manage.py runserver",
|
|
29
|
+
"install": "npm install && pip install -r requirements.txt",
|
|
30
|
+
"seed": "",
|
|
31
|
+
"resetDb": ""
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
"migrations": {
|
|
35
|
+
"command": "python manage.py migrate",
|
|
36
|
+
"pattern": "migrations/.*\\.py$"
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
"checks": {
|
|
40
|
+
"typescript": "cd frontend && npx tsc --noEmit",
|
|
41
|
+
"lint": "ruff check .",
|
|
42
|
+
"lintFrontend": "cd frontend && npm run lint",
|
|
43
|
+
"test": "python manage.py test --keepdb --parallel",
|
|
44
|
+
"testFrontend": "cd frontend && npm test"
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
"api": {
|
|
48
|
+
"baseUrl": "http://localhost:8000",
|
|
49
|
+
"healthEndpoint": "/api/health",
|
|
50
|
+
"timeout": 30
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
"playwright": {
|
|
54
|
+
"enabled": true,
|
|
55
|
+
"testDir": "frontend/tests/e2e",
|
|
56
|
+
"projects": ["chromium", "mobile"],
|
|
57
|
+
"baseUrl": "http://localhost:3000"
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
"verification": {
|
|
61
|
+
"codeReviewEnabled": true,
|
|
62
|
+
"browserEnabled": true,
|
|
63
|
+
"a11yEnabled": true,
|
|
64
|
+
"mobileViewport": 375,
|
|
65
|
+
"screenshotOnFailure": true
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
"urls": {
|
|
69
|
+
"frontend": "http://localhost:3000",
|
|
70
|
+
"backend": "http://localhost:8000",
|
|
71
|
+
"docs": "http://localhost:8000/api/docs"
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
"env": {
|
|
75
|
+
"required": ["DATABASE_URL", "SECRET_KEY"],
|
|
76
|
+
"optional": ["REDIS_URL", "SENTRY_DSN"]
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
"maxIterations": 20,
|
|
80
|
+
"maxSessionSeconds": 600,
|
|
81
|
+
|
|
82
|
+
"contextRotThreshold": {
|
|
83
|
+
"maxStories": 10,
|
|
84
|
+
"maxFilesChanged": 20
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"auth": {
|
|
3
|
+
"testUser": "",
|
|
4
|
+
"testPassword": "",
|
|
5
|
+
"loginEndpoint": "/api/auth/login",
|
|
6
|
+
"loginMethod": "POST",
|
|
7
|
+
"tokenType": "jwt",
|
|
8
|
+
"tokenHeader": "Authorization",
|
|
9
|
+
"tokenPrefix": "Bearer"
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
"docker": {
|
|
13
|
+
"enabled": false,
|
|
14
|
+
"composeFile": "docker-compose.yml",
|
|
15
|
+
"serviceName": "app",
|
|
16
|
+
"execPrefix": "docker compose exec -T"
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
"paths": {
|
|
20
|
+
"src": ".",
|
|
21
|
+
"tests": ".",
|
|
22
|
+
"e2e": "tests/e2e"
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"commands": {
|
|
26
|
+
"dev": "go run .",
|
|
27
|
+
"install": "go mod download",
|
|
28
|
+
"seed": "",
|
|
29
|
+
"resetDb": ""
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
"migrations": {
|
|
33
|
+
"command": "migrate -path migrations -database $DATABASE_URL up",
|
|
34
|
+
"pattern": "migrations/.*\\.sql$"
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
"checks": {
|
|
38
|
+
"build": "go build ./...",
|
|
39
|
+
"lint": "golangci-lint run",
|
|
40
|
+
"test": "go test ./..."
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
"api": {
|
|
44
|
+
"baseUrl": "http://localhost:8080",
|
|
45
|
+
"healthEndpoint": "/health",
|
|
46
|
+
"timeout": 30
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
"playwright": {
|
|
50
|
+
"enabled": false,
|
|
51
|
+
"testDir": "tests/e2e",
|
|
52
|
+
"projects": ["chromium"],
|
|
53
|
+
"baseUrl": "http://localhost:8080"
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
"verification": {
|
|
57
|
+
"codeReviewEnabled": true,
|
|
58
|
+
"browserEnabled": true,
|
|
59
|
+
"a11yEnabled": false,
|
|
60
|
+
"mobileViewport": 375,
|
|
61
|
+
"screenshotOnFailure": true
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
"urls": {
|
|
65
|
+
"app": "http://localhost:8080",
|
|
66
|
+
"docs": "http://localhost:8080/swagger"
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
"env": {
|
|
70
|
+
"required": ["DATABASE_URL"],
|
|
71
|
+
"optional": ["REDIS_URL"]
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
"maxIterations": 20,
|
|
75
|
+
"maxSessionSeconds": 600,
|
|
76
|
+
|
|
77
|
+
"contextRotThreshold": {
|
|
78
|
+
"maxStories": 10,
|
|
79
|
+
"maxFilesChanged": 20
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"auth": {
|
|
3
|
+
"testUser": "",
|
|
4
|
+
"testPassword": "",
|
|
5
|
+
"loginEndpoint": "/api/auth/login",
|
|
6
|
+
"loginMethod": "POST",
|
|
7
|
+
"tokenType": "session",
|
|
8
|
+
"tokenHeader": "Authorization",
|
|
9
|
+
"tokenPrefix": "Bearer"
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
"docker": {
|
|
13
|
+
"enabled": false,
|
|
14
|
+
"composeFile": "docker-compose.yml",
|
|
15
|
+
"serviceName": "app",
|
|
16
|
+
"execPrefix": "docker compose exec -T"
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
"paths": {
|
|
20
|
+
"src": "src",
|
|
21
|
+
"tests": "tests",
|
|
22
|
+
"e2e": "tests/e2e"
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"commands": {
|
|
26
|
+
"dev": "",
|
|
27
|
+
"install": "",
|
|
28
|
+
"seed": "",
|
|
29
|
+
"resetDb": ""
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
"migrations": {
|
|
33
|
+
"command": "",
|
|
34
|
+
"pattern": ""
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
"checks": {},
|
|
38
|
+
|
|
39
|
+
"api": {
|
|
40
|
+
"baseUrl": "http://localhost:3000",
|
|
41
|
+
"healthEndpoint": "/health",
|
|
42
|
+
"timeout": 30
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
"playwright": {
|
|
46
|
+
"enabled": false,
|
|
47
|
+
"testDir": "tests/e2e",
|
|
48
|
+
"projects": ["chromium"],
|
|
49
|
+
"baseUrl": "http://localhost:3000"
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
"verification": {
|
|
53
|
+
"codeReviewEnabled": false,
|
|
54
|
+
"browserEnabled": false,
|
|
55
|
+
"a11yEnabled": false,
|
|
56
|
+
"mobileViewport": 375,
|
|
57
|
+
"screenshotOnFailure": false
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
"urls": {
|
|
61
|
+
"app": "http://localhost:3000"
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
"env": {
|
|
65
|
+
"required": [],
|
|
66
|
+
"optional": []
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
"maxIterations": 20,
|
|
70
|
+
"maxSessionSeconds": 600,
|
|
71
|
+
|
|
72
|
+
"contextRotThreshold": {
|
|
73
|
+
"maxStories": 10,
|
|
74
|
+
"maxFilesChanged": 20
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"auth": {
|
|
3
|
+
"testUser": "",
|
|
4
|
+
"testPassword": "",
|
|
5
|
+
"loginEndpoint": "/api/auth/login",
|
|
6
|
+
"loginMethod": "POST",
|
|
7
|
+
"tokenType": "jwt",
|
|
8
|
+
"tokenHeader": "Authorization",
|
|
9
|
+
"tokenPrefix": "Bearer"
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
"docker": {
|
|
13
|
+
"enabled": false,
|
|
14
|
+
"composeFile": "docker-compose.yml",
|
|
15
|
+
"serviceName": "app",
|
|
16
|
+
"execPrefix": "docker compose exec -T"
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
"paths": {
|
|
20
|
+
"src": "src",
|
|
21
|
+
"tests": "tests",
|
|
22
|
+
"e2e": "tests/e2e"
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"commands": {
|
|
26
|
+
"dev": "npm run dev",
|
|
27
|
+
"install": "npm install",
|
|
28
|
+
"seed": "",
|
|
29
|
+
"resetDb": ""
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
"migrations": {
|
|
33
|
+
"command": "npx prisma migrate deploy",
|
|
34
|
+
"pattern": "prisma/migrations/.*"
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
"checks": {
|
|
38
|
+
"typescript": "npx tsc --noEmit",
|
|
39
|
+
"lint": "npm run lint",
|
|
40
|
+
"test": "npm test"
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
"api": {
|
|
44
|
+
"baseUrl": "http://localhost:3000",
|
|
45
|
+
"healthEndpoint": "/api/health",
|
|
46
|
+
"timeout": 30
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
"playwright": {
|
|
50
|
+
"enabled": true,
|
|
51
|
+
"testDir": "tests/e2e",
|
|
52
|
+
"projects": ["chromium", "mobile"],
|
|
53
|
+
"baseUrl": "http://localhost:3000"
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
"verification": {
|
|
57
|
+
"codeReviewEnabled": true,
|
|
58
|
+
"browserEnabled": true,
|
|
59
|
+
"a11yEnabled": true,
|
|
60
|
+
"mobileViewport": 375,
|
|
61
|
+
"screenshotOnFailure": true
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
"urls": {
|
|
65
|
+
"app": "http://localhost:3000",
|
|
66
|
+
"docs": "http://localhost:3000/api/docs"
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
"env": {
|
|
70
|
+
"required": ["DATABASE_URL"],
|
|
71
|
+
"optional": ["REDIS_URL", "SENTRY_DSN"]
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
"maxIterations": 20,
|
|
75
|
+
"maxSessionSeconds": 600,
|
|
76
|
+
|
|
77
|
+
"contextRotThreshold": {
|
|
78
|
+
"maxStories": 10,
|
|
79
|
+
"maxFilesChanged": 20
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"auth": {
|
|
3
|
+
"testUser": "",
|
|
4
|
+
"testPassword": "",
|
|
5
|
+
"loginEndpoint": "/api/auth/login",
|
|
6
|
+
"loginMethod": "POST",
|
|
7
|
+
"tokenType": "jwt",
|
|
8
|
+
"tokenHeader": "Authorization",
|
|
9
|
+
"tokenPrefix": "Bearer"
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
"docker": {
|
|
13
|
+
"enabled": false,
|
|
14
|
+
"composeFile": "docker-compose.yml",
|
|
15
|
+
"serviceName": "app",
|
|
16
|
+
"execPrefix": "docker compose exec -T"
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
"paths": {
|
|
20
|
+
"src": "src",
|
|
21
|
+
"tests": "tests",
|
|
22
|
+
"e2e": "tests/e2e"
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"commands": {
|
|
26
|
+
"dev": "uvicorn main:app --reload",
|
|
27
|
+
"install": "pip install -r requirements.txt",
|
|
28
|
+
"seed": "",
|
|
29
|
+
"resetDb": ""
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
"migrations": {
|
|
33
|
+
"command": "alembic upgrade head",
|
|
34
|
+
"pattern": "alembic/versions/.*\\.py$"
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
"checks": {
|
|
38
|
+
"lint": "ruff check .",
|
|
39
|
+
"typecheck": "mypy .",
|
|
40
|
+
"test": "pytest"
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
"api": {
|
|
44
|
+
"baseUrl": "http://localhost:8000",
|
|
45
|
+
"healthEndpoint": "/api/health",
|
|
46
|
+
"timeout": 30
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
"playwright": {
|
|
50
|
+
"enabled": false,
|
|
51
|
+
"testDir": "tests/e2e",
|
|
52
|
+
"projects": ["chromium"],
|
|
53
|
+
"baseUrl": "http://localhost:8000"
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
"verification": {
|
|
57
|
+
"codeReviewEnabled": true,
|
|
58
|
+
"browserEnabled": true,
|
|
59
|
+
"a11yEnabled": false,
|
|
60
|
+
"mobileViewport": 375,
|
|
61
|
+
"screenshotOnFailure": true
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
"urls": {
|
|
65
|
+
"app": "http://localhost:8000",
|
|
66
|
+
"docs": "http://localhost:8000/docs"
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
"env": {
|
|
70
|
+
"required": ["DATABASE_URL"],
|
|
71
|
+
"optional": ["REDIS_URL", "SENTRY_DSN"]
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
"maxIterations": 20,
|
|
75
|
+
"maxSessionSeconds": 600,
|
|
76
|
+
|
|
77
|
+
"contextRotThreshold": {
|
|
78
|
+
"maxStories": 10,
|
|
79
|
+
"maxFilesChanged": 20
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"auth": {
|
|
3
|
+
"testUser": "",
|
|
4
|
+
"testPassword": "",
|
|
5
|
+
"loginEndpoint": "/api/auth/login",
|
|
6
|
+
"loginMethod": "POST",
|
|
7
|
+
"tokenType": "jwt",
|
|
8
|
+
"tokenHeader": "Authorization",
|
|
9
|
+
"tokenPrefix": "Bearer"
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
"docker": {
|
|
13
|
+
"enabled": false,
|
|
14
|
+
"composeFile": "docker-compose.yml",
|
|
15
|
+
"serviceName": "app",
|
|
16
|
+
"execPrefix": "docker compose exec -T"
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
"paths": {
|
|
20
|
+
"src": "src",
|
|
21
|
+
"tests": "tests",
|
|
22
|
+
"e2e": "tests/e2e"
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"commands": {
|
|
26
|
+
"dev": "cargo run",
|
|
27
|
+
"install": "cargo build",
|
|
28
|
+
"seed": "",
|
|
29
|
+
"resetDb": ""
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
"migrations": {
|
|
33
|
+
"command": "sqlx migrate run",
|
|
34
|
+
"pattern": "migrations/.*\\.sql$"
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
"checks": {
|
|
38
|
+
"build": "cargo build",
|
|
39
|
+
"lint": "cargo clippy -- -D warnings",
|
|
40
|
+
"test": "cargo test"
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
"api": {
|
|
44
|
+
"baseUrl": "http://localhost:8080",
|
|
45
|
+
"healthEndpoint": "/health",
|
|
46
|
+
"timeout": 30
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
"playwright": {
|
|
50
|
+
"enabled": false,
|
|
51
|
+
"testDir": "tests/e2e",
|
|
52
|
+
"projects": ["chromium"],
|
|
53
|
+
"baseUrl": "http://localhost:8080"
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
"verification": {
|
|
57
|
+
"codeReviewEnabled": true,
|
|
58
|
+
"browserEnabled": true,
|
|
59
|
+
"a11yEnabled": false,
|
|
60
|
+
"mobileViewport": 375,
|
|
61
|
+
"screenshotOnFailure": true
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
"urls": {
|
|
65
|
+
"app": "http://localhost:8080",
|
|
66
|
+
"docs": "http://localhost:8080/swagger"
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
"env": {
|
|
70
|
+
"required": ["DATABASE_URL"],
|
|
71
|
+
"optional": ["REDIS_URL"]
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
"maxIterations": 20,
|
|
75
|
+
"maxSessionSeconds": 600,
|
|
76
|
+
|
|
77
|
+
"contextRotThreshold": {
|
|
78
|
+
"maxStories": 10,
|
|
79
|
+
"maxFilesChanged": 20
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Project Instructions for AI Coding Agents
|
|
2
|
+
|
|
3
|
+
## Naming Conventions
|
|
4
|
+
- **Files**: `snake_case.py` — e.g., `user_views.py`, `auth_serializers.py`
|
|
5
|
+
- **Functions/Variables**: `snake_case` — e.g., `get_user_by_id`, `is_authenticated`
|
|
6
|
+
- **Classes**: `PascalCase` — e.g., `UserViewSet`, `AuthSerializer`
|
|
7
|
+
- **Models**: `PascalCase` singular — e.g., `User`, `BlogPost` (Django pluralizes table names)
|
|
8
|
+
- **Constants**: `SCREAMING_SNAKE` — e.g., `MAX_UPLOAD_SIZE`, `DEFAULT_PAGE_SIZE`
|
|
9
|
+
- **URL patterns**: `kebab-case` — e.g., `/api/user-profile/`, `/api/blog-posts/`
|
|
10
|
+
- **Template files**: `snake_case.html` — e.g., `user_detail.html`
|
|
11
|
+
|
|
12
|
+
## Tech Stack
|
|
13
|
+
- **Backend**: Django 5, Django REST Framework
|
|
14
|
+
- **Database**: PostgreSQL
|
|
15
|
+
- **Cache/Queue**: Redis, Celery
|
|
16
|
+
- **Testing**: pytest, pytest-django
|
|
17
|
+
|
|
18
|
+
## Code Quality Standards
|
|
19
|
+
|
|
20
|
+
### Python Style
|
|
21
|
+
- Follow PEP 8
|
|
22
|
+
- Use type hints for function signatures
|
|
23
|
+
- Maximum line length: 88 (Black default)
|
|
24
|
+
- Use f-strings for string formatting
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
# Good
|
|
28
|
+
def get_user_by_email(email: str) -> User | None:
|
|
29
|
+
"""Fetch a user by their email address."""
|
|
30
|
+
return User.objects.filter(email=email).first()
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Django Models
|
|
34
|
+
- Use explicit `related_name` on ForeignKey/M2M
|
|
35
|
+
- Add `__str__` method to all models
|
|
36
|
+
- Use model managers for complex queries
|
|
37
|
+
- Add indexes for frequently queried fields
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
class Order(models.Model):
|
|
41
|
+
user = models.ForeignKey(
|
|
42
|
+
User,
|
|
43
|
+
on_delete=models.CASCADE,
|
|
44
|
+
related_name='orders'
|
|
45
|
+
)
|
|
46
|
+
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
47
|
+
|
|
48
|
+
class Meta:
|
|
49
|
+
ordering = ['-created_at']
|
|
50
|
+
|
|
51
|
+
def __str__(self):
|
|
52
|
+
return f"Order {self.id} by {self.user.email}"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Django REST Framework
|
|
56
|
+
- Use serializers for all input/output
|
|
57
|
+
- Use ViewSets for CRUD operations
|
|
58
|
+
- Use proper permission classes
|
|
59
|
+
- Return appropriate HTTP status codes
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
class OrderViewSet(viewsets.ModelViewSet):
|
|
63
|
+
serializer_class = OrderSerializer
|
|
64
|
+
permission_classes = [IsAuthenticated]
|
|
65
|
+
|
|
66
|
+
def get_queryset(self):
|
|
67
|
+
# Only return user's own orders
|
|
68
|
+
return Order.objects.filter(user=self.request.user)
|
|
69
|
+
|
|
70
|
+
def perform_create(self, serializer):
|
|
71
|
+
serializer.save(user=self.request.user)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Error Handling
|
|
75
|
+
- Use DRF exceptions for API errors
|
|
76
|
+
- Log errors with context
|
|
77
|
+
- Never expose internal errors to users
|
|
78
|
+
- Handle specific exceptions, not bare except
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
# Bad
|
|
82
|
+
try:
|
|
83
|
+
process_order(order)
|
|
84
|
+
except Exception:
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
# Good
|
|
88
|
+
try:
|
|
89
|
+
process_order(order)
|
|
90
|
+
except PaymentError as e:
|
|
91
|
+
logger.error(f"Payment failed for order {order.id}: {e}")
|
|
92
|
+
raise ValidationError({"payment": "Payment processing failed"})
|
|
93
|
+
except InventoryError as e:
|
|
94
|
+
logger.warning(f"Inventory issue for order {order.id}: {e}")
|
|
95
|
+
raise ValidationError({"inventory": str(e)})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Database Queries
|
|
99
|
+
- Avoid N+1 queries (use select_related/prefetch_related)
|
|
100
|
+
- Use .only() or .defer() for large models
|
|
101
|
+
- Use database transactions for multi-step operations
|
|
102
|
+
- Add indexes for filter/order fields
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
# Bad - N+1 query
|
|
106
|
+
orders = Order.objects.all()
|
|
107
|
+
for order in orders:
|
|
108
|
+
print(order.user.email) # Hits DB for each order
|
|
109
|
+
|
|
110
|
+
# Good
|
|
111
|
+
orders = Order.objects.select_related('user').all()
|
|
112
|
+
for order in orders:
|
|
113
|
+
print(order.user.email) # No additional queries
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Security
|
|
117
|
+
- Use Django's CSRF protection
|
|
118
|
+
- Validate all user input with serializers
|
|
119
|
+
- Use parameterized queries (Django ORM does this)
|
|
120
|
+
- Never trust user input for file paths or shell commands
|
|
121
|
+
|
|
122
|
+
### Testing
|
|
123
|
+
- Use pytest and pytest-django
|
|
124
|
+
- Use fixtures for test data
|
|
125
|
+
- Test API endpoints with APIClient
|
|
126
|
+
- Mock external services
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
@pytest.mark.django_db
|
|
130
|
+
class TestOrderAPI:
|
|
131
|
+
def test_create_order(self, authenticated_client, product):
|
|
132
|
+
response = authenticated_client.post('/api/orders/', {
|
|
133
|
+
'product_id': product.id,
|
|
134
|
+
'quantity': 2,
|
|
135
|
+
})
|
|
136
|
+
assert response.status_code == 201
|
|
137
|
+
assert Order.objects.count() == 1
|
|
138
|
+
|
|
139
|
+
def test_cannot_create_order_unauthenticated(self, client):
|
|
140
|
+
response = client.post('/api/orders/', {})
|
|
141
|
+
assert response.status_code == 401
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## File Structure
|
|
145
|
+
```
|
|
146
|
+
project/
|
|
147
|
+
├── config/ # Django settings, URLs, WSGI
|
|
148
|
+
├── apps/
|
|
149
|
+
│ ├── users/ # User-related models, views
|
|
150
|
+
│ ├── orders/ # Order-related models, views
|
|
151
|
+
│ └── common/ # Shared utilities
|
|
152
|
+
├── tests/ # Test files
|
|
153
|
+
└── manage.py
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Environment Variables
|
|
157
|
+
```python
|
|
158
|
+
# settings.py
|
|
159
|
+
DATABASE_URL = os.getenv('DATABASE_URL')
|
|
160
|
+
SECRET_KEY = os.getenv('SECRET_KEY')
|
|
161
|
+
DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Pre-commit Hooks
|
|
165
|
+
This project uses thrivekit hooks. Run `/vibe-check` before committing.
|
|
166
|
+
|
|
167
|
+
## Common Commands
|
|
168
|
+
```bash
|
|
169
|
+
make up # Start Docker services
|
|
170
|
+
make migrate # Run migrations
|
|
171
|
+
make test # Run tests
|
|
172
|
+
make shell # Django shell
|
|
173
|
+
make logs # View logs
|
|
174
|
+
```
|