aigent-team 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +253 -0
- package/dist/chunk-N3RYHWTR.js +267 -0
- package/dist/cli.js +576 -0
- package/dist/index.d.ts +234 -0
- package/dist/index.js +27 -0
- package/package.json +67 -0
- package/templates/shared/git-workflow.md +44 -0
- package/templates/shared/project-conventions.md +48 -0
- package/templates/teams/ba/agent.yaml +25 -0
- package/templates/teams/ba/references/acceptance-criteria.md +87 -0
- package/templates/teams/ba/references/api-contract-design.md +110 -0
- package/templates/teams/ba/references/requirements-analysis.md +83 -0
- package/templates/teams/ba/references/user-story-mapping.md +73 -0
- package/templates/teams/ba/skill.md +85 -0
- package/templates/teams/be/agent.yaml +34 -0
- package/templates/teams/be/conventions.md +102 -0
- package/templates/teams/be/references/api-design.md +91 -0
- package/templates/teams/be/references/async-processing.md +86 -0
- package/templates/teams/be/references/auth-security.md +58 -0
- package/templates/teams/be/references/caching.md +79 -0
- package/templates/teams/be/references/database.md +65 -0
- package/templates/teams/be/references/error-handling.md +106 -0
- package/templates/teams/be/references/observability.md +83 -0
- package/templates/teams/be/references/review-checklist.md +50 -0
- package/templates/teams/be/references/testing.md +100 -0
- package/templates/teams/be/review-checklist.md +54 -0
- package/templates/teams/be/skill.md +71 -0
- package/templates/teams/devops/agent.yaml +35 -0
- package/templates/teams/devops/conventions.md +133 -0
- package/templates/teams/devops/references/ci-cd.md +218 -0
- package/templates/teams/devops/references/cost-optimization.md +218 -0
- package/templates/teams/devops/references/disaster-recovery.md +199 -0
- package/templates/teams/devops/references/docker.md +237 -0
- package/templates/teams/devops/references/infrastructure-as-code.md +238 -0
- package/templates/teams/devops/references/kubernetes.md +397 -0
- package/templates/teams/devops/references/monitoring.md +224 -0
- package/templates/teams/devops/references/review-checklist.md +149 -0
- package/templates/teams/devops/references/security.md +225 -0
- package/templates/teams/devops/review-checklist.md +72 -0
- package/templates/teams/devops/skill.md +131 -0
- package/templates/teams/fe/agent.yaml +28 -0
- package/templates/teams/fe/conventions.md +80 -0
- package/templates/teams/fe/references/accessibility.md +92 -0
- package/templates/teams/fe/references/component-architecture.md +87 -0
- package/templates/teams/fe/references/css-styling.md +89 -0
- package/templates/teams/fe/references/forms.md +73 -0
- package/templates/teams/fe/references/performance.md +104 -0
- package/templates/teams/fe/references/review-checklist.md +51 -0
- package/templates/teams/fe/references/security.md +90 -0
- package/templates/teams/fe/references/state-management.md +117 -0
- package/templates/teams/fe/references/testing.md +112 -0
- package/templates/teams/fe/review-checklist.md +53 -0
- package/templates/teams/fe/skill.md +68 -0
- package/templates/teams/lead/agent.yaml +18 -0
- package/templates/teams/lead/references/cross-team-coordination.md +68 -0
- package/templates/teams/lead/references/quality-gates.md +64 -0
- package/templates/teams/lead/references/task-decomposition.md +69 -0
- package/templates/teams/lead/skill.md +83 -0
- package/templates/teams/qa/agent.yaml +32 -0
- package/templates/teams/qa/conventions.md +130 -0
- package/templates/teams/qa/references/ci-integration.md +337 -0
- package/templates/teams/qa/references/e2e-testing.md +292 -0
- package/templates/teams/qa/references/mocking.md +249 -0
- package/templates/teams/qa/references/performance-testing.md +288 -0
- package/templates/teams/qa/references/review-checklist.md +143 -0
- package/templates/teams/qa/references/security-testing.md +271 -0
- package/templates/teams/qa/references/test-data.md +275 -0
- package/templates/teams/qa/references/test-strategy.md +192 -0
- package/templates/teams/qa/review-checklist.md +53 -0
- package/templates/teams/qa/skill.md +131 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const PLATFORMS: readonly ["claude-code", "cursor", "codex", "antigravity"];
|
|
4
|
+
type Platform = (typeof PLATFORMS)[number];
|
|
5
|
+
declare const TEAM_ROLES: readonly ["lead", "ba", "fe", "be", "qa", "devops"];
|
|
6
|
+
type TeamRole = (typeof TEAM_ROLES)[number];
|
|
7
|
+
interface ReferenceFile {
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
description: string;
|
|
11
|
+
whenToRead: string;
|
|
12
|
+
content: string;
|
|
13
|
+
}
|
|
14
|
+
interface TechStackConfig {
|
|
15
|
+
languages: string[];
|
|
16
|
+
frameworks: string[];
|
|
17
|
+
libraries: string[];
|
|
18
|
+
buildTools: string[];
|
|
19
|
+
}
|
|
20
|
+
interface ToolPermissions {
|
|
21
|
+
allowed: string[];
|
|
22
|
+
denied?: string[];
|
|
23
|
+
}
|
|
24
|
+
interface WorkflowDefinition {
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
steps: string[];
|
|
28
|
+
}
|
|
29
|
+
interface AgentDefinition {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
description: string;
|
|
33
|
+
role: TeamRole;
|
|
34
|
+
systemPrompt: string;
|
|
35
|
+
skillContent: string;
|
|
36
|
+
techStack: TechStackConfig;
|
|
37
|
+
conventions: string;
|
|
38
|
+
reviewChecklist: string;
|
|
39
|
+
tools: ToolPermissions;
|
|
40
|
+
workflows: WorkflowDefinition[];
|
|
41
|
+
sharedKnowledge: string[];
|
|
42
|
+
references: ReferenceFile[];
|
|
43
|
+
globs?: string[];
|
|
44
|
+
}
|
|
45
|
+
declare const ConfigSchema: z.ZodObject<{
|
|
46
|
+
projectName: z.ZodString;
|
|
47
|
+
platforms: z.ZodArray<z.ZodEnum<["claude-code", "cursor", "codex", "antigravity"]>, "many">;
|
|
48
|
+
teams: z.ZodArray<z.ZodEnum<["lead", "ba", "fe", "be", "qa", "devops"]>, "many">;
|
|
49
|
+
overrides: z.ZodOptional<z.ZodRecord<z.ZodEnum<["lead", "ba", "fe", "be", "qa", "devops"]>, z.ZodObject<{
|
|
50
|
+
name: z.ZodOptional<z.ZodString>;
|
|
51
|
+
description: z.ZodOptional<z.ZodString>;
|
|
52
|
+
systemPrompt: z.ZodOptional<z.ZodString>;
|
|
53
|
+
techStack: z.ZodOptional<z.ZodObject<{
|
|
54
|
+
languages: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
55
|
+
frameworks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
56
|
+
libraries: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
57
|
+
buildTools: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
58
|
+
}, "strip", z.ZodTypeAny, {
|
|
59
|
+
languages?: string[] | undefined;
|
|
60
|
+
frameworks?: string[] | undefined;
|
|
61
|
+
libraries?: string[] | undefined;
|
|
62
|
+
buildTools?: string[] | undefined;
|
|
63
|
+
}, {
|
|
64
|
+
languages?: string[] | undefined;
|
|
65
|
+
frameworks?: string[] | undefined;
|
|
66
|
+
libraries?: string[] | undefined;
|
|
67
|
+
buildTools?: string[] | undefined;
|
|
68
|
+
}>>;
|
|
69
|
+
conventions: z.ZodOptional<z.ZodString>;
|
|
70
|
+
reviewChecklist: z.ZodOptional<z.ZodString>;
|
|
71
|
+
tools: z.ZodOptional<z.ZodObject<{
|
|
72
|
+
allowed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
73
|
+
denied: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
74
|
+
}, "strip", z.ZodTypeAny, {
|
|
75
|
+
allowed?: string[] | undefined;
|
|
76
|
+
denied?: string[] | undefined;
|
|
77
|
+
}, {
|
|
78
|
+
allowed?: string[] | undefined;
|
|
79
|
+
denied?: string[] | undefined;
|
|
80
|
+
}>>;
|
|
81
|
+
globs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
82
|
+
}, "strip", z.ZodTypeAny, {
|
|
83
|
+
name?: string | undefined;
|
|
84
|
+
description?: string | undefined;
|
|
85
|
+
systemPrompt?: string | undefined;
|
|
86
|
+
techStack?: {
|
|
87
|
+
languages?: string[] | undefined;
|
|
88
|
+
frameworks?: string[] | undefined;
|
|
89
|
+
libraries?: string[] | undefined;
|
|
90
|
+
buildTools?: string[] | undefined;
|
|
91
|
+
} | undefined;
|
|
92
|
+
conventions?: string | undefined;
|
|
93
|
+
reviewChecklist?: string | undefined;
|
|
94
|
+
tools?: {
|
|
95
|
+
allowed?: string[] | undefined;
|
|
96
|
+
denied?: string[] | undefined;
|
|
97
|
+
} | undefined;
|
|
98
|
+
globs?: string[] | undefined;
|
|
99
|
+
}, {
|
|
100
|
+
name?: string | undefined;
|
|
101
|
+
description?: string | undefined;
|
|
102
|
+
systemPrompt?: string | undefined;
|
|
103
|
+
techStack?: {
|
|
104
|
+
languages?: string[] | undefined;
|
|
105
|
+
frameworks?: string[] | undefined;
|
|
106
|
+
libraries?: string[] | undefined;
|
|
107
|
+
buildTools?: string[] | undefined;
|
|
108
|
+
} | undefined;
|
|
109
|
+
conventions?: string | undefined;
|
|
110
|
+
reviewChecklist?: string | undefined;
|
|
111
|
+
tools?: {
|
|
112
|
+
allowed?: string[] | undefined;
|
|
113
|
+
denied?: string[] | undefined;
|
|
114
|
+
} | undefined;
|
|
115
|
+
globs?: string[] | undefined;
|
|
116
|
+
}>>>;
|
|
117
|
+
shared: z.ZodOptional<z.ZodObject<{
|
|
118
|
+
conventions: z.ZodOptional<z.ZodString>;
|
|
119
|
+
apiSpecs: z.ZodOptional<z.ZodString>;
|
|
120
|
+
architecture: z.ZodOptional<z.ZodString>;
|
|
121
|
+
}, "strip", z.ZodTypeAny, {
|
|
122
|
+
conventions?: string | undefined;
|
|
123
|
+
apiSpecs?: string | undefined;
|
|
124
|
+
architecture?: string | undefined;
|
|
125
|
+
}, {
|
|
126
|
+
conventions?: string | undefined;
|
|
127
|
+
apiSpecs?: string | undefined;
|
|
128
|
+
architecture?: string | undefined;
|
|
129
|
+
}>>;
|
|
130
|
+
output: z.ZodOptional<z.ZodObject<{
|
|
131
|
+
directory: z.ZodOptional<z.ZodString>;
|
|
132
|
+
}, "strip", z.ZodTypeAny, {
|
|
133
|
+
directory?: string | undefined;
|
|
134
|
+
}, {
|
|
135
|
+
directory?: string | undefined;
|
|
136
|
+
}>>;
|
|
137
|
+
}, "strip", z.ZodTypeAny, {
|
|
138
|
+
projectName: string;
|
|
139
|
+
platforms: ("claude-code" | "cursor" | "codex" | "antigravity")[];
|
|
140
|
+
teams: ("lead" | "ba" | "fe" | "be" | "qa" | "devops")[];
|
|
141
|
+
overrides?: Partial<Record<"lead" | "ba" | "fe" | "be" | "qa" | "devops", {
|
|
142
|
+
name?: string | undefined;
|
|
143
|
+
description?: string | undefined;
|
|
144
|
+
systemPrompt?: string | undefined;
|
|
145
|
+
techStack?: {
|
|
146
|
+
languages?: string[] | undefined;
|
|
147
|
+
frameworks?: string[] | undefined;
|
|
148
|
+
libraries?: string[] | undefined;
|
|
149
|
+
buildTools?: string[] | undefined;
|
|
150
|
+
} | undefined;
|
|
151
|
+
conventions?: string | undefined;
|
|
152
|
+
reviewChecklist?: string | undefined;
|
|
153
|
+
tools?: {
|
|
154
|
+
allowed?: string[] | undefined;
|
|
155
|
+
denied?: string[] | undefined;
|
|
156
|
+
} | undefined;
|
|
157
|
+
globs?: string[] | undefined;
|
|
158
|
+
}>> | undefined;
|
|
159
|
+
shared?: {
|
|
160
|
+
conventions?: string | undefined;
|
|
161
|
+
apiSpecs?: string | undefined;
|
|
162
|
+
architecture?: string | undefined;
|
|
163
|
+
} | undefined;
|
|
164
|
+
output?: {
|
|
165
|
+
directory?: string | undefined;
|
|
166
|
+
} | undefined;
|
|
167
|
+
}, {
|
|
168
|
+
projectName: string;
|
|
169
|
+
platforms: ("claude-code" | "cursor" | "codex" | "antigravity")[];
|
|
170
|
+
teams: ("lead" | "ba" | "fe" | "be" | "qa" | "devops")[];
|
|
171
|
+
overrides?: Partial<Record<"lead" | "ba" | "fe" | "be" | "qa" | "devops", {
|
|
172
|
+
name?: string | undefined;
|
|
173
|
+
description?: string | undefined;
|
|
174
|
+
systemPrompt?: string | undefined;
|
|
175
|
+
techStack?: {
|
|
176
|
+
languages?: string[] | undefined;
|
|
177
|
+
frameworks?: string[] | undefined;
|
|
178
|
+
libraries?: string[] | undefined;
|
|
179
|
+
buildTools?: string[] | undefined;
|
|
180
|
+
} | undefined;
|
|
181
|
+
conventions?: string | undefined;
|
|
182
|
+
reviewChecklist?: string | undefined;
|
|
183
|
+
tools?: {
|
|
184
|
+
allowed?: string[] | undefined;
|
|
185
|
+
denied?: string[] | undefined;
|
|
186
|
+
} | undefined;
|
|
187
|
+
globs?: string[] | undefined;
|
|
188
|
+
}>> | undefined;
|
|
189
|
+
shared?: {
|
|
190
|
+
conventions?: string | undefined;
|
|
191
|
+
apiSpecs?: string | undefined;
|
|
192
|
+
architecture?: string | undefined;
|
|
193
|
+
} | undefined;
|
|
194
|
+
output?: {
|
|
195
|
+
directory?: string | undefined;
|
|
196
|
+
} | undefined;
|
|
197
|
+
}>;
|
|
198
|
+
type AigentTeamConfig = z.infer<typeof ConfigSchema>;
|
|
199
|
+
interface CompiledOutput {
|
|
200
|
+
filePath: string;
|
|
201
|
+
content: string;
|
|
202
|
+
overwriteStrategy: 'replace' | 'merge' | 'skip-if-exists';
|
|
203
|
+
}
|
|
204
|
+
interface ValidationResult {
|
|
205
|
+
valid: boolean;
|
|
206
|
+
errors: string[];
|
|
207
|
+
warnings: string[];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
declare function loadConfig(cwd?: string): Promise<AigentTeamConfig>;
|
|
211
|
+
declare function configExists(cwd?: string): boolean;
|
|
212
|
+
|
|
213
|
+
declare function loadAgents(config: AigentTeamConfig, cwd?: string): AgentDefinition[];
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Assemble the slim skill index for an agent (~150-200 lines).
|
|
217
|
+
* Used as the primary agent content that's always loaded.
|
|
218
|
+
* If agent has skillContent (from skill.md), use that directly.
|
|
219
|
+
* Otherwise, fall back to legacy assembly from parts.
|
|
220
|
+
*/
|
|
221
|
+
declare function assembleSkillIndex(agent: AgentDefinition): string;
|
|
222
|
+
/**
|
|
223
|
+
* Legacy: assemble full agent markdown from all parts.
|
|
224
|
+
* Used when no skill.md exists.
|
|
225
|
+
*/
|
|
226
|
+
declare function assembleAgentMarkdown(agent: AgentDefinition): string;
|
|
227
|
+
/**
|
|
228
|
+
* Format a single reference file for output.
|
|
229
|
+
*/
|
|
230
|
+
declare function assembleReference(ref: ReferenceFile): string;
|
|
231
|
+
|
|
232
|
+
declare function defineConfig(config: AigentTeamConfig): AigentTeamConfig;
|
|
233
|
+
|
|
234
|
+
export { type AgentDefinition, type AigentTeamConfig, type CompiledOutput, PLATFORMS, type Platform, type ReferenceFile, TEAM_ROLES, type TeamRole, type TechStackConfig, type ToolPermissions, type ValidationResult, type WorkflowDefinition, assembleAgentMarkdown, assembleReference, assembleSkillIndex, configExists, defineConfig, loadAgents, loadConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
PLATFORMS,
|
|
4
|
+
TEAM_ROLES,
|
|
5
|
+
assembleAgentMarkdown,
|
|
6
|
+
assembleReference,
|
|
7
|
+
assembleSkillIndex,
|
|
8
|
+
configExists,
|
|
9
|
+
loadAgents,
|
|
10
|
+
loadConfig
|
|
11
|
+
} from "./chunk-N3RYHWTR.js";
|
|
12
|
+
|
|
13
|
+
// src/index.ts
|
|
14
|
+
function defineConfig(config) {
|
|
15
|
+
return config;
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
PLATFORMS,
|
|
19
|
+
TEAM_ROLES,
|
|
20
|
+
assembleAgentMarkdown,
|
|
21
|
+
assembleReference,
|
|
22
|
+
assembleSkillIndex,
|
|
23
|
+
configExists,
|
|
24
|
+
defineConfig,
|
|
25
|
+
loadAgents,
|
|
26
|
+
loadConfig
|
|
27
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aigent-team",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Cross-platform AI agent team plugin for Claude Code, Cursor, Codex, and Antigravity",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"aigent-team": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"templates"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev": "tsup --watch",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"lint": "tsc --noEmit",
|
|
27
|
+
"prepublishOnly": "npm run build"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"ai",
|
|
31
|
+
"agent",
|
|
32
|
+
"claude",
|
|
33
|
+
"cursor",
|
|
34
|
+
"codex",
|
|
35
|
+
"antigravity",
|
|
36
|
+
"cli"
|
|
37
|
+
],
|
|
38
|
+
"author": "Đức Trần Xuân <ductranxuan.29710@gmail.com> (https://github.com/ducsatthu)",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/ducsatthu/aigent-team.git"
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/ducsatthu/aigent-team/issues"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/ducsatthu/aigent-team#readme",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=18"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"chalk": "^5.4.1",
|
|
53
|
+
"commander": "^13.1.0",
|
|
54
|
+
"deepmerge-ts": "^7.1.5",
|
|
55
|
+
"glob": "^11.0.1",
|
|
56
|
+
"gray-matter": "^4.0.3",
|
|
57
|
+
"inquirer": "^12.4.0",
|
|
58
|
+
"yaml": "^2.7.1",
|
|
59
|
+
"zod": "^3.24.3"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/node": "^22.13.0",
|
|
63
|
+
"tsup": "^8.4.0",
|
|
64
|
+
"typescript": "^5.7.3",
|
|
65
|
+
"vitest": "^3.1.1"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
## Branch Strategy
|
|
2
|
+
|
|
3
|
+
- **Main branch** (`main`): Always deployable. Protected — no direct pushes. All changes via PR.
|
|
4
|
+
- **Feature branches**: `feat/{ticket-id}-{short-description}` — e.g., `feat/PROJ-123-add-oauth-login`
|
|
5
|
+
- **Bug fix branches**: `fix/{ticket-id}-{short-description}` — e.g., `fix/PROJ-456-null-pointer-on-empty-cart`
|
|
6
|
+
- **Other types**: `refactor/`, `docs/`, `test/`, `chore/`, `ci/`
|
|
7
|
+
- **Hotfix**: `hotfix/{ticket-id}-{description}` — branches from the production tag, merges to main AND production.
|
|
8
|
+
|
|
9
|
+
## Commit Standards
|
|
10
|
+
|
|
11
|
+
- Follow Conventional Commits: `type(scope): description`
|
|
12
|
+
- `feat`: New functionality visible to users
|
|
13
|
+
- `fix`: Bug fix
|
|
14
|
+
- `refactor`: Code change that neither fixes a bug nor adds a feature
|
|
15
|
+
- `test`: Adding or modifying tests
|
|
16
|
+
- `docs`: Documentation only
|
|
17
|
+
- `chore`: Build process, tooling, dependency updates
|
|
18
|
+
- `ci`: CI/CD pipeline changes
|
|
19
|
+
- `perf`: Performance improvement
|
|
20
|
+
- Description is imperative mood, lowercase, no period: `add login form` not `Added login form.`
|
|
21
|
+
- Body (optional): explain **why**, not what. The diff shows what changed.
|
|
22
|
+
- Breaking changes: add `!` after type — `feat(api)!: remove deprecated /v1/users endpoint`
|
|
23
|
+
|
|
24
|
+
## Pull Request Process
|
|
25
|
+
|
|
26
|
+
1. **Before opening PR**: Rebase on latest main. Run linter + tests locally. Self-review your own diff.
|
|
27
|
+
2. **PR title**: Same as commit message format. Keep under 72 characters.
|
|
28
|
+
3. **PR description must include**:
|
|
29
|
+
- **What**: Brief summary of the change (1-3 sentences)
|
|
30
|
+
- **Why**: Link to ticket/issue. Business context for the change.
|
|
31
|
+
- **How to test**: Step-by-step verification instructions. Include curl commands, screenshots, or test commands.
|
|
32
|
+
- **Breaking changes**: If any, describe migration steps.
|
|
33
|
+
4. **Review requirements**: Minimum 1 approval. 2 approvals for: database migrations, auth changes, infrastructure, CI/CD, and changes touching >10 files.
|
|
34
|
+
5. **Merge strategy**: Squash merge for feature branches (clean history). Merge commit for release branches (preserve individual commits).
|
|
35
|
+
6. **Post-merge**: Delete the branch. Verify CI passes on main. Check staging deployment if auto-deployed.
|
|
36
|
+
|
|
37
|
+
## Release Process
|
|
38
|
+
|
|
39
|
+
- Semantic versioning: `MAJOR.MINOR.PATCH`
|
|
40
|
+
- MAJOR: Breaking API changes
|
|
41
|
+
- MINOR: New features, backward compatible
|
|
42
|
+
- PATCH: Bug fixes, backward compatible
|
|
43
|
+
- Tag releases on main: `git tag -a v1.2.3 -m "Release v1.2.3"`
|
|
44
|
+
- Changelog generated from conventional commit messages (using `standard-version` or `changesets`).
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
## Naming Conventions
|
|
2
|
+
|
|
3
|
+
- Variables/functions: `camelCase` (JS/TS), `snake_case` (Python/Go/Rust)
|
|
4
|
+
- Types/classes/interfaces: `PascalCase`
|
|
5
|
+
- Constants: `UPPER_SNAKE_CASE` for true compile-time constants. Regular `camelCase` for runtime values that don't change.
|
|
6
|
+
- File names: `kebab-case.ts` for modules, `PascalCase.tsx` for React components
|
|
7
|
+
- Database tables: `snake_case` plural (`users`, `order_items`). Columns: `snake_case` singular.
|
|
8
|
+
- API URLs: `kebab-case` (`/api/user-profiles`). Query params: `camelCase` or `snake_case` (be consistent).
|
|
9
|
+
|
|
10
|
+
## Code Quality Rules
|
|
11
|
+
|
|
12
|
+
- **Single responsibility**: Functions do one thing. If you can't name it without "and", split it.
|
|
13
|
+
- **Early returns**: Validate preconditions at the top and return early. Avoid nested if-else pyramids:
|
|
14
|
+
```typescript
|
|
15
|
+
// BAD
|
|
16
|
+
function process(user) {
|
|
17
|
+
if (user) {
|
|
18
|
+
if (user.active) {
|
|
19
|
+
// ...30 lines of logic
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// GOOD
|
|
24
|
+
function process(user) {
|
|
25
|
+
if (!user) return;
|
|
26
|
+
if (!user.active) return;
|
|
27
|
+
// ...30 lines of logic
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
- **Explicit over implicit**: Named parameters over boolean flags. `createUser({ admin: true })` not `createUser(true)`.
|
|
31
|
+
- **Error handling**: Handle errors explicitly at the point where you can do something useful about them. Don't catch at every level — let errors propagate to a handler that can provide meaningful feedback.
|
|
32
|
+
- **No magic numbers/strings**: Extract to named constants. `const MAX_RETRY_ATTEMPTS = 3` not bare `3` in a loop.
|
|
33
|
+
- **Dependencies**: Pin exact versions in lockfiles. Audit dependencies quarterly — remove unused, update vulnerable.
|
|
34
|
+
- **Environment config**: All environment-specific values via environment variables. Use a typed config module that validates at startup (fail fast, not on first use).
|
|
35
|
+
|
|
36
|
+
## Code Review Standards
|
|
37
|
+
|
|
38
|
+
- Review for correctness first, then maintainability, then style. Don't bikeshed formatting — that's the linter's job.
|
|
39
|
+
- Every PR must answer: what changed, why, and how to verify. If the reviewer can't understand the "why", the PR description needs work.
|
|
40
|
+
- Look for what's NOT there: missing error handling, missing tests, missing logging, missing edge cases.
|
|
41
|
+
- Large PRs (>500 lines changed) should be broken into smaller, reviewable chunks. Exception: mechanical refactors (renames, moves) where the diff is large but the change is simple.
|
|
42
|
+
|
|
43
|
+
## Git Hygiene
|
|
44
|
+
|
|
45
|
+
- Commit messages: `type(scope): description` — e.g., `feat(auth): add OAuth2 login flow`
|
|
46
|
+
- Atomic commits: each commit compiles and passes tests. Don't commit broken intermediate states.
|
|
47
|
+
- Rebase feature branches on main before merging. Resolve conflicts locally, not in the merge commit.
|
|
48
|
+
- Delete merged branches immediately. Stale branches are noise.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
id: ba
|
|
2
|
+
name: BA Agent
|
|
3
|
+
description: >
|
|
4
|
+
Business Analyst agent. Translates business requirements into technical specs,
|
|
5
|
+
acceptance criteria, user stories, API contracts, and data flow diagrams.
|
|
6
|
+
role: ba
|
|
7
|
+
techStack:
|
|
8
|
+
languages: [Markdown, YAML, JSON]
|
|
9
|
+
frameworks: []
|
|
10
|
+
libraries: [Mermaid, OpenAPI]
|
|
11
|
+
buildTools: []
|
|
12
|
+
tools:
|
|
13
|
+
allowed: [Read, Write, Edit, Grep, Glob]
|
|
14
|
+
globs:
|
|
15
|
+
- "docs/**/*"
|
|
16
|
+
- "specs/**/*"
|
|
17
|
+
- "requirements/**/*"
|
|
18
|
+
- "**/*.md"
|
|
19
|
+
- "**/*.yaml"
|
|
20
|
+
- "**/*.yml"
|
|
21
|
+
- "openapi.*"
|
|
22
|
+
- "swagger.*"
|
|
23
|
+
sharedKnowledge:
|
|
24
|
+
- project-conventions
|
|
25
|
+
- git-workflow
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Writing Acceptance Criteria
|
|
2
|
+
|
|
3
|
+
## Format: Given / When / Then
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
GIVEN [precondition — the state of the world before the action]
|
|
7
|
+
WHEN [action — what the user does]
|
|
8
|
+
THEN [expected outcome — what should happen]
|
|
9
|
+
AND [additional outcomes if needed]
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Rules for Good Acceptance Criteria
|
|
13
|
+
|
|
14
|
+
1. **Testable**: QA must be able to write an automated test from this criterion alone
|
|
15
|
+
- BAD: "The form should be user-friendly"
|
|
16
|
+
- GOOD: "GIVEN an empty form WHEN user submits THEN inline errors appear below each required field"
|
|
17
|
+
|
|
18
|
+
2. **Specific**: Include exact values, behaviors, and states
|
|
19
|
+
- BAD: "The page loads quickly"
|
|
20
|
+
- GOOD: "GIVEN a list of 1000 items WHEN user loads the page THEN first 20 items render within 2 seconds"
|
|
21
|
+
|
|
22
|
+
3. **Independent**: Each criterion should be verifiable on its own
|
|
23
|
+
|
|
24
|
+
4. **Complete**: Cover happy path AND failure paths AND edge cases
|
|
25
|
+
|
|
26
|
+
## Coverage Checklist
|
|
27
|
+
|
|
28
|
+
For every user story, write criteria covering:
|
|
29
|
+
|
|
30
|
+
- [ ] **Happy path**: Normal successful flow
|
|
31
|
+
- [ ] **Validation errors**: What happens with invalid input?
|
|
32
|
+
- [ ] **Authentication**: What if user is not logged in?
|
|
33
|
+
- [ ] **Authorization**: What if user doesn't have permission?
|
|
34
|
+
- [ ] **Empty state**: What if there's no data to display?
|
|
35
|
+
- [ ] **Error state**: What if the server returns an error?
|
|
36
|
+
- [ ] **Loading state**: What does the user see while waiting?
|
|
37
|
+
- [ ] **Boundary values**: Minimum, maximum, empty string, very long text
|
|
38
|
+
- [ ] **Concurrent action**: What if the same action happens simultaneously?
|
|
39
|
+
|
|
40
|
+
## Example: User Registration
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Story: As a new user, I want to register an account so I can access the platform.
|
|
44
|
+
|
|
45
|
+
AC1: Successful registration
|
|
46
|
+
GIVEN I am on the registration page
|
|
47
|
+
WHEN I enter a valid email, password (8+ chars, 1 uppercase, 1 number), and name
|
|
48
|
+
AND I click "Register"
|
|
49
|
+
THEN my account is created
|
|
50
|
+
AND I receive a verification email within 60 seconds
|
|
51
|
+
AND I am redirected to the "check your email" page
|
|
52
|
+
|
|
53
|
+
AC2: Duplicate email
|
|
54
|
+
GIVEN a user with email "existing@example.com" already exists
|
|
55
|
+
WHEN I enter "existing@example.com" and a valid password
|
|
56
|
+
AND I click "Register"
|
|
57
|
+
THEN I see an error "An account with this email already exists"
|
|
58
|
+
AND a "Sign in" link is shown
|
|
59
|
+
|
|
60
|
+
AC3: Weak password
|
|
61
|
+
GIVEN I am on the registration page
|
|
62
|
+
WHEN I enter a password shorter than 8 characters
|
|
63
|
+
AND I move focus away from the password field (blur)
|
|
64
|
+
THEN I see inline error "Password must be at least 8 characters"
|
|
65
|
+
AND the submit button remains enabled (errors shown inline, not blocking)
|
|
66
|
+
|
|
67
|
+
AC4: Email format validation
|
|
68
|
+
GIVEN I am on the registration page
|
|
69
|
+
WHEN I enter "not-an-email" in the email field
|
|
70
|
+
AND I move focus away (blur)
|
|
71
|
+
THEN I see inline error "Please enter a valid email address"
|
|
72
|
+
|
|
73
|
+
AC5: Empty form submission
|
|
74
|
+
GIVEN I am on the registration page with all fields empty
|
|
75
|
+
WHEN I click "Register"
|
|
76
|
+
THEN inline errors appear below each required field
|
|
77
|
+
AND focus moves to the first field with an error
|
|
78
|
+
AND the page does NOT scroll to top or show a toast
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Anti-patterns
|
|
82
|
+
|
|
83
|
+
- **Vague criteria**: "System should handle errors gracefully" — which errors? What does "gracefully" mean?
|
|
84
|
+
- **Implementation details**: "System stores user in PostgreSQL users table" — that's a design decision, not a requirement
|
|
85
|
+
- **Untestable**: "System should be fast" — what's "fast"? Specify response time targets.
|
|
86
|
+
- **Missing negative cases**: Only happy path criteria = bugs in production from unhandled edge cases
|
|
87
|
+
- **Ambiguous pronouns**: "It should display the message" — which message? To whom?
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# API Contract Design
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
An API contract is the agreement between FE and BE about how they communicate. It must be defined BEFORE implementation starts so both can work in parallel against the same spec.
|
|
6
|
+
|
|
7
|
+
## Contract Template
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
# Endpoint: Create Order
|
|
11
|
+
method: POST
|
|
12
|
+
path: /api/v1/orders
|
|
13
|
+
auth: required (role: user)
|
|
14
|
+
rate_limit: 30/min per user
|
|
15
|
+
|
|
16
|
+
request:
|
|
17
|
+
headers:
|
|
18
|
+
Content-Type: application/json
|
|
19
|
+
Authorization: Bearer {access_token}
|
|
20
|
+
body:
|
|
21
|
+
productId:
|
|
22
|
+
type: string
|
|
23
|
+
required: true
|
|
24
|
+
example: "prod_abc123"
|
|
25
|
+
quantity:
|
|
26
|
+
type: integer
|
|
27
|
+
required: true
|
|
28
|
+
min: 1
|
|
29
|
+
max: 100
|
|
30
|
+
couponCode:
|
|
31
|
+
type: string
|
|
32
|
+
required: false
|
|
33
|
+
maxLength: 20
|
|
34
|
+
example: "SAVE10"
|
|
35
|
+
|
|
36
|
+
response:
|
|
37
|
+
201 Created:
|
|
38
|
+
description: Order created successfully
|
|
39
|
+
body:
|
|
40
|
+
data:
|
|
41
|
+
id: string (e.g., "ord_xyz789")
|
|
42
|
+
productId: string
|
|
43
|
+
quantity: integer
|
|
44
|
+
unitPrice: integer (cents)
|
|
45
|
+
discount: integer (cents)
|
|
46
|
+
total: integer (cents)
|
|
47
|
+
status: "pending" | "confirmed" | "shipped"
|
|
48
|
+
createdAt: string (ISO 8601)
|
|
49
|
+
|
|
50
|
+
400 Bad Request:
|
|
51
|
+
description: Validation error
|
|
52
|
+
body:
|
|
53
|
+
error:
|
|
54
|
+
code: "VALIDATION_ERROR"
|
|
55
|
+
message: string
|
|
56
|
+
details:
|
|
57
|
+
- field: string
|
|
58
|
+
message: string
|
|
59
|
+
|
|
60
|
+
401 Unauthorized:
|
|
61
|
+
body:
|
|
62
|
+
error:
|
|
63
|
+
code: "UNAUTHORIZED"
|
|
64
|
+
message: "Authentication required"
|
|
65
|
+
|
|
66
|
+
404 Not Found:
|
|
67
|
+
description: Product not found
|
|
68
|
+
body:
|
|
69
|
+
error:
|
|
70
|
+
code: "PRODUCT_NOT_FOUND"
|
|
71
|
+
message: "Product {productId} does not exist"
|
|
72
|
+
|
|
73
|
+
409 Conflict:
|
|
74
|
+
description: Insufficient stock
|
|
75
|
+
body:
|
|
76
|
+
error:
|
|
77
|
+
code: "INSUFFICIENT_STOCK"
|
|
78
|
+
message: "Only {available} units available"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Design Principles
|
|
82
|
+
|
|
83
|
+
1. **BE owns the data model, FE drives the API shape** — FE knows what it needs to render, BE knows how to store/compute it. Meet in the middle.
|
|
84
|
+
|
|
85
|
+
2. **Response includes everything FE needs** — FE should not make N requests to assemble one view. If a list page needs user name + avatar, include them in the list response.
|
|
86
|
+
|
|
87
|
+
3. **Consistent patterns across endpoints** — same pagination format, same error format, same date format everywhere.
|
|
88
|
+
|
|
89
|
+
4. **Version from day one** — `/v1/` prefix. Even if you never make v2, it costs nothing and saves you later.
|
|
90
|
+
|
|
91
|
+
5. **Error codes are machine-readable** — FE switches on `error.code` (not `error.message`) to decide what to show the user.
|
|
92
|
+
|
|
93
|
+
## Review Checklist
|
|
94
|
+
|
|
95
|
+
Before finalizing a contract, verify:
|
|
96
|
+
- [ ] All FE views can be rendered with the data in the response
|
|
97
|
+
- [ ] All user actions have a corresponding endpoint
|
|
98
|
+
- [ ] Error responses cover all failure modes (validation, auth, not-found, conflict)
|
|
99
|
+
- [ ] Pagination included for list endpoints
|
|
100
|
+
- [ ] Sorting and filtering params defined
|
|
101
|
+
- [ ] Response includes `id` for every entity (for FE to use as key/link)
|
|
102
|
+
- [ ] Date/time fields are ISO 8601 strings
|
|
103
|
+
- [ ] Money fields are integers in smallest unit (cents)
|
|
104
|
+
- [ ] Consistent naming (camelCase for JSON, snake_case only if project convention)
|
|
105
|
+
|
|
106
|
+
## Contract Evolution
|
|
107
|
+
|
|
108
|
+
- **Non-breaking** (no version bump needed): add optional request field, add response field, add new endpoint
|
|
109
|
+
- **Breaking** (requires v2): remove/rename field, change field type, add required request field, change URL
|
|
110
|
+
- **Migration path**: support v1 and v2 simultaneously for 3 months, then deprecate v1
|