ai-team 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/manifest.json +170 -0
- package/.agents/skills/agent-creator/SKILL.md +28 -0
- package/.agents/skills/ai-integration/SKILL.md +69 -0
- package/.agents/skills/back-end-development/SKILL.md +44 -0
- package/.agents/skills/database-management/SKILL.md +111 -0
- package/.agents/skills/front-end-development/SKILL.md +39 -0
- package/.agents/skills/front-end-development/references/component-architecture.md +213 -0
- package/.agents/skills/front-end-development/references/data-fetching-pattern.md +111 -0
- package/.agents/skills/front-end-development/references/state-management.md +223 -0
- package/.agents/skills/front-end-development/references/styling.md +226 -0
- package/.agents/skills/self-improvement/SKILL.md +32 -0
- package/.agents/skills/self-improvement/templates/handoff-template.md +35 -0
- package/.agents/skills/self-improvement/templates/plan-template.md +55 -0
- package/.agents/skills/visual-testing/SKILL.md +40 -0
- package/.agents/teams/web-product/README.md +65 -0
- package/.agents/teams/web-product/workflows/feature-lifecycle.md +101 -0
- package/.github/agents/agent-creator.agent.md +66 -0
- package/.github/agents/cli-dev.agent.md +57 -0
- package/.github/agents/code-reviewer.agent.md +66 -0
- package/.github/agents/documentation-writer.agent.md +62 -0
- package/.github/agents/planning-agent.agent.md +70 -0
- package/.github/agents/product-team-orchestrator.agent.md +82 -0
- package/.github/agents/requirement-analyst.agent.md +65 -0
- package/.vscode/mcp.json +15 -0
- package/README.md +121 -0
- package/docs/agents/README.md +36 -0
- package/docs/cli.md +65 -0
- package/docs/plan.md +95 -0
- package/package.json +30 -0
- package/src/agents/definitions/agent-creator.yaml +68 -0
- package/src/agents/definitions/backend-dev.yaml +69 -0
- package/src/agents/definitions/cli-dev.yaml +59 -0
- package/src/agents/definitions/code-reviewer.yaml +67 -0
- package/src/agents/definitions/documentation-writer.yaml +74 -0
- package/src/agents/definitions/frontend-dev.yaml +68 -0
- package/src/agents/definitions/planning-agent.yaml +72 -0
- package/src/agents/definitions/product-team-orchestrator.yaml +83 -0
- package/src/agents/definitions/requirement-analyst.yaml +67 -0
- package/src/agents/definitions/tester.yaml +81 -0
- package/src/agents/generate.js +213 -0
- package/src/cli.js +398 -0
- package/src/lib/adapters.js +41 -0
- package/src/lib/fs-utils.js +60 -0
- package/src/lib/hash.js +9 -0
- package/src/lib/manifest.js +50 -0
- package/src/lib/migration.js +60 -0
- package/src/lib/prompts.js +104 -0
- package/src/lib/sync-engine.js +319 -0
- package/src/lib/template-registry.js +107 -0
- package/templates/bootstrap/base/.agents/skills/agent-creator/SKILL.md +28 -0
- package/templates/bootstrap/base/.agents/skills/ai-integration/SKILL.md +69 -0
- package/templates/bootstrap/base/.agents/skills/back-end-development/SKILL.md +44 -0
- package/templates/bootstrap/base/.agents/skills/database-management/SKILL.md +111 -0
- package/templates/bootstrap/base/.agents/skills/front-end-development/SKILL.md +39 -0
- package/templates/bootstrap/base/.agents/skills/front-end-development/references/component-architecture.md +213 -0
- package/templates/bootstrap/base/.agents/skills/front-end-development/references/data-fetching-pattern.md +111 -0
- package/templates/bootstrap/base/.agents/skills/front-end-development/references/state-management.md +223 -0
- package/templates/bootstrap/base/.agents/skills/front-end-development/references/styling.md +226 -0
- package/templates/bootstrap/base/.agents/skills/self-improvement/SKILL.md +32 -0
- package/templates/bootstrap/base/.agents/skills/self-improvement/templates/handoff-template.md +35 -0
- package/templates/bootstrap/base/.agents/skills/self-improvement/templates/plan-template.md +55 -0
- package/templates/bootstrap/base/.agents/skills/visual-testing/SKILL.md +40 -0
- package/templates/bootstrap/base/.agents/teams/web-product/README.md +65 -0
- package/templates/bootstrap/base/.agents/teams/web-product/workflows/feature-lifecycle.md +101 -0
- package/templates/bootstrap/manifest.json +32 -0
- package/templates/bootstrap/overlays/claude-code/.claude/agents/agent-creator.md +55 -0
- package/templates/bootstrap/overlays/claude-code/.claude/agents/backend-dev.md +48 -0
- package/templates/bootstrap/overlays/claude-code/.claude/agents/cli-dev.md +47 -0
- package/templates/bootstrap/overlays/claude-code/.claude/agents/code-reviewer.md +52 -0
- package/templates/bootstrap/overlays/claude-code/.claude/agents/documentation-writer.md +56 -0
- package/templates/bootstrap/overlays/claude-code/.claude/agents/frontend-dev.md +47 -0
- package/templates/bootstrap/overlays/claude-code/.claude/agents/planning-agent.md +51 -0
- package/templates/bootstrap/overlays/claude-code/.claude/agents/product-team-orchestrator.md +51 -0
- package/templates/bootstrap/overlays/claude-code/.claude/agents/requirement-analyst.md +54 -0
- package/templates/bootstrap/overlays/claude-code/.claude/agents/tester.md +58 -0
- package/templates/bootstrap/overlays/claude-code/.mcp.json +3 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/agent-creator.agent.md +66 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/backend-dev.agent.md +67 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/cli-dev.agent.md +57 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/code-reviewer.agent.md +64 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/documentation-writer.agent.md +72 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/frontend-dev.agent.md +66 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/planning-agent.agent.md +70 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/product-team-orchestrator.agent.md +82 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/requirement-analyst.agent.md +65 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/tester-agent.agent.md +69 -0
- package/templates/bootstrap/overlays/vscode-copilot/.github/agents/tester.agent.md +80 -0
- package/templates/bootstrap/overlays/vscode-copilot/.vscode/mcp.json +12 -0
- package/tests/cli.integration.test.js +63 -0
- package/tests/hash.test.js +9 -0
- package/tests/sync-engine.test.js +77 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"templateVersion": "0.1.0",
|
|
4
|
+
"installedAt": "2026-02-20T20:52:41.398Z",
|
|
5
|
+
"updatedAt": "2026-02-20T20:56:44.196Z",
|
|
6
|
+
"profile": {
|
|
7
|
+
"ide": "vscode",
|
|
8
|
+
"team": "web-product",
|
|
9
|
+
"includeMcp": true,
|
|
10
|
+
"agents": [
|
|
11
|
+
"cli-dev"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"files": {
|
|
15
|
+
".agents/skills/agent-creator/SKILL.md": {
|
|
16
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/agent-creator/SKILL.md",
|
|
17
|
+
"mode": "copy",
|
|
18
|
+
"sourceHash": "953e166539c8752fcd4b8d7f9215f4ba3f90355515ff50409ab0255b029503b4",
|
|
19
|
+
"installedHash": "953e166539c8752fcd4b8d7f9215f4ba3f90355515ff50409ab0255b029503b4",
|
|
20
|
+
"updatedAt": "2026-02-20T20:52:41.381Z"
|
|
21
|
+
},
|
|
22
|
+
".agents/skills/ai-integration/SKILL.md": {
|
|
23
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/ai-integration/SKILL.md",
|
|
24
|
+
"mode": "copy",
|
|
25
|
+
"sourceHash": "9b3bc7bf3cc1e76da32fdb08a53cfbeb5c39ef09051069f9d643ba652a5d50b6",
|
|
26
|
+
"installedHash": "9b3bc7bf3cc1e76da32fdb08a53cfbeb5c39ef09051069f9d643ba652a5d50b6",
|
|
27
|
+
"updatedAt": "2026-02-20T20:52:41.382Z"
|
|
28
|
+
},
|
|
29
|
+
".agents/skills/back-end-development/SKILL.md": {
|
|
30
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/back-end-development/SKILL.md",
|
|
31
|
+
"mode": "copy",
|
|
32
|
+
"sourceHash": "e3ff67e769102c1aa9c62a9cc0e9f22d78222c1231fe8896360391a063b059b1",
|
|
33
|
+
"installedHash": "e3ff67e769102c1aa9c62a9cc0e9f22d78222c1231fe8896360391a063b059b1",
|
|
34
|
+
"updatedAt": "2026-02-20T20:52:41.383Z"
|
|
35
|
+
},
|
|
36
|
+
".agents/skills/database-management/SKILL.md": {
|
|
37
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/database-management/SKILL.md",
|
|
38
|
+
"mode": "copy",
|
|
39
|
+
"sourceHash": "e7cceb155c549bdb61102db1488165156a54252fef87345baef2f65938562f1b",
|
|
40
|
+
"installedHash": "e7cceb155c549bdb61102db1488165156a54252fef87345baef2f65938562f1b",
|
|
41
|
+
"updatedAt": "2026-02-20T20:52:41.384Z"
|
|
42
|
+
},
|
|
43
|
+
".agents/skills/front-end-development/SKILL.md": {
|
|
44
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/front-end-development/SKILL.md",
|
|
45
|
+
"mode": "copy",
|
|
46
|
+
"sourceHash": "513e5da53f3bc76c152b066e4ff5fe180bf9934e7035ee95c2255564600893ac",
|
|
47
|
+
"installedHash": "513e5da53f3bc76c152b066e4ff5fe180bf9934e7035ee95c2255564600893ac",
|
|
48
|
+
"updatedAt": "2026-02-20T20:52:41.385Z"
|
|
49
|
+
},
|
|
50
|
+
".agents/skills/front-end-development/references/component-architecture.md": {
|
|
51
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/front-end-development/references/component-architecture.md",
|
|
52
|
+
"mode": "copy",
|
|
53
|
+
"sourceHash": "88fc68f9f442c2c1fd5c18d4e12e003bc68372c20283a78a0db44bd668ad3421",
|
|
54
|
+
"installedHash": "88fc68f9f442c2c1fd5c18d4e12e003bc68372c20283a78a0db44bd668ad3421",
|
|
55
|
+
"updatedAt": "2026-02-20T20:52:41.386Z"
|
|
56
|
+
},
|
|
57
|
+
".agents/skills/front-end-development/references/data-fetching-pattern.md": {
|
|
58
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/front-end-development/references/data-fetching-pattern.md",
|
|
59
|
+
"mode": "copy",
|
|
60
|
+
"sourceHash": "1feef85053f1e9594861708a8104cac62d63e3c0d2ab3696b12da76b533c3add",
|
|
61
|
+
"installedHash": "1feef85053f1e9594861708a8104cac62d63e3c0d2ab3696b12da76b533c3add",
|
|
62
|
+
"updatedAt": "2026-02-20T20:52:41.387Z"
|
|
63
|
+
},
|
|
64
|
+
".agents/skills/front-end-development/references/state-management.md": {
|
|
65
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/front-end-development/references/state-management.md",
|
|
66
|
+
"mode": "copy",
|
|
67
|
+
"sourceHash": "8739bcd011466649bad63f502b055cddec8336cb0603bb6ec3c7eaec7902df1e",
|
|
68
|
+
"installedHash": "8739bcd011466649bad63f502b055cddec8336cb0603bb6ec3c7eaec7902df1e",
|
|
69
|
+
"updatedAt": "2026-02-20T20:52:41.387Z"
|
|
70
|
+
},
|
|
71
|
+
".agents/skills/front-end-development/references/styling.md": {
|
|
72
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/front-end-development/references/styling.md",
|
|
73
|
+
"mode": "copy",
|
|
74
|
+
"sourceHash": "7ff0d87b439ded009ae001529111fc9f90e6c6621d6a8ef9f92c7acabf02f167",
|
|
75
|
+
"installedHash": "7ff0d87b439ded009ae001529111fc9f90e6c6621d6a8ef9f92c7acabf02f167",
|
|
76
|
+
"updatedAt": "2026-02-20T20:52:41.388Z"
|
|
77
|
+
},
|
|
78
|
+
".agents/skills/self-improvement/SKILL.md": {
|
|
79
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/self-improvement/SKILL.md",
|
|
80
|
+
"mode": "copy",
|
|
81
|
+
"sourceHash": "afe83660246c12ff227424bb73874d6e607ebb2b00603f21009a94b6ff391035",
|
|
82
|
+
"installedHash": "afe83660246c12ff227424bb73874d6e607ebb2b00603f21009a94b6ff391035",
|
|
83
|
+
"updatedAt": "2026-02-20T20:52:41.390Z"
|
|
84
|
+
},
|
|
85
|
+
".agents/skills/self-improvement/templates/handoff-template.md": {
|
|
86
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/self-improvement/templates/handoff-template.md",
|
|
87
|
+
"mode": "copy",
|
|
88
|
+
"sourceHash": "99dba34951306295439a77a8a16d9525144d99866dbe537c09dfddf1a637ae55",
|
|
89
|
+
"installedHash": "99dba34951306295439a77a8a16d9525144d99866dbe537c09dfddf1a637ae55",
|
|
90
|
+
"updatedAt": "2026-02-20T20:52:41.390Z"
|
|
91
|
+
},
|
|
92
|
+
".agents/skills/self-improvement/templates/plan-template.md": {
|
|
93
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/self-improvement/templates/plan-template.md",
|
|
94
|
+
"mode": "copy",
|
|
95
|
+
"sourceHash": "19fe377c4340f944d4c6be0e10f8e160e25bbe49dbe3ef915b9475f19c6a35b0",
|
|
96
|
+
"installedHash": "19fe377c4340f944d4c6be0e10f8e160e25bbe49dbe3ef915b9475f19c6a35b0",
|
|
97
|
+
"updatedAt": "2026-02-20T20:52:41.391Z"
|
|
98
|
+
},
|
|
99
|
+
".agents/skills/visual-testing/SKILL.md": {
|
|
100
|
+
"sourcePath": "templates/bootstrap/base/.agents/skills/visual-testing/SKILL.md",
|
|
101
|
+
"mode": "copy",
|
|
102
|
+
"sourceHash": "eb8c32f51731ce6e00715aa4da1ca5cd59f25674bc2c1e9a859d1469d4ce2538",
|
|
103
|
+
"installedHash": "eb8c32f51731ce6e00715aa4da1ca5cd59f25674bc2c1e9a859d1469d4ce2538",
|
|
104
|
+
"updatedAt": "2026-02-20T20:52:41.392Z"
|
|
105
|
+
},
|
|
106
|
+
".agents/teams/web-product/README.md": {
|
|
107
|
+
"sourcePath": "templates/bootstrap/base/.agents/teams/web-product/README.md",
|
|
108
|
+
"mode": "copy",
|
|
109
|
+
"sourceHash": "29d0cc9b5203643ae4a8b9c211d8e6374b11ee209afba815649c40a26a0591e3",
|
|
110
|
+
"installedHash": "29d0cc9b5203643ae4a8b9c211d8e6374b11ee209afba815649c40a26a0591e3",
|
|
111
|
+
"updatedAt": "2026-02-20T20:52:41.393Z"
|
|
112
|
+
},
|
|
113
|
+
".agents/teams/web-product/workflows/feature-lifecycle.md": {
|
|
114
|
+
"sourcePath": "templates/bootstrap/base/.agents/teams/web-product/workflows/feature-lifecycle.md",
|
|
115
|
+
"mode": "copy",
|
|
116
|
+
"sourceHash": "349e4a862f3838440272844d1b781f6832c5b40a915bf62e20733cf9e5a41247",
|
|
117
|
+
"installedHash": "349e4a862f3838440272844d1b781f6832c5b40a915bf62e20733cf9e5a41247",
|
|
118
|
+
"updatedAt": "2026-02-20T20:52:41.394Z"
|
|
119
|
+
},
|
|
120
|
+
".github/agents/agent-creator.agent.md": {
|
|
121
|
+
"sourcePath": "templates/bootstrap/overlays/vscode-copilot/.github/agents/agent-creator.agent.md",
|
|
122
|
+
"mode": "copy",
|
|
123
|
+
"sourceHash": "7b103e957a2cbde45b78c2feae3ff8714b427e172dac2a2c6cb85b65ccd85bef",
|
|
124
|
+
"installedHash": "7b103e957a2cbde45b78c2feae3ff8714b427e172dac2a2c6cb85b65ccd85bef",
|
|
125
|
+
"updatedAt": "2026-02-20T20:52:41.395Z"
|
|
126
|
+
},
|
|
127
|
+
".github/agents/code-reviewer.agent.md": {
|
|
128
|
+
"sourcePath": "templates/bootstrap/overlays/vscode-copilot/.github/agents/code-reviewer.agent.md",
|
|
129
|
+
"mode": "copy",
|
|
130
|
+
"sourceHash": "6487e579b9ab127ff707699f3e597cf15bd1f81054c06171a10d81021b68a3e4",
|
|
131
|
+
"installedHash": "6487e579b9ab127ff707699f3e597cf15bd1f81054c06171a10d81021b68a3e4",
|
|
132
|
+
"updatedAt": "2026-02-20T20:52:41.395Z"
|
|
133
|
+
},
|
|
134
|
+
".github/agents/planning-agent.agent.md": {
|
|
135
|
+
"sourcePath": "templates/bootstrap/overlays/vscode-copilot/.github/agents/planning-agent.agent.md",
|
|
136
|
+
"mode": "copy",
|
|
137
|
+
"sourceHash": "2722a36e94db7d11d80d8cbc4c318f93e4b680319f2406a33a55df3b320690b6",
|
|
138
|
+
"installedHash": "2722a36e94db7d11d80d8cbc4c318f93e4b680319f2406a33a55df3b320690b6",
|
|
139
|
+
"updatedAt": "2026-02-20T20:52:41.395Z"
|
|
140
|
+
},
|
|
141
|
+
".github/agents/product-team-orchestrator.agent.md": {
|
|
142
|
+
"sourcePath": "templates/bootstrap/overlays/vscode-copilot/.github/agents/product-team-orchestrator.agent.md",
|
|
143
|
+
"mode": "copy",
|
|
144
|
+
"sourceHash": "5ad463a2ce918e3e1cbf77ff26fb9177a16d48d07fa8422dfdcbb8bfef4309a0",
|
|
145
|
+
"installedHash": "5ad463a2ce918e3e1cbf77ff26fb9177a16d48d07fa8422dfdcbb8bfef4309a0",
|
|
146
|
+
"updatedAt": "2026-02-20T20:52:41.396Z"
|
|
147
|
+
},
|
|
148
|
+
".github/agents/requirement-analyst.agent.md": {
|
|
149
|
+
"sourcePath": "templates/bootstrap/overlays/vscode-copilot/.github/agents/requirement-analyst.agent.md",
|
|
150
|
+
"mode": "copy",
|
|
151
|
+
"sourceHash": "f698954d2ad05262f4c5b2da054a4726bcd66331049b36e2b145cdc5068bfaad",
|
|
152
|
+
"installedHash": "f698954d2ad05262f4c5b2da054a4726bcd66331049b36e2b145cdc5068bfaad",
|
|
153
|
+
"updatedAt": "2026-02-20T20:52:41.397Z"
|
|
154
|
+
},
|
|
155
|
+
".vscode/mcp.json": {
|
|
156
|
+
"sourcePath": "templates/bootstrap/overlays/vscode-copilot/.vscode/mcp.json",
|
|
157
|
+
"mode": "json-merge",
|
|
158
|
+
"sourceHash": "dfe8d7335274421b65f693697d40d4574fe48b875e71098f5c4401466bae5088",
|
|
159
|
+
"installedHash": "84550ae09a0e8b10fb63cb5bac6a13eab109557a83701237fb927066e14b0b52",
|
|
160
|
+
"updatedAt": "2026-02-20T20:52:41.398Z"
|
|
161
|
+
},
|
|
162
|
+
".github/agents/cli-dev.agent.md": {
|
|
163
|
+
"sourcePath": "templates/bootstrap/overlays/vscode-copilot/.github/agents/cli-dev.agent.md",
|
|
164
|
+
"mode": "copy",
|
|
165
|
+
"sourceHash": "89482787a53bae281b8a4f68c38b42aa52eb73cc72d4627d19ec1b4c52e15b0d",
|
|
166
|
+
"installedHash": "89482787a53bae281b8a4f68c38b42aa52eb73cc72d4627d19ec1b4c52e15b0d",
|
|
167
|
+
"updatedAt": "2026-02-20T20:56:44.195Z"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Agent Creator Skill
|
|
2
|
+
|
|
3
|
+
This skill defines the process and best practices for creating new custom agents in this workspace.
|
|
4
|
+
|
|
5
|
+
## Reference
|
|
6
|
+
|
|
7
|
+
- [Custom Agents in VS Code Copilot](https://code.visualstudio.com/docs/copilot/customization/custom-agents)
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Standardize how new agents are defined and integrated into the team workflow.
|
|
12
|
+
|
|
13
|
+
## Process for Creating a New Agent
|
|
14
|
+
|
|
15
|
+
1. **Identify the Role**: Determine the specific responsibilities, inputs, and outputs for the agent.
|
|
16
|
+
2. **Create Agent Definition**: Create a new source definition in `src/agents/definitions/<role-name>.yaml`.
|
|
17
|
+
3. **Follow the Template**: Use existing definition files as a template (e.g., `src/agents/definitions/backend-dev.yaml`).
|
|
18
|
+
- Define `name`, `description`, `argumentHint`, `target`, `tools`, and `handoffs` in YAML.
|
|
19
|
+
- Write clear instructions in the `body` block.
|
|
20
|
+
4. **Regenerate Outputs**: Regenerate overlay agent files from definitions.
|
|
21
|
+
5. **Register Skills**: Ensure the agent has access to relevant skills by listing them in the "Required References" section.
|
|
22
|
+
6. **Update Documentation**: Add the new agent to `.agents/teams/web-product/README.md` and `docs/agents/README.md` if necessary.
|
|
23
|
+
|
|
24
|
+
## Best Practices
|
|
25
|
+
|
|
26
|
+
- Keep agent scope focused and single-purpose where possible.
|
|
27
|
+
- Define clear handoffs to other agents (e.g., "Handoff to Tester").
|
|
28
|
+
- Ensure the agent updates knowledge artifacts (`knowledge/`, `plans/`, etc.) as part of its workflow.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ai-integration
|
|
3
|
+
description: Guidelines for using Gemini with OpenAI compatibility, specifically for handling Structured Outputs and Zod schema limitations.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# AI Integration & Gemini Compatibility
|
|
7
|
+
|
|
8
|
+
This project uses Google Gemini models via the OpenAI compatibility layer. While this allows us to use the standard OpenAI SDK, there are specific constraints and workarounds required for **Structured Outputs** (JSON Schema).
|
|
9
|
+
|
|
10
|
+
For the official list of supported JSON Schema features, refer to the [Gemini API Structured Output Documentation](https://ai.google.dev/gemini-api/docs/structured-output#json-schema-support).
|
|
11
|
+
|
|
12
|
+
## Zod Schema Compatibility
|
|
13
|
+
|
|
14
|
+
When defining Zod schemas for AI structured outputs, follow these guidelines to ensure compatibility with Gemini:
|
|
15
|
+
|
|
16
|
+
### 1. Avoid `z.tuple()`
|
|
17
|
+
|
|
18
|
+
Gemini's JSON Schema validator has issues with `prefixItems` which `z.tuple()` generates.
|
|
19
|
+
**❌ Avoid:**
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
reps: z.tuple([z.number(), z.number()])
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**✅ Use:**
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
reps: z.array(z.number()) // You can add .length(2) if needed, though strict length validation might also be tricky
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. Nullable Fields & Unions
|
|
32
|
+
|
|
33
|
+
Zod's `.nullable()` often generates an `anyOf` structure (e.g., `anyOf: [{type: 'string'}, {type: 'null'}]`). Gemini prefers a single schema with a type array (e.g., `type: ['string', 'null']`).
|
|
34
|
+
|
|
35
|
+
We have implemented a `patchSchema` utility in `server/utils/ai.ts` that automatically handles this conversion at runtime. However, keeping schemas simple helps.
|
|
36
|
+
|
|
37
|
+
### 3. `exclusiveMinimum`
|
|
38
|
+
|
|
39
|
+
Gemini prefers `minimum` (inclusive) over `exclusiveMinimum`. The `patchSchema` utility automatically converts `exclusiveMinimum` to `minimum + 1` for integers.
|
|
40
|
+
|
|
41
|
+
## Schema Patching (`server/utils/ai.ts`)
|
|
42
|
+
|
|
43
|
+
We use a custom `patchSchema` function that intercepts the JSON Schema generated by `zodResponseFormat` before sending it to the API.
|
|
44
|
+
|
|
45
|
+
**What it does:**
|
|
46
|
+
|
|
47
|
+
1. **Flattens `anyOf`**: Recursively flattens nested `anyOf` structures (common with complex unions + nullable).
|
|
48
|
+
2. **Merges Types**: Collects all types from the flattened options into a single `type` array (e.g., `type: ["integer", "array", "null"]`).
|
|
49
|
+
3. **Merges Properties**: Naively merges properties from all union members.
|
|
50
|
+
4. **Converts `exclusiveMinimum`**: Transforms to `minimum`.
|
|
51
|
+
|
|
52
|
+
**Important:** When using this patching logic, we explicitly set `strict: false` in the API request, as the patched schema might not strictly adhere to the original Zod definition's structure (though it validates the same data).
|
|
53
|
+
|
|
54
|
+
## Example Usage
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// Define schema
|
|
58
|
+
const MySchema = z.object({
|
|
59
|
+
name: z.string(),
|
|
60
|
+
tags: z.array(z.string()).nullable(), // Will be patched to type: ['array', 'null']
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// Call AI
|
|
64
|
+
const response = await callAI({
|
|
65
|
+
// ...
|
|
66
|
+
responseSchema: MySchema,
|
|
67
|
+
schemaName: 'MySchema',
|
|
68
|
+
})
|
|
69
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: back-end-development
|
|
3
|
+
description: Best practices for Nuxt/Node backend development, API contracts, error handling, and observability.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Back-End Development Skill
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
Use this skill for:
|
|
11
|
+
|
|
12
|
+
- `server/api/` route implementation
|
|
13
|
+
- validation and API contract design
|
|
14
|
+
- business logic isolation in `server/shared/`
|
|
15
|
+
- data access and migration-safe schema changes
|
|
16
|
+
|
|
17
|
+
## Standards
|
|
18
|
+
|
|
19
|
+
1. Define strict input/output schemas.
|
|
20
|
+
2. Return stable error shapes and HTTP semantics.
|
|
21
|
+
3. Keep handlers thin; move logic to shared services.
|
|
22
|
+
4. Add structured logs for failures and key state transitions.
|
|
23
|
+
5. Enforce idempotency for mutating operations when relevant.
|
|
24
|
+
6. Protect secrets and sensitive payload fields.
|
|
25
|
+
7. For each endpoint, add unit tests that cover core functionality and boundary conditions.
|
|
26
|
+
|
|
27
|
+
## Data & Migration Rules
|
|
28
|
+
|
|
29
|
+
- For DB work, follow `.agents/skills/database-management/SKILL.md`.
|
|
30
|
+
- Migrations must be reversible when feasible.
|
|
31
|
+
- Update RLS policies and verify access paths.
|
|
32
|
+
|
|
33
|
+
## AI Route Rules
|
|
34
|
+
|
|
35
|
+
- For model integration and structured outputs, follow `.agents/skills/ai-integration/SKILL.md`.
|
|
36
|
+
- Validate model output before persistence.
|
|
37
|
+
|
|
38
|
+
## Definition of Done
|
|
39
|
+
|
|
40
|
+
- Contract documented and validated
|
|
41
|
+
- Endpoint unit tests cover functionality and boundaries
|
|
42
|
+
- Error paths covered
|
|
43
|
+
- Logging and monitoring hooks added
|
|
44
|
+
- Handoff note includes API examples and edge cases
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: database-management
|
|
3
|
+
description: Workflow for Drizzle ORM migrations, schema changes, and applying RLS policies.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Database Migrations & Management
|
|
7
|
+
|
|
8
|
+
This project uses **Drizzle ORM** with a migration-based workflow for production-ready database management.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
- **Schema source of truth**: `db/schema/*.ts` (TypeScript)
|
|
13
|
+
- **Migrations folder**: `db/migrations/` (generated SQL)
|
|
14
|
+
- **RLS policies**: `db/rls-policies.sql` (manually maintained)
|
|
15
|
+
- **Database**: Supabase (PostgreSQL)
|
|
16
|
+
|
|
17
|
+
## Migration Workflow
|
|
18
|
+
|
|
19
|
+
### 1. Make Schema Changes
|
|
20
|
+
|
|
21
|
+
Edit the Drizzle schema files in `db/schema/`:
|
|
22
|
+
|
|
23
|
+
- `profiles.ts` - User profiles
|
|
24
|
+
- `training-plans.ts` - Training plans
|
|
25
|
+
- `sessions.ts` - Workout sessions
|
|
26
|
+
- `index.ts` - Export new schemas here
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// db/schema/sessions.ts
|
|
32
|
+
export const sessions = pgTable('sessions', {
|
|
33
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
34
|
+
// ... add or modify columns here
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Generate Migration
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pnpm db:generate
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This compares your schema to the last snapshot and creates a new SQL migration file in `db/migrations/`.
|
|
45
|
+
|
|
46
|
+
### 3. Apply Migration
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm db:migrate
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This runs all pending migrations against your database. Migrations are tracked in `drizzle.__drizzle_migrations`.
|
|
53
|
+
|
|
54
|
+
### Alternative: Push Schema Directly
|
|
55
|
+
|
|
56
|
+
For development or when migrations are out of sync:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx drizzle-kit push
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This directly pushes schema changes to the database without creating migration files. Use when:
|
|
63
|
+
|
|
64
|
+
- Migrations failed and need to force schema sync
|
|
65
|
+
- Development environment needs quick schema updates
|
|
66
|
+
- Migration state is out of sync with actual database
|
|
67
|
+
|
|
68
|
+
**Warning:** This bypasses migration history. Use `db:migrate` workflow for production.
|
|
69
|
+
|
|
70
|
+
### 4. Apply RLS Policies (if needed)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pnpm db:apply-rls
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Run this after migrations if you've added new tables or need to refresh RLS policies.
|
|
77
|
+
|
|
78
|
+
## Available Scripts
|
|
79
|
+
|
|
80
|
+
| Script | Command | Description |
|
|
81
|
+
| -------------- | -------------------------- | ------------------------------------------------------ |
|
|
82
|
+
| `db:generate` | `drizzle-kit generate` | Generate migration from schema changes |
|
|
83
|
+
| `db:migrate` | `tsx scripts/migrate.ts` | Apply pending migrations |
|
|
84
|
+
| `db:push` | `drizzle-kit push` | Push schema directly to database (bypasses migrations) |
|
|
85
|
+
| `db:studio` | `drizzle-kit studio` | Open Drizzle Studio GUI |
|
|
86
|
+
| `db:apply-rls` | `tsx scripts/apply-rls.ts` | Apply RLS policies and FK constraints |
|
|
87
|
+
|
|
88
|
+
## Important Notes
|
|
89
|
+
|
|
90
|
+
### What Drizzle Manages
|
|
91
|
+
|
|
92
|
+
- Table creation and modifications
|
|
93
|
+
- Column types, defaults, constraints
|
|
94
|
+
- Migration history tracking
|
|
95
|
+
|
|
96
|
+
### What Drizzle Does NOT Manage
|
|
97
|
+
|
|
98
|
+
These are handled separately in `db/rls-policies.sql`:
|
|
99
|
+
|
|
100
|
+
- **RLS (Row Level Security) policies** - User data isolation
|
|
101
|
+
- **Foreign keys to `auth.users`** - Supabase auth integration
|
|
102
|
+
- **Custom indexes** - Performance optimization
|
|
103
|
+
|
|
104
|
+
### Adding a New Table
|
|
105
|
+
|
|
106
|
+
1. Create schema in `db/schema/new-table.ts`
|
|
107
|
+
2. Export from `db/schema/index.ts`
|
|
108
|
+
3. Run `pnpm db:generate`
|
|
109
|
+
4. Run `pnpm db:migrate`
|
|
110
|
+
5. Add RLS policy in `db/rls-policies.sql`
|
|
111
|
+
6. Run `pnpm db:apply-rls`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: front-end-development
|
|
3
|
+
description: Best practices for Vue front-end development including state management, ui component architecture, and styling standards.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Front-End Development Skills
|
|
7
|
+
|
|
8
|
+
This skill provides guidelines and best practices for front-end development in this project.
|
|
9
|
+
|
|
10
|
+
## References
|
|
11
|
+
|
|
12
|
+
- [State Management](./references/state-management.md)
|
|
13
|
+
Pinia stores, data fetching patterns, and deduplication strategies.
|
|
14
|
+
|
|
15
|
+
- [Data Fetching Pattern](./references/data-fetching-pattern.md)
|
|
16
|
+
The specific pattern for deduplicating API calls in Pinia stores.
|
|
17
|
+
|
|
18
|
+
- [Component Architecture](./references/component-architecture.md)
|
|
19
|
+
Component communication, composables, performance, and reusability guidelines.
|
|
20
|
+
|
|
21
|
+
- [Styling Standards](./references/styling.md)
|
|
22
|
+
CSS units, Nuxt UI variables, design tokens, and spacing scales.
|
|
23
|
+
|
|
24
|
+
## Core Best Practices
|
|
25
|
+
|
|
26
|
+
1. **Single Responsibility** - Each component should do one thing well
|
|
27
|
+
2. **Composition over Inheritance** - Use composables to share logic
|
|
28
|
+
3. **Type Safety** - Define TypeScript interfaces for all props and emits
|
|
29
|
+
4. **Reactive Patterns** - Use Vue's reactivity system, don't fight it
|
|
30
|
+
5. **Avoid Deep Nesting** - Keep component trees shallow when possible
|
|
31
|
+
6. **Test Boundaries** - Components should be testable in isolation
|
|
32
|
+
7. **Reusability First** - Extract repeated patterns into shared components
|
|
33
|
+
8. **Flexible Components** - Use slots for customization points
|
|
34
|
+
9. **Design Tokens First** - Use existing tokens when available; create component-specific tokens for reusable components; otherwise use direct `rem` values
|
|
35
|
+
10. **Rem Units Always** - Use rem for scalability, never px
|
|
36
|
+
|
|
37
|
+
**Important Rule:** Whenever using Nuxt UI components, you must use the `nuxt-ui` MCP tools to verify component names, props, and availability. Do not assume component exist without verification.
|
|
38
|
+
|
|
39
|
+
- When creating base components, make sure NO Tailwind CSS classes are used directly in the component templates. Instead, use scoped CSS to handle styling.
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Component Architecture
|
|
2
|
+
|
|
3
|
+
## Component Communication
|
|
4
|
+
|
|
5
|
+
- Avoid prop-drilling and event emits for workflow actions; prefer Pinia store actions or composables
|
|
6
|
+
- Reusable base components - no store context - use props and events
|
|
7
|
+
|
|
8
|
+
### v-model Pattern (Use Sparingly)
|
|
9
|
+
|
|
10
|
+
- Avoid `v-model` for feature components; it relies on emits
|
|
11
|
+
- Use `v-model` only for low-level input components where two-way binding is required
|
|
12
|
+
- For complex objects, update via a store action instead of emitting the object
|
|
13
|
+
- Avoid mutating props directly
|
|
14
|
+
|
|
15
|
+
**Correct v-model implementation (use `defineModel` macro):**
|
|
16
|
+
|
|
17
|
+
Child.vue:
|
|
18
|
+
|
|
19
|
+
```vue
|
|
20
|
+
<script setup>
|
|
21
|
+
const model = defineModel()
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<button @click="model.value++">Increment</button>
|
|
26
|
+
</template>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Parent.vue:
|
|
30
|
+
|
|
31
|
+
```vue
|
|
32
|
+
<Child v-model="countModel" />
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
More examples at Vue doc site: https://vuejs.org/guide/components/v-model.html#multiple-v-model-bindings
|
|
36
|
+
|
|
37
|
+
## Composables
|
|
38
|
+
|
|
39
|
+
### Reusable Logic
|
|
40
|
+
|
|
41
|
+
- Extract reusable logic into composables (`use*` pattern)
|
|
42
|
+
- Composables can access Pinia stores
|
|
43
|
+
- Keep composables focused and single-purpose
|
|
44
|
+
|
|
45
|
+
### Example
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// composables/useProfile.ts
|
|
49
|
+
export function useProfile() {
|
|
50
|
+
const profileStore = useProfileStore()
|
|
51
|
+
|
|
52
|
+
async function saveProfile(data: ProfileFormData) {
|
|
53
|
+
await $fetch('/api/profile', {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
body: data,
|
|
56
|
+
})
|
|
57
|
+
await profileStore.fetchProfile()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return { saveProfile }
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Performance
|
|
65
|
+
|
|
66
|
+
### Computed Properties
|
|
67
|
+
|
|
68
|
+
- Use `computed()` for derived state
|
|
69
|
+
- Computed values are cached and only recalculate when dependencies change
|
|
70
|
+
- Prefer computed over methods for template expressions
|
|
71
|
+
|
|
72
|
+
### Lazy Loading
|
|
73
|
+
|
|
74
|
+
- Use dynamic imports for route components
|
|
75
|
+
- Lazy load heavy components not immediately visible
|
|
76
|
+
- Code-split by route for optimal bundle sizes
|
|
77
|
+
|
|
78
|
+
## Component Reusability
|
|
79
|
+
|
|
80
|
+
### Extract Repeated Patterns
|
|
81
|
+
|
|
82
|
+
- **Identify repeated UI patterns** across pages and components
|
|
83
|
+
- **Create shared components** for patterns used 2+ times
|
|
84
|
+
- **Prioritize reusability** - easier to update in one place
|
|
85
|
+
- **Use generic naming** - avoid page-specific names for shared components
|
|
86
|
+
|
|
87
|
+
### When to Extract a Component
|
|
88
|
+
|
|
89
|
+
**Extract if:**
|
|
90
|
+
|
|
91
|
+
- Pattern appears 2+ times in codebase
|
|
92
|
+
- Pattern has consistent structure/behavior
|
|
93
|
+
- Pattern will likely be used in future features
|
|
94
|
+
- Updating the pattern requires changes in multiple places
|
|
95
|
+
|
|
96
|
+
**Don't extract if:**
|
|
97
|
+
|
|
98
|
+
- Pattern appears only once
|
|
99
|
+
- Pattern is highly page-specific
|
|
100
|
+
- Extraction adds unnecessary complexity
|
|
101
|
+
- Pattern is likely to diverge in different contexts
|
|
102
|
+
|
|
103
|
+
### Shared Component Patterns
|
|
104
|
+
|
|
105
|
+
#### Display Components
|
|
106
|
+
|
|
107
|
+
For read-only data display patterns:
|
|
108
|
+
|
|
109
|
+
```vue
|
|
110
|
+
<!-- components/display/FieldRow.vue -->
|
|
111
|
+
<template>
|
|
112
|
+
<div class="field-row">
|
|
113
|
+
<label class="field-label">{{ label }}</label>
|
|
114
|
+
<div class="field-value">
|
|
115
|
+
<slot>{{ value }}</slot>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</template>
|
|
119
|
+
|
|
120
|
+
<script setup lang="ts">
|
|
121
|
+
defineProps<{
|
|
122
|
+
label: string
|
|
123
|
+
value?: string | number
|
|
124
|
+
}>()
|
|
125
|
+
</script>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Usage:**
|
|
129
|
+
|
|
130
|
+
```vue
|
|
131
|
+
<FieldRow label="Experience Level" :value="profile.experienceLevel" />
|
|
132
|
+
<FieldRow label="Goals">
|
|
133
|
+
<span class="custom-formatting">{{ formatGoals(profile.goals) }}</span>
|
|
134
|
+
</FieldRow>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### Form Components
|
|
138
|
+
|
|
139
|
+
For input patterns with consistent styling:
|
|
140
|
+
|
|
141
|
+
```vue
|
|
142
|
+
<!-- components/form/FormField.vue -->
|
|
143
|
+
<template>
|
|
144
|
+
<div class="form-field">
|
|
145
|
+
<label class="field-label">{{ label }}</label>
|
|
146
|
+
<slot />
|
|
147
|
+
<small v-if="hint" class="field-hint">{{ hint }}</small>
|
|
148
|
+
</div>
|
|
149
|
+
</template>
|
|
150
|
+
|
|
151
|
+
<script setup lang="ts">
|
|
152
|
+
defineProps<{
|
|
153
|
+
label: string
|
|
154
|
+
hint?: string
|
|
155
|
+
}>()
|
|
156
|
+
</script>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Component Organization
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
components/
|
|
163
|
+
├── display/ # Read-only display components
|
|
164
|
+
│ ├── FieldRow.vue
|
|
165
|
+
│ ├── StatCard.vue
|
|
166
|
+
│ └── DataList.vue
|
|
167
|
+
├── form/ # Form input components
|
|
168
|
+
│ ├── FormField.vue
|
|
169
|
+
│ ├── ChipGroup.vue
|
|
170
|
+
│ └── RadioGroup.vue
|
|
171
|
+
├── layout/ # Layout components
|
|
172
|
+
│ ├── PageHeader.vue
|
|
173
|
+
│ └── Section.vue
|
|
174
|
+
└── [feature]/ # Feature-specific components
|
|
175
|
+
└── SessionRunner.vue
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Refactoring Guidelines
|
|
179
|
+
|
|
180
|
+
1. **Identify the pattern** - Look for repeated markup/logic
|
|
181
|
+
2. **Extract to component** - Create in appropriate directory
|
|
182
|
+
3. **Add TypeScript types** - Props and emits interfaces
|
|
183
|
+
4. **Add slots for flexibility** - Allow customization where needed
|
|
184
|
+
5. **Update all usages** - Replace old pattern with new component
|
|
185
|
+
6. **Test thoroughly** - Ensure all instances work correctly
|
|
186
|
+
|
|
187
|
+
### Example Refactor
|
|
188
|
+
|
|
189
|
+
**Before:**
|
|
190
|
+
|
|
191
|
+
```vue
|
|
192
|
+
<!-- Repeated in multiple places -->
|
|
193
|
+
<div class="profile-field">
|
|
194
|
+
<label>Experience Level</label>
|
|
195
|
+
<div class="field-value">{{ profile.experienceLevel }}</div>
|
|
196
|
+
</div>
|
|
197
|
+
<Divider />
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**After:**
|
|
201
|
+
|
|
202
|
+
```vue
|
|
203
|
+
<!-- components/display/FieldRow.vue created -->
|
|
204
|
+
<FieldRow label="Experience Level" :value="profile.experienceLevel" />
|
|
205
|
+
<Divider />
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Benefits:**
|
|
209
|
+
|
|
210
|
+
- ✅ Update styling in one place
|
|
211
|
+
- ✅ Consistent appearance across app
|
|
212
|
+
- ✅ Easier to add features (icons, tooltips, etc.)
|
|
213
|
+
- ✅ Reduced code duplication
|