- Rename all package names from companion-* to clanker-* - Update npm scopes from @mariozechner to @harivansh-afk - Rename config directories .companion -> .clanker - Rename environment variables COMPANION_* -> CLANKER_* - Update all documentation, README files, and install scripts - Rename package directories (companion-channels, companion-grind, companion-teams) - Update GitHub URLs to harivansh-afk/clanker-agent - Preserve full git history from companion-cloud monorepo
6.8 KiB
clanker-teams Core Features Implementation Plan
REQUIRED SUB-SKILL: Use the executing-plans skill to implement this plan task-by-task.
Goal: Implement Plan Approval Mode, Broadcast Messaging, and Quality Gate Hooks for the clanker-teams repository to achieve functional parity with Claude Code Agent Teams.
Architecture:
- Plan Approval: Add a
planningstatus toTaskFile.status. Createtask_submit_planandtask_evaluate_plantools. Lead can approve/reject. - Broadcast Messaging: Add a
broadcast_messagetool that iterates through the team roster inconfig.jsonand sends messages to all active members. - Quality Gate Hooks: Introduce a simple hook system that triggers on
task_update(specifically when status becomescompleted). For now, it will look for a.clanker/team-hooks/task_completed.shor similar.
Tech Stack: Node.js, TypeScript, Vitest
Phase 1: Plan Approval Mode
Task 1: Update Task Models and Statuses
Files:
- Modify:
src/utils/models.ts
Step 1: Add planning to TaskFile.status and add plan field
export interface TaskFile {
id: string;
subject: string;
description: string;
activeForm?: string;
status: "pending" | "in_progress" | "planning" | "completed" | "deleted";
blocks: string[];
blockedBy: string[];
owner?: string;
plan?: string;
planFeedback?: string;
metadata?: Record<string, any>;
}
Step 2: Commit
git add src/utils/models.ts
git commit -m "feat: add planning status to TaskFile"
Task 2: Implement Plan Submission Tool
Files:
- Modify:
src/utils/tasks.ts - Test:
src/utils/tasks.test.ts
Step 1: Write test for submitPlan
it("should update task status to planning and save plan", async () => {
const task = await createTask("test-team", "Task 1", "Desc");
const updated = await submitPlan("test-team", task.id, "My Plan");
expect(updated.status).toBe("planning");
expect(updated.plan).toBe("My Plan");
});
Step 2: Implement submitPlan in tasks.ts
export async function submitPlan(
teamName: string,
taskId: string,
plan: string,
): Promise<TaskFile> {
return await updateTask(teamName, taskId, { status: "planning", plan });
}
Step 3: Run tests
npx vitest run src/utils/tasks.test.ts
Step 4: Commit
git add src/utils/tasks.ts src/utils/tasks.test.ts
git commit -m "feat: implement submitPlan tool"
Task 3: Implement Plan Evaluation Tool (Approve/Reject)
Files:
- Modify:
src/utils/tasks.ts - Test:
src/utils/tasks.test.ts
Step 1: Write test for evaluatePlan
it("should set status to in_progress on approval", async () => {
const task = await createTask("test-team", "Task 1", "Desc");
await submitPlan("test-team", task.id, "My Plan");
const approved = await evaluatePlan("test-team", task.id, "approve");
expect(approved.status).toBe("in_progress");
});
it("should set status back to in_progress or pending on reject with feedback", async () => {
const task = await createTask("test-team", "Task 1", "Desc");
await submitPlan("test-team", task.id, "My Plan");
const rejected = await evaluatePlan(
"test-team",
task.id,
"reject",
"More detail needed",
);
expect(rejected.status).toBe("in_progress"); // Teammate stays in implementation but needs to revise
expect(rejected.planFeedback).toBe("More detail needed");
});
Step 2: Implement evaluatePlan in tasks.ts
export async function evaluatePlan(
teamName: string,
taskId: string,
action: "approve" | "reject",
feedback?: string,
): Promise<TaskFile> {
const status = action === "approve" ? "in_progress" : "in_progress"; // Simplified for now
return await updateTask(teamName, taskId, { status, planFeedback: feedback });
}
Step 3: Run tests and commit
npx vitest run src/utils/tasks.test.ts
git add src/utils/tasks.ts
git commit -m "feat: implement evaluatePlan tool"
Phase 2: Broadcast Messaging
Task 4: Implement Broadcast Messaging Tool
Files:
- Modify:
src/utils/messaging.ts - Test:
src/utils/messaging.test.ts
Step 1: Write test for broadcastMessage
it("should send message to all team members except sender", async () => {
// setup team with lead, m1, m2
await broadcastMessage(
"test-team",
"team-lead",
"Hello everyone!",
"Broadcast",
);
// verify m1 and m2 inboxes have the message
});
Step 2: Implement broadcastMessage
import { readConfig } from "./teams";
export async function broadcastMessage(
teamName: string,
fromName: string,
text: string,
summary: string,
color?: string,
) {
const config = await readConfig(teamName);
for (const member of config.members) {
if (member.name !== fromName) {
await sendPlainMessage(
teamName,
fromName,
member.name,
text,
summary,
color,
);
}
}
}
Step 3: Run tests and commit
npx vitest run src/utils/messaging.test.ts
git add src/utils/messaging.ts
git commit -m "feat: implement broadcastMessage tool"
Phase 3: Quality Gate Hooks
Task 5: Implement Simple Hook System for Task Completion
Files:
- Modify:
src/utils/tasks.ts - Create:
src/utils/hooks.ts - Test:
src/utils/hooks.test.ts
Step 1: Create hooks.ts to run local hook scripts
import { execSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
export function runHook(
teamName: string,
hookName: string,
payload: any,
): boolean {
const hookPath = path.join(
process.cwd(),
".clanker",
"team-hooks",
`${hookName}.sh`,
);
if (!fs.existsSync(hookPath)) return true; // No hook, success
try {
const payloadStr = JSON.stringify(payload);
execSync(`sh ${hookPath} '${payloadStr}'`, { stdio: "inherit" });
return true;
} catch (e) {
console.error(`Hook ${hookName} failed`, e);
return false;
}
}
Step 2: Modify updateTask in tasks.ts to trigger hook
// in updateTask, after saving:
if (updates.status === "completed") {
const success = runHook(teamName, "task_completed", updated);
if (!success) {
// Optionally revert or mark as failed
}
}
Step 3: Write test and verify
npx vitest run src/utils/hooks.test.ts
git add src/utils/tasks.ts src/utils/hooks.ts
git commit -m "feat: implement basic hook system for task completion"
Phase 4: Expose New Tools to Agents
Task 6: Expose Tools in extensions/index.ts
Files:
- Modify:
extensions/index.ts
Step 1: Add broadcast_message, task_submit_plan, and task_evaluate_plan tools
Step 2: Update spawn_teammate to include plan_mode_required
Step 3: Update task_update to allow planning status