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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Đức Trần Xuân (ducsatthu)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# aigent-team
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/aigent-team)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](package.json)
|
|
6
|
+
|
|
7
|
+
One config, six AI agents, four platforms. Generate senior-level AI coding agent configurations from a single source of truth.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
aigent-team generate
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> Requires **Node.js >= 18**
|
|
14
|
+
|
|
15
|
+
## What it does
|
|
16
|
+
|
|
17
|
+
aigent-team compiles YAML+Markdown templates into platform-native agent configs for:
|
|
18
|
+
|
|
19
|
+
| Platform | Output format |
|
|
20
|
+
|---|---|
|
|
21
|
+
| **Claude Code** | `.claude/agents/*.md` with YAML frontmatter |
|
|
22
|
+
| **Cursor** | `.cursor/rules/*.mdc` with MDC frontmatter + globs |
|
|
23
|
+
| **Codex** | `AGENTS.md` + `.codex/agents/*.md` |
|
|
24
|
+
| **Antigravity** | `GEMINI.md` + `.agents/skills/*/SKILL.md` |
|
|
25
|
+
|
|
26
|
+
Each agent is a senior-level specialist (8+ years expertise) with deep knowledge baked into reference files:
|
|
27
|
+
|
|
28
|
+
| Agent | Role | Reference topics |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| **Lead** | Tech Lead / PM orchestrator | Task decomposition, cross-team coordination, quality gates |
|
|
31
|
+
| **BA** | Business Analyst | Requirements analysis, acceptance criteria, API contracts, story mapping |
|
|
32
|
+
| **FE** | Frontend Engineer | Components, state, performance, a11y, security, CSS, forms, testing |
|
|
33
|
+
| **BE** | Backend Engineer | API design, database, auth, error handling, observability, caching, async |
|
|
34
|
+
| **QA** | QA Engineer | Test strategy, E2E, test data, mocking, perf testing, security testing, CI |
|
|
35
|
+
| **DevOps** | DevOps / SRE | IaC, Docker, K8s, CI/CD, monitoring, security, DR, cost optimization |
|
|
36
|
+
|
|
37
|
+
## Architecture
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
┌─────────────────┐
|
|
41
|
+
│ Lead Agent │ orchestrator
|
|
42
|
+
│ (Tech Lead) │
|
|
43
|
+
└───────┬─────────┘
|
|
44
|
+
│ spawn & assign
|
|
45
|
+
┌─────────┬───────┼───────┬──────────┐
|
|
46
|
+
▼ ▼ ▼ ▼ ▼
|
|
47
|
+
┌─────┐ ┌─────┐ ┌─────┐ ┌──────┐ ┌───────┐
|
|
48
|
+
│ BA │ │ FE │ │ BE │ │ QA │ │DevOps │
|
|
49
|
+
└─────┘ └─────┘ └─────┘ └──────┘ └───────┘
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Each agent has:
|
|
53
|
+
- **Skill index** (~80-150 lines) — always loaded in context. Core principles, anti-patterns, decision frameworks.
|
|
54
|
+
- **Reference files** (3-9 per agent) — loaded on-demand when the task requires deep knowledge.
|
|
55
|
+
|
|
56
|
+
This keeps the always-loaded context slim while providing access to thousands of lines of senior expertise when needed.
|
|
57
|
+
|
|
58
|
+
## Quick start
|
|
59
|
+
|
|
60
|
+
### Install
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install -D aigent-team
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Or use directly:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npx aigent-team init
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Initialize
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npx aigent-team init
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Interactive wizard that:
|
|
79
|
+
1. Detects which AI tools you have installed (Claude Code, Cursor, Codex, Antigravity)
|
|
80
|
+
2. Lets you pick which team agents to enable
|
|
81
|
+
3. Creates `aigent-team.config.json`
|
|
82
|
+
|
|
83
|
+
### Generate
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx aigent-team generate
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Generates agent configs for all configured platforms. Run this after changing your config or updating aigent-team.
|
|
90
|
+
|
|
91
|
+
### Validate
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npx aigent-team validate
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Checks generated files against each platform's constraints (file size, frontmatter format, naming).
|
|
98
|
+
|
|
99
|
+
## Configuration
|
|
100
|
+
|
|
101
|
+
Create `aigent-team.config.json` (or `.ts` / `.js`) in your project root:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"projectName": "my-app",
|
|
106
|
+
"platforms": ["claude-code", "cursor"],
|
|
107
|
+
"teams": ["lead", "fe", "be", "qa"],
|
|
108
|
+
"overrides": {
|
|
109
|
+
"fe": {
|
|
110
|
+
"techStack": {
|
|
111
|
+
"frameworks": ["Next.js 15", "React 19"],
|
|
112
|
+
"libraries": ["Tailwind CSS 4", "Zustand", "TanStack Query"]
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"be": {
|
|
116
|
+
"techStack": {
|
|
117
|
+
"frameworks": ["NestJS", "Prisma"],
|
|
118
|
+
"libraries": ["PostgreSQL", "Redis", "BullMQ"]
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Config options
|
|
126
|
+
|
|
127
|
+
| Field | Type | Required | Description |
|
|
128
|
+
|---|---|---|---|
|
|
129
|
+
| `projectName` | `string` | Yes | Your project name |
|
|
130
|
+
| `platforms` | `string[]` | Yes | Target platforms: `claude-code`, `cursor`, `codex`, `antigravity` |
|
|
131
|
+
| `teams` | `string[]` | Yes | Agent teams to enable: `lead`, `ba`, `fe`, `be`, `qa`, `devops` |
|
|
132
|
+
| `overrides` | `object` | No | Per-team overrides for `techStack`, `tools`, `globs` |
|
|
133
|
+
| `overrides.<team>.techStack` | `object` | No | Override `languages`, `frameworks`, `libraries`, `buildTools` |
|
|
134
|
+
|
|
135
|
+
### Programmatic config
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// aigent-team.config.ts
|
|
139
|
+
import { defineConfig } from 'aigent-team';
|
|
140
|
+
|
|
141
|
+
export default defineConfig({
|
|
142
|
+
projectName: 'my-app',
|
|
143
|
+
platforms: ['claude-code', 'cursor'],
|
|
144
|
+
teams: ['lead', 'fe', 'be', 'qa'],
|
|
145
|
+
overrides: {
|
|
146
|
+
fe: {
|
|
147
|
+
techStack: {
|
|
148
|
+
frameworks: ['Next.js 15'],
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Platform-specific flags
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Generate only for a specific platform
|
|
159
|
+
npx aigent-team generate --platform claude-code
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Generated output
|
|
163
|
+
|
|
164
|
+
After running `aigent-team generate`, you'll see:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
# Claude Code
|
|
168
|
+
.claude/agents/lead-agent.md # Skill index (always loaded)
|
|
169
|
+
.claude/agents/lead-agent/references/ # Deep reference docs
|
|
170
|
+
.claude/agents/fe-agent.md
|
|
171
|
+
.claude/agents/fe-agent/references/
|
|
172
|
+
├── component-architecture.md
|
|
173
|
+
├── state-management.md
|
|
174
|
+
├── performance.md
|
|
175
|
+
├── accessibility.md
|
|
176
|
+
├── security.md
|
|
177
|
+
├── testing.md
|
|
178
|
+
├── css-styling.md
|
|
179
|
+
├── forms.md
|
|
180
|
+
└── review-checklist.md
|
|
181
|
+
...
|
|
182
|
+
CLAUDE.md # Agent team overview
|
|
183
|
+
|
|
184
|
+
# Cursor
|
|
185
|
+
.cursor/rules/fe-agent.mdc # Glob-scoped skill
|
|
186
|
+
.cursor/rules/fe-refs/ # Glob-scoped references
|
|
187
|
+
...
|
|
188
|
+
|
|
189
|
+
# Codex
|
|
190
|
+
AGENTS.md # Combined agent doc
|
|
191
|
+
.codex/agents/fe-agent.md # Individual agent
|
|
192
|
+
.codex/agents/fe-agent/references/ # References
|
|
193
|
+
...
|
|
194
|
+
|
|
195
|
+
# Antigravity
|
|
196
|
+
GEMINI.md # Agent overview
|
|
197
|
+
.agents/skills/fe-agent/SKILL.md # Skill file
|
|
198
|
+
.agents/skills/fe-agent/references/ # References
|
|
199
|
+
...
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## What to commit
|
|
203
|
+
|
|
204
|
+
Generated files **should be committed** to your repo — they are the actual agent configs your AI tools read. Add this to your workflow:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
npx aigent-team generate
|
|
208
|
+
git add .claude/ .cursor/ .codex/ .agents/ CLAUDE.md AGENTS.md GEMINI.md
|
|
209
|
+
git commit -m "chore: regenerate agent configs"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Only `.aigent-team/` (local overrides) and `aigent-team.config.json` are your source files. Everything else is generated output.
|
|
213
|
+
|
|
214
|
+
## Local overrides
|
|
215
|
+
|
|
216
|
+
Create a `.aigent-team/` directory in your project to override any template locally:
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
.aigent-team/
|
|
220
|
+
├── teams/
|
|
221
|
+
│ └── fe/
|
|
222
|
+
│ └── references/
|
|
223
|
+
│ └── component-architecture.md # Your custom version
|
|
224
|
+
└── shared/
|
|
225
|
+
└── git-workflow.md # Your git workflow
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Local overrides take priority over built-in templates. This lets you customize agent knowledge for your specific project without forking.
|
|
229
|
+
|
|
230
|
+
## How the Lead agent works
|
|
231
|
+
|
|
232
|
+
The Lead agent acts as orchestrator. When it receives a task, it:
|
|
233
|
+
|
|
234
|
+
1. **Analyzes** the requirement — identifies which teams are involved
|
|
235
|
+
2. **Spawns** the right team agents (BA for specs, FE/BE for implementation, QA for tests)
|
|
236
|
+
3. **Coordinates** cross-team work (e.g., FE+BE align on API contract via BA specs)
|
|
237
|
+
4. **Reviews** output quality before delivery
|
|
238
|
+
|
|
239
|
+
This mirrors how a real tech lead operates — delegating to specialists and ensuring alignment.
|
|
240
|
+
|
|
241
|
+
## Contributing
|
|
242
|
+
|
|
243
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
|
|
244
|
+
|
|
245
|
+
Issues and PRs welcome at [github.com/ducsatthu/aigent-team](https://github.com/ducsatthu/aigent-team).
|
|
246
|
+
|
|
247
|
+
## Author
|
|
248
|
+
|
|
249
|
+
**Đức Trần Xuân** ([@ducsatthu](https://github.com/ducsatthu)) — ductranxuan.29710@gmail.com
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/core/types.ts
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
var PLATFORMS = ["claude-code", "cursor", "codex", "antigravity"];
|
|
6
|
+
var TEAM_ROLES = ["lead", "ba", "fe", "be", "qa", "devops"];
|
|
7
|
+
var TechStackSchema = z.object({
|
|
8
|
+
languages: z.array(z.string()).optional(),
|
|
9
|
+
frameworks: z.array(z.string()).optional(),
|
|
10
|
+
libraries: z.array(z.string()).optional(),
|
|
11
|
+
buildTools: z.array(z.string()).optional()
|
|
12
|
+
});
|
|
13
|
+
var AgentOverrideSchema = z.object({
|
|
14
|
+
name: z.string().optional(),
|
|
15
|
+
description: z.string().optional(),
|
|
16
|
+
systemPrompt: z.string().optional(),
|
|
17
|
+
techStack: TechStackSchema.optional(),
|
|
18
|
+
conventions: z.string().optional(),
|
|
19
|
+
reviewChecklist: z.string().optional(),
|
|
20
|
+
tools: z.object({
|
|
21
|
+
allowed: z.array(z.string()).optional(),
|
|
22
|
+
denied: z.array(z.string()).optional()
|
|
23
|
+
}).optional(),
|
|
24
|
+
globs: z.array(z.string()).optional()
|
|
25
|
+
});
|
|
26
|
+
var ConfigSchema = z.object({
|
|
27
|
+
projectName: z.string(),
|
|
28
|
+
platforms: z.array(z.enum(PLATFORMS)).min(1),
|
|
29
|
+
teams: z.array(z.enum(TEAM_ROLES)).min(1),
|
|
30
|
+
overrides: z.record(z.enum(TEAM_ROLES), AgentOverrideSchema).optional(),
|
|
31
|
+
shared: z.object({
|
|
32
|
+
conventions: z.string().optional(),
|
|
33
|
+
apiSpecs: z.string().optional(),
|
|
34
|
+
architecture: z.string().optional()
|
|
35
|
+
}).optional(),
|
|
36
|
+
output: z.object({
|
|
37
|
+
directory: z.string().optional()
|
|
38
|
+
}).optional()
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// src/core/config-loader.ts
|
|
42
|
+
import { readFileSync, existsSync } from "fs";
|
|
43
|
+
import { resolve } from "path";
|
|
44
|
+
import { pathToFileURL } from "url";
|
|
45
|
+
var CONFIG_FILES = [
|
|
46
|
+
"aigent-team.config.ts",
|
|
47
|
+
"aigent-team.config.js",
|
|
48
|
+
"aigent-team.config.json"
|
|
49
|
+
];
|
|
50
|
+
async function loadConfig(cwd = process.cwd()) {
|
|
51
|
+
for (const file of CONFIG_FILES) {
|
|
52
|
+
const filePath = resolve(cwd, file);
|
|
53
|
+
if (!existsSync(filePath)) continue;
|
|
54
|
+
if (file.endsWith(".json")) {
|
|
55
|
+
const raw = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
56
|
+
return ConfigSchema.parse(raw);
|
|
57
|
+
}
|
|
58
|
+
const mod = await import(pathToFileURL(filePath).href);
|
|
59
|
+
const config = mod.default ?? mod;
|
|
60
|
+
return ConfigSchema.parse(config);
|
|
61
|
+
}
|
|
62
|
+
throw new Error(
|
|
63
|
+
`No aigent-team config found. Run \`aigent-team init\` to create one.`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
function configExists(cwd = process.cwd()) {
|
|
67
|
+
return CONFIG_FILES.some((f) => existsSync(resolve(cwd, f)));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/core/agent-loader.ts
|
|
71
|
+
import { readFileSync as readFileSync2, existsSync as existsSync2, readdirSync } from "fs";
|
|
72
|
+
import { resolve as resolve2, dirname } from "path";
|
|
73
|
+
import { fileURLToPath } from "url";
|
|
74
|
+
import { parse as parseYaml } from "yaml";
|
|
75
|
+
import { deepmerge } from "deepmerge-ts";
|
|
76
|
+
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
77
|
+
var PACKAGE_ROOT = resolve2(__dirname, "..");
|
|
78
|
+
var TEMPLATES_DIR = existsSync2(resolve2(PACKAGE_ROOT, "templates")) ? resolve2(PACKAGE_ROOT, "templates") : resolve2(__dirname, "../../templates");
|
|
79
|
+
function readIfExists(path) {
|
|
80
|
+
return existsSync2(path) ? readFileSync2(path, "utf-8").trim() : "";
|
|
81
|
+
}
|
|
82
|
+
function loadReferences(refsDir) {
|
|
83
|
+
if (!existsSync2(refsDir)) return [];
|
|
84
|
+
const refs = [];
|
|
85
|
+
const files = readdirSync(refsDir, { withFileTypes: true });
|
|
86
|
+
for (const file of files) {
|
|
87
|
+
if (file.isDirectory()) {
|
|
88
|
+
const subDir = resolve2(refsDir, file.name);
|
|
89
|
+
const subFiles = readdirSync(subDir).filter((f) => f.endsWith(".md"));
|
|
90
|
+
for (const subFile of subFiles) {
|
|
91
|
+
const content = readFileSync2(resolve2(subDir, subFile), "utf-8").trim();
|
|
92
|
+
const id = `${file.name}/${subFile.replace(".md", "")}`;
|
|
93
|
+
refs.push({
|
|
94
|
+
id,
|
|
95
|
+
title: subFile.replace(".md", "").replace(/-/g, " "),
|
|
96
|
+
description: "",
|
|
97
|
+
whenToRead: "",
|
|
98
|
+
content
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
} else if (file.name.endsWith(".md")) {
|
|
102
|
+
const content = readFileSync2(resolve2(refsDir, file.name), "utf-8").trim();
|
|
103
|
+
const id = file.name.replace(".md", "");
|
|
104
|
+
refs.push({
|
|
105
|
+
id,
|
|
106
|
+
title: id.replace(/-/g, " "),
|
|
107
|
+
description: "",
|
|
108
|
+
whenToRead: "",
|
|
109
|
+
content
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return refs;
|
|
114
|
+
}
|
|
115
|
+
function loadBuiltinAgent(role) {
|
|
116
|
+
const teamDir = resolve2(TEMPLATES_DIR, "teams", role);
|
|
117
|
+
const agentYaml = readFileSync2(resolve2(teamDir, "agent.yaml"), "utf-8");
|
|
118
|
+
const agentDef = parseYaml(agentYaml);
|
|
119
|
+
const skillContent = readIfExists(resolve2(teamDir, "skill.md"));
|
|
120
|
+
const conventions = readIfExists(resolve2(teamDir, "conventions.md"));
|
|
121
|
+
const reviewChecklist = readIfExists(resolve2(teamDir, "review-checklist.md"));
|
|
122
|
+
const references = loadReferences(resolve2(teamDir, "references"));
|
|
123
|
+
return {
|
|
124
|
+
id: agentDef.id,
|
|
125
|
+
name: agentDef.name,
|
|
126
|
+
description: agentDef.description,
|
|
127
|
+
role: agentDef.role,
|
|
128
|
+
systemPrompt: agentDef.systemPrompt || "",
|
|
129
|
+
skillContent,
|
|
130
|
+
techStack: agentDef.techStack || { languages: [], frameworks: [], libraries: [], buildTools: [] },
|
|
131
|
+
conventions,
|
|
132
|
+
reviewChecklist,
|
|
133
|
+
tools: agentDef.tools || { allowed: [] },
|
|
134
|
+
workflows: agentDef.workflows || [],
|
|
135
|
+
sharedKnowledge: agentDef.sharedKnowledge || [],
|
|
136
|
+
references,
|
|
137
|
+
globs: agentDef.globs || []
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function loadSharedKnowledge() {
|
|
141
|
+
const sharedDir = resolve2(TEMPLATES_DIR, "shared");
|
|
142
|
+
const knowledge = {};
|
|
143
|
+
const files = ["project-conventions.md", "git-workflow.md"];
|
|
144
|
+
for (const file of files) {
|
|
145
|
+
const key = file.replace(".md", "");
|
|
146
|
+
knowledge[key] = readIfExists(resolve2(sharedDir, file));
|
|
147
|
+
}
|
|
148
|
+
return knowledge;
|
|
149
|
+
}
|
|
150
|
+
function loadAgents(config, cwd = process.cwd()) {
|
|
151
|
+
const sharedKnowledge = loadSharedKnowledge();
|
|
152
|
+
const agents = [];
|
|
153
|
+
for (const role of config.teams) {
|
|
154
|
+
let agent = loadBuiltinAgent(role);
|
|
155
|
+
const override = config.overrides?.[role];
|
|
156
|
+
if (override) {
|
|
157
|
+
let conventions = agent.conventions;
|
|
158
|
+
if (override.conventions && existsSync2(resolve2(cwd, override.conventions))) {
|
|
159
|
+
conventions = readFileSync2(resolve2(cwd, override.conventions), "utf-8").trim();
|
|
160
|
+
}
|
|
161
|
+
agent = deepmerge(agent, {
|
|
162
|
+
...override,
|
|
163
|
+
conventions
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
const localDir = resolve2(cwd, ".aigent-team", "teams", role);
|
|
167
|
+
if (existsSync2(localDir)) {
|
|
168
|
+
const localConventions = readIfExists(resolve2(localDir, "conventions.md"));
|
|
169
|
+
const localChecklist = readIfExists(resolve2(localDir, "review-checklist.md"));
|
|
170
|
+
const localSkill = readIfExists(resolve2(localDir, "skill.md"));
|
|
171
|
+
if (localConventions) agent.conventions = localConventions;
|
|
172
|
+
if (localChecklist) agent.reviewChecklist = localChecklist;
|
|
173
|
+
if (localSkill) agent.skillContent = localSkill;
|
|
174
|
+
const localRefs = loadReferences(resolve2(localDir, "references"));
|
|
175
|
+
if (localRefs.length) {
|
|
176
|
+
agent.references = [...agent.references, ...localRefs];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const resolvedShared = [];
|
|
180
|
+
for (const ref of agent.sharedKnowledge) {
|
|
181
|
+
if (sharedKnowledge[ref]) {
|
|
182
|
+
resolvedShared.push(sharedKnowledge[ref]);
|
|
183
|
+
}
|
|
184
|
+
if (ref === "project-conventions" && config.shared?.conventions) {
|
|
185
|
+
const p = resolve2(cwd, config.shared.conventions);
|
|
186
|
+
if (existsSync2(p)) resolvedShared.push(readFileSync2(p, "utf-8").trim());
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
agent.sharedKnowledge = resolvedShared;
|
|
190
|
+
agents.push(agent);
|
|
191
|
+
}
|
|
192
|
+
return agents;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// src/core/template-engine.ts
|
|
196
|
+
function assembleSkillIndex(agent) {
|
|
197
|
+
if (agent.skillContent) {
|
|
198
|
+
return agent.skillContent;
|
|
199
|
+
}
|
|
200
|
+
return assembleAgentMarkdown(agent);
|
|
201
|
+
}
|
|
202
|
+
function assembleAgentMarkdown(agent) {
|
|
203
|
+
const sections = [];
|
|
204
|
+
sections.push(`# ${agent.name}
|
|
205
|
+
|
|
206
|
+
${agent.description}`);
|
|
207
|
+
if (agent.systemPrompt) {
|
|
208
|
+
sections.push(agent.systemPrompt);
|
|
209
|
+
}
|
|
210
|
+
const { techStack } = agent;
|
|
211
|
+
const stackLines = [];
|
|
212
|
+
if (techStack.languages.length) stackLines.push(`- **Languages**: ${techStack.languages.join(", ")}`);
|
|
213
|
+
if (techStack.frameworks.length) stackLines.push(`- **Frameworks**: ${techStack.frameworks.join(", ")}`);
|
|
214
|
+
if (techStack.libraries.length) stackLines.push(`- **Libraries**: ${techStack.libraries.join(", ")}`);
|
|
215
|
+
if (techStack.buildTools.length) stackLines.push(`- **Build Tools**: ${techStack.buildTools.join(", ")}`);
|
|
216
|
+
if (stackLines.length) {
|
|
217
|
+
sections.push(`## Tech Stack
|
|
218
|
+
|
|
219
|
+
${stackLines.join("\n")}`);
|
|
220
|
+
}
|
|
221
|
+
if (agent.conventions) {
|
|
222
|
+
sections.push(`## Coding Conventions
|
|
223
|
+
|
|
224
|
+
${agent.conventions}`);
|
|
225
|
+
}
|
|
226
|
+
if (agent.reviewChecklist) {
|
|
227
|
+
sections.push(`## Review Checklist
|
|
228
|
+
|
|
229
|
+
${agent.reviewChecklist}`);
|
|
230
|
+
}
|
|
231
|
+
if (agent.workflows.length) {
|
|
232
|
+
const wfLines = agent.workflows.map((wf) => {
|
|
233
|
+
const steps = wf.steps.map((s, i) => `${i + 1}. ${s}`).join("\n");
|
|
234
|
+
return `### ${wf.name}
|
|
235
|
+
|
|
236
|
+
${wf.description}
|
|
237
|
+
|
|
238
|
+
${steps}`;
|
|
239
|
+
}).join("\n\n");
|
|
240
|
+
sections.push(`## Workflows
|
|
241
|
+
|
|
242
|
+
${wfLines}`);
|
|
243
|
+
}
|
|
244
|
+
if (agent.sharedKnowledge.length) {
|
|
245
|
+
const knowledge = agent.sharedKnowledge.filter(Boolean).join("\n\n---\n\n");
|
|
246
|
+
if (knowledge) {
|
|
247
|
+
sections.push(`## Project Knowledge
|
|
248
|
+
|
|
249
|
+
${knowledge}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return sections.join("\n\n");
|
|
253
|
+
}
|
|
254
|
+
function assembleReference(ref) {
|
|
255
|
+
return ref.content;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export {
|
|
259
|
+
PLATFORMS,
|
|
260
|
+
TEAM_ROLES,
|
|
261
|
+
loadConfig,
|
|
262
|
+
configExists,
|
|
263
|
+
loadAgents,
|
|
264
|
+
assembleSkillIndex,
|
|
265
|
+
assembleAgentMarkdown,
|
|
266
|
+
assembleReference
|
|
267
|
+
};
|