@su-record/vibe 2.5.11 → 2.5.13
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.md +243 -0
- package/LICENSE +21 -21
- package/README.md +262 -262
- package/agents/architect-low.md +41 -41
- package/agents/architect-medium.md +59 -59
- package/agents/architect.md +80 -80
- package/agents/build-error-resolver.md +115 -115
- package/agents/compounder.md +261 -261
- package/agents/diagrammer.md +178 -178
- package/agents/e2e-tester.md +266 -266
- package/agents/explorer-low.md +42 -42
- package/agents/explorer-medium.md +59 -59
- package/agents/explorer.md +48 -48
- package/agents/implementer-low.md +43 -43
- package/agents/implementer-medium.md +52 -52
- package/agents/implementer.md +54 -54
- package/agents/refactor-cleaner.md +143 -143
- package/agents/research/best-practices-agent.md +189 -189
- package/agents/research/codebase-patterns-agent.md +147 -147
- package/agents/research/framework-docs-agent.md +178 -178
- package/agents/research/security-advisory-agent.md +203 -203
- package/agents/review/architecture-reviewer.md +107 -107
- package/agents/review/complexity-reviewer.md +116 -116
- package/agents/review/data-integrity-reviewer.md +88 -88
- package/agents/review/git-history-reviewer.md +103 -103
- package/agents/review/performance-reviewer.md +86 -86
- package/agents/review/python-reviewer.md +150 -150
- package/agents/review/rails-reviewer.md +139 -139
- package/agents/review/react-reviewer.md +144 -144
- package/agents/review/security-reviewer.md +80 -80
- package/agents/review/simplicity-reviewer.md +140 -140
- package/agents/review/test-coverage-reviewer.md +116 -116
- package/agents/review/typescript-reviewer.md +127 -127
- package/agents/searcher.md +54 -54
- package/agents/simplifier.md +120 -120
- package/agents/tester.md +49 -49
- package/agents/ui-previewer.md +129 -129
- package/commands/vibe.analyze.md +356 -356
- package/commands/vibe.reason.md +329 -329
- package/commands/vibe.review.md +326 -326
- package/commands/vibe.run.md +1117 -1051
- package/commands/vibe.spec.md +1058 -1058
- package/commands/vibe.utils.md +353 -296
- package/commands/vibe.verify.md +375 -375
- package/dist/cli/collaborator.js +52 -52
- package/dist/cli/detect.js +32 -32
- package/dist/cli/index.js +102 -102
- package/dist/cli/llm.js +144 -144
- package/dist/cli/mcp.d.ts +49 -0
- package/dist/cli/mcp.d.ts.map +1 -0
- package/dist/cli/mcp.js +169 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/postinstall.js +180 -2
- package/dist/cli/postinstall.js.map +1 -1
- package/dist/cli/setup/GlobalInstaller.d.ts +24 -0
- package/dist/cli/setup/GlobalInstaller.d.ts.map +1 -0
- package/dist/cli/setup/GlobalInstaller.js +130 -0
- package/dist/cli/setup/GlobalInstaller.js.map +1 -0
- package/dist/cli/setup/LanguageDetector.d.ts +16 -0
- package/dist/cli/setup/LanguageDetector.d.ts.map +1 -0
- package/dist/cli/setup/LanguageDetector.js +49 -0
- package/dist/cli/setup/LanguageDetector.js.map +1 -0
- package/dist/cli/setup/LegacyMigration.d.ts +25 -0
- package/dist/cli/setup/LegacyMigration.d.ts.map +1 -0
- package/dist/cli/setup/LegacyMigration.js +162 -0
- package/dist/cli/setup/LegacyMigration.js.map +1 -0
- package/dist/cli/setup/ProjectSetup.d.ts +30 -0
- package/dist/cli/setup/ProjectSetup.d.ts.map +1 -0
- package/dist/cli/setup/ProjectSetup.js +238 -0
- package/dist/cli/setup/ProjectSetup.js.map +1 -0
- package/dist/cli/setup/index.d.ts +14 -0
- package/dist/cli/setup/index.d.ts.map +1 -0
- package/dist/cli/setup/index.js +18 -0
- package/dist/cli/setup/index.js.map +1 -0
- package/dist/cli/setup.d.ts +10 -77
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +15 -592
- package/dist/cli/setup.js.map +1 -1
- package/dist/lib/DeepInit.d.ts +0 -2
- package/dist/lib/DeepInit.d.ts.map +1 -1
- package/dist/lib/DeepInit.js +24 -26
- package/dist/lib/DeepInit.js.map +1 -1
- package/dist/lib/IterationTracker.d.ts +0 -2
- package/dist/lib/IterationTracker.d.ts.map +1 -1
- package/dist/lib/IterationTracker.js +11 -13
- package/dist/lib/IterationTracker.js.map +1 -1
- package/dist/lib/ModelRouter.d.ts +0 -2
- package/dist/lib/ModelRouter.d.ts.map +1 -1
- package/dist/lib/ModelRouter.js +0 -2
- package/dist/lib/ModelRouter.js.map +1 -1
- package/dist/lib/OrchestrateWorkflow.d.ts +1 -3
- package/dist/lib/OrchestrateWorkflow.d.ts.map +1 -1
- package/dist/lib/OrchestrateWorkflow.js +1 -3
- package/dist/lib/OrchestrateWorkflow.js.map +1 -1
- package/dist/lib/PythonParser.js +108 -108
- package/dist/lib/SkillFrontmatter.d.ts +0 -2
- package/dist/lib/SkillFrontmatter.d.ts.map +1 -1
- package/dist/lib/SkillFrontmatter.js +28 -30
- package/dist/lib/SkillFrontmatter.js.map +1 -1
- package/dist/lib/SkillQualityGate.d.ts +0 -2
- package/dist/lib/SkillQualityGate.d.ts.map +1 -1
- package/dist/lib/SkillQualityGate.js +9 -11
- package/dist/lib/SkillQualityGate.js.map +1 -1
- package/dist/lib/SkillRepository.d.ts +117 -0
- package/dist/lib/SkillRepository.d.ts.map +1 -0
- package/dist/lib/SkillRepository.js +477 -0
- package/dist/lib/SkillRepository.js.map +1 -0
- package/dist/lib/UltraQA.d.ts +0 -2
- package/dist/lib/UltraQA.d.ts.map +1 -1
- package/dist/lib/UltraQA.js +77 -79
- package/dist/lib/UltraQA.js.map +1 -1
- package/dist/lib/gemini-mcp.d.ts +10 -0
- package/dist/lib/gemini-mcp.d.ts.map +1 -0
- package/dist/lib/gemini-mcp.js +353 -0
- package/dist/lib/gemini-mcp.js.map +1 -0
- package/dist/lib/gpt-api.js +4 -4
- package/dist/lib/gpt-mcp.d.ts +10 -0
- package/dist/lib/gpt-mcp.d.ts.map +1 -0
- package/dist/lib/gpt-mcp.js +352 -0
- package/dist/lib/gpt-mcp.js.map +1 -0
- package/dist/lib/llm/auth/ApiKeyManager.d.ts +21 -0
- package/dist/lib/llm/auth/ApiKeyManager.d.ts.map +1 -0
- package/dist/lib/llm/auth/ApiKeyManager.js +43 -0
- package/dist/lib/llm/auth/ApiKeyManager.js.map +1 -0
- package/dist/lib/llm/auth/ConfigManager.d.ts +29 -0
- package/dist/lib/llm/auth/ConfigManager.d.ts.map +1 -0
- package/dist/lib/llm/auth/ConfigManager.js +67 -0
- package/dist/lib/llm/auth/ConfigManager.js.map +1 -0
- package/dist/lib/llm/auth/index.d.ts +25 -0
- package/dist/lib/llm/auth/index.d.ts.map +1 -0
- package/dist/lib/llm/auth/index.js +83 -0
- package/dist/lib/llm/auth/index.js.map +1 -0
- package/dist/lib/llm/index.d.ts +10 -0
- package/dist/lib/llm/index.d.ts.map +1 -0
- package/dist/lib/llm/index.js +12 -0
- package/dist/lib/llm/index.js.map +1 -0
- package/dist/lib/llm/types.d.ts +96 -0
- package/dist/lib/llm/types.d.ts.map +1 -0
- package/dist/lib/llm/types.js +17 -0
- package/dist/lib/llm/types.js.map +1 -0
- package/dist/lib/llm/utils/index.d.ts +6 -0
- package/dist/lib/llm/utils/index.d.ts.map +1 -0
- package/dist/lib/llm/utils/index.js +6 -0
- package/dist/lib/llm/utils/index.js.map +1 -0
- package/dist/lib/llm/utils/retry.d.ts +25 -0
- package/dist/lib/llm/utils/retry.d.ts.map +1 -0
- package/dist/lib/llm/utils/retry.js +72 -0
- package/dist/lib/llm/utils/retry.js.map +1 -0
- package/dist/lib/llm/utils/stream.d.ts +13 -0
- package/dist/lib/llm/utils/stream.d.ts.map +1 -0
- package/dist/lib/llm/utils/stream.js +110 -0
- package/dist/lib/llm/utils/stream.js.map +1 -0
- package/dist/lib/memory/KnowledgeGraph.js +4 -4
- package/dist/lib/memory/MemorySearch.js +20 -20
- package/dist/lib/memory/MemoryStorage.js +64 -64
- package/dist/orchestrator/AgentExecutor.d.ts +23 -0
- package/dist/orchestrator/AgentExecutor.d.ts.map +1 -0
- package/dist/orchestrator/AgentExecutor.js +231 -0
- package/dist/orchestrator/AgentExecutor.js.map +1 -0
- package/dist/orchestrator/AgentManager.d.ts +73 -0
- package/dist/orchestrator/AgentManager.d.ts.map +1 -0
- package/dist/orchestrator/AgentManager.js +184 -0
- package/dist/orchestrator/AgentManager.js.map +1 -0
- package/dist/orchestrator/LLMCluster.d.ts +70 -0
- package/dist/orchestrator/LLMCluster.d.ts.map +1 -0
- package/dist/orchestrator/LLMCluster.js +91 -0
- package/dist/orchestrator/LLMCluster.js.map +1 -0
- package/dist/orchestrator/MultiLlmResearch.d.ts +27 -0
- package/dist/orchestrator/MultiLlmResearch.d.ts.map +1 -0
- package/dist/orchestrator/MultiLlmResearch.js +145 -0
- package/dist/orchestrator/MultiLlmResearch.js.map +1 -0
- package/dist/orchestrator/SessionStore.d.ts +41 -0
- package/dist/orchestrator/SessionStore.d.ts.map +1 -0
- package/dist/orchestrator/SessionStore.js +117 -0
- package/dist/orchestrator/SessionStore.js.map +1 -0
- package/dist/orchestrator/SmartRouter.d.ts +68 -0
- package/dist/orchestrator/SmartRouter.d.ts.map +1 -0
- package/dist/orchestrator/SmartRouter.js +256 -0
- package/dist/orchestrator/SmartRouter.js.map +1 -0
- package/dist/orchestrator/backgroundAgent.d.ts +10 -28
- package/dist/orchestrator/backgroundAgent.d.ts.map +1 -1
- package/dist/orchestrator/backgroundAgent.js +11 -346
- package/dist/orchestrator/backgroundAgent.js.map +1 -1
- package/dist/orchestrator/index.d.ts +3 -0
- package/dist/orchestrator/index.d.ts.map +1 -1
- package/dist/orchestrator/index.js +4 -0
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/orchestrator.d.ts +19 -154
- package/dist/orchestrator/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/orchestrator.js +90 -514
- package/dist/orchestrator/orchestrator.js.map +1 -1
- package/dist/orchestrator/parallelResearch.d.ts +5 -12
- package/dist/orchestrator/parallelResearch.d.ts.map +1 -1
- package/dist/orchestrator/parallelResearch.js +10 -193
- package/dist/orchestrator/parallelResearch.js.map +1 -1
- package/dist/tools/analytics/getUsageAnalytics.d.ts +10 -0
- package/dist/tools/analytics/getUsageAnalytics.d.ts.map +1 -0
- package/dist/tools/analytics/getUsageAnalytics.js +246 -0
- package/dist/tools/analytics/getUsageAnalytics.js.map +1 -0
- package/dist/tools/analytics/index.d.ts +5 -0
- package/dist/tools/analytics/index.d.ts.map +1 -0
- package/dist/tools/analytics/index.js +5 -0
- package/dist/tools/analytics/index.js.map +1 -0
- package/dist/tools/convention/analyzeComplexity.test.js +115 -115
- package/dist/tools/convention/getCodingGuide.d.ts +7 -0
- package/dist/tools/convention/getCodingGuide.d.ts.map +1 -0
- package/dist/tools/convention/getCodingGuide.js +69 -0
- package/dist/tools/convention/getCodingGuide.js.map +1 -0
- package/dist/tools/convention/validateCodeQuality.test.js +104 -104
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/planning/analyzeRequirements.d.ts +9 -0
- package/dist/tools/planning/analyzeRequirements.d.ts.map +1 -0
- package/dist/tools/planning/analyzeRequirements.js +171 -0
- package/dist/tools/planning/analyzeRequirements.js.map +1 -0
- package/dist/tools/planning/createUserStories.d.ts +9 -0
- package/dist/tools/planning/createUserStories.d.ts.map +1 -0
- package/dist/tools/planning/createUserStories.js +124 -0
- package/dist/tools/planning/createUserStories.js.map +1 -0
- package/dist/tools/planning/featureRoadmap.d.ts +10 -0
- package/dist/tools/planning/featureRoadmap.d.ts.map +1 -0
- package/dist/tools/planning/featureRoadmap.js +207 -0
- package/dist/tools/planning/featureRoadmap.js.map +1 -0
- package/dist/tools/planning/generatePrd.d.ts +11 -0
- package/dist/tools/planning/generatePrd.d.ts.map +1 -0
- package/dist/tools/planning/generatePrd.js +161 -0
- package/dist/tools/planning/generatePrd.js.map +1 -0
- package/dist/tools/planning/index.d.ts +8 -0
- package/dist/tools/planning/index.d.ts.map +1 -0
- package/dist/tools/planning/index.js +8 -0
- package/dist/tools/planning/index.js.map +1 -0
- package/dist/tools/prompt/analyzePrompt.d.ts +7 -0
- package/dist/tools/prompt/analyzePrompt.d.ts.map +1 -0
- package/dist/tools/prompt/analyzePrompt.js +150 -0
- package/dist/tools/prompt/analyzePrompt.js.map +1 -0
- package/dist/tools/prompt/enhancePrompt.d.ts +8 -0
- package/dist/tools/prompt/enhancePrompt.d.ts.map +1 -0
- package/dist/tools/prompt/enhancePrompt.js +110 -0
- package/dist/tools/prompt/enhancePrompt.js.map +1 -0
- package/dist/tools/prompt/enhancePromptGemini.d.ts +8 -0
- package/dist/tools/prompt/enhancePromptGemini.d.ts.map +1 -0
- package/dist/tools/prompt/enhancePromptGemini.js +332 -0
- package/dist/tools/prompt/enhancePromptGemini.js.map +1 -0
- package/dist/tools/prompt/index.d.ts +7 -0
- package/dist/tools/prompt/index.d.ts.map +1 -0
- package/dist/tools/prompt/index.js +7 -0
- package/dist/tools/prompt/index.js.map +1 -0
- package/dist/tools/reasoning/applyReasoningFramework.d.ts +8 -0
- package/dist/tools/reasoning/applyReasoningFramework.d.ts.map +1 -0
- package/dist/tools/reasoning/applyReasoningFramework.js +266 -0
- package/dist/tools/reasoning/applyReasoningFramework.js.map +1 -0
- package/dist/tools/reasoning/index.d.ts +5 -0
- package/dist/tools/reasoning/index.d.ts.map +1 -0
- package/dist/tools/reasoning/index.js +5 -0
- package/dist/tools/reasoning/index.js.map +1 -0
- package/dist/tools/thinking/analyzeProblem.d.ts +7 -0
- package/dist/tools/thinking/analyzeProblem.d.ts.map +1 -0
- package/dist/tools/thinking/analyzeProblem.js +55 -0
- package/dist/tools/thinking/analyzeProblem.js.map +1 -0
- package/dist/tools/thinking/breakDownProblem.d.ts +8 -0
- package/dist/tools/thinking/breakDownProblem.d.ts.map +1 -0
- package/dist/tools/thinking/breakDownProblem.js +145 -0
- package/dist/tools/thinking/breakDownProblem.js.map +1 -0
- package/dist/tools/thinking/createThinkingChain.d.ts +7 -0
- package/dist/tools/thinking/createThinkingChain.d.ts.map +1 -0
- package/dist/tools/thinking/createThinkingChain.js +44 -0
- package/dist/tools/thinking/createThinkingChain.js.map +1 -0
- package/dist/tools/thinking/formatAsPlan.d.ts +9 -0
- package/dist/tools/thinking/formatAsPlan.d.ts.map +1 -0
- package/dist/tools/thinking/formatAsPlan.js +78 -0
- package/dist/tools/thinking/formatAsPlan.js.map +1 -0
- package/dist/tools/thinking/index.d.ts +10 -0
- package/dist/tools/thinking/index.d.ts.map +1 -0
- package/dist/tools/thinking/index.js +10 -0
- package/dist/tools/thinking/index.js.map +1 -0
- package/dist/tools/thinking/stepByStepAnalysis.d.ts +8 -0
- package/dist/tools/thinking/stepByStepAnalysis.d.ts.map +1 -0
- package/dist/tools/thinking/stepByStepAnalysis.js +63 -0
- package/dist/tools/thinking/stepByStepAnalysis.js.map +1 -0
- package/dist/tools/thinking/thinkAloudProcess.d.ts +8 -0
- package/dist/tools/thinking/thinkAloudProcess.d.ts.map +1 -0
- package/dist/tools/thinking/thinkAloudProcess.js +80 -0
- package/dist/tools/thinking/thinkAloudProcess.js.map +1 -0
- package/hooks/hooks.json +222 -222
- package/hooks/scripts/code-check.js +22 -22
- package/hooks/scripts/code-review.js +22 -22
- package/hooks/scripts/complexity.js +22 -22
- package/hooks/scripts/compound.js +23 -23
- package/hooks/scripts/context-save.js +33 -33
- package/hooks/scripts/generate-brand-assets.js +472 -0
- package/hooks/scripts/hud-multiline.js +262 -264
- package/hooks/scripts/hud-status.js +291 -293
- package/hooks/scripts/keyword-detector.js +214 -216
- package/hooks/scripts/llm-orchestrate.js +171 -171
- package/hooks/scripts/post-edit.js +97 -97
- package/hooks/scripts/post-tool-verify.js +210 -212
- package/hooks/scripts/pre-tool-guard.js +125 -127
- package/hooks/scripts/recall.js +22 -22
- package/hooks/scripts/session-start.js +30 -30
- package/hooks/scripts/skill-injector.js +191 -193
- package/hooks/scripts/utils.js +97 -97
- package/languages/csharp-unity.md +515 -515
- package/languages/gdscript-godot.md +470 -470
- package/languages/ruby-rails.md +489 -489
- package/languages/typescript-angular.md +433 -433
- package/languages/typescript-astro.md +416 -416
- package/languages/typescript-electron.md +406 -406
- package/languages/typescript-nestjs.md +524 -524
- package/languages/typescript-svelte.md +407 -407
- package/languages/typescript-tauri.md +365 -365
- package/package.json +83 -83
- package/skills/brand-assets.md +141 -0
- package/skills/commerce-patterns.md +361 -0
- package/skills/context7-usage.md +102 -102
- package/skills/e2e-commerce.md +304 -0
- package/skills/frontend-design.md +92 -0
- package/skills/git-worktree.md +181 -181
- package/skills/parallel-research.md +77 -77
- package/skills/priority-todos.md +239 -239
- package/skills/seo-checklist.md +244 -0
- package/skills/tool-fallback.md +190 -190
- package/skills/vibe-capabilities.md +161 -161
- package/vibe/constitution.md +227 -227
- package/vibe/rules/core/communication-guide.md +98 -98
- package/vibe/rules/core/development-philosophy.md +52 -52
- package/vibe/rules/core/quick-start.md +102 -102
- package/vibe/rules/quality/bdd-contract-testing.md +393 -393
- package/vibe/rules/quality/checklist.md +276 -276
- package/vibe/rules/quality/testing-strategy.md +440 -440
- package/vibe/rules/standards/anti-patterns.md +541 -541
- package/vibe/rules/standards/code-structure.md +291 -291
- package/vibe/rules/standards/complexity-metrics.md +313 -313
- package/vibe/rules/standards/naming-conventions.md +198 -198
- package/vibe/setup.sh +31 -31
- package/vibe/templates/constitution-template.md +252 -252
- package/vibe/templates/contract-backend-template.md +526 -526
- package/vibe/templates/contract-frontend-template.md +599 -599
- package/vibe/templates/feature-template.md +96 -96
- package/vibe/templates/spec-template.md +221 -221
package/package.json
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@su-record/vibe",
|
|
3
|
-
"version": "2.5.
|
|
4
|
-
"description": "Vibe - Claude Code exclusive SPEC-driven AI coding framework with 35+ integrated tools",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/cli/index.js",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": "./dist/cli/index.js",
|
|
9
|
-
"./tools": "./dist/tools/index.js",
|
|
10
|
-
"./tools/memory": "./dist/tools/memory/index.js",
|
|
11
|
-
"./tools/convention": "./dist/tools/convention/index.js",
|
|
12
|
-
"./tools/semantic": "./dist/tools/semantic/index.js",
|
|
13
|
-
"./tools/ui": "./dist/tools/ui/index.js",
|
|
14
|
-
"./tools/time": "./dist/tools/time/index.js",
|
|
15
|
-
"./orchestrator": "./dist/orchestrator/index.js",
|
|
16
|
-
"./lib/gpt": "./dist/lib/gpt-api.js",
|
|
17
|
-
"./lib/gemini": "./dist/lib/gemini-api.js"
|
|
18
|
-
},
|
|
19
|
-
"bin": {
|
|
20
|
-
"vibe": "./dist/cli/index.js"
|
|
21
|
-
},
|
|
22
|
-
"scripts": {
|
|
23
|
-
"build": "tsc",
|
|
24
|
-
"dev": "tsc --watch",
|
|
25
|
-
"test": "vitest run",
|
|
26
|
-
"test:watch": "vitest",
|
|
27
|
-
"prepublishOnly": "npm run build",
|
|
28
|
-
"postinstall": "node dist/cli/postinstall.js"
|
|
29
|
-
},
|
|
30
|
-
"keywords": [
|
|
31
|
-
"ai",
|
|
32
|
-
"vibe",
|
|
33
|
-
"coding",
|
|
34
|
-
"spec-driven",
|
|
35
|
-
"claude",
|
|
36
|
-
"mcp",
|
|
37
|
-
"framework",
|
|
38
|
-
"requirements",
|
|
39
|
-
"user-story",
|
|
40
|
-
"ultrawork",
|
|
41
|
-
"parallel-agents",
|
|
42
|
-
"memory-management",
|
|
43
|
-
"knowledge-graph",
|
|
44
|
-
"code-analysis",
|
|
45
|
-
"code-quality"
|
|
46
|
-
],
|
|
47
|
-
"author": "Su",
|
|
48
|
-
"license": "MIT",
|
|
49
|
-
"repository": {
|
|
50
|
-
"type": "git",
|
|
51
|
-
"url": "https://github.com/su-record/vibe.git"
|
|
52
|
-
},
|
|
53
|
-
"homepage": "https://github.com/su-record/vibe#readme",
|
|
54
|
-
"engines": {
|
|
55
|
-
"node": ">=18.0.0"
|
|
56
|
-
},
|
|
57
|
-
"dependencies": {
|
|
58
|
-
"@anthropic-ai/claude-agent-sdk": "^0.2.6",
|
|
59
|
-
"better-sqlite3": "^12.4.1",
|
|
60
|
-
"chalk": "^5.3.0",
|
|
61
|
-
"glob": "^11.0.3",
|
|
62
|
-
"ts-morph": "^26.0.0"
|
|
63
|
-
},
|
|
64
|
-
"devDependencies": {
|
|
65
|
-
"@types/better-sqlite3": "^7.6.13",
|
|
66
|
-
"@types/glob": "^8.1.0",
|
|
67
|
-
"@types/node": "^22.0.0",
|
|
68
|
-
"typescript": "^5.5.4",
|
|
69
|
-
"vitest": "^4.0.9"
|
|
70
|
-
},
|
|
71
|
-
"files": [
|
|
72
|
-
"dist/",
|
|
73
|
-
"vibe/",
|
|
74
|
-
"languages/",
|
|
75
|
-
"commands/",
|
|
76
|
-
"agents/",
|
|
77
|
-
"skills/",
|
|
78
|
-
"hooks/",
|
|
79
|
-
"CLAUDE.md",
|
|
80
|
-
"README.md",
|
|
81
|
-
"LICENSE"
|
|
82
|
-
]
|
|
83
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@su-record/vibe",
|
|
3
|
+
"version": "2.5.13",
|
|
4
|
+
"description": "Vibe - Claude Code exclusive SPEC-driven AI coding framework with 35+ integrated tools",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/cli/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/cli/index.js",
|
|
9
|
+
"./tools": "./dist/tools/index.js",
|
|
10
|
+
"./tools/memory": "./dist/tools/memory/index.js",
|
|
11
|
+
"./tools/convention": "./dist/tools/convention/index.js",
|
|
12
|
+
"./tools/semantic": "./dist/tools/semantic/index.js",
|
|
13
|
+
"./tools/ui": "./dist/tools/ui/index.js",
|
|
14
|
+
"./tools/time": "./dist/tools/time/index.js",
|
|
15
|
+
"./orchestrator": "./dist/orchestrator/index.js",
|
|
16
|
+
"./lib/gpt": "./dist/lib/gpt-api.js",
|
|
17
|
+
"./lib/gemini": "./dist/lib/gemini-api.js"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"vibe": "./dist/cli/index.js"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"dev": "tsc --watch",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest",
|
|
27
|
+
"prepublishOnly": "npm run build",
|
|
28
|
+
"postinstall": "node dist/cli/postinstall.js"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"ai",
|
|
32
|
+
"vibe",
|
|
33
|
+
"coding",
|
|
34
|
+
"spec-driven",
|
|
35
|
+
"claude",
|
|
36
|
+
"mcp",
|
|
37
|
+
"framework",
|
|
38
|
+
"requirements",
|
|
39
|
+
"user-story",
|
|
40
|
+
"ultrawork",
|
|
41
|
+
"parallel-agents",
|
|
42
|
+
"memory-management",
|
|
43
|
+
"knowledge-graph",
|
|
44
|
+
"code-analysis",
|
|
45
|
+
"code-quality"
|
|
46
|
+
],
|
|
47
|
+
"author": "Su",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/su-record/vibe.git"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/su-record/vibe#readme",
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=18.0.0"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.6",
|
|
59
|
+
"better-sqlite3": "^12.4.1",
|
|
60
|
+
"chalk": "^5.3.0",
|
|
61
|
+
"glob": "^11.0.3",
|
|
62
|
+
"ts-morph": "^26.0.0"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
66
|
+
"@types/glob": "^8.1.0",
|
|
67
|
+
"@types/node": "^22.0.0",
|
|
68
|
+
"typescript": "^5.5.4",
|
|
69
|
+
"vitest": "^4.0.9"
|
|
70
|
+
},
|
|
71
|
+
"files": [
|
|
72
|
+
"dist/",
|
|
73
|
+
"vibe/",
|
|
74
|
+
"languages/",
|
|
75
|
+
"commands/",
|
|
76
|
+
"agents/",
|
|
77
|
+
"skills/",
|
|
78
|
+
"hooks/",
|
|
79
|
+
"CLAUDE.md",
|
|
80
|
+
"README.md",
|
|
81
|
+
"LICENSE"
|
|
82
|
+
]
|
|
83
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brand-assets
|
|
3
|
+
description: "Auto-generate app icons and favicons from SPEC brand information using Gemini Image API"
|
|
4
|
+
triggers: [icon, favicon, brand, logo, app icon, branding, assets]
|
|
5
|
+
priority: 65
|
|
6
|
+
---
|
|
7
|
+
# Brand Assets Generation Skill
|
|
8
|
+
|
|
9
|
+
Auto-generate app icons and favicons based on SPEC brand information.
|
|
10
|
+
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
- First-time project setup with `/vibe.run`
|
|
14
|
+
- When SPEC contains brand/design information
|
|
15
|
+
- When Gemini API key is configured
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- Gemini API key configured (`vibe gemini auth`)
|
|
20
|
+
- SPEC with brand context (app name, colors, style)
|
|
21
|
+
|
|
22
|
+
## Generated Assets
|
|
23
|
+
|
|
24
|
+
### Web
|
|
25
|
+
- `favicon.ico` (16x16, 32x32, 48x48)
|
|
26
|
+
- `favicon-16x16.png`
|
|
27
|
+
- `favicon-32x32.png`
|
|
28
|
+
- `apple-touch-icon.png` (180x180)
|
|
29
|
+
- `android-chrome-192x192.png`
|
|
30
|
+
- `android-chrome-512x512.png`
|
|
31
|
+
|
|
32
|
+
### Mobile (if applicable)
|
|
33
|
+
- iOS: `AppIcon.appiconset/` with all sizes
|
|
34
|
+
- Android: `mipmap-*/` adaptive icons
|
|
35
|
+
|
|
36
|
+
## SPEC Brand Section
|
|
37
|
+
|
|
38
|
+
For best results, include brand info in your SPEC:
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
<context>
|
|
42
|
+
Brand:
|
|
43
|
+
- App Name: MyApp
|
|
44
|
+
- Primary Color: #2F6BFF
|
|
45
|
+
- Style: Modern, minimal, flat design
|
|
46
|
+
- Icon Concept: Abstract geometric shape representing connectivity
|
|
47
|
+
</context>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Generation Flow
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
SPEC Brand Info
|
|
54
|
+
|
|
|
55
|
+
v
|
|
56
|
+
Extract: name, colors, style keywords
|
|
57
|
+
|
|
|
58
|
+
v
|
|
59
|
+
Generate Prompt: "App icon for [name], [style], [colors]..."
|
|
60
|
+
|
|
|
61
|
+
v
|
|
62
|
+
Gemini Image API (imagen-3)
|
|
63
|
+
|
|
|
64
|
+
v
|
|
65
|
+
Resize & Convert: All platform sizes
|
|
66
|
+
|
|
|
67
|
+
v
|
|
68
|
+
Save to: public/ or assets/
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Auto-Trigger Conditions
|
|
72
|
+
|
|
73
|
+
1. First `/vibe.run` execution (no existing icons)
|
|
74
|
+
2. SPEC contains brand/design context
|
|
75
|
+
3. Gemini API key is available
|
|
76
|
+
4. `--generate-icons` flag passed
|
|
77
|
+
|
|
78
|
+
## Skip Conditions
|
|
79
|
+
|
|
80
|
+
- Icons already exist (unless `--regenerate-icons`)
|
|
81
|
+
- No brand info in SPEC
|
|
82
|
+
- Gemini API not configured
|
|
83
|
+
|
|
84
|
+
## Prompt Template
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
Create a modern app icon for "[APP_NAME]".
|
|
88
|
+
|
|
89
|
+
Style: [STYLE_KEYWORDS]
|
|
90
|
+
Primary color: [PRIMARY_COLOR]
|
|
91
|
+
Design: Minimalist, professional, suitable for mobile app
|
|
92
|
+
Format: Square, clean edges, simple recognizable shape
|
|
93
|
+
Background: Solid color or subtle gradient
|
|
94
|
+
|
|
95
|
+
Requirements:
|
|
96
|
+
- Works at small sizes (16x16 to 512x512)
|
|
97
|
+
- No text or letters
|
|
98
|
+
- Single focal element
|
|
99
|
+
- High contrast for visibility
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Manual Usage
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Generate via hook script (when Gemini configured)
|
|
106
|
+
node hooks/scripts/generate-brand-assets.js \
|
|
107
|
+
--name "MyApp" \
|
|
108
|
+
--color "#2F6BFF" \
|
|
109
|
+
--style "modern minimal" \
|
|
110
|
+
--output "./public"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Integration with /vibe.run
|
|
114
|
+
|
|
115
|
+
During Phase 1 (Setup), if brand assets don't exist:
|
|
116
|
+
|
|
117
|
+
1. Parse SPEC for brand context
|
|
118
|
+
2. Generate icon via Gemini Image API
|
|
119
|
+
3. Create all size variants
|
|
120
|
+
4. Place in appropriate directories
|
|
121
|
+
5. Update manifest files if needed
|
|
122
|
+
|
|
123
|
+
## Fallback Strategy
|
|
124
|
+
|
|
125
|
+
If Gemini Image fails:
|
|
126
|
+
1. Generate text-based monogram icon (first letter)
|
|
127
|
+
2. Use project primary color as background
|
|
128
|
+
3. Create simple geometric placeholder
|
|
129
|
+
|
|
130
|
+
## Output Structure
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
public/
|
|
134
|
+
favicon.ico
|
|
135
|
+
favicon-16x16.png
|
|
136
|
+
favicon-32x32.png
|
|
137
|
+
apple-touch-icon.png
|
|
138
|
+
android-chrome-192x192.png
|
|
139
|
+
android-chrome-512x512.png
|
|
140
|
+
site.webmanifest
|
|
141
|
+
```
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: commerce-patterns
|
|
3
|
+
description: "E-commerce domain patterns - cart, payment, inventory with transaction safety"
|
|
4
|
+
triggers: [commerce, ecommerce, cart, payment, checkout, inventory, stock, order, pg, toss, stripe]
|
|
5
|
+
priority: 70
|
|
6
|
+
---
|
|
7
|
+
# Commerce Patterns Skill
|
|
8
|
+
|
|
9
|
+
E-commerce domain patterns for reliable transactions.
|
|
10
|
+
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
- Shopping cart implementation
|
|
14
|
+
- Payment integration (PG, Stripe, Toss)
|
|
15
|
+
- Inventory/stock management
|
|
16
|
+
- Order processing systems
|
|
17
|
+
|
|
18
|
+
## Core Patterns
|
|
19
|
+
|
|
20
|
+
### 1. Cart (Shopping Cart)
|
|
21
|
+
|
|
22
|
+
#### State Model
|
|
23
|
+
```typescript
|
|
24
|
+
interface CartItem {
|
|
25
|
+
productId: string;
|
|
26
|
+
variantId?: string;
|
|
27
|
+
quantity: number;
|
|
28
|
+
price: number; // Snapshot at add time
|
|
29
|
+
originalPrice: number; // For comparison
|
|
30
|
+
addedAt: Date;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface Cart {
|
|
34
|
+
id: string;
|
|
35
|
+
userId?: string; // null for guest
|
|
36
|
+
sessionId: string; // For guest merge
|
|
37
|
+
items: CartItem[];
|
|
38
|
+
couponCode?: string;
|
|
39
|
+
updatedAt: Date;
|
|
40
|
+
expiresAt: Date; // Cart expiration
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### Key Patterns
|
|
45
|
+
|
|
46
|
+
| Pattern | Description |
|
|
47
|
+
|---------|-------------|
|
|
48
|
+
| **Guest → User Merge** | Merge localStorage cart on login |
|
|
49
|
+
| **Price Snapshot** | Store price at add time, revalidate at checkout |
|
|
50
|
+
| **Expiration** | Clear abandoned carts after N days |
|
|
51
|
+
| **Validation** | Check stock/price at checkout entry |
|
|
52
|
+
|
|
53
|
+
#### Implementation
|
|
54
|
+
```typescript
|
|
55
|
+
class CartService {
|
|
56
|
+
async addItem(cartId: string, item: AddItemRequest): Promise<Cart> {
|
|
57
|
+
// 1. Validate product exists and in stock
|
|
58
|
+
const product = await this.productService.get(item.productId);
|
|
59
|
+
if (!product || product.stock < item.quantity) {
|
|
60
|
+
throw new OutOfStockError();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 2. Snapshot current price
|
|
64
|
+
const cartItem: CartItem = {
|
|
65
|
+
...item,
|
|
66
|
+
price: product.currentPrice,
|
|
67
|
+
originalPrice: product.originalPrice,
|
|
68
|
+
addedAt: new Date(),
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// 3. Add or update quantity
|
|
72
|
+
return this.cartRepository.upsertItem(cartId, cartItem);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async mergeGuestCart(userId: string, sessionId: string): Promise<Cart> {
|
|
76
|
+
const guestCart = await this.cartRepository.findBySession(sessionId);
|
|
77
|
+
const userCart = await this.cartRepository.findByUser(userId);
|
|
78
|
+
|
|
79
|
+
if (!guestCart) return userCart;
|
|
80
|
+
|
|
81
|
+
// Merge: user cart takes priority for duplicates
|
|
82
|
+
const merged = this.mergeItems(userCart.items, guestCart.items);
|
|
83
|
+
await this.cartRepository.delete(guestCart.id);
|
|
84
|
+
|
|
85
|
+
return this.cartRepository.update(userCart.id, { items: merged });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. Payment
|
|
91
|
+
|
|
92
|
+
#### State Machine
|
|
93
|
+
```
|
|
94
|
+
PENDING → PROCESSING → AUTHORIZED → CAPTURED → COMPLETED
|
|
95
|
+
↘ FAILED
|
|
96
|
+
↘ CANCELED
|
|
97
|
+
COMPLETED → REFUND_REQUESTED → REFUNDED (partial/full)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
#### Idempotency Pattern (Critical)
|
|
101
|
+
```typescript
|
|
102
|
+
interface PaymentRequest {
|
|
103
|
+
orderId: string;
|
|
104
|
+
amount: number;
|
|
105
|
+
currency: string;
|
|
106
|
+
idempotencyKey: string; // REQUIRED: `order_${orderId}_${timestamp}`
|
|
107
|
+
paymentMethod: PaymentMethod;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
class PaymentService {
|
|
111
|
+
async processPayment(request: PaymentRequest): Promise<PaymentResult> {
|
|
112
|
+
// 1. Check idempotency - prevent duplicate charges
|
|
113
|
+
const existing = await this.paymentRepository.findByIdempotencyKey(
|
|
114
|
+
request.idempotencyKey
|
|
115
|
+
);
|
|
116
|
+
if (existing) {
|
|
117
|
+
return existing.result; // Return cached result
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 2. Create payment record (PENDING)
|
|
121
|
+
const payment = await this.paymentRepository.create({
|
|
122
|
+
...request,
|
|
123
|
+
status: 'PENDING',
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
// 3. Call PG adapter
|
|
128
|
+
const pgResult = await this.pgAdapter.authorize(request);
|
|
129
|
+
|
|
130
|
+
// 4. Update status
|
|
131
|
+
return this.paymentRepository.update(payment.id, {
|
|
132
|
+
status: pgResult.success ? 'AUTHORIZED' : 'FAILED',
|
|
133
|
+
pgTransactionId: pgResult.transactionId,
|
|
134
|
+
result: pgResult,
|
|
135
|
+
});
|
|
136
|
+
} catch (error) {
|
|
137
|
+
await this.paymentRepository.update(payment.id, {
|
|
138
|
+
status: 'FAILED',
|
|
139
|
+
error: error.message,
|
|
140
|
+
});
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### PG Adapter Pattern
|
|
148
|
+
```typescript
|
|
149
|
+
interface PGAdapter {
|
|
150
|
+
authorize(request: PaymentRequest): Promise<PGResult>;
|
|
151
|
+
capture(transactionId: string): Promise<PGResult>;
|
|
152
|
+
cancel(transactionId: string): Promise<PGResult>;
|
|
153
|
+
refund(transactionId: string, amount?: number): Promise<PGResult>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Implementations
|
|
157
|
+
class TossPaymentsAdapter implements PGAdapter { /* ... */ }
|
|
158
|
+
class StripeAdapter implements PGAdapter { /* ... */ }
|
|
159
|
+
class PortOneAdapter implements PGAdapter { /* ... */ }
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### Webhook Handling
|
|
163
|
+
```typescript
|
|
164
|
+
class PaymentWebhookHandler {
|
|
165
|
+
async handle(event: WebhookEvent): Promise<void> {
|
|
166
|
+
// 1. Verify signature
|
|
167
|
+
if (!this.verifySignature(event)) {
|
|
168
|
+
throw new UnauthorizedError();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 2. Idempotency check - process each event only once
|
|
172
|
+
const processed = await this.eventStore.find(event.id);
|
|
173
|
+
if (processed) {
|
|
174
|
+
return; // Already processed
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 3. Process event
|
|
178
|
+
await this.processEvent(event);
|
|
179
|
+
|
|
180
|
+
// 4. Mark as processed
|
|
181
|
+
await this.eventStore.save({
|
|
182
|
+
eventId: event.id,
|
|
183
|
+
processedAt: new Date(),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### 3. Inventory (Stock Management)
|
|
190
|
+
|
|
191
|
+
#### Reservation Pattern (Two-Phase)
|
|
192
|
+
```typescript
|
|
193
|
+
interface StockReservation {
|
|
194
|
+
id: string;
|
|
195
|
+
productId: string;
|
|
196
|
+
quantity: number;
|
|
197
|
+
orderId: string;
|
|
198
|
+
status: 'RESERVED' | 'COMMITTED' | 'RELEASED';
|
|
199
|
+
expiresAt: Date; // Auto-release if not committed
|
|
200
|
+
createdAt: Date;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
class InventoryService {
|
|
204
|
+
// Phase 1: Reserve stock (at checkout start)
|
|
205
|
+
async reserve(orderId: string, items: OrderItem[]): Promise<void> {
|
|
206
|
+
for (const item of items) {
|
|
207
|
+
// Atomic decrement with check
|
|
208
|
+
const result = await this.db.query(`
|
|
209
|
+
UPDATE products
|
|
210
|
+
SET reserved_stock = reserved_stock + $1
|
|
211
|
+
WHERE id = $2
|
|
212
|
+
AND (available_stock - reserved_stock) >= $1
|
|
213
|
+
RETURNING *
|
|
214
|
+
`, [item.quantity, item.productId]);
|
|
215
|
+
|
|
216
|
+
if (result.rowCount === 0) {
|
|
217
|
+
// Rollback previous reservations
|
|
218
|
+
await this.releaseAll(orderId);
|
|
219
|
+
throw new InsufficientStockError(item.productId);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
await this.reservationRepository.create({
|
|
223
|
+
orderId,
|
|
224
|
+
productId: item.productId,
|
|
225
|
+
quantity: item.quantity,
|
|
226
|
+
status: 'RESERVED',
|
|
227
|
+
expiresAt: addMinutes(new Date(), 15), // 15min hold
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Phase 2: Commit stock (after payment success)
|
|
233
|
+
async commit(orderId: string): Promise<void> {
|
|
234
|
+
const reservations = await this.reservationRepository.findByOrder(orderId);
|
|
235
|
+
|
|
236
|
+
for (const reservation of reservations) {
|
|
237
|
+
await this.db.query(`
|
|
238
|
+
UPDATE products
|
|
239
|
+
SET
|
|
240
|
+
available_stock = available_stock - $1,
|
|
241
|
+
reserved_stock = reserved_stock - $1
|
|
242
|
+
WHERE id = $2
|
|
243
|
+
`, [reservation.quantity, reservation.productId]);
|
|
244
|
+
|
|
245
|
+
await this.reservationRepository.update(reservation.id, {
|
|
246
|
+
status: 'COMMITTED',
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Rollback: Release stock (payment failed or timeout)
|
|
252
|
+
async release(orderId: string): Promise<void> {
|
|
253
|
+
const reservations = await this.reservationRepository.findByOrder(orderId);
|
|
254
|
+
|
|
255
|
+
for (const reservation of reservations) {
|
|
256
|
+
if (reservation.status === 'RESERVED') {
|
|
257
|
+
await this.db.query(`
|
|
258
|
+
UPDATE products
|
|
259
|
+
SET reserved_stock = reserved_stock - $1
|
|
260
|
+
WHERE id = $2
|
|
261
|
+
`, [reservation.quantity, reservation.productId]);
|
|
262
|
+
|
|
263
|
+
await this.reservationRepository.update(reservation.id, {
|
|
264
|
+
status: 'RELEASED',
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### Concurrency Control
|
|
273
|
+
```typescript
|
|
274
|
+
// Option 1: Optimistic Locking
|
|
275
|
+
await db.query(`
|
|
276
|
+
UPDATE products
|
|
277
|
+
SET stock = stock - $1, version = version + 1
|
|
278
|
+
WHERE id = $2 AND version = $3 AND stock >= $1
|
|
279
|
+
`, [quantity, productId, expectedVersion]);
|
|
280
|
+
|
|
281
|
+
// Option 2: Pessimistic Locking (for high contention)
|
|
282
|
+
await db.query(`
|
|
283
|
+
SELECT * FROM products WHERE id = $1 FOR UPDATE
|
|
284
|
+
`, [productId]);
|
|
285
|
+
|
|
286
|
+
// Option 3: Redis Distributed Lock
|
|
287
|
+
const lock = await redlock.lock(`stock:${productId}`, 5000);
|
|
288
|
+
try {
|
|
289
|
+
// Update stock
|
|
290
|
+
} finally {
|
|
291
|
+
await lock.unlock();
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Order Flow (Complete)
|
|
296
|
+
|
|
297
|
+
```
|
|
298
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
299
|
+
│ CHECKOUT FLOW │
|
|
300
|
+
├─────────────────────────────────────────────────────────────┤
|
|
301
|
+
│ │
|
|
302
|
+
│ 1. Cart Validation │
|
|
303
|
+
│ └─ Revalidate prices, check stock availability │
|
|
304
|
+
│ │
|
|
305
|
+
│ 2. Order Creation (PENDING) │
|
|
306
|
+
│ └─ Generate orderId, snapshot cart │
|
|
307
|
+
│ │
|
|
308
|
+
│ 3. Stock Reservation │
|
|
309
|
+
│ └─ Reserve inventory (15min hold) │
|
|
310
|
+
│ │
|
|
311
|
+
│ 4. Payment Processing │
|
|
312
|
+
│ ├─ Success → Order PAID, Stock COMMIT │
|
|
313
|
+
│ └─ Failure → Order FAILED, Stock RELEASE │
|
|
314
|
+
│ │
|
|
315
|
+
│ 5. Order Confirmation │
|
|
316
|
+
│ └─ Send notification, trigger fulfillment │
|
|
317
|
+
│ │
|
|
318
|
+
└─────────────────────────────────────────────────────────────┘
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Common Bugs & Prevention
|
|
322
|
+
|
|
323
|
+
| Bug | Cause | Prevention |
|
|
324
|
+
|-----|-------|------------|
|
|
325
|
+
| **Duplicate payment** | User double-click, webhook retry | Idempotency key |
|
|
326
|
+
| **Negative stock** | Race condition | Atomic update with check |
|
|
327
|
+
| **Price mismatch** | Price changed during checkout | Snapshot + revalidation |
|
|
328
|
+
| **Orphan reservation** | Payment timeout without release | TTL + scheduled cleanup |
|
|
329
|
+
| **Lost webhook** | Network failure | Retry + idempotent handler |
|
|
330
|
+
| **Order state corruption** | Concurrent updates | State machine + versioning |
|
|
331
|
+
|
|
332
|
+
## Integration with /vibe.run
|
|
333
|
+
|
|
334
|
+
During commerce feature implementation:
|
|
335
|
+
|
|
336
|
+
1. **Phase 1**: Define domain models (Cart, Order, Payment, Inventory)
|
|
337
|
+
2. **Phase 2**: Implement core services with patterns above
|
|
338
|
+
3. **Phase 3**: Add PG adapter and webhook handlers
|
|
339
|
+
4. **Phase 4**: Implement compensating transactions (Saga)
|
|
340
|
+
5. **Phase 5**: E2E test critical flows
|
|
341
|
+
|
|
342
|
+
## Checklist
|
|
343
|
+
|
|
344
|
+
### Cart
|
|
345
|
+
- [ ] Guest/user cart merge on login
|
|
346
|
+
- [ ] Price snapshot at add time
|
|
347
|
+
- [ ] Stock validation at checkout
|
|
348
|
+
- [ ] Cart expiration cleanup
|
|
349
|
+
|
|
350
|
+
### Payment
|
|
351
|
+
- [ ] Idempotency key on all requests
|
|
352
|
+
- [ ] Webhook signature verification
|
|
353
|
+
- [ ] Duplicate event handling
|
|
354
|
+
- [ ] Timeout/retry strategy
|
|
355
|
+
- [ ] Refund flow tested
|
|
356
|
+
|
|
357
|
+
### Inventory
|
|
358
|
+
- [ ] Two-phase reservation (reserve → commit/release)
|
|
359
|
+
- [ ] Atomic stock updates
|
|
360
|
+
- [ ] Reservation TTL and cleanup job
|
|
361
|
+
- [ ] Concurrency control tested
|