ai-team 1.2.0 → 1.3.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/CHANGELOG.md +8 -0
- package/package.json +1 -1
- package/src/lib/prompts.js +8 -1
- package/src/lib/sync-engine.js +10 -4
- package/src/lib/template-registry.js +22 -2
- package/tests/sync-engine.test.js +23 -0
- package/tests/template-registry.test.js +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# [1.3.0](https://github.com/seanwuapps/ai-team/compare/v1.2.0...v1.3.0) (2026-02-23)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* ensure mandatory agents are included in profiles and templates ([f48c99c](https://github.com/seanwuapps/ai-team/commit/f48c99c3953303dfee9e552c56dffe36979a692c))
|
|
7
|
+
* update mandatory agents to include product-team-orchestrator ([16bbc8e](https://github.com/seanwuapps/ai-team/commit/16bbc8e5a1292f6c68a00e01be68d14073817741))
|
|
8
|
+
|
|
1
9
|
# [1.2.0](https://github.com/seanwuapps/ai-team/compare/v1.1.0...v1.2.0) (2026-02-23)
|
|
2
10
|
|
|
3
11
|
|
package/package.json
CHANGED
package/src/lib/prompts.js
CHANGED
|
@@ -4,6 +4,10 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
import { readdir, readFile } from "node:fs/promises";
|
|
5
5
|
import { confirm, select, checkbox } from "@inquirer/prompts";
|
|
6
6
|
import YAML from "yaml";
|
|
7
|
+
import {
|
|
8
|
+
MANDATORY_AGENTS,
|
|
9
|
+
ensureMandatoryAgents,
|
|
10
|
+
} from "./template-registry.js";
|
|
7
11
|
|
|
8
12
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
13
|
const definitionsDir = path.resolve(__dirname, "../agents/definitions");
|
|
@@ -47,7 +51,7 @@ export async function collectInteractiveProfile({
|
|
|
47
51
|
ide: ide ?? "vscode",
|
|
48
52
|
team: team ?? "web-product",
|
|
49
53
|
includeMcp: includeMcp ?? true,
|
|
50
|
-
agents: agents
|
|
54
|
+
agents: ensureMandatoryAgents(agents),
|
|
51
55
|
};
|
|
52
56
|
}
|
|
53
57
|
|
|
@@ -80,6 +84,7 @@ export async function collectInteractiveProfile({
|
|
|
80
84
|
name: def.emoji ? `${def.emoji} ${def.name}` : def.name,
|
|
81
85
|
value: def.name,
|
|
82
86
|
checked: true,
|
|
87
|
+
disabled: MANDATORY_AGENTS.includes(def.name) ? "required" : undefined,
|
|
83
88
|
description: def.description,
|
|
84
89
|
})),
|
|
85
90
|
});
|
|
@@ -87,6 +92,8 @@ export async function collectInteractiveProfile({
|
|
|
87
92
|
selected.length > 0 ? selected : definitions.map((d) => d.name);
|
|
88
93
|
}
|
|
89
94
|
|
|
95
|
+
agentsAnswer = ensureMandatoryAgents(agentsAnswer);
|
|
96
|
+
|
|
90
97
|
let includeMcpAnswer = includeMcp;
|
|
91
98
|
if (includeMcpAnswer === undefined) {
|
|
92
99
|
includeMcpAnswer = await confirm({
|
package/src/lib/sync-engine.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
createManifest,
|
|
8
8
|
bumpManifest,
|
|
9
9
|
} from "./manifest.js";
|
|
10
|
+
import { ensureMandatoryAgents } from "./template-registry.js";
|
|
10
11
|
import { readTextIfExists, writeText } from "./fs-utils.js";
|
|
11
12
|
import { hashText } from "./hash.js";
|
|
12
13
|
import { detectLegacyLayout, applyLegacyMigration } from "./migration.js";
|
|
@@ -102,11 +103,16 @@ export async function planSync({
|
|
|
102
103
|
force = false,
|
|
103
104
|
command = "plan",
|
|
104
105
|
}) {
|
|
106
|
+
const normalizedProfile = {
|
|
107
|
+
...profile,
|
|
108
|
+
agents: ensureMandatoryAgents(profile.agents),
|
|
109
|
+
};
|
|
110
|
+
|
|
105
111
|
const { templateVersion, schemaVersion, entries } =
|
|
106
112
|
await collectTemplateEntries({
|
|
107
|
-
ide:
|
|
108
|
-
includeMcp:
|
|
109
|
-
agents:
|
|
113
|
+
ide: normalizedProfile.ide,
|
|
114
|
+
includeMcp: normalizedProfile.includeMcp,
|
|
115
|
+
agents: normalizedProfile.agents,
|
|
110
116
|
});
|
|
111
117
|
|
|
112
118
|
const installedManifest = await loadInstalledManifest(targetDir);
|
|
@@ -176,7 +182,7 @@ export async function planSync({
|
|
|
176
182
|
return {
|
|
177
183
|
command,
|
|
178
184
|
targetDir,
|
|
179
|
-
profile,
|
|
185
|
+
profile: normalizedProfile,
|
|
180
186
|
schemaVersion,
|
|
181
187
|
templateVersion,
|
|
182
188
|
hasManifest: Boolean(installedManifest),
|
|
@@ -8,6 +8,26 @@ import { generateAgentEntriesForIde } from "../agents/generate.js";
|
|
|
8
8
|
|
|
9
9
|
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
export const TEMPLATE_ROOT = path.resolve(dirname, "../../templates/bootstrap");
|
|
11
|
+
export const MANDATORY_AGENTS = ["agent-manager", "product-team-orchestrator"];
|
|
12
|
+
|
|
13
|
+
export function ensureMandatoryAgents(agents) {
|
|
14
|
+
if (!Array.isArray(agents) || agents.length === 0) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const normalized = new Set(
|
|
19
|
+
agents
|
|
20
|
+
.filter((value) => typeof value === "string")
|
|
21
|
+
.map((value) => value.trim())
|
|
22
|
+
.filter(Boolean),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
for (const mandatoryAgent of MANDATORY_AGENTS) {
|
|
26
|
+
normalized.add(mandatoryAgent);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return Array.from(normalized);
|
|
30
|
+
}
|
|
11
31
|
|
|
12
32
|
export async function loadTemplateManifest() {
|
|
13
33
|
const filePath = path.join(TEMPLATE_ROOT, "manifest.json");
|
|
@@ -87,8 +107,8 @@ export async function collectTemplateEntries({ ide, includeMcp, agents }) {
|
|
|
87
107
|
const entries = [];
|
|
88
108
|
|
|
89
109
|
// Normalise agent filter to a Set for fast lookup (null/undefined = include all)
|
|
90
|
-
const
|
|
91
|
-
|
|
110
|
+
const normalizedAgents = ensureMandatoryAgents(agents);
|
|
111
|
+
const agentFilter = normalizedAgents ? new Set(normalizedAgents) : null;
|
|
92
112
|
|
|
93
113
|
for (const absolutePath of baseFiles) {
|
|
94
114
|
const relative = path.relative(baseRoot, absolutePath);
|
|
@@ -105,3 +105,26 @@ test("json merge keeps local MCP servers in safe mode", async () => {
|
|
|
105
105
|
const updated = JSON.parse(await fs.readFile(mcpPath, "utf8"));
|
|
106
106
|
assert.ok(updated.servers["custom-local"]);
|
|
107
107
|
});
|
|
108
|
+
|
|
109
|
+
test("applySync persists mandatory agent-manager in manifest profile", async () => {
|
|
110
|
+
const targetDir = await makeTempDir();
|
|
111
|
+
const profile = {
|
|
112
|
+
ide: "vscode",
|
|
113
|
+
team: "web-product",
|
|
114
|
+
includeMcp: true,
|
|
115
|
+
agents: ["planning-agent"],
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const plan = await planSync({ targetDir, profile });
|
|
119
|
+
const result = await applySync(plan);
|
|
120
|
+
|
|
121
|
+
assert.deepEqual(result.manifest.profile.agents, [
|
|
122
|
+
"planning-agent",
|
|
123
|
+
"agent-manager",
|
|
124
|
+
]);
|
|
125
|
+
assert.ok(
|
|
126
|
+
plan.actions.some(
|
|
127
|
+
(action) => action.targetPath === ".github/agents/agent-manager.agent.md",
|
|
128
|
+
),
|
|
129
|
+
);
|
|
130
|
+
});
|
|
@@ -30,6 +30,21 @@ test("collectTemplateEntries omits MCP output when includeMcp is false", async (
|
|
|
30
30
|
assert.ok(result.entries.every((entry) => entry.targetPath !== ".mcp.json"));
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
+
test("collectTemplateEntries always includes agent-manager", async () => {
|
|
34
|
+
const result = await collectTemplateEntries({
|
|
35
|
+
ide: "vscode",
|
|
36
|
+
includeMcp: false,
|
|
37
|
+
agents: ["planning-agent"],
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const generatedAgents = result.entries
|
|
41
|
+
.filter((entry) => entry.targetPath.startsWith(".github/agents/"))
|
|
42
|
+
.map((entry) => entry.targetPath);
|
|
43
|
+
|
|
44
|
+
assert.ok(generatedAgents.includes(".github/agents/planning-agent.agent.md"));
|
|
45
|
+
assert.ok(generatedAgents.includes(".github/agents/agent-manager.agent.md"));
|
|
46
|
+
});
|
|
47
|
+
|
|
33
48
|
test("getIdePack supports legacy packs.overlays manifest shape", () => {
|
|
34
49
|
const legacyManifest = {
|
|
35
50
|
packs: {
|