mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-06 16:31:12 +08:00
feat: Add coordinator commands and role specifications for UI design team
- Implemented the 'monitor' command for coordinator role to handle monitoring events, task completion, and pipeline management. - Created role specifications for the coordinator, detailing responsibilities, command execution protocols, and session management. - Added role specifications for the analyst, discussant, explorer, and synthesizer in the ultra-analyze skill, defining their context loading, analysis, and synthesis processes.
This commit is contained in:
@@ -358,7 +358,7 @@ export function run(argv: string[]): void {
|
||||
program
|
||||
.command('team [subcommand] [args...]')
|
||||
.description('Team message bus for Agent Team communication')
|
||||
.option('--team <name>', 'Session ID (e.g., TLS-my-project-2026-02-27)')
|
||||
.option('--session-id <id>', 'Session ID (e.g., TLS-my-project-2026-02-27)')
|
||||
.option('--from <role>', 'Sender role name')
|
||||
.option('--to <role>', 'Recipient role name (default: coordinator)')
|
||||
.option('--type <type>', 'Message type')
|
||||
|
||||
@@ -3,21 +3,21 @@
|
||||
* Delegates to team-msg.ts handler for JSONL-based persistent messaging
|
||||
*
|
||||
* Commands:
|
||||
* ccw team log --team <session-id> --from <role> [--to <role>] [--type <type>] [--summary "..."]
|
||||
* ccw team broadcast --team <session-id> --from <role> [--type <type>] [--summary "..."]
|
||||
* ccw team get_state --team <session-id> [--role <role>]
|
||||
* ccw team read --team <session-id> --id <MSG-NNN>
|
||||
* ccw team list --team <session-id> [--from <role>] [--to <role>] [--type <type>] [--last <n>]
|
||||
* ccw team status --team <session-id>
|
||||
* ccw team delete --team <session-id> --id <MSG-NNN>
|
||||
* ccw team clear --team <session-id>
|
||||
* ccw team log --session-id <id> --from <role> [--to <role>] [--type <type>] [--summary "..."]
|
||||
* ccw team broadcast --session-id <id> --from <role> [--type <type>] [--summary "..."]
|
||||
* ccw team get_state --session-id <id> [--role <role>]
|
||||
* ccw team read --session-id <id> --id <MSG-NNN>
|
||||
* ccw team list --session-id <id> [--from <role>] [--to <role>] [--type <type>] [--last <n>]
|
||||
* ccw team status --session-id <id>
|
||||
* ccw team delete --session-id <id> --id <MSG-NNN>
|
||||
* ccw team clear --session-id <id>
|
||||
*/
|
||||
|
||||
import chalk from 'chalk';
|
||||
import { handler } from '../tools/team-msg.js';
|
||||
|
||||
interface TeamOptions {
|
||||
team?: string;
|
||||
sessionId?: string;
|
||||
from?: string;
|
||||
to?: string;
|
||||
type?: string;
|
||||
@@ -40,15 +40,15 @@ export async function teamCommand(
|
||||
return;
|
||||
}
|
||||
|
||||
if (!options.team) {
|
||||
console.error(chalk.red('Error: --team is required'));
|
||||
if (!options.sessionId) {
|
||||
console.error(chalk.red('Error: --session-id is required'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Build params for handler
|
||||
const params: Record<string, unknown> = {
|
||||
operation: subcommand,
|
||||
team: options.team,
|
||||
session_id: options.sessionId,
|
||||
};
|
||||
|
||||
if (options.from) params.from = options.from;
|
||||
@@ -165,7 +165,7 @@ function printHelp(): void {
|
||||
console.log(chalk.gray(' clear Clear all messages for a team'));
|
||||
console.log();
|
||||
console.log(' Required:');
|
||||
console.log(chalk.gray(' --team <session-id> Session ID (e.g., TLS-my-project-2026-02-27), NOT team name'));
|
||||
console.log(chalk.gray(' --session-id <id> Session ID (e.g., TLS-my-project-2026-02-27), NOT team name'));
|
||||
console.log();
|
||||
console.log(' Log/Broadcast Options:');
|
||||
console.log(chalk.gray(' --from <role> Sender role name (required)'));
|
||||
@@ -190,11 +190,11 @@ function printHelp(): void {
|
||||
console.log(chalk.gray(' --json Output as JSON'));
|
||||
console.log();
|
||||
console.log(' Examples:');
|
||||
console.log(chalk.gray(' ccw team log --team TLS-xxx --from executor --type state_update --data \'{"status":"done"}\''));
|
||||
console.log(chalk.gray(' ccw team broadcast --team TLS-xxx --from coordinator --type shutdown'));
|
||||
console.log(chalk.gray(' ccw team get_state --team TLS-xxx --role executor'));
|
||||
console.log(chalk.gray(' ccw team list --team TLS-xxx --last 5'));
|
||||
console.log(chalk.gray(' ccw team read --team TLS-xxx --id MSG-003'));
|
||||
console.log(chalk.gray(' ccw team status --team TLS-xxx'));
|
||||
console.log(chalk.gray(' ccw team log --session-id TLS-xxx --from executor --type state_update --data \'{"status":"done"}\''));
|
||||
console.log(chalk.gray(' ccw team broadcast --session-id TLS-xxx --from coordinator --type shutdown'));
|
||||
console.log(chalk.gray(' ccw team get_state --session-id TLS-xxx --role executor'));
|
||||
console.log(chalk.gray(' ccw team list --session-id TLS-xxx --last 5'));
|
||||
console.log(chalk.gray(' ccw team read --session-id TLS-xxx --id MSG-003'));
|
||||
console.log(chalk.gray(' ccw team status --session-id TLS-xxx'));
|
||||
console.log();
|
||||
}
|
||||
|
||||
@@ -186,9 +186,12 @@ export interface StatusEntry {
|
||||
const ParamsSchema = z.object({
|
||||
operation: z.enum(['log', 'read', 'list', 'status', 'delete', 'clear', 'broadcast', 'get_state']).describe('Operation to perform'),
|
||||
|
||||
// Accept both 'team' (legacy) and 'team_session_id' (preferred)
|
||||
team: z.string().optional().describe('[deprecated] Use team_session_id instead'),
|
||||
team_session_id: z.string().optional().describe('Session ID that determines message storage path (e.g., TLS-my-project-2026-02-27)'),
|
||||
// Session identifier (primary)
|
||||
session_id: z.string().optional().describe('Session ID that determines message storage path (e.g., TLS-my-project-2026-02-27)'),
|
||||
|
||||
// Legacy params (backward compat)
|
||||
team_session_id: z.string().optional().describe('[deprecated] Use session_id'),
|
||||
team: z.string().optional().describe('[deprecated] Use session_id'),
|
||||
|
||||
// log/broadcast params
|
||||
from: z.string().optional().describe('[log/broadcast/list] Sender role name'),
|
||||
@@ -206,16 +209,15 @@ const ParamsSchema = z.object({
|
||||
// get_state params
|
||||
role: z.string().optional().describe('[get_state] Role name to query. Omit to get all role states'),
|
||||
|
||||
// Legacy backward compat (accepted but ignored — team_session_id replaces this)
|
||||
// Legacy backward compat (accepted but ignored — session_id replaces this)
|
||||
ref: z.string().optional().describe('[deprecated] Use data.ref instead'),
|
||||
session_id: z.string().optional().describe('[deprecated] Use team_session_id instead'),
|
||||
});
|
||||
|
||||
type Params = z.infer<typeof ParamsSchema>;
|
||||
|
||||
/** Resolve team session ID from params, supporting legacy 'team' and new 'team_session_id' */
|
||||
/** Resolve team session ID from params, supporting legacy 'team_session_id' and 'team' */
|
||||
function resolveTeamId(params: Params): string | null {
|
||||
return params.team_session_id || params.team || params.session_id || null;
|
||||
return params.session_id || params.team_session_id || params.team || null;
|
||||
}
|
||||
|
||||
// --- Tool Schema ---
|
||||
@@ -231,15 +233,15 @@ Directory Structure (LEGACY):
|
||||
.workflow/.team-msg/{team-name}/messages.jsonl
|
||||
|
||||
Operations:
|
||||
team_msg(operation="log", team_session_id="TLS-xxx", from="planner", type="plan_ready", data={ref: "plan.json"})
|
||||
team_msg(operation="log", team_session_id="TLS-xxx", from="coordinator", type="state_update", data={pipeline_mode: "full"})
|
||||
team_msg(operation="broadcast", team_session_id="TLS-xxx", from="coordinator", type="shutdown")
|
||||
team_msg(operation="get_state", team_session_id="TLS-xxx", role="researcher")
|
||||
team_msg(operation="read", team_session_id="TLS-xxx", id="MSG-003")
|
||||
team_msg(operation="list", team_session_id="TLS-xxx", from="tester", last=5)
|
||||
team_msg(operation="status", team_session_id="TLS-xxx")
|
||||
team_msg(operation="delete", team_session_id="TLS-xxx", id="MSG-003")
|
||||
team_msg(operation="clear", team_session_id="TLS-xxx")
|
||||
team_msg(operation="log", session_id="TLS-xxx", from="planner", type="plan_ready", data={ref: "plan.json"})
|
||||
team_msg(operation="log", session_id="TLS-xxx", from="coordinator", type="state_update", data={pipeline_mode: "full"})
|
||||
team_msg(operation="broadcast", session_id="TLS-xxx", from="coordinator", type="shutdown")
|
||||
team_msg(operation="get_state", session_id="TLS-xxx", role="researcher")
|
||||
team_msg(operation="read", session_id="TLS-xxx", id="MSG-003")
|
||||
team_msg(operation="list", session_id="TLS-xxx", from="tester", last=5)
|
||||
team_msg(operation="status", session_id="TLS-xxx")
|
||||
team_msg(operation="delete", session_id="TLS-xxx", id="MSG-003")
|
||||
team_msg(operation="clear", session_id="TLS-xxx")
|
||||
|
||||
Defaults: to="coordinator", summary=auto-generated if omitted, type="message"
|
||||
Message types: plan_ready, plan_approved, plan_revision, task_unblocked, impl_complete, impl_progress, test_result, review_result, fix_required, error, shutdown, state_update`,
|
||||
@@ -251,7 +253,7 @@ Message types: plan_ready, plan_approved, plan_revision, task_unblocked, impl_co
|
||||
enum: ['log', 'read', 'list', 'status', 'delete', 'clear', 'broadcast', 'get_state'],
|
||||
description: 'Operation: log | read | list | status | delete | clear | broadcast | get_state',
|
||||
},
|
||||
team_session_id: {
|
||||
session_id: {
|
||||
type: 'string',
|
||||
description: 'Session ID (e.g., TLS-my-project-2026-02-27). Maps to .workflow/.team/{session-id}/.msg/',
|
||||
},
|
||||
@@ -264,9 +266,9 @@ Message types: plan_ready, plan_approved, plan_revision, task_unblocked, impl_co
|
||||
last: { type: 'number', description: '[list] Last N messages (default 20)', minimum: 1, maximum: 100 },
|
||||
role: { type: 'string', description: '[get_state] Role name to query. Omit for all roles' },
|
||||
// Legacy params (backward compat)
|
||||
team: { type: 'string', description: '[deprecated] Use team_session_id' },
|
||||
team_session_id: { type: 'string', description: '[deprecated] Use session_id' },
|
||||
team: { type: 'string', description: '[deprecated] Use session_id' },
|
||||
ref: { type: 'string', description: '[deprecated] Use data.ref instead' },
|
||||
session_id: { type: 'string', description: '[deprecated] Use team_session_id' },
|
||||
},
|
||||
required: ['operation'],
|
||||
},
|
||||
@@ -541,10 +543,10 @@ export async function handler(params: Record<string, unknown>): Promise<ToolResu
|
||||
|
||||
const p = parsed.data;
|
||||
|
||||
// Resolve team ID from team_session_id / team / session_id (backward compat)
|
||||
// Resolve team ID from session_id / team_session_id / team (backward compat)
|
||||
const teamId = resolveTeamId(p);
|
||||
if (!teamId) {
|
||||
return { success: false, error: 'Missing required parameter: team_session_id (or legacy "team")' };
|
||||
return { success: false, error: 'Missing required parameter: session_id (or legacy "team_session_id" / "team")' };
|
||||
}
|
||||
|
||||
switch (p.operation) {
|
||||
|
||||
Reference in New Issue
Block a user