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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +253 -0
  3. package/dist/chunk-N3RYHWTR.js +267 -0
  4. package/dist/cli.js +576 -0
  5. package/dist/index.d.ts +234 -0
  6. package/dist/index.js +27 -0
  7. package/package.json +67 -0
  8. package/templates/shared/git-workflow.md +44 -0
  9. package/templates/shared/project-conventions.md +48 -0
  10. package/templates/teams/ba/agent.yaml +25 -0
  11. package/templates/teams/ba/references/acceptance-criteria.md +87 -0
  12. package/templates/teams/ba/references/api-contract-design.md +110 -0
  13. package/templates/teams/ba/references/requirements-analysis.md +83 -0
  14. package/templates/teams/ba/references/user-story-mapping.md +73 -0
  15. package/templates/teams/ba/skill.md +85 -0
  16. package/templates/teams/be/agent.yaml +34 -0
  17. package/templates/teams/be/conventions.md +102 -0
  18. package/templates/teams/be/references/api-design.md +91 -0
  19. package/templates/teams/be/references/async-processing.md +86 -0
  20. package/templates/teams/be/references/auth-security.md +58 -0
  21. package/templates/teams/be/references/caching.md +79 -0
  22. package/templates/teams/be/references/database.md +65 -0
  23. package/templates/teams/be/references/error-handling.md +106 -0
  24. package/templates/teams/be/references/observability.md +83 -0
  25. package/templates/teams/be/references/review-checklist.md +50 -0
  26. package/templates/teams/be/references/testing.md +100 -0
  27. package/templates/teams/be/review-checklist.md +54 -0
  28. package/templates/teams/be/skill.md +71 -0
  29. package/templates/teams/devops/agent.yaml +35 -0
  30. package/templates/teams/devops/conventions.md +133 -0
  31. package/templates/teams/devops/references/ci-cd.md +218 -0
  32. package/templates/teams/devops/references/cost-optimization.md +218 -0
  33. package/templates/teams/devops/references/disaster-recovery.md +199 -0
  34. package/templates/teams/devops/references/docker.md +237 -0
  35. package/templates/teams/devops/references/infrastructure-as-code.md +238 -0
  36. package/templates/teams/devops/references/kubernetes.md +397 -0
  37. package/templates/teams/devops/references/monitoring.md +224 -0
  38. package/templates/teams/devops/references/review-checklist.md +149 -0
  39. package/templates/teams/devops/references/security.md +225 -0
  40. package/templates/teams/devops/review-checklist.md +72 -0
  41. package/templates/teams/devops/skill.md +131 -0
  42. package/templates/teams/fe/agent.yaml +28 -0
  43. package/templates/teams/fe/conventions.md +80 -0
  44. package/templates/teams/fe/references/accessibility.md +92 -0
  45. package/templates/teams/fe/references/component-architecture.md +87 -0
  46. package/templates/teams/fe/references/css-styling.md +89 -0
  47. package/templates/teams/fe/references/forms.md +73 -0
  48. package/templates/teams/fe/references/performance.md +104 -0
  49. package/templates/teams/fe/references/review-checklist.md +51 -0
  50. package/templates/teams/fe/references/security.md +90 -0
  51. package/templates/teams/fe/references/state-management.md +117 -0
  52. package/templates/teams/fe/references/testing.md +112 -0
  53. package/templates/teams/fe/review-checklist.md +53 -0
  54. package/templates/teams/fe/skill.md +68 -0
  55. package/templates/teams/lead/agent.yaml +18 -0
  56. package/templates/teams/lead/references/cross-team-coordination.md +68 -0
  57. package/templates/teams/lead/references/quality-gates.md +64 -0
  58. package/templates/teams/lead/references/task-decomposition.md +69 -0
  59. package/templates/teams/lead/skill.md +83 -0
  60. package/templates/teams/qa/agent.yaml +32 -0
  61. package/templates/teams/qa/conventions.md +130 -0
  62. package/templates/teams/qa/references/ci-integration.md +337 -0
  63. package/templates/teams/qa/references/e2e-testing.md +292 -0
  64. package/templates/teams/qa/references/mocking.md +249 -0
  65. package/templates/teams/qa/references/performance-testing.md +288 -0
  66. package/templates/teams/qa/references/review-checklist.md +143 -0
  67. package/templates/teams/qa/references/security-testing.md +271 -0
  68. package/templates/teams/qa/references/test-data.md +275 -0
  69. package/templates/teams/qa/references/test-strategy.md +192 -0
  70. package/templates/teams/qa/review-checklist.md +53 -0
  71. 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
+ [![npm version](https://img.shields.io/npm/v/aigent-team)](https://www.npmjs.com/package/aigent-team)
4
+ [![license](https://img.shields.io/npm/l/aigent-team)](LICENSE)
5
+ [![node](https://img.shields.io/node/v/aigent-team)](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
+ };