refactor: migrate role handling from tiers to roles module

- Removed the deprecated tiers.ts file and migrated all related functionality to roles/index.js.
- Updated tests and tools to reflect the new role structure, replacing references to "dev", "qa", and "architect" with "developer", "tester", and "architect".
- Adjusted workflow configurations and state management to accommodate the new role naming conventions.
- Enhanced project registration and health check tools to support dynamic role handling.
- Updated task creation, update, and completion processes to align with the new role definitions.
- Improved documentation and comments to clarify role responsibilities and usage.
This commit is contained in:
Lauren ten Hoor
2026-02-15 18:32:10 +08:00
parent 6a99752e5f
commit 0e24a68882
44 changed files with 1162 additions and 762 deletions

View File

@@ -15,40 +15,26 @@ import { resolveRepoPath } from "../projects.js";
import { createProvider } from "../providers/index.js";
import { log as auditLog } from "../audit.js";
import { getAllRoleIds, getLevelsForRole } from "../roles/index.js";
import { DEFAULT_DEV_INSTRUCTIONS, DEFAULT_QA_INSTRUCTIONS, DEFAULT_ARCHITECT_INSTRUCTIONS } from "../templates.js";
import { DEFAULT_ROLE_INSTRUCTIONS } from "../templates.js";
/**
* Scaffold project-specific prompt files.
* Scaffold project-specific prompt files for all registered roles.
* Returns true if files were created, false if they already existed.
*/
async function scaffoldPromptFiles(workspaceDir: string, projectName: string): Promise<boolean> {
const projectDir = path.join(workspaceDir, "projects", "roles", projectName);
await fs.mkdir(projectDir, { recursive: true });
const projectDev = path.join(projectDir, "dev.md");
const projectQa = path.join(projectDir, "qa.md");
let created = false;
try {
await fs.access(projectDev);
} catch {
await fs.writeFile(projectDev, DEFAULT_DEV_INSTRUCTIONS, "utf-8");
created = true;
}
try {
await fs.access(projectQa);
} catch {
await fs.writeFile(projectQa, DEFAULT_QA_INSTRUCTIONS, "utf-8");
created = true;
}
const projectArchitect = path.join(projectDir, "architect.md");
try {
await fs.access(projectArchitect);
} catch {
await fs.writeFile(projectArchitect, DEFAULT_ARCHITECT_INSTRUCTIONS, "utf-8");
created = true;
for (const role of getAllRoleIds()) {
const filePath = path.join(projectDir, `${role}.md`);
try {
await fs.access(filePath);
} catch {
const content = DEFAULT_ROLE_INSTRUCTIONS[role] ?? `# ${role.toUpperCase()} Worker Instructions\n\nAdd role-specific instructions here.\n`;
await fs.writeFile(filePath, content, "utf-8");
created = true;
}
}
return created;
@@ -122,7 +108,8 @@ export function createProjectRegisterTool() {
// 1. Check project not already registered (allow re-register if incomplete)
const data = await readProjects(workspaceDir);
const existing = data.projects[groupId];
if (existing && existing.dev?.sessions && Object.keys(existing.dev.sessions).length > 0) {
const existingWorkers = existing?.workers ?? {};
if (existing && Object.values(existingWorkers).some(w => w.sessions && Object.keys(w.sessions).length > 0)) {
throw new Error(
`Project already registered for this group: "${existing.name}". Remove the existing entry first or use a different group.`,
);
@@ -153,6 +140,12 @@ export function createProjectRegisterTool() {
await provider.ensureAllStateLabels();
// 5. Add project to projects.json
// Build workers map from all registered roles
const workers: Record<string, import("../projects.js").WorkerState> = {};
for (const role of getAllRoleIds()) {
workers[role] = emptyWorkerState([...getLevelsForRole(role)]);
}
data.projects[groupId] = {
name,
repo,
@@ -163,9 +156,7 @@ export function createProjectRegisterTool() {
channel,
provider: providerType,
roleExecution,
dev: emptyWorkerState([...getLevelsForRole("dev")]),
qa: emptyWorkerState([...getLevelsForRole("qa")]),
architect: emptyWorkerState([...getLevelsForRole("architect")]),
workers,
};
await writeProjects(workspaceDir, data);